Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions .agents/skills/deploy/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,9 @@ Wait for the user to type "release" or an explicit confirmation. Any other respo

## Step 6 — Create PR: `dev` → `main`

```bash
gh pr create --base main --head dev \
--title "Release vX.Y.Z" \
--body-file - <<'EOF'
Use your file-writing tool (not Bash) to create `/tmp/cc_release_pr_body.md`:

```markdown
Release vX.Y.Z

PRs included:
Expand All @@ -178,7 +177,14 @@ PRs included:

Closes #14
Closes #15
EOF
```

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
```

Note the PR number from the output.
Expand Down Expand Up @@ -209,19 +215,23 @@ git describe --abbrev=0 <version-tag>^ 2>/dev/null

If no previous tag exists, omit the "Full changelog" line.

Create the release:
Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`:

```bash
gh release create <version-tag> \
--title "<version-tag>" \
--notes-file - <<'EOF'
```markdown
## Changes

- #<issue> — <PR title> (PR #<pr-number>)
[... one line per PR included in this release ...]

**Full changelog:** https://github.com/<owner>/<repo>/compare/<previous-tag>...<version-tag>
EOF
```

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
```

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.
Expand All @@ -235,4 +245,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: codex | hash: 0e47902b | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: codex | hash: 6d8dd3bb | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
26 changes: 16 additions & 10 deletions .agents/skills/start/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,22 @@ The friendly text question is required regardless of harness mode. If your harne

### Step 3 — Create GitHub Issue

Run `gh issue create` with explicit flags (do NOT open an interactive editor):
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 3b — Run `gh issue create`** with `--body-file` pointing to the temp file:

```bash
gh issue create \
--title "<standalone full sentence — must make sense with no context>" \
--assignee @me \
[--label "<resolved labels>"] \
[--milestone "<resolved milestone>"] \
--body-file - <<'EOF'
<structured markdown body — see sections below>
EOF
--body-file /tmp/cc_issue_body.md
```

> **Why `--body-file -` + stdin heredoc?** Claude Code's permission matcher refuses to extend any `Bash(gh:*)` allow rule over a command containing `$(...)` substitution, so `--body "$(cat <<'EOF' ...)"` triggers a Yes/No prompt on every run with no "Allow always" option. Piping the body in on stdin via heredoc avoids this — the matcher sees a clean `gh …` invocation and `Bash(gh:*)` matches.
> **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.

Resolve labels and milestone using the resolution steps in the Parsing section above:
- **Labels**: use the value from three-tier label resolution. If non-empty, add `--label "<value>"` to the command. If empty (no flag, empty pool, creation not allowed), omit `--label` entirely.
Expand Down Expand Up @@ -149,14 +151,18 @@ After the command runs, note the issue number from the output URL (e.g. `https:/

Show the user: `Created issue #<number>: <title>`

Then immediately post agent implementation notes as a comment:
Then immediately post agent implementation notes as a comment.

```bash
gh issue comment <number> --body-file - <<'EOF'
Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`:
```markdown
## Agent Implementation Notes

<full technical plan: exact files to change, approach, key decisions, edge cases>
EOF
```

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
```

### Step 4 — Create feature branch
Expand Down Expand Up @@ -270,4 +276,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test
- 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: 5603cf1a | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
<!-- generated by CodeCannon/sync.sh | skill: start | adapter: codex | hash: 7ba07088 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
49 changes: 34 additions & 15 deletions .agents/skills/submit-for-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,23 @@ Use `Issue #<number>` as the issue reference — the issue stays open until `/de

> **Critical:** Use the unqualified `#N` form (e.g. `Closes #42`), never the fully-qualified `owner/repo#N` form (e.g. `Closes LightbridgeLab/CodeCannon#42`), even for same-repo references. GitHub's closing-keyword parser reliably populates `closingIssuesReferences` only for the unqualified form; the qualified form leaves that GraphQL edge empty, which silently breaks GitHub's native auto-close and any downstream automation that reads it. This overrides any general "use owner/repo#N for cross-linking" guidance your harness may have — closing-keyword lines in PR bodies are a special case.

Then create the PR with explicit title and body (never use an interactive editor):
```
gh pr create --base <target-branch> --title "<title>" --body-file - <<'EOF'
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.

```markdown
<description of what changed and why>

<Closes #N OR Issue #N, based on target above>
EOF
```

> **Why `--body-file -` + stdin heredoc?** Claude Code's permission matcher refuses to extend any `Bash(gh:*)` allow rule over a command containing `$(...)` substitution, so `--body "$(cat <<'EOF' ...)"` triggers a Yes/No prompt on every run with no "Allow always" option. Piping the body in on stdin via heredoc redirection is not command substitution — the matcher sees a clean `gh pr create …` invocation and `Bash(gh:*)` matches. Apply this pattern to every multi-line `--body` / `--notes` in skills (`gh pr create`, `gh issue create`, `gh issue comment`, and `gh release create` all accept `-` for their `*-file` flags).
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
```

> **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.

