- Use allowlist for issue view (numeric issue numbers only)
- Enforce zero positional args for issue list / label list
- Pin GH_HOST and GH_REPO explicitly to avoid ambient state
- Add descriptive error messages with usage examples
The native binary (install.sh) requires posix_getdents which is only
available in Alpine edge (musl 1.2.5-r21+), not in any stable Alpine
release. Detect musl upfront via ldd and skip straight to npm install,
avoiding 15+ seconds of wasted retries on deterministic failures.
On glibc systems the native install path is unchanged with npm as a
fallback if it fails.
Use generic email for mirror commits (noreply@forgejo-actions)
to avoid exposing internal domain on Codeberg.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Push clean copy (without .forgejo/ and prds/) to Codeberg on
each push to main. Uses SSH deploy key for authentication.
Also bumps kcl-ci to v1.40.0.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a mirror-branch workflow that copies main to a `codeberg` branch
excluding .forgejo/ and prds/ directories. Configure Forgejo push mirror
on this branch to sync a clean copy to Codeberg.
Also picks up updated allowed_tools from kcl-ci (adds bunx/npx patterns).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace git.wxs.ro with forgejo.example.com in tests and docs.
Add public repo guidelines to CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Self-trigger guard now only blocks comment/review events, not all
events. Updated CLAUDE.md, docs/forgejo.md API table, and known
limitations section.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The self-trigger guard blocked the claude bot on all events. Loop risk
only exists for comment/review events (tag mode). PR, workflow_dispatch,
and schedule events are safe — refined the guard to only block on
issue_comment, issues, pull_request_review, and
pull_request_review_comment events.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The actor guard (github.actor != 'claude') was skipping test-agent-mode
on upstream-sync PRs. Refined the condition to only skip on non-PR events
(where tag mode loop risk exists) while allowing PR events through.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Forgejo's /issues?labels= filter requires integer IDs, not label names.
The workflow was searching by name (returning 0 results) then creating
a new issue every run.
Fix: look up label first, only create if missing, then use the ID for
both issue search and issue creation. This prevents both duplicate
issues and duplicate labels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add command execution rules to prompt (no env prefixes, no 2>&1)
- Document pre-existing test failures so Claude doesn't waste turns
- Add Bash(echo:*) and Bash(cat:*) to allowed_tools
- Delete stale remote branches before creating new ones
Addresses 24 permission denials in last run where Claude spent
~15 of 47 turns on blocked commands.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Forgejo's create-issue API expects `labels` as `[int64]` (label IDs),
not `[{"name": "..."}]` like GitHub. The previous format caused a JSON
unmarshal error, silently returning null instead of creating the issue.
Changes:
- Split label step to create-if-missing then look up the ID
- Pass label ID as integer to issue creation: `labels: [169]`
- Add error handling: log API response if issue creation returns null
- Also cleaned up another duplicate upstream-sync label
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>