diff --git a/.agents/skills/checkpoint/SKILL.md b/.agents/skills/checkpoint/SKILL.md new file mode 100644 index 0000000..cab107f --- /dev/null +++ b/.agents/skills/checkpoint/SKILL.md @@ -0,0 +1,93 @@ +--- +name: checkpoint +description: Code Cannon: Commit and push WIP without review or merge +--- + +> **Codex CLI:** This skill is triggered by description matching. State any arguments in your message. Sub-agent spawning is not supported — perform any review steps inline. + +--- + +## What `/checkpoint` does + +`/checkpoint` is a lightweight save point — commit and push work-in-progress to the remote without triggering type-checks, reviews, PR creation, or merge. Use it to persist progress during long coding sessions or before context-switching. + +--- + +## Step 1 — Verify branch + +```bash +git branch --show-current +``` + +Protected branches (not a feature branch): +- `main` +- `dev` + +If the current branch matches any of the above, **abort immediately** and say: + +> "You are on ``. `/checkpoint` must be run from a feature branch." + +--- + +## Step 2 — Check for changes + +```bash +git status --porcelain +``` + +If the output is empty (no staged, unstaged, or untracked changes), say: + +> "Nothing to checkpoint — working tree is clean." + +Stop. Do not create an empty commit. + +--- + +## Step 3 — Stage and commit + +```bash +git add -A +git commit -m "WIP: " +``` + +**Commit message rules:** +- Always prefix with `WIP: ` so these commits are visually distinct in `git log`. +- If `$ARGUMENTS` is provided, use it as `` (e.g. `WIP: add auth middleware`). +- If `$ARGUMENTS` is empty, auto-generate from the diff summary (e.g. `WIP: update auth.ts, add login tests`). Keep it under 72 characters. +- Do not commit `.env` files, secrets, or build artifacts. If `git status` shows such files, add them to `.gitignore` or exclude them from staging before committing. + +--- + +## Step 4 — Push + +```bash +git push -u origin HEAD +``` + +If the push fails because the remote branch does not exist yet, the `-u` flag handles creation. If it fails for another reason, report the error and stop. + +--- + +## Step 5 — Report + +Count the files in the commit: + +```bash +git diff --stat HEAD~1 +``` + +Say: + +> "Checkpoint saved. N file(s) committed and pushed to ``. Run `/submit-for-review` when ready to open a PR." + +--- + +## Hard rules + +- Never create a PR. +- Never trigger a review. +- Never merge. +- Never apply labels or modify issues. +- Never run `make check` — checkpoints are not quality gates. +- Do not prompt for confirmation — `/checkpoint` is a quick save, not a ceremony. + diff --git a/.agents/skills/deploy/SKILL.md b/.agents/skills/deploy/SKILL.md index 7d00d24..5ae2bbb 100644 --- a/.agents/skills/deploy/SKILL.md +++ b/.agents/skills/deploy/SKILL.md @@ -166,7 +166,15 @@ Wait for the user to type "release" or an explicit confirmation. Any other respo ## Step 6 — Create PR: `dev` → `main` -Use your file-writing tool (not Bash) to create `/tmp/cc_release_pr_body.md`: +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (not Bash) to create `/release_pr_body.md`: ```markdown Release vX.Y.Z @@ -184,7 +192,7 @@ Then create the PR (do NOT use `--body`, `--body-file -`, or heredocs): ```bash gh pr create --base main --head dev \ --title "Release vX.Y.Z" \ - --body-file /tmp/cc_release_pr_body.md + --body-file /release_pr_body.md ``` Note the PR number from the output. @@ -215,7 +223,7 @@ git describe --abbrev=0 ^ 2>/dev/null If no previous tag exists, omit the "Full changelog" line. -Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`: +Use your file-writing tool (not Bash) to create `/release_notes.md` (same temp directory from Step 6): ```markdown ## Changes @@ -231,7 +239,7 @@ Then create the release (do NOT use `--notes`, `--notes-file -`, or heredocs): ```bash gh release create \ --title "" \ - --notes-file /tmp/cc_release_notes.md + --notes-file /release_notes.md ``` Format each PR line as `- # (PR #)`. If a PR had no linked issue, omit the `#` prefix and use just the PR title. @@ -245,4 +253,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.agents/skills/start/SKILL.md b/.agents/skills/start/SKILL.md index 837fb80..27c02ed 100644 --- a/.agents/skills/start/SKILL.md +++ b/.agents/skills/start/SKILL.md @@ -68,6 +68,35 @@ After parsing flags, determine the active milestone in this order: --- +## Pre-check: Existing feature branch + +Before entering Case A or Case B, check the current branch: + +```bash +git branch --show-current +``` + +If already on a `feature/*` branch and `$ARGUMENTS` is **not** a number (i.e. this is new work, not a resume): + +Say: + +> **"You're already on `feature/`. Would you like to create a GitHub issue linked to this branch and start coding? Or switch to the base branch first? (yes to continue here / no to abort)"** + +Stop. Wait for the user to respond. + +- **Yes** → proceed to **Case A**, but **skip Step 4** (branch creation) entirely. The current branch is used as-is. In Step 3, after creating the issue, link it to the existing branch by running: + ```bash + gh issue develop --base --name + ``` + This links the issue to the branch in GitHub without creating or checking out a new branch. If `gh issue develop` fails because the branch already exists on the remote, that is fine — the link may already be established. Continue to Step 5. +- **No / abort** → stop. Tell the user to switch to the base branch and run `/start` again. + +If already on a `feature/*` branch and `$ARGUMENTS` **is** a number → proceed to **Case B** normally (it handles branch checkout itself). + +If on any other branch → proceed to Case A or Case B as determined by the `$ARGUMENTS` check above. + +--- + ## Case A: New work (text description) ### Step 1 — Investigate @@ -95,7 +124,15 @@ The friendly text question is required regardless of harness mode. If your harne Create the issue in two steps — **this exact sequence is mandatory**: -**Step 3a — Write the body to a temp file.** Use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_issue_body.md` with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs, `cat`, or `echo`. The file-writing tool bypasses shell parsing entirely. +**Step 3a — Create a temp directory and write the body file.** Run: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/issue_body.md` with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs, `cat`, or `echo`. The file-writing tool bypasses shell parsing entirely. **Step 3b — Run `gh issue create`** with `--body-file` pointing to the temp file: @@ -105,7 +142,7 @@ gh issue create \ --assignee @me \ [--label ""] \ [--milestone ""] \ - --body-file /tmp/cc_issue_body.md + --body-file /issue_body.md ``` > **IMPORTANT — never pass body content inline in the `gh` command.** Do not use `--body`, `--body-file -`, heredocs (`<` — is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex. @@ -153,7 +190,7 @@ Show the user: `Created issue #: ` Then immediately post agent implementation notes as a comment. -Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/issue_comment.md` (same temp directory from Step 3a): ```markdown ## Agent Implementation Notes @@ -162,7 +199,7 @@ Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`: Then post it (do NOT use `--body` or heredocs — same rule as Step 3): ```bash -gh issue comment <number> --body-file /tmp/cc_issue_comment.md +gh issue comment <number> --body-file <tmpdir>/issue_comment.md ``` ### Step 4 — Create feature branch @@ -271,9 +308,9 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - Do not write or edit any source file before `git branch --show-current` shows `feature/*`. - Do not use `make branch` — always use `gh issue develop` so the branch is linked to the issue in GitHub. - Do not commit during `/start` — commits happen in `/submit-for-review`. -- If already on a feature branch when `/start` is invoked, warn the user before creating another branch. +- If already on a feature branch when `/start` is invoked with new work (Case A), prompt the user to either continue on the current branch (skipping branch creation) or abort. See **Pre-check: Existing feature branch** above. - `gh issue create` must use `--title` and `--body` flags. Never open an interactive editor. - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit <number> --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. -<!-- generated by CodeCannon/sync.sh | skill: start | adapter: codex | hash: 7ba07088 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: start | adapter: codex | hash: a1701c1d | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.agents/skills/submit-for-review/SKILL.md b/.agents/skills/submit-for-review/SKILL.md index d711c85..5cab5f5 100644 --- a/.agents/skills/submit-for-review/SKILL.md +++ b/.agents/skills/submit-for-review/SKILL.md @@ -111,7 +111,15 @@ Use `Issue #<number>` as the issue reference — the issue stays open until `/de Then create the PR in two steps — **this exact sequence is mandatory**: -First, use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_pr_body.md`. Do NOT use Bash/shell to write this file. +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `<tmpdir>/pr_body.md`. Do NOT use Bash/shell to write this file. ```markdown <description of what changed and why> @@ -122,7 +130,7 @@ First, use your file-writing tool (Write in Claude Code, equivalent in other age Then create the PR (do NOT use `--body`, `--body-file -`, heredocs, or `$(cat ...)`): ``` -gh pr create --base <target-branch> --title "<title>" --body-file /tmp/cc_pr_body.md +gh pr create --base <target-branch> --title "<title>" --body-file <tmpdir>/pr_body.md ``` > **IMPORTANT — never pass body content inline in the `gh` command.** Do not use `--body`, `--body-file -`, heredocs (`<<EOF` or `<<'EOF'`), or `$(cat ...)`. All of these embed markdown in a Bash command, which triggers permission prompts that cannot be permanently allowed (the shell parser flags `#` headings, quoted delimiters, and substitutions). The two-step pattern above — file-writing tool then `--body-file <path>` — is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex. @@ -226,7 +234,7 @@ If no linked issue was found, skip silently. Read the issue body (from Step 3 or via `gh issue view <number>`) to recall the original problem description. Then post a comment summarizing what was done: -Use your file-writing tool (not Bash) to create `/tmp/cc_resolution_comment.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/resolution_comment.md` (same temp directory from Step 6): ```markdown ## Resolution @@ -239,7 +247,7 @@ See #<PR-number> for full technical details. Then post it (do NOT use `--body` or heredocs): ``` -gh issue comment <number> --body-file /tmp/cc_resolution_comment.md +gh issue comment <number> --body-file <tmpdir>/resolution_comment.md ``` **Resolution writing rules:** @@ -275,7 +283,7 @@ Accept: comma-separated numbers, `all`, or `none`/`skip`/empty. If the input is **Create the selected issues.** For each selected finding, run `gh issue create` with explicit flags: -Use your file-writing tool (not Bash) to create `/tmp/cc_followup_body.md` for each finding: +Use your file-writing tool (not Bash) to create `<tmpdir>/followup_body.md` for each finding (same temp directory from Step 6): ```markdown Follow-up from PR #<merged-pr-number> — auto-proposed from the code review. @@ -291,7 +299,7 @@ Then create the issue (do NOT use `--body` or heredocs): gh issue create \ --title "<finding text with [WARNING]/[NOTE]/[CRITICAL] prefix stripped, trimmed to a standalone sentence>" \ [--label "<pool-selected labels>"] \ - --body-file /tmp/cc_followup_body.md + --body-file <tmpdir>/followup_body.md ``` Label resolution for each follow-up issue: use the pool-based selection tier from `/start` — pick 1–3 labels from `bug, documentation, enhancement, chore` that genuinely fit the finding. If `bug, documentation, enhancement, chore` is empty or no pool label fits, omit `--label`. Do not attempt per-invocation flag resolution (there is no flag here) and never create new labels from follow-ups, even if label creation is enabled for the project. @@ -317,4 +325,4 @@ If a single `gh issue create` call fails, report the failure for that finding an - `/submit-for-review` merges only to `dev` — never directly to `main`. - If `make merge` fails for any reason, report it and stop — do not attempt workarounds. - The follow-up issue offer in Step 9 runs only after a successful merge and only when the review produced non-blocking findings. Never prompt the user for follow-ups when the review blocked the merge — those findings should be fixed, not ticketed. -<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: codex | hash: d09ab40d | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: codex | hash: 7da4e9fb | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.claude/commands/checkpoint.md b/.claude/commands/checkpoint.md new file mode 100644 index 0000000..c7e8473 --- /dev/null +++ b/.claude/commands/checkpoint.md @@ -0,0 +1,88 @@ +Code Cannon: Commit and push WIP without review or merge + +--- + +## What `/checkpoint` does + +`/checkpoint` is a lightweight save point — commit and push work-in-progress to the remote without triggering type-checks, reviews, PR creation, or merge. Use it to persist progress during long coding sessions or before context-switching. + +--- + +## Step 1 — Verify branch + +```bash +git branch --show-current +``` + +Protected branches (not a feature branch): +- `main` +- `dev` + +If the current branch matches any of the above, **abort immediately** and say: + +> "You are on `<branch>`. `/checkpoint` must be run from a feature branch." + +--- + +## Step 2 — Check for changes + +```bash +git status --porcelain +``` + +If the output is empty (no staged, unstaged, or untracked changes), say: + +> "Nothing to checkpoint — working tree is clean." + +Stop. Do not create an empty commit. + +--- + +## Step 3 — Stage and commit + +```bash +git add -A +git commit -m "WIP: <message>" +``` + +**Commit message rules:** +- Always prefix with `WIP: ` so these commits are visually distinct in `git log`. +- If `$ARGUMENTS` is provided, use it as `<message>` (e.g. `WIP: add auth middleware`). +- If `$ARGUMENTS` is empty, auto-generate from the diff summary (e.g. `WIP: update auth.ts, add login tests`). Keep it under 72 characters. +- Do not commit `.env` files, secrets, or build artifacts. If `git status` shows such files, add them to `.gitignore` or exclude them from staging before committing. + +--- + +## Step 4 — Push + +```bash +git push -u origin HEAD +``` + +If the push fails because the remote branch does not exist yet, the `-u` flag handles creation. If it fails for another reason, report the error and stop. + +--- + +## Step 5 — Report + +Count the files in the commit: + +```bash +git diff --stat HEAD~1 +``` + +Say: + +> "Checkpoint saved. N file(s) committed and pushed to `<branch>`. Run `/submit-for-review` when ready to open a PR." + +--- + +## Hard rules + +- Never create a PR. +- Never trigger a review. +- Never merge. +- Never apply labels or modify issues. +- Never run `make check` — checkpoints are not quality gates. +- Do not prompt for confirmation — `/checkpoint` is a quick save, not a ceremony. +<!-- generated by CodeCannon/sync.sh | skill: checkpoint | adapter: claude | hash: cc7e9e00 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.claude/commands/deploy.md b/.claude/commands/deploy.md index 962a484..9a5a2cb 100644 --- a/.claude/commands/deploy.md +++ b/.claude/commands/deploy.md @@ -161,7 +161,15 @@ Wait for the user to type "release" or an explicit confirmation. Any other respo ## Step 6 — Create PR: `dev` → `main` -Use your file-writing tool (not Bash) to create `/tmp/cc_release_pr_body.md`: +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (not Bash) to create `<tmpdir>/release_pr_body.md`: ```markdown Release vX.Y.Z @@ -179,7 +187,7 @@ Then create the PR (do NOT use `--body`, `--body-file -`, or heredocs): ```bash gh pr create --base main --head dev \ --title "Release vX.Y.Z" \ - --body-file /tmp/cc_release_pr_body.md + --body-file <tmpdir>/release_pr_body.md ``` Note the PR number from the output. @@ -210,7 +218,7 @@ git describe --abbrev=0 <version-tag>^ 2>/dev/null If no previous tag exists, omit the "Full changelog" line. -Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/release_notes.md` (same temp directory from Step 6): ```markdown ## Changes @@ -226,7 +234,7 @@ Then create the release (do NOT use `--notes`, `--notes-file -`, or heredocs): ```bash gh release create <version-tag> \ --title "<version-tag>" \ - --notes-file /tmp/cc_release_notes.md + --notes-file <tmpdir>/release_notes.md ``` Format each PR line as `- #<linked-issue> — <PR title> (PR #<N>)`. If a PR had no linked issue, omit the `#<issue>` prefix and use just the PR title. @@ -240,4 +248,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at `<url>`. Run `make deploy-prod` to ship to production." -<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: claude | hash: 88439028 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: claude | hash: 1fa58dba | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.claude/commands/start.md b/.claude/commands/start.md index 2458d44..b769146 100644 --- a/.claude/commands/start.md +++ b/.claude/commands/start.md @@ -63,6 +63,35 @@ After parsing flags, determine the active milestone in this order: --- +## Pre-check: Existing feature branch + +Before entering Case A or Case B, check the current branch: + +```bash +git branch --show-current +``` + +If already on a `feature/*` branch and `$ARGUMENTS` is **not** a number (i.e. this is new work, not a resume): + +Say: + +> **"You're already on `feature/<name>`. Would you like to create a GitHub issue linked to this branch and start coding? Or switch to the base branch first? (yes to continue here / no to abort)"** + +Stop. Wait for the user to respond. + +- **Yes** → proceed to **Case A**, but **skip Step 4** (branch creation) entirely. The current branch is used as-is. In Step 3, after creating the issue, link it to the existing branch by running: + ```bash + gh issue develop <number> --base <base-branch> --name <current-branch-name> + ``` + This links the issue to the branch in GitHub without creating or checking out a new branch. If `gh issue develop` fails because the branch already exists on the remote, that is fine — the link may already be established. Continue to Step 5. +- **No / abort** → stop. Tell the user to switch to the base branch and run `/start` again. + +If already on a `feature/*` branch and `$ARGUMENTS` **is** a number → proceed to **Case B** normally (it handles branch checkout itself). + +If on any other branch → proceed to Case A or Case B as determined by the `$ARGUMENTS` check above. + +--- + ## Case A: New work (text description) ### Step 1 — Investigate @@ -90,7 +119,15 @@ The friendly text question is required regardless of harness mode. If your harne Create the issue in two steps — **this exact sequence is mandatory**: -**Step 3a — Write the body to a temp file.** Use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_issue_body.md` with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs, `cat`, or `echo`. The file-writing tool bypasses shell parsing entirely. +**Step 3a — Create a temp directory and write the body file.** Run: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `<tmpdir>/issue_body.md` with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs, `cat`, or `echo`. The file-writing tool bypasses shell parsing entirely. **Step 3b — Run `gh issue create`** with `--body-file` pointing to the temp file: @@ -100,7 +137,7 @@ gh issue create \ --assignee @me \ [--label "<resolved labels>"] \ [--milestone "<resolved milestone>"] \ - --body-file /tmp/cc_issue_body.md + --body-file <tmpdir>/issue_body.md ``` > **IMPORTANT — never pass body content inline in the `gh` command.** Do not use `--body`, `--body-file -`, heredocs (`<<EOF` or `<<'EOF'`), or `$(cat ...)`. All of these embed markdown in a Bash command, which triggers permission prompts that cannot be permanently allowed (the shell parser flags `#` headings, quoted delimiters, and substitutions). The two-step pattern above — file-writing tool then `--body-file <path>` — is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex. @@ -148,7 +185,7 @@ Show the user: `Created issue #<number>: <title>` Then immediately post agent implementation notes as a comment. -Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/issue_comment.md` (same temp directory from Step 3a): ```markdown ## Agent Implementation Notes @@ -157,7 +194,7 @@ Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`: Then post it (do NOT use `--body` or heredocs — same rule as Step 3): ```bash -gh issue comment <number> --body-file /tmp/cc_issue_comment.md +gh issue comment <number> --body-file <tmpdir>/issue_comment.md ``` ### Step 4 — Create feature branch @@ -266,9 +303,9 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - Do not write or edit any source file before `git branch --show-current` shows `feature/*`. - Do not use `make branch` — always use `gh issue develop` so the branch is linked to the issue in GitHub. - Do not commit during `/start` — commits happen in `/submit-for-review`. -- If already on a feature branch when `/start` is invoked, warn the user before creating another branch. +- If already on a feature branch when `/start` is invoked with new work (Case A), prompt the user to either continue on the current branch (skipping branch creation) or abort. See **Pre-check: Existing feature branch** above. - `gh issue create` must use `--title` and `--body` flags. Never open an interactive editor. - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit <number> --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. -<!-- generated by CodeCannon/sync.sh | skill: start | adapter: claude | hash: d1144b46 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: start | adapter: claude | hash: 3761be9e | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.claude/commands/submit-for-review.md b/.claude/commands/submit-for-review.md index 98a6d71..6ae24c6 100644 --- a/.claude/commands/submit-for-review.md +++ b/.claude/commands/submit-for-review.md @@ -106,7 +106,15 @@ Use `Issue #<number>` as the issue reference — the issue stays open until `/de Then create the PR in two steps — **this exact sequence is mandatory**: -First, use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_pr_body.md`. Do NOT use Bash/shell to write this file. +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `<tmpdir>/pr_body.md`. Do NOT use Bash/shell to write this file. ```markdown <description of what changed and why> @@ -117,7 +125,7 @@ First, use your file-writing tool (Write in Claude Code, equivalent in other age Then create the PR (do NOT use `--body`, `--body-file -`, heredocs, or `$(cat ...)`): ``` -gh pr create --base <target-branch> --title "<title>" --body-file /tmp/cc_pr_body.md +gh pr create --base <target-branch> --title "<title>" --body-file <tmpdir>/pr_body.md ``` > **IMPORTANT — never pass body content inline in the `gh` command.** Do not use `--body`, `--body-file -`, heredocs (`<<EOF` or `<<'EOF'`), or `$(cat ...)`. All of these embed markdown in a Bash command, which triggers permission prompts that cannot be permanently allowed (the shell parser flags `#` headings, quoted delimiters, and substitutions). The two-step pattern above — file-writing tool then `--body-file <path>` — is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex. @@ -221,7 +229,7 @@ If no linked issue was found, skip silently. Read the issue body (from Step 3 or via `gh issue view <number>`) to recall the original problem description. Then post a comment summarizing what was done: -Use your file-writing tool (not Bash) to create `/tmp/cc_resolution_comment.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/resolution_comment.md` (same temp directory from Step 6): ```markdown ## Resolution @@ -234,7 +242,7 @@ See #<PR-number> for full technical details. Then post it (do NOT use `--body` or heredocs): ``` -gh issue comment <number> --body-file /tmp/cc_resolution_comment.md +gh issue comment <number> --body-file <tmpdir>/resolution_comment.md ``` **Resolution writing rules:** @@ -270,7 +278,7 @@ Accept: comma-separated numbers, `all`, or `none`/`skip`/empty. If the input is **Create the selected issues.** For each selected finding, run `gh issue create` with explicit flags: -Use your file-writing tool (not Bash) to create `/tmp/cc_followup_body.md` for each finding: +Use your file-writing tool (not Bash) to create `<tmpdir>/followup_body.md` for each finding (same temp directory from Step 6): ```markdown Follow-up from PR #<merged-pr-number> — auto-proposed from the code review. @@ -286,7 +294,7 @@ Then create the issue (do NOT use `--body` or heredocs): gh issue create \ --title "<finding text with [WARNING]/[NOTE]/[CRITICAL] prefix stripped, trimmed to a standalone sentence>" \ [--label "<pool-selected labels>"] \ - --body-file /tmp/cc_followup_body.md + --body-file <tmpdir>/followup_body.md ``` Label resolution for each follow-up issue: use the pool-based selection tier from `/start` — pick 1–3 labels from `bug, documentation, enhancement, chore` that genuinely fit the finding. If `bug, documentation, enhancement, chore` is empty or no pool label fits, omit `--label`. Do not attempt per-invocation flag resolution (there is no flag here) and never create new labels from follow-ups, even if label creation is enabled for the project. @@ -312,4 +320,4 @@ If a single `gh issue create` call fails, report the failure for that finding an - `/submit-for-review` merges only to `dev` — never directly to `main`. - If `make merge` fails for any reason, report it and stop — do not attempt workarounds. - The follow-up issue offer in Step 9 runs only after a successful merge and only when the review produced non-blocking findings. Never prompt the user for follow-ups when the review blocked the merge — those findings should be fixed, not ticketed. -<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: claude | hash: 7cc1a5b2 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: claude | hash: f9e7a62e | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.cursor/rules/checkpoint.mdc b/.cursor/rules/checkpoint.mdc new file mode 100644 index 0000000..5ec2e26 --- /dev/null +++ b/.cursor/rules/checkpoint.mdc @@ -0,0 +1,94 @@ +--- +description: Code Cannon: Commit and push WIP without review or merge +globs: +alwaysApply: false +--- + +> **Cursor:** Trigger this skill via `@checkpoint` in Agent mode. State any arguments in your message. Sub-agent spawning is not supported — the automated review step in `/submit-for-review` must be done manually using the review-agent prompt. + +--- + +## What `/checkpoint` does + +`/checkpoint` is a lightweight save point — commit and push work-in-progress to the remote without triggering type-checks, reviews, PR creation, or merge. Use it to persist progress during long coding sessions or before context-switching. + +--- + +## Step 1 — Verify branch + +```bash +git branch --show-current +``` + +Protected branches (not a feature branch): +- `main` +- `dev` + +If the current branch matches any of the above, **abort immediately** and say: + +> "You are on `<branch>`. `/checkpoint` must be run from a feature branch." + +--- + +## Step 2 — Check for changes + +```bash +git status --porcelain +``` + +If the output is empty (no staged, unstaged, or untracked changes), say: + +> "Nothing to checkpoint — working tree is clean." + +Stop. Do not create an empty commit. + +--- + +## Step 3 — Stage and commit + +```bash +git add -A +git commit -m "WIP: <message>" +``` + +**Commit message rules:** +- Always prefix with `WIP: ` so these commits are visually distinct in `git log`. +- If `$ARGUMENTS` is provided, use it as `<message>` (e.g. `WIP: add auth middleware`). +- If `$ARGUMENTS` is empty, auto-generate from the diff summary (e.g. `WIP: update auth.ts, add login tests`). Keep it under 72 characters. +- Do not commit `.env` files, secrets, or build artifacts. If `git status` shows such files, add them to `.gitignore` or exclude them from staging before committing. + +--- + +## Step 4 — Push + +```bash +git push -u origin HEAD +``` + +If the push fails because the remote branch does not exist yet, the `-u` flag handles creation. If it fails for another reason, report the error and stop. + +--- + +## Step 5 — Report + +Count the files in the commit: + +```bash +git diff --stat HEAD~1 +``` + +Say: + +> "Checkpoint saved. N file(s) committed and pushed to `<branch>`. Run `/submit-for-review` when ready to open a PR." + +--- + +## Hard rules + +- Never create a PR. +- Never trigger a review. +- Never merge. +- Never apply labels or modify issues. +- Never run `make check` — checkpoints are not quality gates. +- Do not prompt for confirmation — `/checkpoint` is a quick save, not a ceremony. +<!-- generated by CodeCannon/sync.sh | skill: checkpoint | adapter: cursor | hash: 1b224590 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.cursor/rules/deploy.mdc b/.cursor/rules/deploy.mdc index d4e7d70..664a54a 100644 --- a/.cursor/rules/deploy.mdc +++ b/.cursor/rules/deploy.mdc @@ -167,7 +167,15 @@ Wait for the user to type "release" or an explicit confirmation. Any other respo ## Step 6 — Create PR: `dev` → `main` -Use your file-writing tool (not Bash) to create `/tmp/cc_release_pr_body.md`: +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (not Bash) to create `<tmpdir>/release_pr_body.md`: ```markdown Release vX.Y.Z @@ -185,7 +193,7 @@ Then create the PR (do NOT use `--body`, `--body-file -`, or heredocs): ```bash gh pr create --base main --head dev \ --title "Release vX.Y.Z" \ - --body-file /tmp/cc_release_pr_body.md + --body-file <tmpdir>/release_pr_body.md ``` Note the PR number from the output. @@ -216,7 +224,7 @@ git describe --abbrev=0 <version-tag>^ 2>/dev/null If no previous tag exists, omit the "Full changelog" line. -Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/release_notes.md` (same temp directory from Step 6): ```markdown ## Changes @@ -232,7 +240,7 @@ Then create the release (do NOT use `--notes`, `--notes-file -`, or heredocs): ```bash gh release create <version-tag> \ --title "<version-tag>" \ - --notes-file /tmp/cc_release_notes.md + --notes-file <tmpdir>/release_notes.md ``` Format each PR line as `- #<linked-issue> — <PR title> (PR #<N>)`. If a PR had no linked issue, omit the `#<issue>` prefix and use just the PR title. @@ -246,4 +254,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at `<url>`. Run `make deploy-prod` to ship to production." -<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: cursor | hash: a7a8fe00 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: cursor | hash: 31e92299 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.cursor/rules/start.mdc b/.cursor/rules/start.mdc index 3adac90..58440b6 100644 --- a/.cursor/rules/start.mdc +++ b/.cursor/rules/start.mdc @@ -69,6 +69,35 @@ After parsing flags, determine the active milestone in this order: --- +## Pre-check: Existing feature branch + +Before entering Case A or Case B, check the current branch: + +```bash +git branch --show-current +``` + +If already on a `feature/*` branch and `$ARGUMENTS` is **not** a number (i.e. this is new work, not a resume): + +Say: + +> **"You're already on `feature/<name>`. Would you like to create a GitHub issue linked to this branch and start coding? Or switch to the base branch first? (yes to continue here / no to abort)"** + +Stop. Wait for the user to respond. + +- **Yes** → proceed to **Case A**, but **skip Step 4** (branch creation) entirely. The current branch is used as-is. In Step 3, after creating the issue, link it to the existing branch by running: + ```bash + gh issue develop <number> --base <base-branch> --name <current-branch-name> + ``` + This links the issue to the branch in GitHub without creating or checking out a new branch. If `gh issue develop` fails because the branch already exists on the remote, that is fine — the link may already be established. Continue to Step 5. +- **No / abort** → stop. Tell the user to switch to the base branch and run `/start` again. + +If already on a `feature/*` branch and `$ARGUMENTS` **is** a number → proceed to **Case B** normally (it handles branch checkout itself). + +If on any other branch → proceed to Case A or Case B as determined by the `$ARGUMENTS` check above. + +--- + ## Case A: New work (text description) ### Step 1 — Investigate @@ -96,7 +125,15 @@ The friendly text question is required regardless of harness mode. If your harne Create the issue in two steps — **this exact sequence is mandatory**: -**Step 3a — Write the body to a temp file.** Use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_issue_body.md` with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs, `cat`, or `echo`. The file-writing tool bypasses shell parsing entirely. +**Step 3a — Create a temp directory and write the body file.** Run: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `<tmpdir>/issue_body.md` with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs, `cat`, or `echo`. The file-writing tool bypasses shell parsing entirely. **Step 3b — Run `gh issue create`** with `--body-file` pointing to the temp file: @@ -106,7 +143,7 @@ gh issue create \ --assignee @me \ [--label "<resolved labels>"] \ [--milestone "<resolved milestone>"] \ - --body-file /tmp/cc_issue_body.md + --body-file <tmpdir>/issue_body.md ``` > **IMPORTANT — never pass body content inline in the `gh` command.** Do not use `--body`, `--body-file -`, heredocs (`<<EOF` or `<<'EOF'`), or `$(cat ...)`. All of these embed markdown in a Bash command, which triggers permission prompts that cannot be permanently allowed (the shell parser flags `#` headings, quoted delimiters, and substitutions). The two-step pattern above — file-writing tool then `--body-file <path>` — is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex. @@ -154,7 +191,7 @@ Show the user: `Created issue #<number>: <title>` Then immediately post agent implementation notes as a comment. -Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/issue_comment.md` (same temp directory from Step 3a): ```markdown ## Agent Implementation Notes @@ -163,7 +200,7 @@ Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`: Then post it (do NOT use `--body` or heredocs — same rule as Step 3): ```bash -gh issue comment <number> --body-file /tmp/cc_issue_comment.md +gh issue comment <number> --body-file <tmpdir>/issue_comment.md ``` ### Step 4 — Create feature branch @@ -272,9 +309,9 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - Do not write or edit any source file before `git branch --show-current` shows `feature/*`. - Do not use `make branch` — always use `gh issue develop` so the branch is linked to the issue in GitHub. - Do not commit during `/start` — commits happen in `/submit-for-review`. -- If already on a feature branch when `/start` is invoked, warn the user before creating another branch. +- If already on a feature branch when `/start` is invoked with new work (Case A), prompt the user to either continue on the current branch (skipping branch creation) or abort. See **Pre-check: Existing feature branch** above. - `gh issue create` must use `--title` and `--body` flags. Never open an interactive editor. - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit <number> --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. -<!-- generated by CodeCannon/sync.sh | skill: start | adapter: cursor | hash: 99965523 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: start | adapter: cursor | hash: 1c0ca80d | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.cursor/rules/submit-for-review.mdc b/.cursor/rules/submit-for-review.mdc index 89107be..085ebad 100644 --- a/.cursor/rules/submit-for-review.mdc +++ b/.cursor/rules/submit-for-review.mdc @@ -112,7 +112,15 @@ Use `Issue #<number>` as the issue reference — the issue stays open until `/de Then create the PR in two steps — **this exact sequence is mandatory**: -First, use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_pr_body.md`. Do NOT use Bash/shell to write this file. +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `<tmpdir>/pr_body.md`. Do NOT use Bash/shell to write this file. ```markdown <description of what changed and why> @@ -123,7 +131,7 @@ First, use your file-writing tool (Write in Claude Code, equivalent in other age Then create the PR (do NOT use `--body`, `--body-file -`, heredocs, or `$(cat ...)`): ``` -gh pr create --base <target-branch> --title "<title>" --body-file /tmp/cc_pr_body.md +gh pr create --base <target-branch> --title "<title>" --body-file <tmpdir>/pr_body.md ``` > **IMPORTANT — never pass body content inline in the `gh` command.** Do not use `--body`, `--body-file -`, heredocs (`<<EOF` or `<<'EOF'`), or `$(cat ...)`. All of these embed markdown in a Bash command, which triggers permission prompts that cannot be permanently allowed (the shell parser flags `#` headings, quoted delimiters, and substitutions). The two-step pattern above — file-writing tool then `--body-file <path>` — is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex. @@ -227,7 +235,7 @@ If no linked issue was found, skip silently. Read the issue body (from Step 3 or via `gh issue view <number>`) to recall the original problem description. Then post a comment summarizing what was done: -Use your file-writing tool (not Bash) to create `/tmp/cc_resolution_comment.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/resolution_comment.md` (same temp directory from Step 6): ```markdown ## Resolution @@ -240,7 +248,7 @@ See #<PR-number> for full technical details. Then post it (do NOT use `--body` or heredocs): ``` -gh issue comment <number> --body-file /tmp/cc_resolution_comment.md +gh issue comment <number> --body-file <tmpdir>/resolution_comment.md ``` **Resolution writing rules:** @@ -276,7 +284,7 @@ Accept: comma-separated numbers, `all`, or `none`/`skip`/empty. If the input is **Create the selected issues.** For each selected finding, run `gh issue create` with explicit flags: -Use your file-writing tool (not Bash) to create `/tmp/cc_followup_body.md` for each finding: +Use your file-writing tool (not Bash) to create `<tmpdir>/followup_body.md` for each finding (same temp directory from Step 6): ```markdown Follow-up from PR #<merged-pr-number> — auto-proposed from the code review. @@ -292,7 +300,7 @@ Then create the issue (do NOT use `--body` or heredocs): gh issue create \ --title "<finding text with [WARNING]/[NOTE]/[CRITICAL] prefix stripped, trimmed to a standalone sentence>" \ [--label "<pool-selected labels>"] \ - --body-file /tmp/cc_followup_body.md + --body-file <tmpdir>/followup_body.md ``` Label resolution for each follow-up issue: use the pool-based selection tier from `/start` — pick 1–3 labels from `bug, documentation, enhancement, chore` that genuinely fit the finding. If `bug, documentation, enhancement, chore` is empty or no pool label fits, omit `--label`. Do not attempt per-invocation flag resolution (there is no flag here) and never create new labels from follow-ups, even if label creation is enabled for the project. @@ -318,4 +326,4 @@ If a single `gh issue create` call fails, report the failure for that finding an - `/submit-for-review` merges only to `dev` — never directly to `main`. - If `make merge` fails for any reason, report it and stop — do not attempt workarounds. - The follow-up issue offer in Step 9 runs only after a successful merge and only when the review produced non-blocking findings. Never prompt the user for follow-ups when the review blocked the merge — those findings should be fixed, not ticketed. -<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: cursor | hash: 141fa52f | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: cursor | hash: f7cf15c3 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.gemini/skills/checkpoint/SKILL.md b/.gemini/skills/checkpoint/SKILL.md new file mode 100644 index 0000000..beb2bf8 --- /dev/null +++ b/.gemini/skills/checkpoint/SKILL.md @@ -0,0 +1,93 @@ +--- +name: checkpoint +description: Code Cannon: Commit and push WIP without review or merge +--- + +> **Gemini CLI:** This skill is triggered by description matching. State any arguments in your message. Sub-agent spawning is not supported — the automated review step in `/submit-for-review` must be done manually using the review-agent prompt in a separate session. + +--- + +## What `/checkpoint` does + +`/checkpoint` is a lightweight save point — commit and push work-in-progress to the remote without triggering type-checks, reviews, PR creation, or merge. Use it to persist progress during long coding sessions or before context-switching. + +--- + +## Step 1 — Verify branch + +```bash +git branch --show-current +``` + +Protected branches (not a feature branch): +- `main` +- `dev` + +If the current branch matches any of the above, **abort immediately** and say: + +> "You are on `<branch>`. `/checkpoint` must be run from a feature branch." + +--- + +## Step 2 — Check for changes + +```bash +git status --porcelain +``` + +If the output is empty (no staged, unstaged, or untracked changes), say: + +> "Nothing to checkpoint — working tree is clean." + +Stop. Do not create an empty commit. + +--- + +## Step 3 — Stage and commit + +```bash +git add -A +git commit -m "WIP: <message>" +``` + +**Commit message rules:** +- Always prefix with `WIP: ` so these commits are visually distinct in `git log`. +- If `$ARGUMENTS` is provided, use it as `<message>` (e.g. `WIP: add auth middleware`). +- If `$ARGUMENTS` is empty, auto-generate from the diff summary (e.g. `WIP: update auth.ts, add login tests`). Keep it under 72 characters. +- Do not commit `.env` files, secrets, or build artifacts. If `git status` shows such files, add them to `.gitignore` or exclude them from staging before committing. + +--- + +## Step 4 — Push + +```bash +git push -u origin HEAD +``` + +If the push fails because the remote branch does not exist yet, the `-u` flag handles creation. If it fails for another reason, report the error and stop. + +--- + +## Step 5 — Report + +Count the files in the commit: + +```bash +git diff --stat HEAD~1 +``` + +Say: + +> "Checkpoint saved. N file(s) committed and pushed to `<branch>`. Run `/submit-for-review` when ready to open a PR." + +--- + +## Hard rules + +- Never create a PR. +- Never trigger a review. +- Never merge. +- Never apply labels or modify issues. +- Never run `make check` — checkpoints are not quality gates. +- Do not prompt for confirmation — `/checkpoint` is a quick save, not a ceremony. +<!-- generated by CodeCannon/sync.sh | skill: checkpoint | adapter: gemini | hash: 1a1dbbb0 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.gemini/skills/deploy/SKILL.md b/.gemini/skills/deploy/SKILL.md index aaf65c2..c50671f 100644 --- a/.gemini/skills/deploy/SKILL.md +++ b/.gemini/skills/deploy/SKILL.md @@ -166,7 +166,15 @@ Wait for the user to type "release" or an explicit confirmation. Any other respo ## Step 6 — Create PR: `dev` → `main` -Use your file-writing tool (not Bash) to create `/tmp/cc_release_pr_body.md`: +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (not Bash) to create `<tmpdir>/release_pr_body.md`: ```markdown Release vX.Y.Z @@ -184,7 +192,7 @@ Then create the PR (do NOT use `--body`, `--body-file -`, or heredocs): ```bash gh pr create --base main --head dev \ --title "Release vX.Y.Z" \ - --body-file /tmp/cc_release_pr_body.md + --body-file <tmpdir>/release_pr_body.md ``` Note the PR number from the output. @@ -215,7 +223,7 @@ git describe --abbrev=0 <version-tag>^ 2>/dev/null If no previous tag exists, omit the "Full changelog" line. -Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/release_notes.md` (same temp directory from Step 6): ```markdown ## Changes @@ -231,7 +239,7 @@ Then create the release (do NOT use `--notes`, `--notes-file -`, or heredocs): ```bash gh release create <version-tag> \ --title "<version-tag>" \ - --notes-file /tmp/cc_release_notes.md + --notes-file <tmpdir>/release_notes.md ``` Format each PR line as `- #<linked-issue> — <PR title> (PR #<N>)`. If a PR had no linked issue, omit the `#<issue>` prefix and use just the PR title. @@ -245,4 +253,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at `<url>`. Run `make deploy-prod` to ship to production." -<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: gemini | hash: 1b252e14 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: gemini | hash: 7e8845cd | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.gemini/skills/start/SKILL.md b/.gemini/skills/start/SKILL.md index bd2678f..640d717 100644 --- a/.gemini/skills/start/SKILL.md +++ b/.gemini/skills/start/SKILL.md @@ -68,6 +68,35 @@ After parsing flags, determine the active milestone in this order: --- +## Pre-check: Existing feature branch + +Before entering Case A or Case B, check the current branch: + +```bash +git branch --show-current +``` + +If already on a `feature/*` branch and `$ARGUMENTS` is **not** a number (i.e. this is new work, not a resume): + +Say: + +> **"You're already on `feature/<name>`. Would you like to create a GitHub issue linked to this branch and start coding? Or switch to the base branch first? (yes to continue here / no to abort)"** + +Stop. Wait for the user to respond. + +- **Yes** → proceed to **Case A**, but **skip Step 4** (branch creation) entirely. The current branch is used as-is. In Step 3, after creating the issue, link it to the existing branch by running: + ```bash + gh issue develop <number> --base <base-branch> --name <current-branch-name> + ``` + This links the issue to the branch in GitHub without creating or checking out a new branch. If `gh issue develop` fails because the branch already exists on the remote, that is fine — the link may already be established. Continue to Step 5. +- **No / abort** → stop. Tell the user to switch to the base branch and run `/start` again. + +If already on a `feature/*` branch and `$ARGUMENTS` **is** a number → proceed to **Case B** normally (it handles branch checkout itself). + +If on any other branch → proceed to Case A or Case B as determined by the `$ARGUMENTS` check above. + +--- + ## Case A: New work (text description) ### Step 1 — Investigate @@ -95,7 +124,15 @@ The friendly text question is required regardless of harness mode. If your harne Create the issue in two steps — **this exact sequence is mandatory**: -**Step 3a — Write the body to a temp file.** Use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_issue_body.md` with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs, `cat`, or `echo`. The file-writing tool bypasses shell parsing entirely. +**Step 3a — Create a temp directory and write the body file.** Run: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `<tmpdir>/issue_body.md` with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs, `cat`, or `echo`. The file-writing tool bypasses shell parsing entirely. **Step 3b — Run `gh issue create`** with `--body-file` pointing to the temp file: @@ -105,7 +142,7 @@ gh issue create \ --assignee @me \ [--label "<resolved labels>"] \ [--milestone "<resolved milestone>"] \ - --body-file /tmp/cc_issue_body.md + --body-file <tmpdir>/issue_body.md ``` > **IMPORTANT — never pass body content inline in the `gh` command.** Do not use `--body`, `--body-file -`, heredocs (`<<EOF` or `<<'EOF'`), or `$(cat ...)`. All of these embed markdown in a Bash command, which triggers permission prompts that cannot be permanently allowed (the shell parser flags `#` headings, quoted delimiters, and substitutions). The two-step pattern above — file-writing tool then `--body-file <path>` — is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex. @@ -153,7 +190,7 @@ Show the user: `Created issue #<number>: <title>` Then immediately post agent implementation notes as a comment. -Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/issue_comment.md` (same temp directory from Step 3a): ```markdown ## Agent Implementation Notes @@ -162,7 +199,7 @@ Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`: Then post it (do NOT use `--body` or heredocs — same rule as Step 3): ```bash -gh issue comment <number> --body-file /tmp/cc_issue_comment.md +gh issue comment <number> --body-file <tmpdir>/issue_comment.md ``` ### Step 4 — Create feature branch @@ -271,9 +308,9 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - Do not write or edit any source file before `git branch --show-current` shows `feature/*`. - Do not use `make branch` — always use `gh issue develop` so the branch is linked to the issue in GitHub. - Do not commit during `/start` — commits happen in `/submit-for-review`. -- If already on a feature branch when `/start` is invoked, warn the user before creating another branch. +- If already on a feature branch when `/start` is invoked with new work (Case A), prompt the user to either continue on the current branch (skipping branch creation) or abort. See **Pre-check: Existing feature branch** above. - `gh issue create` must use `--title` and `--body` flags. Never open an interactive editor. - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit <number> --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. -<!-- generated by CodeCannon/sync.sh | skill: start | adapter: gemini | hash: 250dcb74 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: start | adapter: gemini | hash: 6a465756 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.gemini/skills/submit-for-review/SKILL.md b/.gemini/skills/submit-for-review/SKILL.md index ec193b8..5a58f16 100644 --- a/.gemini/skills/submit-for-review/SKILL.md +++ b/.gemini/skills/submit-for-review/SKILL.md @@ -111,7 +111,15 @@ Use `Issue #<number>` as the issue reference — the issue stays open until `/de Then create the PR in two steps — **this exact sequence is mandatory**: -First, use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_pr_body.md`. Do NOT use Bash/shell to write this file. +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `<tmpdir>/pr_body.md`. Do NOT use Bash/shell to write this file. ```markdown <description of what changed and why> @@ -122,7 +130,7 @@ First, use your file-writing tool (Write in Claude Code, equivalent in other age Then create the PR (do NOT use `--body`, `--body-file -`, heredocs, or `$(cat ...)`): ``` -gh pr create --base <target-branch> --title "<title>" --body-file /tmp/cc_pr_body.md +gh pr create --base <target-branch> --title "<title>" --body-file <tmpdir>/pr_body.md ``` > **IMPORTANT — never pass body content inline in the `gh` command.** Do not use `--body`, `--body-file -`, heredocs (`<<EOF` or `<<'EOF'`), or `$(cat ...)`. All of these embed markdown in a Bash command, which triggers permission prompts that cannot be permanently allowed (the shell parser flags `#` headings, quoted delimiters, and substitutions). The two-step pattern above — file-writing tool then `--body-file <path>` — is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex. @@ -226,7 +234,7 @@ If no linked issue was found, skip silently. Read the issue body (from Step 3 or via `gh issue view <number>`) to recall the original problem description. Then post a comment summarizing what was done: -Use your file-writing tool (not Bash) to create `/tmp/cc_resolution_comment.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/resolution_comment.md` (same temp directory from Step 6): ```markdown ## Resolution @@ -239,7 +247,7 @@ See #<PR-number> for full technical details. Then post it (do NOT use `--body` or heredocs): ``` -gh issue comment <number> --body-file /tmp/cc_resolution_comment.md +gh issue comment <number> --body-file <tmpdir>/resolution_comment.md ``` **Resolution writing rules:** @@ -275,7 +283,7 @@ Accept: comma-separated numbers, `all`, or `none`/`skip`/empty. If the input is **Create the selected issues.** For each selected finding, run `gh issue create` with explicit flags: -Use your file-writing tool (not Bash) to create `/tmp/cc_followup_body.md` for each finding: +Use your file-writing tool (not Bash) to create `<tmpdir>/followup_body.md` for each finding (same temp directory from Step 6): ```markdown Follow-up from PR #<merged-pr-number> — auto-proposed from the code review. @@ -291,7 +299,7 @@ Then create the issue (do NOT use `--body` or heredocs): gh issue create \ --title "<finding text with [WARNING]/[NOTE]/[CRITICAL] prefix stripped, trimmed to a standalone sentence>" \ [--label "<pool-selected labels>"] \ - --body-file /tmp/cc_followup_body.md + --body-file <tmpdir>/followup_body.md ``` Label resolution for each follow-up issue: use the pool-based selection tier from `/start` — pick 1–3 labels from `bug, documentation, enhancement, chore` that genuinely fit the finding. If `bug, documentation, enhancement, chore` is empty or no pool label fits, omit `--label`. Do not attempt per-invocation flag resolution (there is no flag here) and never create new labels from follow-ups, even if label creation is enabled for the project. @@ -317,4 +325,4 @@ If a single `gh issue create` call fails, report the failure for that finding an - `/submit-for-review` merges only to `dev` — never directly to `main`. - If `make merge` fails for any reason, report it and stop — do not attempt workarounds. - The follow-up issue offer in Step 9 runs only after a successful merge and only when the review produced non-blocking findings. Never prompt the user for follow-ups when the review blocked the merge — those findings should be fixed, not ticketed. -<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: gemini | hash: ba3271f2 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: gemini | hash: 9915fca9 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/skills/checkpoint.md b/skills/checkpoint.md new file mode 100644 index 0000000..7cbe0ff --- /dev/null +++ b/skills/checkpoint.md @@ -0,0 +1,95 @@ +--- +skill: checkpoint +type: skill +description: "Code Cannon: Commit and push WIP without review or merge" +args: "optional commit message" +--- + +## What `/checkpoint` does + +`/checkpoint` is a lightweight save point — commit and push work-in-progress to the remote without triggering type-checks, reviews, PR creation, or merge. Use it to persist progress during long coding sessions or before context-switching. + +--- + +## Step 1 — Verify branch + +```bash +git branch --show-current +``` + +Protected branches (not a feature branch): +- `{{BRANCH_PROD}}` +{{#if BRANCH_DEV}} +- `{{BRANCH_DEV}}` +{{/if}} +{{#if BRANCH_TEST}} +- `{{BRANCH_TEST}}` +{{/if}} + +If the current branch matches any of the above, **abort immediately** and say: + +> "You are on `<branch>`. `/checkpoint` must be run from a feature branch." + +--- + +## Step 2 — Check for changes + +```bash +git status --porcelain +``` + +If the output is empty (no staged, unstaged, or untracked changes), say: + +> "Nothing to checkpoint — working tree is clean." + +Stop. Do not create an empty commit. + +--- + +## Step 3 — Stage and commit + +```bash +git add -A +git commit -m "WIP: <message>" +``` + +**Commit message rules:** +- Always prefix with `WIP: ` so these commits are visually distinct in `git log`. +- If `$ARGUMENTS` is provided, use it as `<message>` (e.g. `WIP: add auth middleware`). +- If `$ARGUMENTS` is empty, auto-generate from the diff summary (e.g. `WIP: update auth.ts, add login tests`). Keep it under 72 characters. +- Do not commit `.env` files, secrets, or build artifacts. If `git status` shows such files, add them to `.gitignore` or exclude them from staging before committing. + +--- + +## Step 4 — Push + +```bash +git push -u origin HEAD +``` + +If the push fails because the remote branch does not exist yet, the `-u` flag handles creation. If it fails for another reason, report the error and stop. + +--- + +## Step 5 — Report + +Count the files in the commit: + +```bash +git diff --stat HEAD~1 +``` + +Say: + +> "Checkpoint saved. N file(s) committed and pushed to `<branch>`. Run `/submit-for-review` when ready to open a PR." + +--- + +## Hard rules + +- Never create a PR. +- Never trigger a review. +- Never merge. +- Never apply labels or modify issues. +- Never run `{{CHECK_CMD}}` — checkpoints are not quality gates. +- Do not prompt for confirmation — `/checkpoint` is a quick save, not a ceremony. diff --git a/skills/deploy.md b/skills/deploy.md index cbf7cdc..ffdcd4b 100644 --- a/skills/deploy.md +++ b/skills/deploy.md @@ -239,7 +239,15 @@ Wait for the user to type "release" or an explicit confirmation. Any other respo The version tag and PR/issue list are already known. If no previous tag exists, omit the "Full changelog" line. -Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`: +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (not Bash) to create `<tmpdir>/release_notes.md`: ```markdown ## Changes @@ -255,7 +263,7 @@ Then create the release (do NOT use `--notes`, `--notes-file -`, or heredocs): ```bash gh release create <version-tag> \ --title "<version-tag>" \ - --notes-file /tmp/cc_release_notes.md + --notes-file <tmpdir>/release_notes.md ``` Format each PR line as `- #<linked-issue> — <PR title> (PR #<N>)`. If a PR had no linked issue, use just the PR title. @@ -274,7 +282,15 @@ Tell the user: {{#if !BRANCH_TEST}} ## Step 6 — Create PR: `{{BRANCH_DEV}}` → `{{BRANCH_PROD}}` -Use your file-writing tool (not Bash) to create `/tmp/cc_release_pr_body.md`: +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (not Bash) to create `<tmpdir>/release_pr_body.md`: ```markdown Release vX.Y.Z @@ -292,7 +308,7 @@ Then create the PR (do NOT use `--body`, `--body-file -`, or heredocs): ```bash gh pr create --base {{BRANCH_PROD}} --head {{BRANCH_DEV}} \ --title "Release vX.Y.Z" \ - --body-file /tmp/cc_release_pr_body.md + --body-file <tmpdir>/release_pr_body.md ``` Note the PR number from the output. @@ -323,7 +339,7 @@ git describe --abbrev=0 <version-tag>^ 2>/dev/null If no previous tag exists, omit the "Full changelog" line. -Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/release_notes.md` (same temp directory from Step 6): ```markdown ## Changes @@ -339,7 +355,7 @@ Then create the release (do NOT use `--notes`, `--notes-file -`, or heredocs): ```bash gh release create <version-tag> \ --title "<version-tag>" \ - --notes-file /tmp/cc_release_notes.md + --notes-file <tmpdir>/release_notes.md ``` Format each PR line as `- #<linked-issue> — <PR title> (PR #<N>)`. If a PR had no linked issue, omit the `#<issue>` prefix and use just the PR title. @@ -357,7 +373,15 @@ Tell the user: {{#if BRANCH_TEST}} ## Step 6 — Create PR: `{{BRANCH_TEST}}` → `{{BRANCH_PROD}}` -Use your file-writing tool (not Bash) to create `/tmp/cc_release_pr_body.md`: +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (not Bash) to create `<tmpdir>/release_pr_body.md`: ```markdown Release vX.Y.Z @@ -375,7 +399,7 @@ Then create the PR (do NOT use `--body`, `--body-file -`, or heredocs): ```bash gh pr create --base {{BRANCH_PROD}} --head {{BRANCH_TEST}} \ --title "Release vX.Y.Z" \ - --body-file /tmp/cc_release_pr_body.md + --body-file <tmpdir>/release_pr_body.md ``` Note the PR number from the output. @@ -406,7 +430,7 @@ git describe --abbrev=0 <version-tag>^ 2>/dev/null If no previous tag exists, omit the "Full changelog" line. -Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/release_notes.md` (same temp directory from Step 6): ```markdown ## Changes @@ -422,7 +446,7 @@ Then create the release (do NOT use `--notes`, `--notes-file -`, or heredocs): ```bash gh release create <version-tag> \ --title "<version-tag>" \ - --notes-file /tmp/cc_release_notes.md + --notes-file <tmpdir>/release_notes.md ``` Format each PR line as `- #<linked-issue> — <PR title> (PR #<N>)`. If a PR had no linked issue, omit the `#<issue>` prefix and use just the PR title. diff --git a/skills/start.md b/skills/start.md index 3d43eed..b404998 100644 --- a/skills/start.md +++ b/skills/start.md @@ -111,6 +111,35 @@ After parsing flags, determine the active milestone in this order: --- +## Pre-check: Existing feature branch + +Before entering Case A or Case B, check the current branch: + +```bash +git branch --show-current +``` + +If already on a `feature/*` branch and `$ARGUMENTS` is **not** a number (i.e. this is new work, not a resume): + +Say: + +> **"You're already on `feature/<name>`. Would you like to create a GitHub issue linked to this branch and start coding? Or switch to the base branch first? (yes to continue here / no to abort)"** + +Stop. Wait for the user to respond. + +- **Yes** → proceed to **Case A**, but **skip Step 4** (branch creation) entirely. The current branch is used as-is. In Step 3, after creating the issue, link it to the existing branch by running: + ```bash + gh issue develop <number> --base <base-branch> --name <current-branch-name> + ``` + This links the issue to the branch in GitHub without creating or checking out a new branch. If `gh issue develop` fails because the branch already exists on the remote, that is fine — the link may already be established. Continue to Step 5. +- **No / abort** → stop. Tell the user to switch to the base branch and run `/start` again. + +If already on a `feature/*` branch and `$ARGUMENTS` **is** a number → proceed to **Case B** normally (it handles branch checkout itself). + +If on any other branch → proceed to Case A or Case B as determined by the `$ARGUMENTS` check above. + +--- + ## Case A: New work (text description) ### Step 1 — Investigate @@ -138,7 +167,15 @@ The friendly text question is required regardless of harness mode. If your harne Create the issue in two steps — **this exact sequence is mandatory**: -**Step 3a — Write the body to a temp file.** Use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_issue_body.md` with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs, `cat`, or `echo`. The file-writing tool bypasses shell parsing entirely. +**Step 3a — Create a temp directory and write the body file.** Run: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `<tmpdir>/issue_body.md` with the structured markdown body (see sections below). Do NOT use Bash/shell to write this file. Do NOT use heredocs, `cat`, or `echo`. The file-writing tool bypasses shell parsing entirely. **Step 3b — Run `gh issue create`** with `--body-file` pointing to the temp file: @@ -148,7 +185,7 @@ gh issue create \ --assignee @me \ [--label "<resolved labels>"] \ [--milestone "<resolved milestone>"] \ - --body-file /tmp/cc_issue_body.md + --body-file <tmpdir>/issue_body.md ``` > **IMPORTANT — never pass body content inline in the `gh` command.** Do not use `--body`, `--body-file -`, heredocs (`<<EOF` or `<<'EOF'`), or `$(cat ...)`. All of these embed markdown in a Bash command, which triggers permission prompts that cannot be permanently allowed (the shell parser flags `#` headings, quoted delimiters, and substitutions). The two-step pattern above — file-writing tool then `--body-file <path>` — is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex. @@ -196,7 +233,7 @@ Show the user: `Created issue #<number>: <title>` Then immediately post agent implementation notes as a comment. -Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/issue_comment.md` (same temp directory from Step 3a): ```markdown ## Agent Implementation Notes @@ -205,7 +242,7 @@ Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`: Then post it (do NOT use `--body` or heredocs — same rule as Step 3): ```bash -gh issue comment <number> --body-file /tmp/cc_issue_comment.md +gh issue comment <number> --body-file <tmpdir>/issue_comment.md ``` ### Step 4 — Create feature branch @@ -346,7 +383,7 @@ When done, say: **"The code is ready for review. Please run `{{DEV_CMD}}` and te - Do not write or edit any source file before `git branch --show-current` shows `feature/*`. - Do not use `make branch` — always use `gh issue develop` so the branch is linked to the issue in GitHub. - Do not commit during `/start` — commits happen in `/submit-for-review`. -- If already on a feature branch when `/start` is invoked, warn the user before creating another branch. +- If already on a feature branch when `/start` is invoked with new work (Case A), prompt the user to either continue on the current branch (skipping branch creation) or abort. See **Pre-check: Existing feature branch** above. - `gh issue create` must use `--title` and `--body` flags. Never open an interactive editor. - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit <number> --remove-assignee @me`. {{#if TICKET_LABELS}} diff --git a/skills/submit-for-review.md b/skills/submit-for-review.md index c1bdf67..5659c6c 100644 --- a/skills/submit-for-review.md +++ b/skills/submit-for-review.md @@ -128,7 +128,15 @@ Use `Closes #<number>` as the issue reference — merging to the default branch Then create the PR in two steps — **this exact sequence is mandatory**: -First, use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `/tmp/cc_pr_body.md`. Do NOT use Bash/shell to write this file. +First, create a temp directory for this invocation: + +```bash +mkdir -p /tmp/CodeCannon && mktemp -d /tmp/CodeCannon/XXXXXX +``` + +Note the returned path (e.g. `/tmp/CodeCannon/a8f3b2`). Use this path for all temp files in this invocation. + +Then use your file-writing tool (Write in Claude Code, equivalent in other agents) to create `<tmpdir>/pr_body.md`. Do NOT use Bash/shell to write this file. ```markdown <description of what changed and why> @@ -139,7 +147,7 @@ First, use your file-writing tool (Write in Claude Code, equivalent in other age Then create the PR (do NOT use `--body`, `--body-file -`, heredocs, or `$(cat ...)`): ``` -gh pr create --base <target-branch> --title "<title>" --body-file /tmp/cc_pr_body.md +gh pr create --base <target-branch> --title "<title>" --body-file <tmpdir>/pr_body.md ``` > **IMPORTANT — never pass body content inline in the `gh` command.** Do not use `--body`, `--body-file -`, heredocs (`<<EOF` or `<<'EOF'`), or `$(cat ...)`. All of these embed markdown in a Bash command, which triggers permission prompts that cannot be permanently allowed (the shell parser flags `#` headings, quoted delimiters, and substitutions). The two-step pattern above — file-writing tool then `--body-file <path>` — is the only approach that works without prompts across Claude Code, Gemini CLI, Cursor, and Codex. @@ -256,7 +264,7 @@ If no linked issue was found, skip silently. Read the issue body (from Step 3 or via `gh issue view <number>`) to recall the original problem description. Then post a comment summarizing what was done: -Use your file-writing tool (not Bash) to create `/tmp/cc_resolution_comment.md`: +Use your file-writing tool (not Bash) to create `<tmpdir>/resolution_comment.md` (same temp directory from Step 6): ```markdown ## Resolution @@ -269,7 +277,7 @@ See #<PR-number> for full technical details. Then post it (do NOT use `--body` or heredocs): ``` -gh issue comment <number> --body-file /tmp/cc_resolution_comment.md +gh issue comment <number> --body-file <tmpdir>/resolution_comment.md ``` **Resolution writing rules:** @@ -315,7 +323,7 @@ Accept: comma-separated numbers, `all`, or `none`/`skip`/empty. If the input is **Create the selected issues.** For each selected finding, run `gh issue create` with explicit flags: -Use your file-writing tool (not Bash) to create `/tmp/cc_followup_body.md` for each finding: +Use your file-writing tool (not Bash) to create `<tmpdir>/followup_body.md` for each finding (same temp directory from Step 6): ```markdown Follow-up from PR #<merged-pr-number> — auto-proposed from the code review. @@ -331,7 +339,7 @@ Then create the issue (do NOT use `--body` or heredocs): gh issue create \ --title "<finding text with [WARNING]/[NOTE]/[CRITICAL] prefix stripped, trimmed to a standalone sentence>" \ [--label "<pool-selected labels>"] \ - --body-file /tmp/cc_followup_body.md + --body-file <tmpdir>/followup_body.md ``` Label resolution for each follow-up issue: use the pool-based selection tier from `/start` — pick 1–3 labels from `{{TICKET_LABELS}}` that genuinely fit the finding. If `{{TICKET_LABELS}}` is empty or no pool label fits, omit `--label`. Do not attempt per-invocation flag resolution (there is no flag here) and never create new labels from follow-ups, even if label creation is enabled for the project.