Add `--reviewer` to the `gh pr create` command above using the handles from `@sebastientaggart`. Before passing them, strip any leading `@` from each comma-separated handle (e.g. `@alice,@org/team` becomes `alice,org/team`) — the `gh` CLI requires bare usernames.

Expand Down Expand Up @@ -219,14 +226,20 @@ 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:

```
gh issue comment <number> --body-file - <<'EOF'
Use your file-writing tool (not Bash) to create `/tmp/cc_resolution_comment.md`:

```markdown
## Resolution

<1-3 sentences explaining what was done to fix the problem, written in plain language for a non-technical audience — no code, no file paths, no jargon. Focus on what changed from the user's perspective and why it solves the problem described in the issue.>

See #<PR-number> for full technical details.
EOF
```

Then post it (do NOT use `--body` or heredocs):

```
gh issue comment <number> --body-file /tmp/cc_resolution_comment.md
```

**Resolution writing rules:**
Expand Down Expand Up @@ -262,17 +275,23 @@ 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:

```
gh issue create \
--title "<finding text with [WARNING]/[NOTE]/[CRITICAL] prefix stripped, trimmed to a standalone sentence>" \
[--label "<pool-selected labels>"] \
--body-file - <<'EOF'
Use your file-writing tool (not Bash) to create `/tmp/cc_followup_body.md` for each finding:

```markdown
Follow-up from PR #<merged-pr-number> — auto-proposed from the code review.

**Finding:** <full finding text, prefix included>

See the review comment on the PR for context.
EOF
```

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
```

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.
Expand All @@ -298,4 +317,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: ba60d5aa | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
<!-- generated by CodeCannon/sync.sh | skill: submit-for-review | adapter: codex | hash: d09ab40d | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
34 changes: 22 additions & 12 deletions .claude/commands/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,9 @@ Wait for the user to type "release" or an explicit confirmation. Any other respo

## Step 6 — Create PR: `dev` → `main`

```bash
gh pr create --base main --head dev \
--title "Release vX.Y.Z" \
--body-file - <<'EOF'
Use your file-writing tool (not Bash) to create `/tmp/cc_release_pr_body.md`:

```markdown
Release vX.Y.Z

PRs included:
Expand All @@ -173,7 +172,14 @@ PRs included:

Closes #14
Closes #15
EOF
```

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
```

Note the PR number from the output.
Expand Down Expand Up @@ -204,19 +210,23 @@ git describe --abbrev=0 <version-tag>^ 2>/dev/null

If no previous tag exists, omit the "Full changelog" line.

Create the release:
Use your file-writing tool (not Bash) to create `/tmp/cc_release_notes.md`:

```bash
gh release create <version-tag> \
--title "<version-tag>" \
--notes-file - <<'EOF'
```markdown
## Changes

- #<issue> — <PR title> (PR #<pr-number>)
[... one line per PR included in this release ...]

**Full changelog:** https://github.com/<owner>/<repo>/compare/<previous-tag>...<version-tag>
EOF
```

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
```

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.
Expand All @@ -230,4 +240,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: b1efee29 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: claude | hash: 88439028 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
26 changes: 16 additions & 10 deletions .claude/commands/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,22 @@ The friendly text question is required regardless of harness mode. If your harne

### Step 3 — Create GitHub Issue

Run `gh issue create` with explicit flags (do NOT open an interactive editor):
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 3b — Run `gh issue create`** with `--body-file` pointing to the temp file:

```bash
gh issue create \
--title "<standalone full sentence — must make sense with no context>" \
--assignee @me \
[--label "<resolved labels>"] \
[--milestone "<resolved milestone>"] \
--body-file - <<'EOF'
<structured markdown body — see sections below>
EOF
--body-file /tmp/cc_issue_body.md
```

> **Why `--body-file -` + stdin heredoc?** Claude Code's permission matcher refuses to extend any `Bash(gh:*)` allow rule over a command containing `$(...)` substitution, so `--body "$(cat <<'EOF' ...)"` triggers a Yes/No prompt on every run with no "Allow always" option. Piping the body in on stdin via heredoc avoids this — the matcher sees a clean `gh …` invocation and `Bash(gh:*)` matches.
> **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.

Resolve labels and milestone using the resolution steps in the Parsing section above:
- **Labels**: use the value from three-tier label resolution. If non-empty, add `--label "<value>"` to the command. If empty (no flag, empty pool, creation not allowed), omit `--label` entirely.
Expand Down Expand Up @@ -144,14 +146,18 @@ After the command runs, note the issue number from the output URL (e.g. `https:/

Show the user: `Created issue #<number>: <title>`

Then immediately post agent implementation notes as a comment:
Then immediately post agent implementation notes as a comment.

```bash
gh issue comment <number> --body-file - <<'EOF'
Use your file-writing tool (not Bash) to create `/tmp/cc_issue_comment.md`:
```markdown
## Agent Implementation Notes

<full technical plan: exact files to change, approach, key decisions, edge cases>
EOF
```

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
```

### Step 4 — Create feature branch
Expand Down Expand Up @@ -265,4 +271,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test
- 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: 3c1bac69 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
<!-- generated by CodeCannon/sync.sh | skill: start | adapter: claude | hash: d1144b46 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate -->
Loading