diff --git a/.agents/skills/deploy/SKILL.md b/.agents/skills/deploy/SKILL.md index c1887ed..274faa4 100644 --- a/.agents/skills/deploy/SKILL.md +++ b/.agents/skills/deploy/SKILL.md @@ -92,7 +92,7 @@ Would you like to bump the version before deploying? - **minor** → X.B.0 - **major** → A.0.0 - **specific** → enter a version number - - **skip** → proceed to release with the current tag + - **skip** → proceed to release with the latest existing tag ``` Wait for their response. @@ -101,12 +101,12 @@ Wait for their response. ## Step 3 — Version bump (if requested) -If the user chose to skip, verify a version tag exists on HEAD: +If the user chose to skip, find the latest version tag in the branch history: ```bash -git describe --exact-match --tags HEAD 2>/dev/null +git describe --tags --abbrev=0 2>/dev/null ``` -If no tag is found when skipping, warn: "No version tag found on HEAD. You must bump the version before deploying." Return to the version bump prompt. +If no tag is found at all (first release), warn: "No version tag found. You must bump the version before deploying." Return to the version bump prompt. Otherwise, use the tag found as the release version. If the user chose a bump level, map their response to a command: @@ -235,4 +235,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/status/SKILL.md b/.agents/skills/status/SKILL.md index 38983e9..e9afa6c 100644 --- a/.agents/skills/status/SKILL.md +++ b/.agents/skills/status/SKILL.md @@ -118,6 +118,68 @@ Do not post, comment, write files, or take any action. Output only. --- +## Step 6 — What's next + +After the status summary, append a single actionable suggestion based on local git state and the GitHub data already fetched. + +### 6a — Gather additional local state + +Run these commands (skip if not in a git repo): + +```bash +git branch --show-current +``` + +```bash +git status --porcelain +``` + +```bash +git describe --tags --abbrev=0 2>/dev/null +``` + +```bash +git rev-list ..HEAD --count 2>/dev/null +``` + +From the GitHub data fetched in Step 2, also check for the current branch's PR approval status: + +```bash +gh pr view --json number,title,url,reviewDecision,statusCheckRollup \ + --jq '{number,title,url,reviewDecision,checks: [.statusCheckRollup[]? | .status]}' +``` + +If `gh pr view` exits non-zero (no PR for current branch), note that there is no open PR. + +### 6b — Determine suggestion + +Evaluate the following conditions **in order**. Use the **first** match: + +| Priority | Condition | Output | +|----------|-----------|--------| +| 1 | On a `feature/*` branch with uncommitted changes (`git status --porcelain` is non-empty) | `What's next: You have uncommitted changes on \`\`. When ready, run \`/submit-for-review\`.` | +| 2 | On a `feature/*` branch with an open PR that has `reviewDecision: APPROVED` and all status checks are `COMPLETED` | `What's next: PR # is approved and checks pass. Consider running \`/deploy\`.` | +| 3 | On a `feature/*` branch with an open PR (any other review/check state) | `What's next: PR # () is open and awaiting review.` | +| 4 | On a `feature/*` branch with no open PR and clean working tree | `What's next: No open PR for \`<branch>\`. Run \`/submit-for-review\` to open one.` | +| 5 | On the integration branch (`dev`, `develop`, or `main` when no integration branch exists) with unreleased commits (rev-list count > 0 since last tag) | `What's next: <N> commit(s) on \`<branch>\` since \`<tag>\`. Run \`/deploy\` when ready to release.` | +| 6 | No open PRs, no open issues assigned to subject | `What's next: Nothing in progress. Run \`/start\` to begin new work.` | +| 7 | Open issues exist in "Up next" | `What's next: Next up is #<number> (<title>). Run \`/start <number>\` to pick it up.` | + +If none of the above match, omit the "What's next" section entirely. + +### 6c — Format + +Print the suggestion after a horizontal rule, below the local commits section: + +``` +--- +🧭 <suggestion text> +``` + +This section is omitted in milestone mode. + +--- + ## Milestone mode (Steps M1–M3) Only entered when `--milestone` or `--sprint` is detected in Step 1. @@ -176,8 +238,7 @@ Do not post, comment, write files, or take any action. Output only. ## Hard rules - Never write to GitHub (no comments, labels, issue updates, or PR changes). -- Never suggest what the developer should work on next. - If `gh` is unauthenticated or any fetch fails, report the error and stop immediately. - Do not retry failed commands. - Strip the leading `@` from the subject when passing to `gh` flags that do not accept it. -<!-- generated by CodeCannon/sync.sh | skill: status | adapter: codex | hash: a0b51014 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: status | adapter: codex | hash: 08068d91 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.claude/commands/deploy.md b/.claude/commands/deploy.md index f53cac1..3cf9838 100644 --- a/.claude/commands/deploy.md +++ b/.claude/commands/deploy.md @@ -87,7 +87,7 @@ Would you like to bump the version before deploying? - **minor** → X.B.0 - **major** → A.0.0 - **specific** → enter a version number - - **skip** → proceed to release with the current tag + - **skip** → proceed to release with the latest existing tag ``` Wait for their response. @@ -96,12 +96,12 @@ Wait for their response. ## Step 3 — Version bump (if requested) -If the user chose to skip, verify a version tag exists on HEAD: +If the user chose to skip, find the latest version tag in the branch history: ```bash -git describe --exact-match --tags HEAD 2>/dev/null +git describe --tags --abbrev=0 2>/dev/null ``` -If no tag is found when skipping, warn: "No version tag found on HEAD. You must bump the version before deploying." Return to the version bump prompt. +If no tag is found at all (first release), warn: "No version tag found. You must bump the version before deploying." Return to the version bump prompt. Otherwise, use the tag found as the release version. If the user chose a bump level, map their response to a command: @@ -230,4 +230,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: 4819f2e7 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: claude | hash: 4e4a48f5 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.claude/commands/status.md b/.claude/commands/status.md index 77d363f..d3dfca6 100644 --- a/.claude/commands/status.md +++ b/.claude/commands/status.md @@ -113,6 +113,68 @@ Do not post, comment, write files, or take any action. Output only. --- +## Step 6 — What's next + +After the status summary, append a single actionable suggestion based on local git state and the GitHub data already fetched. + +### 6a — Gather additional local state + +Run these commands (skip if not in a git repo): + +```bash +git branch --show-current +``` + +```bash +git status --porcelain +``` + +```bash +git describe --tags --abbrev=0 2>/dev/null +``` + +```bash +git rev-list <latest-tag>..HEAD --count 2>/dev/null +``` + +From the GitHub data fetched in Step 2, also check for the current branch's PR approval status: + +```bash +gh pr view --json number,title,url,reviewDecision,statusCheckRollup \ + --jq '{number,title,url,reviewDecision,checks: [.statusCheckRollup[]? | .status]}' +``` + +If `gh pr view` exits non-zero (no PR for current branch), note that there is no open PR. + +### 6b — Determine suggestion + +Evaluate the following conditions **in order**. Use the **first** match: + +| Priority | Condition | Output | +|----------|-----------|--------| +| 1 | On a `feature/*` branch with uncommitted changes (`git status --porcelain` is non-empty) | `What's next: You have uncommitted changes on \`<branch>\`. When ready, run \`/submit-for-review\`.` | +| 2 | On a `feature/*` branch with an open PR that has `reviewDecision: APPROVED` and all status checks are `COMPLETED` | `What's next: PR #<number> is approved and checks pass. Consider running \`/deploy\`.` | +| 3 | On a `feature/*` branch with an open PR (any other review/check state) | `What's next: PR #<number> (<title>) is open and awaiting review.` | +| 4 | On a `feature/*` branch with no open PR and clean working tree | `What's next: No open PR for \`<branch>\`. Run \`/submit-for-review\` to open one.` | +| 5 | On the integration branch (`dev`, `develop`, or `main` when no integration branch exists) with unreleased commits (rev-list count > 0 since last tag) | `What's next: <N> commit(s) on \`<branch>\` since \`<tag>\`. Run \`/deploy\` when ready to release.` | +| 6 | No open PRs, no open issues assigned to subject | `What's next: Nothing in progress. Run \`/start\` to begin new work.` | +| 7 | Open issues exist in "Up next" | `What's next: Next up is #<number> (<title>). Run \`/start <number>\` to pick it up.` | + +If none of the above match, omit the "What's next" section entirely. + +### 6c — Format + +Print the suggestion after a horizontal rule, below the local commits section: + +``` +--- +🧭 <suggestion text> +``` + +This section is omitted in milestone mode. + +--- + ## Milestone mode (Steps M1–M3) Only entered when `--milestone` or `--sprint` is detected in Step 1. @@ -171,8 +233,7 @@ Do not post, comment, write files, or take any action. Output only. ## Hard rules - Never write to GitHub (no comments, labels, issue updates, or PR changes). -- Never suggest what the developer should work on next. - If `gh` is unauthenticated or any fetch fails, report the error and stop immediately. - Do not retry failed commands. - Strip the leading `@` from the subject when passing to `gh` flags that do not accept it. -<!-- generated by CodeCannon/sync.sh | skill: status | adapter: claude | hash: 79583183 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: status | adapter: claude | hash: 9e27a4dc | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.cursor/rules/deploy.mdc b/.cursor/rules/deploy.mdc index 096256f..c9a8a4a 100644 --- a/.cursor/rules/deploy.mdc +++ b/.cursor/rules/deploy.mdc @@ -93,7 +93,7 @@ Would you like to bump the version before deploying? - **minor** → X.B.0 - **major** → A.0.0 - **specific** → enter a version number - - **skip** → proceed to release with the current tag + - **skip** → proceed to release with the latest existing tag ``` Wait for their response. @@ -102,12 +102,12 @@ Wait for their response. ## Step 3 — Version bump (if requested) -If the user chose to skip, verify a version tag exists on HEAD: +If the user chose to skip, find the latest version tag in the branch history: ```bash -git describe --exact-match --tags HEAD 2>/dev/null +git describe --tags --abbrev=0 2>/dev/null ``` -If no tag is found when skipping, warn: "No version tag found on HEAD. You must bump the version before deploying." Return to the version bump prompt. +If no tag is found at all (first release), warn: "No version tag found. You must bump the version before deploying." Return to the version bump prompt. Otherwise, use the tag found as the release version. If the user chose a bump level, map their response to a command: @@ -236,4 +236,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: 415c91f9 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: cursor | hash: 410b3166 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.cursor/rules/status.mdc b/.cursor/rules/status.mdc index 8c4d88d..b94dd3b 100644 --- a/.cursor/rules/status.mdc +++ b/.cursor/rules/status.mdc @@ -119,6 +119,68 @@ Do not post, comment, write files, or take any action. Output only. --- +## Step 6 — What's next + +After the status summary, append a single actionable suggestion based on local git state and the GitHub data already fetched. + +### 6a — Gather additional local state + +Run these commands (skip if not in a git repo): + +```bash +git branch --show-current +``` + +```bash +git status --porcelain +``` + +```bash +git describe --tags --abbrev=0 2>/dev/null +``` + +```bash +git rev-list <latest-tag>..HEAD --count 2>/dev/null +``` + +From the GitHub data fetched in Step 2, also check for the current branch's PR approval status: + +```bash +gh pr view --json number,title,url,reviewDecision,statusCheckRollup \ + --jq '{number,title,url,reviewDecision,checks: [.statusCheckRollup[]? | .status]}' +``` + +If `gh pr view` exits non-zero (no PR for current branch), note that there is no open PR. + +### 6b — Determine suggestion + +Evaluate the following conditions **in order**. Use the **first** match: + +| Priority | Condition | Output | +|----------|-----------|--------| +| 1 | On a `feature/*` branch with uncommitted changes (`git status --porcelain` is non-empty) | `What's next: You have uncommitted changes on \`<branch>\`. When ready, run \`/submit-for-review\`.` | +| 2 | On a `feature/*` branch with an open PR that has `reviewDecision: APPROVED` and all status checks are `COMPLETED` | `What's next: PR #<number> is approved and checks pass. Consider running \`/deploy\`.` | +| 3 | On a `feature/*` branch with an open PR (any other review/check state) | `What's next: PR #<number> (<title>) is open and awaiting review.` | +| 4 | On a `feature/*` branch with no open PR and clean working tree | `What's next: No open PR for \`<branch>\`. Run \`/submit-for-review\` to open one.` | +| 5 | On the integration branch (`dev`, `develop`, or `main` when no integration branch exists) with unreleased commits (rev-list count > 0 since last tag) | `What's next: <N> commit(s) on \`<branch>\` since \`<tag>\`. Run \`/deploy\` when ready to release.` | +| 6 | No open PRs, no open issues assigned to subject | `What's next: Nothing in progress. Run \`/start\` to begin new work.` | +| 7 | Open issues exist in "Up next" | `What's next: Next up is #<number> (<title>). Run \`/start <number>\` to pick it up.` | + +If none of the above match, omit the "What's next" section entirely. + +### 6c — Format + +Print the suggestion after a horizontal rule, below the local commits section: + +``` +--- +🧭 <suggestion text> +``` + +This section is omitted in milestone mode. + +--- + ## Milestone mode (Steps M1–M3) Only entered when `--milestone` or `--sprint` is detected in Step 1. @@ -177,8 +239,7 @@ Do not post, comment, write files, or take any action. Output only. ## Hard rules - Never write to GitHub (no comments, labels, issue updates, or PR changes). -- Never suggest what the developer should work on next. - If `gh` is unauthenticated or any fetch fails, report the error and stop immediately. - Do not retry failed commands. - Strip the leading `@` from the subject when passing to `gh` flags that do not accept it. -<!-- generated by CodeCannon/sync.sh | skill: status | adapter: cursor | hash: 4b3e9659 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: status | adapter: cursor | hash: 3d26eb3e | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.gemini/skills/deploy/SKILL.md b/.gemini/skills/deploy/SKILL.md index 81d0f8d..be52f23 100644 --- a/.gemini/skills/deploy/SKILL.md +++ b/.gemini/skills/deploy/SKILL.md @@ -92,7 +92,7 @@ Would you like to bump the version before deploying? - **minor** → X.B.0 - **major** → A.0.0 - **specific** → enter a version number - - **skip** → proceed to release with the current tag + - **skip** → proceed to release with the latest existing tag ``` Wait for their response. @@ -101,12 +101,12 @@ Wait for their response. ## Step 3 — Version bump (if requested) -If the user chose to skip, verify a version tag exists on HEAD: +If the user chose to skip, find the latest version tag in the branch history: ```bash -git describe --exact-match --tags HEAD 2>/dev/null +git describe --tags --abbrev=0 2>/dev/null ``` -If no tag is found when skipping, warn: "No version tag found on HEAD. You must bump the version before deploying." Return to the version bump prompt. +If no tag is found at all (first release), warn: "No version tag found. You must bump the version before deploying." Return to the version bump prompt. Otherwise, use the tag found as the release version. If the user chose a bump level, map their response to a command: @@ -235,4 +235,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: 2d52ae20 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: deploy | adapter: gemini | hash: 9dc417c9 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/.gemini/skills/status/SKILL.md b/.gemini/skills/status/SKILL.md index 4a58c99..dab504d 100644 --- a/.gemini/skills/status/SKILL.md +++ b/.gemini/skills/status/SKILL.md @@ -118,6 +118,68 @@ Do not post, comment, write files, or take any action. Output only. --- +## Step 6 — What's next + +After the status summary, append a single actionable suggestion based on local git state and the GitHub data already fetched. + +### 6a — Gather additional local state + +Run these commands (skip if not in a git repo): + +```bash +git branch --show-current +``` + +```bash +git status --porcelain +``` + +```bash +git describe --tags --abbrev=0 2>/dev/null +``` + +```bash +git rev-list <latest-tag>..HEAD --count 2>/dev/null +``` + +From the GitHub data fetched in Step 2, also check for the current branch's PR approval status: + +```bash +gh pr view --json number,title,url,reviewDecision,statusCheckRollup \ + --jq '{number,title,url,reviewDecision,checks: [.statusCheckRollup[]? | .status]}' +``` + +If `gh pr view` exits non-zero (no PR for current branch), note that there is no open PR. + +### 6b — Determine suggestion + +Evaluate the following conditions **in order**. Use the **first** match: + +| Priority | Condition | Output | +|----------|-----------|--------| +| 1 | On a `feature/*` branch with uncommitted changes (`git status --porcelain` is non-empty) | `What's next: You have uncommitted changes on \`<branch>\`. When ready, run \`/submit-for-review\`.` | +| 2 | On a `feature/*` branch with an open PR that has `reviewDecision: APPROVED` and all status checks are `COMPLETED` | `What's next: PR #<number> is approved and checks pass. Consider running \`/deploy\`.` | +| 3 | On a `feature/*` branch with an open PR (any other review/check state) | `What's next: PR #<number> (<title>) is open and awaiting review.` | +| 4 | On a `feature/*` branch with no open PR and clean working tree | `What's next: No open PR for \`<branch>\`. Run \`/submit-for-review\` to open one.` | +| 5 | On the integration branch (`dev`, `develop`, or `main` when no integration branch exists) with unreleased commits (rev-list count > 0 since last tag) | `What's next: <N> commit(s) on \`<branch>\` since \`<tag>\`. Run \`/deploy\` when ready to release.` | +| 6 | No open PRs, no open issues assigned to subject | `What's next: Nothing in progress. Run \`/start\` to begin new work.` | +| 7 | Open issues exist in "Up next" | `What's next: Next up is #<number> (<title>). Run \`/start <number>\` to pick it up.` | + +If none of the above match, omit the "What's next" section entirely. + +### 6c — Format + +Print the suggestion after a horizontal rule, below the local commits section: + +``` +--- +🧭 <suggestion text> +``` + +This section is omitted in milestone mode. + +--- + ## Milestone mode (Steps M1–M3) Only entered when `--milestone` or `--sprint` is detected in Step 1. @@ -176,8 +238,7 @@ Do not post, comment, write files, or take any action. Output only. ## Hard rules - Never write to GitHub (no comments, labels, issue updates, or PR changes). -- Never suggest what the developer should work on next. - If `gh` is unauthenticated or any fetch fails, report the error and stop immediately. - Do not retry failed commands. - Strip the leading `@` from the subject when passing to `gh` flags that do not accept it. -<!-- generated by CodeCannon/sync.sh | skill: status | adapter: gemini | hash: 4c095e8c | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> +<!-- generated by CodeCannon/sync.sh | skill: status | adapter: gemini | hash: 394d5e30 | DO NOT EDIT — run CodeCannon/sync.sh to regenerate --> diff --git a/AGENTS.md b/AGENTS.md index 13aea66..d38f85d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,74 +1,225 @@ -# AGENTS.md — Code Cannon +# AGENTS.md — CodeCannon -Instructions for AI coding agents working on the Code Cannon project itself. +Instructions for AI coding agents working on the CodeCannon project itself. -Code Cannon is a skill distribution system. It stores generic agent workflow skills in `skills/`, adapter configs in `adapters/`, and a `sync.sh` script that generates agent-specific skill files for downstream projects. +CodeCannon is a skill distribution system. It stores generic agent workflow skills in `skills/`, adapter configs in `adapters/`, and a `sync.sh` script that generates agent-specific skill files for downstream projects. One source of truth, synced to every project and every AI agent. -## Branch Strategy +## Branch strategy ``` -feature/* → development → main +feature/* → dev → main ``` - `main` — published releases. Never push directly. -- `development` — integration. Never push directly. -- `feature/*` — short-lived. Branch from `development`, PR back. +- `dev` — integration branch. Never push directly. +- `feature/*` — short-lived. Branch from `dev`, PR back to `dev`. -## Working on Code Cannon +## Where things live -### Editing skills +Use this section to orient yourself. Do not search for files when the answer is here. -Skills live in `skills/*.md`. Each file has YAML frontmatter followed by the skill body. Placeholder tokens use `{{UPPERCASE_NAME}}` syntax and are documented in `config.schema.yaml`. +### Source skills (edit here) -When editing a skill: -1. Edit the `.md` file in `skills/`. -2. Test locally by running sync against the APrimeforYou project (a known consumer): `cd ../APrimeforYou && CodeCannon/sync.sh --dry-run` -3. Verify generated output looks correct before committing. +``` +skills/*.md Skill source files — YAML frontmatter + markdown body +``` -### Adding a new adapter +These are the single source of truth for all generated output. Every edit to agent workflows starts here. -1. Create `adapters/{name}/config.yaml` — set `output_directory` and `output_extension`. -2. Create `adapters/{name}/header.md` — the invocation header template. Use `{skill}` and `{description}` as placeholders. -3. Test with `sync.sh --skill start` against a test project. -4. Document any adapter limitations in `config.yaml` under `notes`. +### Generated output (never edit) + +``` +.claude/commands/*.md Claude Code slash commands +.cursor/rules/*.mdc Cursor agent rules +.agents/skills/ Codex / legacy agent skills +.gemini/skills/ Gemini agent skills +``` + +These are regenerated by `./sync.sh`. Each file contains a hash marker for change detection. If you need to change agent output, edit the source skill in `skills/` and re-run sync. + +### Adapters + +``` +adapters/claude/ config.yaml + header.md — Claude Code adapter +adapters/cursor/ config.yaml + header.md — Cursor adapter +adapters/codex/ config.yaml + header.md — Codex adapter +adapters/gemini/ config.yaml + header.md — Gemini adapter +``` + +Each adapter has a `config.yaml` (output directory, file extension, agent name, notes) and a `header.md` (invocation header template using `{skill}` and `{description}` placeholders). + +### Configuration + +``` +.codecannon.yaml This project's own config (adapters list + placeholder values) +config.schema.yaml Canonical documentation for every placeholder +templates/codecannon.yaml Template config for consumer projects to copy +``` + +### Documentation + +``` +docs/index.md Getting started and overview +docs/branching.md Trunk, two-branch, and three-branch workflow docs +docs/customization.md Tailoring skills to a project +docs/config-reference.md Every .codecannon.yaml setting explained +docs/adapters.md Supported agents and how to add new ones +docs/skills/*.md Per-skill documentation (start, deploy, qa, etc.) +README.md User-facing overview and quick start +``` + +When asked to update documentation, check `docs/` first — most detailed docs live there, not in README.md. + +### Build and workflow + +``` +Makefile CodeCannon-specific targets (sync, versioning, deployment) +Makefile.agents.mk Generic git workflow targets (branch, pr, abandon, merge, promote) +sync.sh The core sync engine (Python 3) +VERSION Current version number (plain text, e.g. 0.3.3) +``` + +### Project meta + +``` +AGENTS.md This file — instructions for agents working on CodeCannon +ROADMAP.md Future ideas and planned work +.codecannon.yaml Project config (also listed under Configuration) +``` + +## Skill anatomy + +Each skill in `skills/` follows this structure: + +```yaml +--- +skill: start # Identifier (becomes the filename) +type: skill # "skill" (slash command) or "prompt" (non-invocable) +description: "Start a feature" # Human-readable, used in adapter headers +args: "description text" # What arguments the skill accepts +# Optional: +# output_path_override: path # Override default output location +# no_invocation_header: true # Skip the auto-generated header +--- -### Adding a new placeholder +Markdown body with instructions... +``` + +### Placeholders +Use `{{UPPERCASE_NAME}}` syntax. All placeholders are documented in `config.schema.yaml` with descriptions, defaults, and which skills use them. + +To add a new placeholder: 1. Add it to `config.schema.yaml` with description, default, and `used_in` list. 2. Add it with its default value to `templates/codecannon.yaml`. 3. Use `{{PLACEHOLDER_NAME}}` in the relevant skill files. -### Testing sync.sh +### Conditional blocks + +Skills support conditional rendering: -```bash -cd /path/to/a/consumer/project -../CodeCannon/sync.sh --dry-run # verify output paths and content -../CodeCannon/sync.sh # generate for real ``` +{{#if BRANCH_TEST}} + Content shown only when BRANCH_TEST has a value +{{/if}} + +{{#if !BRANCH_TEST}} + Content shown only when BRANCH_TEST is empty +{{/if}} +``` + +### Change detection + +`sync.sh` embeds an MD5 hash in a marker comment at the end of each generated file: + +``` +<!-- generated by CodeCannon/sync.sh | skill: start | adapter: claude | hash: a1b2c3d4 | DO NOT EDIT --> +``` + +If someone manually edits a generated file, the hash won't match and `sync.sh` will refuse to overwrite it (unless run with `--force`). + +## Working on CodeCannon + +### Make targets + +The primary commands for working on this project: + +| Command | What it does | +|---------|-------------| +| `make check` | Validate that all skill placeholders resolve against config | +| `make dev` | Preview what sync would generate (dry run, no file writes) | +| `make sync` | Regenerate all adapter output from `skills/` | +| `make branch name=X` | Create `feature/X` from `dev` | +| `make pr` | Push current branch and open PR to `dev` | +| `make merge` | Merge current PR into `dev` | +| `make abandon` | Discard changes and delete current feature branch | +| `make bump-patch` | Bump version patch segment, commit, and tag | + +### Editing a skill + +1. Edit the source file in `skills/`. +2. Run `make check` to validate placeholders. +3. Run `make dev` to preview generated output. +4. Run `make sync` to regenerate all adapter output. +5. Commit the skill source **and** the regenerated files together in the same PR. + +### Adding a new adapter + +1. Create `adapters/{name}/config.yaml` — set `agent`, `output_directory`, and `output_extension`. +2. Create `adapters/{name}/header.md` — invocation header template using `{skill}` and `{description}`. +3. Test with `./sync.sh --skill start`. +4. Document any adapter limitations in `config.yaml` under `notes`. +5. Update `docs/adapters.md`. + +### Adding a new skill + +1. Create `skills/{name}.md` with frontmatter (`skill`, `type`, `description`, `args`). +2. Add any new placeholders to `config.schema.yaml` and `templates/codecannon.yaml`. +3. Run `make check` and `make dev` to verify. +4. Run `make sync` to generate output for all adapters. +5. Create `docs/skills/{name}.md` with user-facing documentation. + +## Self-hosting: using CodeCannon to develop CodeCannon -## Self-hosting: using Code Cannon to develop Code Cannon +This repo is the only project that runs sync as `./sync.sh` instead of `CodeCannon/sync.sh`. Every consumer project uses the submodule path — this is the exception. -- **Sync path exception**: agents working on this repo run `./sync.sh`, not `CodeCannon/sync.sh`. Every consumer project uses `CodeCannon/sync.sh` via the submodule path — this repo is the only exception. -- **Edit-test loop**: edit a skill in `skills/` → `make check` to validate placeholders → `make dev` to preview generated output → commit and `/submit-for-review`. -- **Re-run sync after skill edits**: after changing any file in `skills/`, run `./sync.sh` to regenerate `.claude/commands/`. Commit the updated generated files in the same PR as the skill source change. -- **Never edit `.claude/commands/` directly** — those files are generated. Edit the source skill in `skills/` and re-run sync. +- **Edit-test loop**: edit a skill in `skills/` → `make check` → `make dev` → `make sync` → commit source + generated files together. +- **All adapter outputs are generated**: after editing a skill, `make sync` regenerates `.claude/commands/`, `.cursor/rules/`, `.agents/skills/`, and `.gemini/skills/`. Commit all of them. +- **Never edit generated files directly** — edit the source skill in `skills/` and re-run `make sync`. -## What Agents Must Never Do +## What agents must never do -- Push directly to `main` or `development` -- Edit generated files in consumer projects — edit the source skill instead -- Add project-specific content to `skills/` — skills must remain generic (use placeholders) +- Push directly to `main` or `dev`. +- Edit generated files (`.claude/commands/`, `.cursor/rules/`, `.agents/skills/`, `.gemini/skills/`) — edit the source skill in `skills/` instead. +- Add project-specific content to `skills/` — skills must remain generic. Use `{{PLACEHOLDER}}` tokens for anything project-specific. +- Commit skill source changes without also committing the regenerated output (`make sync`). +- Invent placeholder names — check `config.schema.yaml` for the canonical list. -## Project Layout +## Project layout ``` -skills/ source skill files (edit here) -adapters/ per-agent adapter configs and header templates -templates/ files for downstream projects to copy -config.schema.yaml placeholder documentation -sync.sh the installer / generator -Makefile.agents.mk generic git workflow Makefile targets -AGENTS.md this file -README.md human-facing docs -.agents/ legacy workflow files (still functional for template-repo usage) +skills/ source skill files (edit here) +adapters/ per-agent adapter configs and header templates + claude/ Claude Code (.claude/commands/*.md) + cursor/ Cursor (.cursor/rules/*.mdc) + codex/ Codex (.agents/skills/) + gemini/ Gemini (.gemini/skills/) +templates/ files for downstream projects to copy + codecannon.yaml template config +docs/ user-facing documentation + index.md getting started + branching.md branch workflow strategies + customization.md tailoring skills + config-reference.md config setting reference + adapters.md adapter documentation + skills/ per-skill documentation +config.schema.yaml placeholder documentation (canonical) +.codecannon.yaml this project's config +sync.sh the sync engine +Makefile project-specific targets +Makefile.agents.mk generic git workflow targets +VERSION current version +AGENTS.md this file +README.md user-facing overview +ROADMAP.md future ideas ``` diff --git a/README.md b/README.md index b1799a6..daa005a 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,14 @@ cp CodeCannon/templates/codecannon.yaml .codecannon.yaml CodeCannon/sync.sh ``` +To update Code Cannon to the latest version: + +```bash +git submodule update --remote CodeCannon +git add CodeCannon +git commit -m "Update CodeCannon submodule to latest" +``` + Or run `/setup` for a guided walkthrough that detects your project state and configures everything interactively. ## Documentation diff --git a/ROADMAP.md b/ROADMAP.md index 31afaca..4aee4fd 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -4,7 +4,7 @@ Ideas and future work. Not prioritized — just captured so they don't get lost. ## Swarm mode / multi-agent workflows -The current skill set (start/submit-for-review/review/version/release) assumes **deep mode**: one issue, one branch, one coherent PR. This works well for disciplined, sequential work. +The current skill set (start/submit-for-review/review/deploy) assumes **deep mode**: one issue, one branch, one coherent PR. This works well for disciplined, sequential work. In practice, developers often run multiple agents simultaneously on unrelated tasks — "swarm mode." This resists the ticket-per-change structure because the agents share a working directory and branch. Worktrees could isolate agents, but only Claude Code supports them natively; Cursor, Codex, and Gemini don't. diff --git a/VERSION b/VERSION index 1c09c74..42045ac 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.3 +0.3.4 diff --git a/skills/deploy.md b/skills/deploy.md index 33dfb51..9f6c087 100644 --- a/skills/deploy.md +++ b/skills/deploy.md @@ -123,7 +123,7 @@ Would you like to bump the version before deploying? - **minor** → X.B.0 - **major** → A.0.0 - **specific** → enter a version number - - **skip** → proceed to release with the current tag + - **skip** → proceed to release with the latest existing tag ``` Wait for their response. @@ -132,12 +132,12 @@ Wait for their response. ## Step 3 — Version bump (if requested) -If the user chose to skip, verify a version tag exists on HEAD: +If the user chose to skip, find the latest version tag in the branch history: ```bash -git describe --exact-match --tags HEAD 2>/dev/null +git describe --tags --abbrev=0 2>/dev/null ``` -If no tag is found when skipping, warn: "No version tag found on HEAD. You must bump the version before deploying." Return to the version bump prompt. +If no tag is found at all (first release), warn: "No version tag found. You must bump the version before deploying." Return to the version bump prompt. Otherwise, use the tag found as the release version. If the user chose a bump level, map their response to a command: