agent-templates 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/package.json +1 -1
- package/patterns/three-agent-architect-builder-reviewer/README.md +2 -0
- package/patterns/three-agent-architect-builder-reviewer/scaffold/.claude/commands/nightly-issues.md +1 -1
- package/patterns/three-agent-architect-builder-reviewer/scaffold/.claude/commands/start-all.md +1 -1
- package/patterns/three-agent-architect-builder-reviewer/scaffold/.claude/commands/start-milestone.md +1 -1
- package/patterns/three-agent-architect-builder-reviewer/scaffold/INSTALL.md +1 -1
- package/patterns/three-agent-architect-builder-reviewer/scaffold/claude-md-snippet.md +1 -0
- package/scripts/adopt.mjs +18 -8
- package/scripts/build-site.mjs +32 -1
package/README.md
CHANGED
|
@@ -22,6 +22,21 @@ npx agent-templates@latest adopt three-agent-architect-builder-reviewer .
|
|
|
22
22
|
|---|---|---|---|
|
|
23
23
|
| [three-agent-architect-builder-reviewer](patterns/three-agent-architect-builder-reviewer/README.md) | trialed | 2026-07-17 | Architect plans → Builder implements → independent Reviewer (fresh context, different model tier) clears or bounces; `/start-milestone` runs a whole module autonomously |
|
|
24
24
|
|
|
25
|
+
## Commands (three-agent-architect-builder-reviewer)
|
|
26
|
+
|
|
27
|
+
Installed into your project by `adopt`; run them in Claude Code. Full list is generated on the [catalog site](https://ruihang2017.github.io/agent-templates/) from the same source.
|
|
28
|
+
|
|
29
|
+
| Command | Argument | What it does |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| `/breakdown-prd` | `[focus notes]` | Decompose `docs/PRD.md` into sub-PRDs + template-compliant tickets (pre-Gate-1 planning). |
|
|
32
|
+
| `/start-milestone` | `<module dir> [supervised\|autonomous]` | Gate 1 for one module — publish its tickets as tracker issues, then run the milestone pipeline. |
|
|
33
|
+
| `/start-all` | `[supervised\|autonomous]` | Gate 1 for the **whole PRD** — compute the module DAG, publish every module, run all modules in dependency order. |
|
|
34
|
+
| `/plan-ticket` | `<ticket-id>` | Architect stage on a ticket. |
|
|
35
|
+
| `/build-ticket` | `<ticket-id>` | Builder stage on a planned ticket. |
|
|
36
|
+
| `/review-ticket` | `<ticket-id> [ref]` | Reviewer stage on a built ticket (fresh context required). |
|
|
37
|
+
| `/verify-delivery` | `<ticket-id>` | Post-merge Definition-of-Done check — verifies delivery instead of assuming it. |
|
|
38
|
+
| `/nightly-issues` | `[max-issues]` | Unattended sweep — triage open issues, auto-fix the fixable ones through the pipeline, post a morning report (headless `claude -p`). |
|
|
39
|
+
|
|
25
40
|
- **Applying a pattern to your project** (new — even a bare `PRD.md` — or existing): [ADOPTING.md](ADOPTING.md) — one command: `node scripts/adopt.mjs <pattern> <target-dir>`
|
|
26
41
|
- Operating manual, pattern schema, grounding rules: [CLAUDE.md](CLAUDE.md)
|
|
27
42
|
- Adding a pattern: start from [templates/pattern-README.template.md](templates/pattern-README.template.md), process in [CLAUDE.md](CLAUDE.md) § "Adding a new pattern"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-templates",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "Catalog of multi-agent development architecture patterns - design write-ups plus drop-in scaffolding (agents, slash commands, workflows, templates).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Horace Hou",
|
|
@@ -153,6 +153,8 @@ Install steps and usage modes: [scaffold/INSTALL.md](scaffold/INSTALL.md). Front
|
|
|
153
153
|
| 2026-07-17 | Gate 1 made concrete: `/start-milestone` = the human start signal → tickets auto-published as tracker issues (`publish-tickets.mjs`, adapted from fx-eye-tracking `create-issues.mjs`; `[<id>]` title prefix as dedupe key; smoke-tested dry-run/no-CLI/usage paths) → deterministic milestone runner (`run-milestone.js` Workflow script: stage order, reviewer freshness, bounce cap, merge policy in code). Added `templates/ticket.template.md` (adapted from fx ticket discipline). Recorded the Bash guard boundary as a known pitfall. Clarified `ultracode`: a session setting (`xhigh` + automatic workflow orchestration), not a model effort level — role efforts unchanged. | Maintainer direction (Horace Hou), 2026-07-17. fx-eye-tracking conventions read the same day (read-only). Workflow tool, `.claude/workflows/`, and `ultracode` semantics verified against live docs (workflows, claude-directory, model-config — record in `scaffold/INSTALL.md`). | Horace Hou (direction) / Claude Fable 5 (write-up) |
|
|
154
154
|
| 2026-07-18 | **`/start-all` shipped** (catalog issue #20; maintainer-decided semantics: failed module blocks dependents, independent branches continue in `autonomous`, any non-CLEAR stops everything in `supervised`, no cost cap, resume via closed-issue filtering): deterministic DAG script (`milestone-dag.mjs`, ticket `blocked_by` as ground truth, cycles/dangling refs are hard errors) + `start-all` workflow composing `run-milestone` per module + `/start-all` command. 19 new E2E checks (DAG fixtures incl. cycle; module-policy scenarios via stubbed child workflows). Per-ticket stages unchanged. | Maintainer answers on issue #20, 2026-07-18. | Horace Hou (decisions) / Claude Fable 5 (build) |
|
|
155
155
|
| 2026-07-18 | **First field bug fixed** (catalog issue #21, reported from Ruihang2017/Groundwork through the upstream feedback channel): CRLF-rewritten workflow scripts are rejected by the Workflow tool on Windows. Fix: repo-wide `.gitattributes` (`eol=lf`), working tree renormalized (67 files), `adopt.mjs` installs all text as LF, E2E `\r` guards added. Recorded as the pattern's first true `[internal]` pitfall observation. | Field report (Horace Hou via Groundwork), 2026-07-18. | Horace Hou (report) / Claude Fable 5 (fix) |
|
|
156
|
+
| 2026-07-20 | **Doc/site command coverage mechanized** (catalog issue #35, maintainer direction: `/start-all` had shipped but never appeared in the npm README or the catalog site, so users could not discover it — surfacing commands must be impossible to forget). The command frontmatter is the single source of truth: `build-site.mjs` now renders a Commands section per pattern from it (site complete by construction), README carries the full command list, and an E2E coverage gate asserts every `scaffold/.claude/commands/*.md` name appears in BOTH the generated site and README with a non-empty description (plus a non-vacuous sentinel guard). Adding a command without documenting it now fails the merge gate. No pattern-behavior change. | Maintainer direction (Horace Hou), 2026-07-20. | Horace Hou (direction) / Claude Opus 4.8 (build) |
|
|
157
|
+
| 2026-07-20 | **Platform compatibility hardened** (catalog issue #34, maintainer question): `adopt.mjs` detection now uses multiple deterministic signals — origin host `gitlab`/`github` substring, then a repo-local signal (`.gitlab-ci.yml` → glab, existing `.github/` → gh), then default gh with a loud ambiguity note — so a self-hosted GitLab on a custom domain is no longer misread as GitHub. The resolved platform is recorded as a `Tracker:` line in the adopted CLAUDE.md, and `/start-milestone` · `/start-all` · `/nightly-issues` now read `platform` from that line instead of guessing (parallel to Operating mode / testCmd). E2E: self-hosted-GitLab detection, `Tracker:` line matches platform, ambiguity note. Runtime scripts' own `--platform`/autodetect unchanged. | Maintainer question (Horace Hou), 2026-07-20. | Horace Hou (question) / Claude Opus 4.8 (fix) |
|
|
156
158
|
| 2026-07-19 | **Field bug #4 fixed** (catalog issue #31, field report from Ruihang2017/Groundwork2): `milestone-dag.mjs` emitted each module's tickets in ID order instead of topologically by intra-module `blocked_by`, so a module whose declared order deviates from ID order dispatched a ticket before its blocker and failed at the Builder's precondition gate. Fix: a shared Kahn `topoSort` now orders both modules and, within each module, tickets by intra-module `blocked_by` (cross-module edges stay module-level; ID order as tiebreak; intra-module cycle fails loudly). E2E +7 (suite-dag D6 the 0502/0503 inversion, D7 intra-module cycle, D8 ID-order tiebreak). run-milestone dispatch loop unchanged. | Field report (Horace Hou via Groundwork2), 2026-07-18. | Horace Hou (report) / Claude Opus 4.8 (fix) |
|
|
157
159
|
| 2026-07-19 | **Pipeline tool surface explicitly pre-allowed** (catalog issue #30, maintainer direction): scaffold `settings.json` now enumerates allow rules for everything the stages legitimately run — deterministic scripts, git branch/commit/push/read set, `npm test`-family, `gh`/`glab` issue list/view/comment/edit|update|note/close/create — so a fully autonomous `/start-all` → deliver → nightly cycle triggers zero interactive approvals. Deliberately not pre-allowed (role discipline stays mechanical): `git merge`/`rebase`/`reset`/`clean`, `gh pr *`, and bare `git:*`/`gh:*`/`glab:*` wildcards — E2E asserts both directions so drift fails the gate. Risk accepted and recorded: `git push:*` includes force variants; `gh issue create:*` is broader than the publish-tickets discipline (nightly report issue needs it); prefix-deny of flags is structurally incomplete so not attempted. | Maintainer direction (Horace Hou), 2026-07-19. | Horace Hou (direction) / Claude Fable 5 (build) |
|
|
158
160
|
| 2026-07-19 | **Delivery made deterministic** (catalog issue #26, field report: harness safety classifiers blocked the agent-run deliver stage 3/3 after journaled CLEARs): new `.claude/scripts/deliver-ticket.mjs` — clean-tree guard, `--no-ff` merge (idempotent on re-runs, conflicts abort clean), push, tracker close with post-close verification (`--issue` or `[<id>]` title-prefix lookup), deterministic DoD, `DELIVER-SUMMARY-JSON` contract; run-milestone's deliver agent reduced to executing that one command and relaying its summary; `settings.json` gained explicit allow rules for the three deterministic scripts. E2E: new suite-deliver (12 scenarios on real temp git repos + fake CLIs). The tracker close only happens after merge AND push actually landed — a closed issue is what resume filtering treats as delivered, so closing on a failed delivery would silently drop the ticket. One DoD item relocated: the post-merge test run executes deterministically when `testCmd` is supplied (workflow arg, forwarded as `--test-cmd`; `/start-all` passes it through) and otherwise stays with `/verify-delivery` — builder and reviewer both already ran tests on the branch. Per-ticket stages before deliver, and the model/effort table, unchanged. | Field report (Horace Hou via Groundwork), 2026-07-18; fix direction proposed in the issue itself. | Horace Hou (report) / Claude Fable 5 (fix) |
|
package/patterns/three-agent-architect-builder-reviewer/scaffold/.claude/commands/nightly-issues.md
CHANGED
|
@@ -8,7 +8,7 @@ Arguments: `$ARGUMENTS` — optional first argument caps how many issues to proc
|
|
|
8
8
|
Execute in order:
|
|
9
9
|
|
|
10
10
|
1. **Collect.** List open issues with the platform CLI (`gh issue list --state open --json number,title,body,labels,createdAt,url` / glab equivalent). Exclude issues labeled `nightly:escalated`, `triage:invalid`, or `needs-human`, and any issue titled `Nightly report ...`. For each remaining issue set `isNew` = created within the last 24 hours. Compute `reportDate` = today's local date (YYYY-MM-DD).
|
|
11
|
-
2. **Launch the sweep.** Call the **Workflow** tool with `name: "nightly-issues"` and `args: { issues, maxIssues, defaultBranch, platform, reportDate }
|
|
11
|
+
2. **Launch the sweep.** Call the **Workflow** tool with `name: "nightly-issues"` and `args: { issues, maxIssues, defaultBranch, platform, reportDate }` — read `platform` from the CLAUDE.md **`Tracker:`** line (`gh` or `glab`; adopt.mjs set it), never guess it. This command's instruction is your authorization to use the Workflow tool. The workflow triages (read-only), runs fixable issues through the run-milestone pipeline autonomously, and posts all tracker writes in one report step.
|
|
12
12
|
3. **Final output** (this is the headless run's stdout): the report issue URL, then one line per processed issue — `#N · <classification or pipeline status> · <one-line reason>` — plus how many eligible issues were left for the next night.
|
|
13
13
|
|
|
14
14
|
Operator notes: scheduling, permissions, and the morning-email mechanics are documented in the scaffold's INSTALL.md § Nightly sweep. You are an observer while the workflow runs — no stage work, no file edits, no tracker writes outside the workflow.
|
package/patterns/three-agent-architect-builder-reviewer/scaffold/.claude/commands/start-all.md
CHANGED
|
@@ -9,7 +9,7 @@ Typing this command is the human Gate 1 sign-off **for the whole PRD** — every
|
|
|
9
9
|
|
|
10
10
|
1. **Compute the plan.** Run `node .claude/scripts/milestone-dag.mjs` and show its output (module order, per-module dependencies). STOP on any error — a dangling `blocked_by` or a cycle is a spec defect for the Architect/human, not something to patch here.
|
|
11
11
|
2. **Publish all tickets.** For each module in DAG order: `node .claude/scripts/publish-tickets.mjs docs/prd/<module>` (dry-run, then `--create`; STOP on `error` entries). Keep each module's `PUBLISH-SUMMARY-JSON` line — step 3 needs it. Then, per module, **filter out tickets whose issues are already closed** (closed = delivered by an earlier run — this makes `/start-all` re-runs resume: fully-closed modules pass an empty ticket list and are marked already-complete).
|
|
12
|
-
3. **Launch the driver.** Call the **Workflow** tool with `name: "start-all"` and `args: { modules: [{name, dependsOn, tickets}] in DAG order, mode, defaultBranch, platform }
|
|
12
|
+
3. **Launch the driver.** Call the **Workflow** tool with `name: "start-all"` and `args: { modules: [{name, dependsOn, tickets}] in DAG order, mode, defaultBranch, platform }` — read `platform` from the CLAUDE.md **`Tracker:`** line (`gh` or `glab`; adopt.mjs set it), never guess it. Each element of `tickets` MUST be an object `{id, path, issue}` — the exact shape run-milestone validates (issue #27; bare id strings fail). Build it by joining the two step outputs per module: ticket ids and their order come from the DAG plan (step 1), `path` and `issue` come from that module's `PUBLISH-SUMMARY-JSON` (step 2), matched by `id`. Add `testCmd` (the repo's test command, if its CLAUDE.md declares one) so the deterministic deliver script re-runs tests on the merged default branch as part of DoD. This command's instruction is your authorization to use the Workflow tool. Failure policy is enforced in the workflow: failed modules block their dependents; independent branches continue in `autonomous`; anything short of a CLEAR stops everything in `supervised`.
|
|
13
13
|
4. **Relay the final report verbatim** — per module: `completed` / `already-complete` / `paused-for-merge` (supervised: tell the human to merge, then re-run this command) / `failed` (with the failing ticket + stage) / `skipped-dependency` / `not-started`. Escalations inside a module carry through from run-milestone unchanged.
|
|
14
14
|
|
|
15
15
|
While the workflow runs you are an observer. Do not do stage work in parallel, do not "help" a slow stage, do not edit files.
|
package/patterns/three-agent-architect-builder-reviewer/scaffold/.claude/commands/start-milestone.md
CHANGED
|
@@ -9,7 +9,7 @@ Typing this command **is** the human Gate 1 sign-off: the sub-PRD and tickets ar
|
|
|
9
9
|
|
|
10
10
|
1. **Verify Gate 1 inputs.** `MODULE/README.md` (the sub-PRD) exists and `MODULE/tickets/*.md` is non-empty; every ticket has the required frontmatter (see `templates/ticket.template.md`). Anything missing → STOP and list exactly what is missing. Do not fix it yourself — that is Architect-stage work.
|
|
11
11
|
2. **Publish tickets as tracker issues.** Run `node .claude/scripts/publish-tickets.mjs MODULE` (dry-run) and show the mapping. If the summary contains `error` entries → STOP and report them. Otherwise re-run with `--create` (idempotent — the `[<id>]` title prefix dedupes, so re-running is safe), and again STOP on any `error` entries.
|
|
12
|
-
3. **Launch the pipeline.** Parse the final `PUBLISH-SUMMARY-JSON` line into `tickets: [{id, path, issue}]`. **Filter out tickets whose issue is already closed** (check via `gh`/`glab` — closed means delivered by an earlier run; this filter is what makes re-runs after supervised pauses or crashes safe). Determine the Operating mode, then call the **Workflow** tool with `name: "run-milestone"` and `args: { tickets, mode, defaultBranch, platform }` — plus `testCmd` (the repo's test command, if its CLAUDE.md declares one) so the deterministic deliver script re-runs tests on the merged default branch as part of DoD. This command's instruction is your authorization to use the Workflow tool.
|
|
12
|
+
3. **Launch the pipeline.** Parse the final `PUBLISH-SUMMARY-JSON` line into `tickets: [{id, path, issue}]`. **Filter out tickets whose issue is already closed** (check via `gh`/`glab` — closed means delivered by an earlier run; this filter is what makes re-runs after supervised pauses or crashes safe). Determine the Operating mode, then call the **Workflow** tool with `name: "run-milestone"` and `args: { tickets, mode, defaultBranch, platform }` — read `platform` from the CLAUDE.md **`Tracker:`** line (`gh` or `glab`; adopt.mjs set it from the origin remote), never guess it — plus `testCmd` (the repo's test command, if its CLAUDE.md declares one) so the deterministic deliver script re-runs tests on the merged default branch as part of DoD. This command's instruction is your authorization to use the Workflow tool.
|
|
13
13
|
4. **Relay the final report verbatim** — per ticket: `delivered` · `awaiting-human-merge` · `escalated` (stage `review`, `reviewer-failed`, or `bounce-fix-build`) · `failed` · `delivery-incomplete`, plus `notStarted` when the run stopped early. Escalated and failed items go to the human; do not fix them inline (the write guard will hold you to that). In `supervised` mode the run stops after each CLEAR verdict — tell the human to merge, then re-run this command to continue.
|
|
14
14
|
|
|
15
15
|
While the workflow runs you are an observer. Do not do stage work in parallel, do not "help" a slow stage, do not edit files.
|
|
@@ -12,7 +12,7 @@ From a checkout of the catalog: `node scripts/adopt.mjs three-agent-architect-bu
|
|
|
12
12
|
2. Install the catalog's **universal templates** (shared by all patterns — source of truth is the catalog root, not this scaffold): `templates/ticket.template.md` → the target repo's `templates/`; the platform half of `templates/tracker/` → `.github/` (ISSUE_TEMPLATE/ + PULL_REQUEST_TEMPLATE.md) or `.gitlab/` (issue_templates/ + merge_request_templates/). Then fill the PR/MR template's **Constraint check** section with the target repo's CLAUDE.md non-negotiables. Hand-written issues and pipeline PRs now share one format that triage can convert and reviewers can verify.
|
|
13
13
|
3. The write-guard hook needs Node.js ≥ 18 on PATH. It denies main-session Edit/Write with a dispatch instruction; subagent writes pass. Override switch for human-approved out-of-pipeline edits: create `.claude/allow-main-writes`, delete it afterwards — and add that path to `.gitignore`.
|
|
14
14
|
4. The tracker steps (`publish-tickets.mjs`, `deliver-ticket.mjs`, `/verify-delivery`, the nightly sweep) need the platform CLI installed and authenticated: `gh` (GitHub) or `glab` (GitLab). The publish script autodetects the platform from the origin remote; override with `--platform gh|glab` (test doubles / non-PATH binaries: `GH_BIN` / `GLAB_BIN` env overrides). Delivery (merge `--no-ff` + push + verified issue close + deterministic DoD) is `deliver-ticket.mjs` — never an agent improvising git/tracker writes; `settings.json` carries explicit allow rules for the pipeline's whole tool surface (the three deterministic scripts, the enumerated git branch/commit/push set, `npm test`-family test commands, and the enumerated `gh`/`glab` issue commands) so unattended runs do not stall waiting for interactive approval (catalog issues #26, #30). Deliberately NOT pre-allowed: `git merge` / `rebase` / `reset` / `clean` and `gh pr *` — merging belongs to `deliver-ticket.mjs`. If your project's test command is not `npm test` / `npm run test` / `node --test`, add one more allow rule for it (e.g. `Bash(pytest:*)`).
|
|
15
|
-
5. Append the content of `claude-md-snippet.md` to the target repo's `CLAUDE.md`, and set the **Operating mode** line (`supervised` for a fresh adoption; `autonomous` is the target).
|
|
15
|
+
5. Append the content of `claude-md-snippet.md` to the target repo's `CLAUDE.md`, and set the **Operating mode** line (`supervised` for a fresh adoption; `autonomous` is the target) and the **Tracker** line (`gh` for GitHub, `glab` for GitLab — the commands and workflows read the platform from this line). `adopt.mjs` sets Tracker automatically from the origin remote; set it by hand only on a manual install.
|
|
16
16
|
6. Ensure the docs layout the pipeline assumes exists: `docs/PRD.md`, `docs/prd/<module>/README.md` (the sub-PRD — `/start-milestone` hard-requires it), `docs/prd/<module>/tickets/` (author tickets from `templates/ticket.template.md`), `docs/adr/`, and an empty `docs/plans/`.
|
|
17
17
|
7. Check the pattern entry's expiry (README metadata table). If expired, re-verify the model/effort table against current official docs before adopting — do not copy an expired recommendation into a new project.
|
|
18
18
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
## Delivery pipeline — three-agent Architect / Builder / Reviewer
|
|
5
5
|
|
|
6
6
|
**Operating mode: `supervised`** <!-- switch to `autonomous` once the pattern holds on this repo -->
|
|
7
|
+
**Tracker: `gh`** <!-- gh (GitHub) or glab (GitLab); set by adopt.mjs from the origin remote. Commands and workflows read the platform from THIS line — correct it if adopt guessed wrong. -->
|
|
7
8
|
|
|
8
9
|
- `supervised` — a human confirms each merge and each tracker close; issue **creation** is authorized by the `/start-milestone` sign-off itself. The milestone runner stops after each CLEAR verdict for the human merge — re-run `/start-milestone` to continue (closed issues are skipped). Use for a fresh adoption.
|
|
9
10
|
- `autonomous` (target) — humans decide at exactly two gates: Gate 1, sign-off of master PRD → sub-PRDs → tickets before the pipeline starts; Gate 2, a smoke test of the delivered milestone. Between them the pipeline self-drives: merge on CLEAR, `/verify-delivery` repairs gaps (including closing the issue) automatically. A human is pulled in only on the exception path — 2 bounce cycles without convergence, a failed build, or an unrepairable verify-delivery item.
|
package/scripts/adopt.mjs
CHANGED
|
@@ -54,18 +54,25 @@ if (!targetOk) {
|
|
|
54
54
|
process.exit(1)
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
// Platform detection (deterministic, offline). Signals in order:
|
|
58
|
+
// 1. origin host contains 'gitlab' / 'github' (covers *.gitlab.com, gitlab.corp, github.com)
|
|
59
|
+
// 2. repo-local signal: .gitlab-ci.yml -> glab; existing .github/ -> gh
|
|
60
|
+
// (this is what catches a self-hosted GitLab on a custom domain like git.company.com)
|
|
61
|
+
// 3. default gh, with a LOUD ambiguity note naming --platform
|
|
57
62
|
if (!PLATFORM) {
|
|
63
|
+
let host = ''
|
|
58
64
|
try {
|
|
59
65
|
const origin = execFileSync('git', ['-C', target, 'remote', 'get-url', 'origin'], {
|
|
60
66
|
encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'],
|
|
61
67
|
}).trim()
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
68
|
+
host = (origin.match(/(?:@|:\/\/)([^/:]+)[/:]/) || [])[1] || origin
|
|
69
|
+
} catch {}
|
|
70
|
+
const inconclusive = host ? `; origin host '${host}' was inconclusive` : ''
|
|
71
|
+
if (/gitlab/i.test(host)) { PLATFORM = 'glab'; console.log(`platform: glab (from origin host '${host}'; override with --platform)`) }
|
|
72
|
+
else if (/github/i.test(host)) { PLATFORM = 'gh'; console.log(`platform: gh (from origin host '${host}'; override with --platform)`) }
|
|
73
|
+
else if (existsSync(join(target, '.gitlab-ci.yml'))) { PLATFORM = 'glab'; console.log(`platform: glab (from .gitlab-ci.yml${inconclusive}; override with --platform)`) }
|
|
74
|
+
else if (existsSync(join(target, '.github'))) { PLATFORM = 'gh'; console.log(`platform: gh (from existing .github/${inconclusive}; override with --platform)`) }
|
|
75
|
+
else { PLATFORM = 'gh'; console.log(`platform: gh (default — ${host ? `could not classify origin host '${host}'` : 'no origin remote'}; pass --platform glab if this is a self-hosted GitLab)`) }
|
|
69
76
|
}
|
|
70
77
|
if (PLATFORM !== 'gh' && PLATFORM !== 'glab') {
|
|
71
78
|
console.error(`unknown platform: ${PLATFORM} (expected gh or glab)`)
|
|
@@ -157,8 +164,11 @@ if (existsSync(rootPrd) && !existsSync(docsPrd)) {
|
|
|
157
164
|
note(' (note) no PRD.md found — write docs/PRD.md before running /breakdown-prd')
|
|
158
165
|
}
|
|
159
166
|
|
|
160
|
-
// 6. CLAUDE.md: create from the snippet, or append it once (marker-checked, never duplicated)
|
|
167
|
+
// 6. CLAUDE.md: create from the snippet, or append it once (marker-checked, never duplicated).
|
|
168
|
+
// The snippet defaults its Tracker line to `gh`; rewrite it to the resolved platform so the
|
|
169
|
+
// pipeline reads the correct tracker from CLAUDE.md instead of re-guessing each run (issue #34).
|
|
161
170
|
const snippet = readFileSync(join(scaffold, 'claude-md-snippet.md'), 'utf8')
|
|
171
|
+
.replace('**Tracker: `gh`**', `**Tracker: \`${PLATFORM}\`**`)
|
|
162
172
|
const MARKER = '## Delivery pipeline — three-agent Architect / Builder / Reviewer'
|
|
163
173
|
const claudeMd = join(target, 'CLAUDE.md')
|
|
164
174
|
if (!existsSync(claudeMd)) {
|
package/scripts/build-site.mjs
CHANGED
|
@@ -61,7 +61,25 @@ function parsePattern(dir) {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
return { dir, title, status, asOf, summary, roles }
|
|
64
|
+
return { dir, title, status, asOf, summary, roles, commands: parseCommands(dir) }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Slash commands are the pattern's user-facing surface; the frontmatter of each
|
|
68
|
+
// scaffold/.claude/commands/*.md is the single source of truth. Rendering them here
|
|
69
|
+
// (and gating on them in E2E) is what keeps the site from silently omitting a shipped
|
|
70
|
+
// command the way /start-all was once missing (catalog issue #35).
|
|
71
|
+
function parseCommands(dir) {
|
|
72
|
+
const cdir = join(ROOT, 'patterns', dir, 'scaffold', '.claude', 'commands')
|
|
73
|
+
if (!existsSync(cdir)) return []
|
|
74
|
+
const fmField = (fm, name) => ((fm.match(new RegExp(`^${name}\\s*:\\s*(.+)$`, 'm')) || [])[1] || '').trim()
|
|
75
|
+
return readdirSync(cdir)
|
|
76
|
+
.filter((f) => f.endsWith('.md'))
|
|
77
|
+
.sort()
|
|
78
|
+
.map((f) => {
|
|
79
|
+
const md = readFileSync(join(cdir, f), 'utf8')
|
|
80
|
+
const fm = (md.match(/^---\r?\n([\s\S]*?)\r?\n---/) || [])[1] || ''
|
|
81
|
+
return { name: '/' + f.replace(/\.md$/, ''), hint: fmField(fm, 'argument-hint'), description: fmField(fm, 'description') }
|
|
82
|
+
})
|
|
65
83
|
}
|
|
66
84
|
|
|
67
85
|
const patterns = readdirSync(join(ROOT, 'patterns'), { withFileTypes: true })
|
|
@@ -155,6 +173,10 @@ const patternCards = patterns
|
|
|
155
173
|
<div class="roles">
|
|
156
174
|
${p.roles.map((r) => { const [dot, dotInk] = roleDot(r.role); return `<span class="role"><span class="dot" style="background:${dot};box-shadow:inset 1px 1.5px 1.5px rgba(255,255,255,0.6),inset -1px -1.5px 2px ${dotInk}"></span><b>${esc(r.role)}</b><span class="sep">·</span><code>${esc(r.model)} <span class="eff">@${esc(r.effort)}</span></code></span>` }).join('\n ')}
|
|
157
175
|
</div>
|
|
176
|
+
${p.commands.length ? `<div class="cmds">
|
|
177
|
+
<div class="cmds-label">Commands</div>
|
|
178
|
+
${p.commands.map((cmd) => `<div class="cmd"><code class="cmd-name">${esc(cmd.name)}</code>${cmd.hint ? `<code class="cmd-hint">${esc(cmd.hint)}</code>` : ''}<span class="cmd-desc">${esc(cmd.description)}</span></div>`).join('\n ')}
|
|
179
|
+
</div>` : ''}
|
|
158
180
|
<div class="links">
|
|
159
181
|
<a class="btn btn-green" href="${GITHUB}/tree/main/patterns/${esc(p.dir)}">Pattern write-up</a>
|
|
160
182
|
<a class="btn btn-purple" href="${GITHUB}/tree/main/patterns/${esc(p.dir)}/scaffold">Scaffold</a>
|
|
@@ -271,6 +293,15 @@ const html = `<!doctype html>
|
|
|
271
293
|
.role .eff{color:#e7548c}
|
|
272
294
|
.links{display:flex;gap:12px;margin-top:17px}
|
|
273
295
|
|
|
296
|
+
.cmds{margin-top:16px;border-radius:16px;background:var(--pill);padding:14px 16px 12px;
|
|
297
|
+
box-shadow:inset 0 3px 6px rgba(var(--flt),0.14),inset 0 -2px 2px rgba(255,255,255,0.7)}
|
|
298
|
+
.cmds-label{font-family:'Baloo 2',cursive;font-weight:700;font-size:13px;color:var(--ink);margin-bottom:9px}
|
|
299
|
+
.cmd{display:flex;align-items:baseline;flex-wrap:wrap;gap:8px;padding:5px 0;border-top:1px solid rgba(var(--flt),0.1)}
|
|
300
|
+
.cmd:first-of-type{border-top:0}
|
|
301
|
+
.cmd-name{font-family:var(--mono);font-size:12px;font-weight:700;color:#8a5fd0;white-space:nowrap}
|
|
302
|
+
.cmd-hint{font-family:var(--mono);font-size:10.5px;font-weight:700;color:var(--mut);white-space:nowrap}
|
|
303
|
+
.cmd-desc{font-size:11.5px;font-weight:700;color:var(--sub);line-height:1.5;flex:1;min-width:180px}
|
|
304
|
+
|
|
274
305
|
.steps{display:grid;grid-template-columns:repeat(5,1fr);gap:14px}
|
|
275
306
|
.step{border-radius:20px;background:var(--card);padding:15px 14px 17px;
|
|
276
307
|
box-shadow:inset 0 2px 2px #fff,inset 0 -3px 6px rgba(var(--ins),0.15),0 10px 20px rgba(var(--amb),0.22)}
|