Claude was resolving merge conflicts but stopping before running tests,
committing, pushing, or creating the PR. Add explicit instruction that
the job is not done until the branch is pushed and PR is created.
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>
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>
Add idempotency to the merge-upstream job:
1. Check for existing open PR from chore/upstream-sync-* branch
2. If PR exists and branch is up to date with upstream → skip
3. If PR exists but upstream has new commits → checkout existing
branch, merge new upstream commits, run Claude to review/test
4. If no PR exists → create new branch (existing behavior)
Also update Claude's prompt to handle both create and update PR
cases, so it knows to push to the existing PR branch instead of
creating a duplicate.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three fixes in the upstream-sync workflow:
1. Replace github.token with CLAUDE_BOT_TOKEN in the check-upstream
job. The default runner token on Forgejo doesn't have issue-write
permissions, so issues were silently failing to create.
2. Output the tracking issue number from check-upstream and pass it
to the merge-upstream job. Claude's prompt now includes the issue
reference and instructs it to add "Closes #N" in the PR body.
3. Capture the issue number from both create and update paths so
the merge job always has it available.
Also cleaned up 6 duplicate upstream-sync labels created by previous
runs that used the unprivileged token.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two fixes for the upstream-sync Claude workflow:
1. Add Bun install + bun install (deps) steps before Claude runs,
so tsc, prettier, and other devDependencies are available.
Previously node_modules/.bin/ didn't exist and typecheck/format
commands failed with "command not found".
2. Add Bash(bunx:*), Bash(npx:*), Bash(./node_modules/.bin/*:*)
to allowed_tools. The existing Bash(bun:*) only covers the `bun`
binary, not `bunx` which is a separate binary.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Picks up the allowed_tools fix from kcl-ci — claude.yml tag-mode
workflow now uses Bash(git:*),Bash(bun:*),Bash(curl:*) sub-patterns
instead of bare Bash, enabling auto-approval in CI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bare `Bash` in allowed_tools makes the tool available but individual
commands still require interactive approval. In CI there's nobody to
approve, so git push, bun test, and curl all fail with
"Error: This command requires approval".
Changes:
- Switch to Bash(git:*), Bash(bun:*), Bash(curl:*) sub-patterns
- Add GITHUB_SERVER_URL env var so Claude doesn't need `export`
- Update prompt to reflect env var is pre-set
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add show_full_output: true to both claude.yml and upstream-sync.yml
- Add allowed_tools (Bash, Read, Write, etc.) to upstream-sync merge step
- Upgrade kcl-ci to v1.37.0 (defaults show_full_output and full tools)
Fixes: Claude was burning 38 turns hitting sandbox permission denials
trying to run bun test and git push during upstream sync.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New merge-upstream job: creates branch, merges upstream, runs Claude
agent mode to review, resolve conflicts, run tests, and create a PR
- Dynamic fork impact analysis: computes overlap between fork-modified
files and upstream-changed files to assess conflict risk
- Claude reviews ALL upstream changes for fork compatibility (renamed
imports, changed APIs, GitHub-only assumptions) not just conflicts
- Maintainability principle: minimize fork divergence, prefer adapters
- Remove ANTHROPIC_API_KEY (using OAuth token only)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add .forgejo/kcl-ci/ with kcl.mod, main.k, Taskfile.yaml
- claude.yml: use claude.k module (fixes #comment YAML validation error,
removes duplicate pull_request_comment trigger)
- ci.yml: add paths-ignore for kcl-ci paths, named jobs for check constants
- test-action.yml: regenerated from KCL (functionally identical)
- upstream-sync.yml: regenerated from KCL (functionally identical)
- kcl-ci-build.yml: new auto-regeneration workflow (waits for CI checks)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>