@mmerterden/multi-agent-pipeline 8.6.0 → 8.6.2
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 +30 -49
- package/package.json +4 -1
- package/pipeline/commands/multi-agent/_account-picker.md +1 -1
- package/pipeline/commands/multi-agent/refs/features/dev-critic.md +44 -0
- package/pipeline/commands/multi-agent/refs/features/external-context-injection.md +63 -0
- package/pipeline/commands/multi-agent/refs/features/plan-todos.md +20 -0
- package/pipeline/commands/multi-agent/refs/features/prior-fix-detection.md +49 -0
- package/pipeline/commands/multi-agent/refs/features/repo-map.md +30 -0
- package/pipeline/commands/multi-agent/refs/features/shadow-git.md +24 -0
- package/pipeline/commands/multi-agent/refs/phases/phase-0-init.md +3 -3
- package/pipeline/commands/multi-agent/refs/phases/phase-1-analysis.md +4 -121
- package/pipeline/commands/multi-agent/refs/phases/phase-3-dev.md +4 -75
- package/pipeline/commands/multi-agent/refs/phases/phase-6-commit.md +1 -1
- package/pipeline/commands/multi-agent/setup.md +14 -6
- package/pipeline/commands/multi-agent/sync.md +26 -25
- package/pipeline/schemas/prefs.schema.json +2 -2
- package/pipeline/scripts/fixtures/install-layout.tsv +11 -11
- package/pipeline/scripts/smoke-issue-comment-template.sh +1 -1
- package/pipeline/scripts/smoke-personal-data.sh +5 -3
- package/pipeline/scripts/smoke-plan-todos.sh +5 -2
- package/pipeline/scripts/smoke-sync-adapters.sh +113 -0
- package/pipeline/scripts/smoke-sync-delegation.sh +1 -1
- package/pipeline/scripts/smoke-url-enrichment.sh +1 -1
- package/pipeline/scripts/sync-adapters.mjs +156 -0
- package/pipeline/skills/figma-common/figma-component-confluence-sync/SKILL.md +1 -1
- package/pipeline/skills/figma-common/figma-issue/SKILL.md +5 -5
- package/pipeline/skills/figma-common/figma-setup/SKILL.md +17 -17
- package/pipeline/skills/figma-common/figma-validate/SKILL.md +1 -1
- package/pipeline/skills/figma-ios/figma-to-component/SKILL.md +1 -1
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-6-code-connect.md +5 -5
- package/pipeline/skills/figma-ios/figma-to-component/reference/code-connect.md +1 -1
- package/pipeline/skills/figma-ios/figma-to-component/reference/rest-api-script.md +1 -1
- package/pipeline/skills/figma-ios/figma-to-component/reference/tools.md +1 -1
- package/pipeline/skills/figma-ios/figma-to-component/scripts/phase1-gather.py +1 -1
- package/pipeline/skills/shared/core/multi-agent-issue/SKILL.md +1 -1
- package/pipeline/scripts/.last-figma-sync-plan.json +0 -23
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
| Figma skills (iOS + Android + Common) | 37 |
|
|
19
19
|
| External skill catalog (`shared/external/`) | 127 |
|
|
20
20
|
| Total `SKILL.md` files across all groups | 196 |
|
|
21
|
-
| Smoke suites |
|
|
21
|
+
| Smoke suites | 88 |
|
|
22
22
|
| Golden-task fixtures (`pipeline/eval/golden-tasks/`) | 2 |
|
|
23
23
|
| Eval-triage fixtures | 11 |
|
|
24
24
|
| JSON schemas | 13 |
|
|
@@ -46,38 +46,24 @@ Full version history lives in [CHANGELOG.md](./CHANGELOG.md). Every release entr
|
|
|
46
46
|
|
|
47
47
|
- Node.js 18+
|
|
48
48
|
- Claude Code (https://claude.ai/code) **or** GitHub Copilot CLI
|
|
49
|
-
- macOS
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
- ✅ `read:packages`
|
|
61
|
-
- ✅ `repo` (required for private package access)
|
|
62
|
-
|
|
63
|
-
If your GitHub account belongs to an SSO-enforced organization, after creating the token click **"Configure SSO" → Authorize** on the token row.
|
|
64
|
-
|
|
65
|
-
### 2. Configure `~/.npmrc`
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
# Replace ghp_xxx with the token from step 1
|
|
69
|
-
echo "@mmerterden:registry=https://npm.pkg.github.com" >> ~/.npmrc
|
|
70
|
-
echo "//npm.pkg.github.com/:_authToken=ghp_xxx" >> ~/.npmrc
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### 3. Verify access
|
|
49
|
+
- macOS, Linux, or Windows (Git Bash / WSL). Native credential storage everywhere:
|
|
50
|
+
- **macOS** → Keychain (`security`)
|
|
51
|
+
- **Linux** → libsecret (`secret-tool` — `apt install libsecret-tools` / `dnf install libsecret`)
|
|
52
|
+
- **Windows** → Credential Manager (PowerShell `CredentialManager` module — `Install-Module CredentialManager`)
|
|
53
|
+
- Runtime CLIs the pipeline shells out to:
|
|
54
|
+
- `gh` (GitHub CLI) for issue / PR flows
|
|
55
|
+
- `jq` for JSON parsing
|
|
56
|
+
- `python3` (stdlib only, used by the deterministic keychain helper)
|
|
57
|
+
- `bash` 4+
|
|
58
|
+
|
|
59
|
+
The package is **public on npmjs.org** — no auth, no PAT, no `~/.npmrc` setup needed:
|
|
74
60
|
|
|
75
61
|
```bash
|
|
76
62
|
npm view @mmerterden/multi-agent-pipeline version
|
|
77
|
-
# → prints "
|
|
63
|
+
# → prints "8.6.1" (or newer)
|
|
78
64
|
```
|
|
79
65
|
|
|
80
|
-
If
|
|
66
|
+
If `npm view` shows a stale version, run `npm cache clean --force` and retry.
|
|
81
67
|
|
|
82
68
|
> **New here?** Worked end-to-end transcripts live in [`examples/`](./examples/) — bug fix from Jira, feature in autopilot, `--dev` fast path, and recovery from a broken run. Read one before you run the pipeline on your own code.
|
|
83
69
|
>
|
|
@@ -87,9 +73,9 @@ If this fails, see [Troubleshooting](#troubleshooting) below.
|
|
|
87
73
|
|
|
88
74
|
## Quick Start
|
|
89
75
|
|
|
90
|
-
### Option A — Install from source (recommended
|
|
76
|
+
### Option A — Install from source (recommended for development)
|
|
91
77
|
|
|
92
|
-
|
|
78
|
+
Clone the repo and run the installer directly — full read access to source files.
|
|
93
79
|
|
|
94
80
|
```bash
|
|
95
81
|
git clone git@github.com:mmerterden/multi-agent-pipeline.git
|
|
@@ -127,7 +113,7 @@ This discovers your Keychain tokens (Jira, Bitbucket, GitHub, etc.), sets up you
|
|
|
127
113
|
|
|
128
114
|
Update later with `git pull && npm install` inside the clone. Pin to a specific version by checking out the corresponding tag (`git tag -l` to list).
|
|
129
115
|
|
|
130
|
-
### Option B — npx (
|
|
116
|
+
### Option B — npx (public registry, no auth)
|
|
131
117
|
|
|
132
118
|
```bash
|
|
133
119
|
npx @mmerterden/multi-agent-pipeline install # Claude Code (default)
|
|
@@ -143,7 +129,7 @@ npx @mmerterden/multi-agent-pipeline uninstall # interactive, all targe
|
|
|
143
129
|
npx @mmerterden/multi-agent-pipeline uninstall --dry-run # preview only
|
|
144
130
|
```
|
|
145
131
|
|
|
146
|
-
### Option C — Global install (
|
|
132
|
+
### Option C — Global install (public registry, no auth)
|
|
147
133
|
|
|
148
134
|
```bash
|
|
149
135
|
npm install -g @mmerterden/multi-agent-pipeline
|
|
@@ -177,32 +163,27 @@ slows down the install.
|
|
|
177
163
|
|
|
178
164
|
### `sh: multi-agent-pipeline: command not found`
|
|
179
165
|
|
|
180
|
-
npx couldn't fetch the package
|
|
166
|
+
`npx` couldn't fetch the package. Most common causes:
|
|
181
167
|
|
|
182
|
-
|
|
168
|
+
- Network blocked or proxy in front of npmjs.org.
|
|
169
|
+
- Stale npx cache — `npx clear-npx-cache` then retry.
|
|
170
|
+
- Wrong package name (it is `@mmerterden/multi-agent-pipeline`, with the scope).
|
|
183
171
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
- PAT is fine-grained instead of **Classic**. Recreate as Classic.
|
|
187
|
-
- PAT is missing `repo` scope. Private packages require both `read:packages` **and** `repo`.
|
|
188
|
-
- SSO not authorized. On the token row, click **"Configure SSO" → Authorize** for the relevant org.
|
|
189
|
-
- Token expired or revoked.
|
|
172
|
+
### `npm error code E404` on `registry.npmjs.org`
|
|
190
173
|
|
|
191
|
-
Quick
|
|
174
|
+
The package wasn't reachable. Quick checks:
|
|
192
175
|
|
|
193
176
|
```bash
|
|
194
|
-
curl -
|
|
195
|
-
|
|
177
|
+
curl -fsSL "https://registry.npmjs.org/@mmerterden/multi-agent-pipeline" | jq -r '."dist-tags".latest'
|
|
178
|
+
# Should print 8.6.1 (or newer)
|
|
196
179
|
```
|
|
197
180
|
|
|
198
|
-
-
|
|
199
|
-
-
|
|
200
|
-
- `403` — token valid but no repo access. Ask the repo owner to add you as a collaborator.
|
|
201
|
-
- `404` — scope misconfigured in `~/.npmrc`, or package name is wrong.
|
|
181
|
+
- If this prints a version → your local npm cache is stale; run `npm cache clean --force` and retry.
|
|
182
|
+
- If it 404s → registry outage or scope/package-name typo. Verify the URL hits the JSON above.
|
|
202
183
|
|
|
203
|
-
###
|
|
184
|
+
### Older PAT / GitHub Packages docs
|
|
204
185
|
|
|
205
|
-
|
|
186
|
+
Earlier README revisions referenced GitHub Packages with a Classic PAT and `~/.npmrc` setup. The package moved to **public npmjs.org** in v8.6.1; no token, no `~/.npmrc` line is needed. If you set one up previously, you can leave it — it just won't be consulted.
|
|
206
187
|
|
|
207
188
|
## Tool support
|
|
208
189
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmerterden/multi-agent-pipeline",
|
|
3
|
-
"version": "8.6.
|
|
3
|
+
"version": "8.6.2",
|
|
4
4
|
"description": "8-phase AI development pipeline. Full orchestration on Claude Code + Copilot CLI; knowledge layer (rules + skills) ports to Cursor, Windsurf, and Cline. Analysis, planning, TDD, CLI-aware parallel review with Opus triage, wiki generation, commit automation. Token-preserving uninstall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -46,6 +46,9 @@
|
|
|
46
46
|
],
|
|
47
47
|
"author": "Mert Erden",
|
|
48
48
|
"license": "MIT",
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"registry": "https://npm.pkg.github.com"
|
|
51
|
+
},
|
|
49
52
|
"repository": {
|
|
50
53
|
"type": "git",
|
|
51
54
|
"url": "https://github.com/mmerterden/multi-agent-pipeline.git"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Feature: Dev Critic (Phase 3 Step 3.5 Evaluator-Optimizer)
|
|
2
|
+
|
|
3
|
+
**Pattern**: Anthropic's evaluator-optimizer from "Building Effective Agents" (Dec 2024). Generator (Phase 3 Dev) and critic (`agents/dev-critic.md`) loop on deterministic criteria already written in `rules/*.md` before any Phase 4 reviewer call.
|
|
4
|
+
|
|
5
|
+
**Gated by `prefs.global.devCritic.enabled`** (default: `false`). When enabled, after the generator's last edit and BEFORE Phase 4:
|
|
6
|
+
|
|
7
|
+
1. Dispatch `dev-critic` sub-agent (Sonnet by default, tools: `Read, Grep, Glob, Bash`).
|
|
8
|
+
2. Critic runs 4 deterministic gates (build / lint / test / secrets) — failure of any → `pass: false` with `blocking` finding.
|
|
9
|
+
3. If gates green, critic walks the platform checklist (iOS 13-item / Android Kotlin / Backend generic — selected by Phase 1 `detectedStack`).
|
|
10
|
+
4. Returns schema-validated JSON (`pipeline/schemas/dev-critic-output.schema.json`): `{pass, iteration, gates, findings[], escalate}`.
|
|
11
|
+
|
|
12
|
+
## Loop cap (STRICT) — max 2 iterations
|
|
13
|
+
|
|
14
|
+
| Round | Behavior |
|
|
15
|
+
|---|---|
|
|
16
|
+
| 1 | Full critic pass — all gates + full checklist |
|
|
17
|
+
| 2 | Re-check only round-1 failures. No new findings allowed (scope creep prevention) |
|
|
18
|
+
| 3+ | NOT ALLOWED. Critic returns `escalate: true`; orchestrator pauses (interactive) or proceeds to Phase 4 with logged failure (autopilot) |
|
|
19
|
+
|
|
20
|
+
## Action by severity
|
|
21
|
+
|
|
22
|
+
- `blocking` → generator MUST fix; another Dev iteration before re-critic
|
|
23
|
+
- `important` → generator SHOULD fix; if skipped, pass through to Phase 4 (legitimate reviewer ground)
|
|
24
|
+
- `suggestion` → generator's judgement; never blocks round 2
|
|
25
|
+
|
|
26
|
+
## Telemetry
|
|
27
|
+
|
|
28
|
+
Each critic call emits `dev_critic.call` with `iteration`, `pass`, `gates_failed`, `blocking`, `important`, `duration_ms`, `tokens_in/out`. Phase 7 cost rollup lists these as `phase 3.5` line items so the net saving (Phase 4 reviewer/triage calls avoided) is measurable.
|
|
29
|
+
|
|
30
|
+
## Off by default reason
|
|
31
|
+
|
|
32
|
+
Introduces ~1× Sonnet call per Dev iteration. On simple bug fixes the cost outweighs the benefit (Phase 4 would have caught the same thing for similar cost). Recommended on:
|
|
33
|
+
|
|
34
|
+
- Feature work (≥200 LOC diff)
|
|
35
|
+
- Security-touching paths (auth, keychain, network)
|
|
36
|
+
- Multi-file refactors where rule violations compound
|
|
37
|
+
|
|
38
|
+
## Why this fits orchestrator-workers + evaluator-optimizer hybrid
|
|
39
|
+
|
|
40
|
+
Phase 4 is parallelization-with-voting — good for *adversarial* perspectives (security, architecture). Phase 3.5 is evaluator-optimizer — good for *deterministic* criteria (build, tests, checklists). Sending failing builds into Phase 4 wastes 2–3 reviewer calls + Opus triage; Phase 3.5 absorbs that cost at one Sonnet call.
|
|
41
|
+
|
|
42
|
+
## Reference
|
|
43
|
+
|
|
44
|
+
See `pipeline/agents/dev-critic.md` for the full agent specification (gates, checklist enumeration, output schema, severity semantics).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Feature: External Context Injection (Phase 1 Step 1.5)
|
|
2
|
+
|
|
3
|
+
Phase 0 Step 1b catalogued every typed external link from the task description into `state.contextLinks[]`. Phase 1 dispatches each entry to its matching fetcher and prepends the result to the analysis prompt under a **Referenced External Sources** section, so the agent doesn't re-discover what the ticket already pointed at.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
jq -c '.contextLinks // []' "$STATE_FILE" \
|
|
7
|
+
| python3 -c '
|
|
8
|
+
import json, sys, os
|
|
9
|
+
links = json.loads(sys.stdin.read() or "[]")
|
|
10
|
+
by_type = {}
|
|
11
|
+
for l in links:
|
|
12
|
+
by_type.setdefault(l["type"], []).append(l)
|
|
13
|
+
print(json.dumps(by_type))
|
|
14
|
+
' > /tmp/context-by-type-${TASK_ID}.json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Dispatch table
|
|
18
|
+
|
|
19
|
+
One fetcher per type. Each fetcher emits a normalized JSON view that the analysis prompt consumes as ground truth for the referenced source.
|
|
20
|
+
|
|
21
|
+
| Type | Fetcher | Output stored in |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `crashlytics` | `~/.claude/lib/fetch-crashlytics.sh <url>` (already invoked in Phase 0 Step 1b.1 for the legacy `state.crashContext` field; Phase 1 reads that field directly) | `state.crashContext` |
|
|
24
|
+
| `fortify` | `~/.claude/lib/fetch-fortify.sh <url>` (already invoked in Phase 0 Step 1b.2 for the legacy `state.fortifyFinding` field; Phase 1 reads that field, Phase 4 reads the full payload for the security gate) | `state.fortifyFinding` |
|
|
25
|
+
| `swagger` | `~/.claude/lib/fetch-swagger.sh <url>` → endpoints[], request/response examples | `state.fetchedContext.swagger[]` |
|
|
26
|
+
| `confluence` | `~/.claude/lib/fetch-confluence.sh <url>` → page body, code blocks, extracted API contracts | `state.fetchedContext.confluence[]` |
|
|
27
|
+
| `figma` | `~/.claude/lib/fetch-figma.sh <url>` (via existing MCP / REST fallback path) when the task is a component; otherwise advisory only | `state.fetchedContext.figma[]` |
|
|
28
|
+
| `generic-doc` | no automatic fetcher — surfaced as advisory; the agent uses WebFetch on demand when the URL turns out to be load-bearing | n/a |
|
|
29
|
+
|
|
30
|
+
## Exit code handling
|
|
31
|
+
|
|
32
|
+
- `0` (success) → output appended to `state.fetchedContext.<type>[]` and injected into the prompt.
|
|
33
|
+
- `2` (blocked / missing token) → run the inline Token Save Flow per `setup.md`; on skip, mark the entry as `{status: "skipped", reason: "missing-token"}` and continue.
|
|
34
|
+
- `3` (network/auth) → mark as `{status: "failed", reason: "<exit-msg>"}`, continue.
|
|
35
|
+
- `4`/`5`/`6` (config errors) → mark as `{status: "failed", reason: "<exit-msg>"}`, continue and log a setup hint.
|
|
36
|
+
|
|
37
|
+
Failures are never fatal at Phase 1 — the agent still runs analysis, just without the referenced source.
|
|
38
|
+
|
|
39
|
+
## Prompt injection shape
|
|
40
|
+
|
|
41
|
+
Added immediately after the knowledge-injection block, before codebase exploration:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
## Referenced External Sources
|
|
45
|
+
|
|
46
|
+
(when fetchers populated `state.fetchedContext.<type>`)
|
|
47
|
+
### <type> — <url>
|
|
48
|
+
<fetched content, scoped to relevance>
|
|
49
|
+
|
|
50
|
+
(when fetcher pending)
|
|
51
|
+
### Pending references
|
|
52
|
+
- <type>: <url> — <one-line metadata>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The agent treats fetched content as **ground truth** for the referenced source (no re-discovery, no contradiction). Pending references are advisories — the agent decides whether to fetch via WebFetch on demand when the task hinges on that source.
|
|
56
|
+
|
|
57
|
+
## Log line shape
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
→ context injection: total=<N>, fetched=<n>, pending=<n>, by-type={swagger:F/P, confluence:F/P, ...}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`F` = fetched, `P` = pending. Empty contextLinks → `total=0`, skip the section entirely.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Feature: Plan Todos Iteration (Phase 3)
|
|
2
|
+
|
|
3
|
+
**Gated by `prefs.global.planTodos.enabled`** (default: `false`). When enabled and Phase 2 Step 4.5 emitted a `plan.todos[]` (conforming to `pipeline/schemas/plan-todos.schema.json`), Phase 3 iterates with the helper instead of walking `tasks[]` directly:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
while next=$(bash "$HOME/.claude/lib/plan-todos.sh" next "$TASK_ID"); [ -n "$next" ]; do
|
|
7
|
+
id=$(printf '%s' "$next" | cut -f1)
|
|
8
|
+
task=$(printf '%s' "$next" | cut -f2)
|
|
9
|
+
bash "$HOME/.claude/lib/plan-todos.sh" start "$TASK_ID" "$id"
|
|
10
|
+
# ... TDD cycle for "$task" ...
|
|
11
|
+
if build_passed; then
|
|
12
|
+
bash "$HOME/.claude/lib/plan-todos.sh" complete "$TASK_ID" "$id" "${COMMIT_HASH} · tests:${TEST_COUNT}"
|
|
13
|
+
else
|
|
14
|
+
bash "$HOME/.claude/lib/plan-todos.sh" fail "$TASK_ID" "$id" "build failed after 3 retries"
|
|
15
|
+
break
|
|
16
|
+
fi
|
|
17
|
+
done
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
When disabled, the loop still walks `tasks[]` from `planning-output` — `plan-todos.sh` adds visibility (status, notes, deps-respecting `next`) but the underlying TDD contract is unchanged.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Feature: Prior Fix Detection (Phase 1 Step 0)
|
|
2
|
+
|
|
3
|
+
Before any analysis, check if this issue was already fixed by someone else.
|
|
4
|
+
|
|
5
|
+
## Check order
|
|
6
|
+
|
|
7
|
+
1. **Git commit search** — look for commits referencing this issue ID across all branches:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git -C $PROJECT_ROOT log --all --oneline --grep="{jiraId}" --since="8 weeks ago"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
2. **Affected file history** — after identifying key files (from issue description keywords), check recent changes:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
git -C $PROJECT_ROOT log --oneline --since="4 weeks ago" -- {affected_file_paths}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
3. **Jira comments/status** — fetch latest comments to see if someone reported a fix:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
curl -s -H "Authorization: Bearer $JIRA_TOKEN" \
|
|
23
|
+
"$JIRA_BASE/issue/{jiraId}?fields=status,comment&expand=changelog" \
|
|
24
|
+
| jq '.fields.status.name, .fields.comment.comments[-3:][]?.body'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## If prior fix commit(s) found
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
This issue appears to already have been addressed:
|
|
31
|
+
{hash} — {message} (by {author}, {date})
|
|
32
|
+
|
|
33
|
+
Options:
|
|
34
|
+
1. Verify fix (check if cherry-pick/merge to base branch is needed)
|
|
35
|
+
2. Stop pipeline (already resolved)
|
|
36
|
+
3. Continue anyway (different fix needed)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- Option 1 → Check if the commit exists on `baseBranch`. If not, suggest cherry-pick. Pipeline pauses.
|
|
40
|
+
- Option 2 → Cleanup and exit:
|
|
41
|
+
1. Checkout back to base branch: `git -C $PROJECT_ROOT checkout {baseBranch}`
|
|
42
|
+
2. Delete the created branch: `git -C $PROJECT_ROOT branch -D {branch}`
|
|
43
|
+
3. If worktree was used: `git -C $PROJECT_ROOT worktree remove {worktreePath} --force`
|
|
44
|
+
4. Set `agent-state.json` status to `"stopped_already_fixed"`. Log and exit.
|
|
45
|
+
- Option 3 → Continue to Step 1 as normal.
|
|
46
|
+
|
|
47
|
+
## If no prior fix found
|
|
48
|
+
|
|
49
|
+
Continue to Step 1 (Knowledge Injection).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Feature: Repo Map Injection (Phase 1 Step 2.5)
|
|
2
|
+
|
|
3
|
+
**Gated by `prefs.global.repoMap.enabled`** (default: `false`). Pattern source: <https://aider.chat/docs/repomap.html>.
|
|
4
|
+
|
|
5
|
+
Before launching Explore agents, run the deterministic repo map renderer and inject the result into each Explore prompt as `${REPO_MAP}`. This gives every explorer a token-budgeted overview of the most-referenced files in the repo — ranked via cross-file declaration references with TF-IDF-style credit splitting so universally-shared helper names (`pass`, `fail`, `init`) don't dominate.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
REPO_MAP=""
|
|
9
|
+
if [ "$(jq -r '.global.repoMap.enabled // false' "$PREFS")" = "true" ]; then
|
|
10
|
+
BUDGET=$(jq -r '.global.repoMap.tokenBudget // 1500' "$PREFS")
|
|
11
|
+
TOP=$(jq -r '.global.repoMap.topFiles // 25' "$PREFS")
|
|
12
|
+
INCLUDE=$(jq -r '.global.repoMap.include // empty' "$PREFS")
|
|
13
|
+
EXCLUDE=$(jq -r '.global.repoMap.exclude // empty' "$PREFS")
|
|
14
|
+
args=(--root "$WORKTREE" --budget "$BUDGET" --top "$TOP" --format md)
|
|
15
|
+
[ -n "$INCLUDE" ] && args+=(--include "$INCLUDE")
|
|
16
|
+
[ -n "$EXCLUDE" ] && args+=(--exclude "$EXCLUDE")
|
|
17
|
+
REPO_MAP=$(node pipeline/scripts/repo-map.mjs "${args[@]}" 2>/dev/null || echo "")
|
|
18
|
+
fi
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Properties
|
|
22
|
+
|
|
23
|
+
- **Deterministic** — same worktree state → same map. No embeddings, no network. Sub-second on monorepos.
|
|
24
|
+
- **Advisory** — Explore agents may ignore the map if they have stronger signals (Phase 0 knowledge cache, explicit user context). Never gates the pipeline.
|
|
25
|
+
- **Truncation-safe** — output is capped at `tokenBudget`; the script falls back to "no files extracted within budget" rather than over-spending.
|
|
26
|
+
- **Cost ledger** — emit `phase-1.repo_map_emitted bytes=$(wc -c <<<"$REPO_MAP") budget=$BUDGET` so Phase 7 cost summary can show the size injected.
|
|
27
|
+
|
|
28
|
+
## When to enable
|
|
29
|
+
|
|
30
|
+
Large repos (>200 source files) where Explore otherwise spends multiple rounds finding the right starting files. Skip on small repos — the overhead exceeds the gain.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Feature: Shadow-Git Checkpoints (Phase 3)
|
|
2
|
+
|
|
3
|
+
**Gated by `prefs.global.shadowGit.enabled`** (default: `false`). The orchestrator snapshots the worktree via `pipeline/lib/shadow-git.sh` so sub-phase rollback is possible without polluting the project's real `.git` history. Pattern source: Cline checkpoints (<https://docs.cline.bot/features/checkpoints>).
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# Phase 0 (one-time per task): initialize shadow repo + baseline snapshot.
|
|
7
|
+
bash "$HOME/.claude/lib/shadow-git.sh" init "$TASK_ID" "$WORKTREE"
|
|
8
|
+
|
|
9
|
+
# Per-step (mode: per-todo-step — default): snapshot AFTER each plan-todos
|
|
10
|
+
# step completes successfully, so restore lands on a known-good state.
|
|
11
|
+
bash "$HOME/.claude/lib/plan-todos.sh" complete "$TASK_ID" "$id" "$notes"
|
|
12
|
+
bash "$HOME/.claude/lib/shadow-git.sh" snapshot "$TASK_ID" "$WORKTREE" "step $id: $task"
|
|
13
|
+
|
|
14
|
+
# Per-mutation (mode: per-tool-call): the orchestrator hooks into every Edit/
|
|
15
|
+
# Write/MultiEdit/Bash-mutation tool call. Higher fidelity, ~50ms × tool-call
|
|
16
|
+
# overhead — recommended only for security-critical paths or experimental
|
|
17
|
+
# refactors where the user values fine-grained rollback over speed.
|
|
18
|
+
|
|
19
|
+
# Rollback on demand (interactive helper):
|
|
20
|
+
bash "$HOME/.claude/lib/shadow-git.sh" list "$TASK_ID"
|
|
21
|
+
bash "$HOME/.claude/lib/shadow-git.sh" restore "$TASK_ID" "$WORKTREE" <sha> --files
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Shadow repo location: `~/.claude/state/shadow-git/<task-id>/.git/`. Storage cap: `prefs.shadowGit.pruneAfterDays` (default 14). `/multi-agent:purge` honors this prune; manual cleanup via `shadow-git.sh prune <task-id>`.
|
|
@@ -65,7 +65,7 @@ Used for: input parsing, branch naming, commit messages.
|
|
|
65
65
|
|
|
66
66
|
**Save rule**: After EVERY selection, append chosen value to relevant array (dedup, most recent first, max 10). Save prefs after Phase 0 and Phase 7.
|
|
67
67
|
|
|
68
|
-
**Recents update map** (which selection writes to which prefs path):
|
|
68
|
+
**v2.1.0+ Recents update map** (which selection writes to which prefs path):
|
|
69
69
|
|
|
70
70
|
| Selection event | Prefs path | Shape | Cap |
|
|
71
71
|
|---|---|---|---|
|
|
@@ -208,7 +208,7 @@ Scan `$HOME` (maxdepth 2) for project markers (`.xcodeproj`, `Package.swift`, `b
|
|
|
208
208
|
|
|
209
209
|
**Otherwise**: Present discovered projects as numbered list (standard UX pattern). Stack tag (`[iOS]`, `[Android]`, etc.) auto-detected from project files. Set `PROJECT_ROOT` to selected directory — all subsequent commands use `git -C $PROJECT_ROOT`. Save to `prefs.global.recentProjects` (dedup, max 10). If bare `#N` was given, now fetch GitHub issue from project's remote.
|
|
210
210
|
|
|
211
|
-
**Multi-Repo Mode** (gated by `prefs.global.settings.multiRepoEnabled`):
|
|
211
|
+
**v2.1.0+ Multi-Repo Mode** (gated by `prefs.global.settings.multiRepoEnabled`):
|
|
212
212
|
|
|
213
213
|
- The picker accepts space-separated numbers (`1 3 4`) for multi-select.
|
|
214
214
|
- `prefs.global.recentGroups[]` (set in setup.md Step 6) surfaces at the top: pressing the group's number selects all its repos in one keystroke.
|
|
@@ -354,7 +354,7 @@ git -C $PROJECT_ROOT config user.email "{identity.email}"
|
|
|
354
354
|
|
|
355
355
|
**If normal mode** (worktree — default): 2. Worktree path: Jira → `.worktrees/{jiraId}/`, GitHub → `.worktrees/GH{issueNo}/`, free-text → `.worktrees/task-{shortId}/` 3. `git -C $PROJECT_ROOT worktree add {path} -b {branch} origin/{baseBranch}` (if exists: enter, pull) 4. Set identity: `git -C {worktree-path} config user.name/email` 5. Create log dir + `agent-log.md` + `agent-state.json`:
|
|
356
356
|
|
|
357
|
-
**Multi-Repo Worktree Setup**:
|
|
357
|
+
**v2.1.0+ Multi-Repo Worktree Setup**:
|
|
358
358
|
|
|
359
359
|
When `state.projects[].length > 1`, repeat steps 2-4 **serially per repo** (worktrees are cheap; serial keeps git index sane and surfaces collisions one at a time):
|
|
360
360
|
|
|
@@ -7,50 +7,7 @@ Progress emission per `refs/progress-contract.md` — lines for each Explore dis
|
|
|
7
7
|
|
|
8
8
|
#### Step 0 — Prior Fix Detection
|
|
9
9
|
|
|
10
|
-
Before any analysis, check if this issue was already fixed by someone else.
|
|
11
|
-
|
|
12
|
-
**Check order:**
|
|
13
|
-
|
|
14
|
-
1. **Git commit search** — look for commits referencing this issue ID across all branches:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
git -C $PROJECT_ROOT log --all --oneline --grep="{jiraId}" --since="8 weeks ago"
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
2. **Affected file history** — after identifying key files (from issue description keywords), check recent changes:
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
git -C $PROJECT_ROOT log --oneline --since="4 weeks ago" -- {affected_file_paths}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
3. **Jira comments/status** — fetch latest comments to see if someone reported a fix:
|
|
27
|
-
```bash
|
|
28
|
-
curl -s -H "Authorization: Bearer $JIRA_TOKEN" \
|
|
29
|
-
"$JIRA_BASE/issue/{jiraId}?fields=status,comment&expand=changelog" \
|
|
30
|
-
| jq '.fields.status.name, .fields.comment.comments[-3:][]?.body'
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
**If prior fix commit(s) found:**
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
This issue appears to already have been addressed:
|
|
37
|
-
{hash} — {message} (by {author}, {date})
|
|
38
|
-
|
|
39
|
-
Options:
|
|
40
|
-
1. Verify fix (check if cherry-pick/merge to base branch is needed)
|
|
41
|
-
2. Stop pipeline (already resolved)
|
|
42
|
-
3. Continue anyway (different fix needed)
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
- Option 1 → Check if the commit exists on `baseBranch`. If not, suggest cherry-pick. Pipeline pauses.
|
|
46
|
-
- Option 2 → Cleanup and exit:
|
|
47
|
-
1. Checkout back to base branch: `git -C $PROJECT_ROOT checkout {baseBranch}`
|
|
48
|
-
2. Delete the created branch: `git -C $PROJECT_ROOT branch -D {branch}`
|
|
49
|
-
3. If worktree was used: `git -C $PROJECT_ROOT worktree remove {worktreePath} --force`
|
|
50
|
-
4. Set `agent-state.json` status to `"stopped_already_fixed"`. Log and exit.
|
|
51
|
-
- Option 3 → Continue to Step 1 as normal.
|
|
52
|
-
|
|
53
|
-
**If no prior fix found** → continue to Step 1.
|
|
10
|
+
Before any analysis, check if this issue was already fixed by someone else. Three signals (git commit grep on issue ID over 8 weeks, recent file-path history over 4 weeks, Jira/issue comments). On hit → prompt: Verify (cherry-pick path) / Stop (cleanup + `stopped_already_fixed` state) / Continue. Miss → Step 1. Full check commands, prompt block, and cleanup commands: `refs/features/prior-fix-detection.md`.
|
|
54
11
|
|
|
55
12
|
#### Step 1 — Knowledge Injection (cached context)
|
|
56
13
|
|
|
@@ -90,63 +47,14 @@ Exit 0 with empty output = pref off or no memory on disk — skip. Otherwise the
|
|
|
90
47
|
|
|
91
48
|
#### Step 1.5 — External Context Injection (`state.contextLinks[]`)
|
|
92
49
|
|
|
93
|
-
Phase 0 Step 1b catalogued every typed external link from the task description into `state.contextLinks[]`. Phase 1
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
jq -c '.contextLinks // []' "$STATE_FILE" \
|
|
97
|
-
| python3 -c '
|
|
98
|
-
import json, sys, os
|
|
99
|
-
links = json.loads(sys.stdin.read() or "[]")
|
|
100
|
-
by_type = {}
|
|
101
|
-
for l in links:
|
|
102
|
-
by_type.setdefault(l["type"], []).append(l)
|
|
103
|
-
print(json.dumps(by_type))
|
|
104
|
-
' > /tmp/context-by-type-${TASK_ID}.json
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Dispatch table — one fetcher per type. Each fetcher emits a normalized JSON view that the analysis prompt consumes as ground truth for the referenced source.
|
|
108
|
-
|
|
109
|
-
| Type | Fetcher | Output stored in |
|
|
110
|
-
|---|---|---|
|
|
111
|
-
| `crashlytics` | `~/.claude/lib/fetch-crashlytics.sh <url>` (already invoked in Phase 0 Step 1b.1 for the legacy `state.crashContext` field; Phase 1 reads that field directly) | `state.crashContext` |
|
|
112
|
-
| `fortify` | `~/.claude/lib/fetch-fortify.sh <url>` (already invoked in Phase 0 Step 1b.2 for the legacy `state.fortifyFinding` field; Phase 1 reads that field, Phase 4 reads the full payload for the security gate) | `state.fortifyFinding` |
|
|
113
|
-
| `swagger` | `~/.claude/lib/fetch-swagger.sh <url>` → endpoints[], request/response examples | `state.fetchedContext.swagger[]` |
|
|
114
|
-
| `confluence` | `~/.claude/lib/fetch-confluence.sh <url>` → page body, code blocks, extracted API contracts | `state.fetchedContext.confluence[]` |
|
|
115
|
-
| `figma` | `~/.claude/lib/fetch-figma.sh <url>` (via existing MCP / REST fallback path) when the task is a component; otherwise advisory only | `state.fetchedContext.figma[]` |
|
|
116
|
-
| `generic-doc` | no automatic fetcher — surfaced as advisory; the agent uses WebFetch on demand when the URL turns out to be load-bearing | n/a |
|
|
50
|
+
Phase 0 Step 1b catalogued every typed external link from the task description into `state.contextLinks[]`. Phase 1 dispatches each entry to its matching fetcher (crashlytics, fortify, swagger, confluence, figma, generic-doc) and prepends results under a **Referenced External Sources** section in the analysis prompt — so the agent doesn't re-discover what the ticket already pointed at. Failures never fatal; pending refs are advisories. Full dispatch table, exit-code handling, prompt injection shape, log line shape: `refs/features/external-context-injection.md`.
|
|
117
51
|
|
|
118
|
-
|
|
119
|
-
- `0` (success) → output appended to `state.fetchedContext.<type>[]` and injected into the prompt.
|
|
120
|
-
- `2` (blocked / missing token) → run the inline Token Save Flow per `setup.md`; on skip, mark the entry as `{status: "skipped", reason: "missing-token"}` and continue.
|
|
121
|
-
- `3` (network/auth) → mark as `{status: "failed", reason: "<exit-msg>"}`, continue.
|
|
122
|
-
- `4`/`5`/`6` (config errors) → mark as `{status: "failed", reason: "<exit-msg>"}`, continue and log a setup hint.
|
|
123
|
-
|
|
124
|
-
Failures are never fatal at Phase 1 — the agent still runs analysis, just without the referenced source.
|
|
125
|
-
|
|
126
|
-
**Prompt injection shape** (added immediately after the knowledge-injection block, before codebase exploration):
|
|
127
|
-
|
|
128
|
-
```
|
|
129
|
-
## Referenced External Sources
|
|
130
|
-
|
|
131
|
-
(when fetchers populated `state.fetchedContext.<type>`)
|
|
132
|
-
### <type> — <url>
|
|
133
|
-
<fetched content, scoped to relevance>
|
|
134
|
-
|
|
135
|
-
(when fetcher pending)
|
|
136
|
-
### Pending references
|
|
137
|
-
- <type>: <url> — <one-line metadata>
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
The agent treats fetched content as **ground truth** for the referenced source (no re-discovery, no contradiction). Pending references are advisories — the agent decides whether to fetch via WebFetch on demand when the task hinges on that source.
|
|
141
|
-
|
|
142
|
-
**Log line shape**:
|
|
52
|
+
**Log line shape** (progress contract):
|
|
143
53
|
|
|
144
54
|
```
|
|
145
55
|
→ context injection: total=<N>, fetched=<n>, pending=<n>, by-type={swagger:F/P, confluence:F/P, ...}
|
|
146
56
|
```
|
|
147
57
|
|
|
148
|
-
`F` = fetched, `P` = pending. Empty contextLinks → `total=0`, skip the section entirely.
|
|
149
|
-
|
|
150
58
|
#### Step 2 — Stack Detection
|
|
151
59
|
|
|
152
60
|
Detect the project's tech stack to load appropriate skills and tooling throughout the pipeline. Auto-detect by scanning `$PROJECT_ROOT` (maxdepth 2) for project markers:
|
|
@@ -171,32 +79,7 @@ This informs:
|
|
|
171
79
|
|
|
172
80
|
#### Step 2.5 — Repo Map Injection (advisory, opt-in)
|
|
173
81
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
Before launching Explore agents, run the deterministic repo map renderer and inject the result into each Explore prompt as `${REPO_MAP}`. This gives every explorer a token-budgeted overview of the most-referenced files in the repo — ranked via cross-file declaration references with TF-IDF-style credit splitting so universally-shared helper names (`pass`, `fail`, `init`) don't dominate.
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
REPO_MAP=""
|
|
180
|
-
if [ "$(jq -r '.global.repoMap.enabled // false' "$PREFS")" = "true" ]; then
|
|
181
|
-
BUDGET=$(jq -r '.global.repoMap.tokenBudget // 1500' "$PREFS")
|
|
182
|
-
TOP=$(jq -r '.global.repoMap.topFiles // 25' "$PREFS")
|
|
183
|
-
INCLUDE=$(jq -r '.global.repoMap.include // empty' "$PREFS")
|
|
184
|
-
EXCLUDE=$(jq -r '.global.repoMap.exclude // empty' "$PREFS")
|
|
185
|
-
args=(--root "$WORKTREE" --budget "$BUDGET" --top "$TOP" --format md)
|
|
186
|
-
[ -n "$INCLUDE" ] && args+=(--include "$INCLUDE")
|
|
187
|
-
[ -n "$EXCLUDE" ] && args+=(--exclude "$EXCLUDE")
|
|
188
|
-
REPO_MAP=$(node pipeline/scripts/repo-map.mjs "${args[@]}" 2>/dev/null || echo "")
|
|
189
|
-
fi
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
**Properties:**
|
|
193
|
-
|
|
194
|
-
- **Deterministic** — same worktree state → same map. No embeddings, no network. Sub-second on monorepos.
|
|
195
|
-
- **Advisory** — Explore agents may ignore the map if they have stronger signals (Phase 0 knowledge cache, explicit user context). Never gates the pipeline.
|
|
196
|
-
- **Truncation-safe** — output is capped at `tokenBudget`; the script falls back to "no files extracted within budget" rather than over-spending.
|
|
197
|
-
- **Cost ledger** — emit `phase-1.repo_map_emitted bytes=$(wc -c <<<"$REPO_MAP") budget=$BUDGET` so Phase 7 cost summary can show the size injected.
|
|
198
|
-
|
|
199
|
-
**When to enable:** large repos (>200 source files) where Explore otherwise spends multiple rounds finding the right starting files. Skip on small repos — the overhead exceeds the gain.
|
|
82
|
+
Gated by `prefs.global.repoMap.enabled` (default: `false`). When enabled, runs `pipeline/scripts/repo-map.mjs` and injects the budgeted result into each Explore prompt as `${REPO_MAP}`. Aider-style: deterministic, no embeddings, sub-second, advisory only. Full wiring (helper invocation, properties, when-to-enable): `refs/features/repo-map.md`.
|
|
200
83
|
|
|
201
84
|
#### Step 3 — Codebase Exploration
|
|
202
85
|
|