@mmerterden/multi-agent-pipeline 15.0.0 → 15.2.0
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/CHANGELOG.md +127 -0
- package/README.md +9 -9
- package/README.tr.md +9 -9
- package/SECURITY.md +43 -0
- package/docs/adr/0007-multi-tool-adapter-framework.md +1 -1
- package/docs/architecture.md +9 -9
- package/docs/ecosystem.md +10 -10
- package/index.js +4 -1
- package/install/_common.mjs +44 -2
- package/install/_platform-filter.mjs +6 -131
- package/install/_plugin-skills.mjs +17 -28
- package/install/claude.mjs +111 -6
- package/install/codex.mjs +0 -3
- package/install/copilot.mjs +36 -1
- package/install/index.mjs +3 -1
- package/package.json +2 -2
- package/pipeline/commands/multi-agent/refactor/SKILL.md +36 -1
- package/pipeline/commands/multi-agent/scan/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/stack/SKILL.md +18 -8
- package/pipeline/commands/multi-agent/update/SKILL.md +31 -4
- package/pipeline/lib/parse-complaints.sh +12 -2
- package/pipeline/multi-agent-refs/complaint-analysis-template.md +1 -1
- package/pipeline/multi-agent-refs/phases/operations.md +7 -1
- package/pipeline/multi-agent-refs/phases/phase-7-report.md +6 -0
- package/pipeline/multi-agent-refs/tracker-contract.md +2 -1
- package/pipeline/preferences-template.json +6 -0
- package/pipeline/schemas/prefs.schema.json +27 -0
- package/pipeline/scripts/README.md +4 -3
- package/pipeline/scripts/check-derived-drift.mjs +5 -2
- package/pipeline/scripts/match-skills.mjs +4 -0
- package/pipeline/scripts/migrate-prefs.mjs +5 -1
- package/pipeline/scripts/phase-tracker.sh +19 -0
- package/pipeline/scripts/uninstall.mjs +3 -1
- package/pipeline/scripts/usage-report.mjs +457 -0
- package/pipeline/scripts/validate-complaint-doc.mjs +32 -11
- package/pipeline/skills/.skill-manifest.json +4 -4
- package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +153 -90
- package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +18 -8
- package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +1 -1
|
@@ -71,6 +71,33 @@ Update the pipeline in one command. Existing preferences are preserved; only ski
|
|
|
71
71
|
fi
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
5b. **Auto-enable usage logging when a token is already onboarded.** The private
|
|
75
|
+
usage dashboard is opt-in and off by default. This step flips it ON only when a
|
|
76
|
+
token can be resolved - it NEVER fabricates a secret or ships one, so a machine
|
|
77
|
+
that was never given the token stays silent. Resolution order: env
|
|
78
|
+
`MULTI_AGENT_USAGE_TOKEN`, then `usageLog.token`, then the Keychain item named by
|
|
79
|
+
`keychainMapping.usage_ingest`. Endpoint is left to the emitter's default.
|
|
80
|
+
```bash
|
|
81
|
+
PREFS="$HOME/.claude/multi-agent-preferences.json"
|
|
82
|
+
if [ -f "$PREFS" ] && command -v jq >/dev/null 2>&1; then
|
|
83
|
+
ENABLED=$(jq -r '.global.usageLog.enabled // false' "$PREFS" 2>/dev/null)
|
|
84
|
+
if [ "$ENABLED" != "true" ]; then
|
|
85
|
+
TOK="${MULTI_AGENT_USAGE_TOKEN:-}"
|
|
86
|
+
[ -z "$TOK" ] && TOK=$(jq -r '.global.usageLog.token // empty' "$PREFS" 2>/dev/null)
|
|
87
|
+
if [ -z "$TOK" ]; then
|
|
88
|
+
KNAME=$(jq -r '.global.keychainMapping.usage_ingest // empty' "$PREFS" 2>/dev/null)
|
|
89
|
+
[ -n "$KNAME" ] && TOK=$(bash "$HOME/.claude/lib/credential-store.sh" get "$KNAME" 2>/dev/null)
|
|
90
|
+
fi
|
|
91
|
+
if [ -n "$TOK" ]; then
|
|
92
|
+
node -e 'const fs=require("fs"),p=process.argv[1];const j=JSON.parse(fs.readFileSync(p,"utf8"));j.global=j.global||{};j.global.usageLog=j.global.usageLog||{};j.global.usageLog.enabled=true;fs.writeFileSync(p,JSON.stringify(j,null,2)+"\n");' "$PREFS"
|
|
93
|
+
echo " -> usage logging activated (ingest token found)"
|
|
94
|
+
else
|
|
95
|
+
echo " -> usage logging left off (no ingest token onboarded)"
|
|
96
|
+
fi
|
|
97
|
+
fi
|
|
98
|
+
fi
|
|
99
|
+
```
|
|
100
|
+
|
|
74
101
|
6. **Show the new version**:
|
|
75
102
|
```bash
|
|
76
103
|
NEW_VERSION=$(node -p "require('$PIPE_DIR/package.json').version" 2>/dev/null || echo "unknown")
|
|
@@ -99,12 +126,12 @@ Update the pipeline in one command. Existing preferences are preserved; only ski
|
|
|
99
126
|
## Output
|
|
100
127
|
|
|
101
128
|
```
|
|
102
|
-
Current:
|
|
129
|
+
Current: v14.2.2
|
|
103
130
|
-> git pull origin main
|
|
104
|
-
-> node install.js --all (
|
|
105
|
-
-> migrate-prefs.mjs (0 changes - already v2.
|
|
131
|
+
-> node install.js --all (51 commands, 228 scripts, 205 skills)
|
|
132
|
+
-> migrate-prefs.mjs (0 changes - already v2.6.0)
|
|
106
133
|
|
|
107
|
-
✓ Updated:
|
|
134
|
+
✓ Updated: v14.2.2 → v15.0.0
|
|
108
135
|
|
|
109
136
|
Changes:
|
|
110
137
|
e3f883e fix(dev): Phase 6 must show local test prompt
|
|
@@ -64,9 +64,13 @@ REDACT="true"
|
|
|
64
64
|
|
|
65
65
|
while [ $# -gt 0 ]; do
|
|
66
66
|
case "$1" in
|
|
67
|
-
--file)
|
|
67
|
+
--file)
|
|
68
|
+
[ $# -ge 2 ] || { echo "ERR: --file needs a value" >&2; exit 4; }
|
|
69
|
+
FILE="$2"; shift 2 ;;
|
|
68
70
|
--stdin) USE_STDIN="true"; shift ;;
|
|
69
|
-
--format)
|
|
71
|
+
--format)
|
|
72
|
+
[ $# -ge 2 ] || { echo "ERR: --format needs a value" >&2; exit 4; }
|
|
73
|
+
FORMAT="$2"; shift 2 ;;
|
|
70
74
|
--no-redact) REDACT="false"; shift ;;
|
|
71
75
|
-h|--help)
|
|
72
76
|
echo "usage: $0 --file <path> [--format csv|xlsx|txt|json|auto] [--no-redact] | --stdin [--format text]" >&2
|
|
@@ -150,6 +154,12 @@ REDACTIONS = [
|
|
|
150
154
|
(re.compile(r"\b\d{11}\b"), "[REDACTED:national-id]"),
|
|
151
155
|
(re.compile(r"(?<![\w.-])\+?\d(?:[ ()-]?\d){8,14}\b"), "[REDACTED:phone]"),
|
|
152
156
|
(re.compile(r"\b(?=[A-Z0-9]{6}\b)(?=[A-Z0-9]*[A-Z])(?=[A-Z0-9]*\d)[A-Z0-9]{6}\b"), "[REDACTED:pnr]"),
|
|
157
|
+
# All-letter PNRs exist too, but a bare 6-letter uppercase word is far too
|
|
158
|
+
# common to redact blind - only take one that follows a PNR-ish keyword.
|
|
159
|
+
(
|
|
160
|
+
re.compile(r"\b(?P<kw>pnr|rezervasyon kodu|booking (?:ref|reference|code))(?P<sep>[^A-Za-z0-9\n]{0,3})[A-Z]{6}\b", re.IGNORECASE),
|
|
161
|
+
lambda m: m.group("kw") + m.group("sep") + "[REDACTED:pnr]",
|
|
162
|
+
),
|
|
153
163
|
]
|
|
154
164
|
|
|
155
165
|
def redact(text):
|
|
@@ -44,7 +44,7 @@ Then the coverage table - every selected repo appears, including the ones that c
|
|
|
44
44
|
|
|
45
45
|
## 2. Triage Tablosu / Triage Table
|
|
46
46
|
|
|
47
|
-
One row per complaint. Verdict tokens are the English enum: `client:ios`, `client:android`, `client:web`, `bff:mobile-bff`, `bff:web-bff`, `core`, `insufficient-evidence`. The validator requires every row
|
|
47
|
+
One row per complaint. Verdict tokens are the English enum: `client:ios`, `client:android`, `client:web`, `bff:mobile-bff`, `bff:web-bff`, `core`, `insufficient-evidence`. The validator requires every row in this section whose FIRST cell is a `C-NN` id to carry one of these tokens in a cell of its own (cell-exact; the Section 1 coverage table citing ids in its last column is exempt by scope).
|
|
48
48
|
|
|
49
49
|
```
|
|
50
50
|
| Id | Özet (redakte) | trx/conv | Verdict | Confidence | Routing |
|
|
@@ -95,7 +95,13 @@ halt per the halt-visibility rule), `3` I/O error.
|
|
|
95
95
|
Reads need no wrapper; the rename makes any read see either the old or the new
|
|
96
96
|
document, never a truncated one.
|
|
97
97
|
|
|
98
|
-
**Halt visibility (required, autopilot included).** A halt is never silent. Whenever a phase halts on a hard error (validator failed twice, no subagent returned, dispatch error past fallback, lock irrecoverable), in addition to the `agent-log.md` line: (a) write `state.status = "paused"` and `state.haltReason = "<phase>:<cause>"`; (b) record the cause on the tracker via `phase-tracker.sh meta <phase> halt "<cause>"` and `phase-tracker.sh update <phase> failed`; (c) emit one `>&2` alert line `HALT phase <N>: <cause> - resume with /multi-agent:resume #<id
|
|
98
|
+
**Halt visibility (required, autopilot included).** A halt is never silent. Whenever a phase halts on a hard error (validator failed twice, no subagent returned, dispatch error past fallback, lock irrecoverable), in addition to the `agent-log.md` line: (a) write `state.status = "paused"` and `state.haltReason = "<phase>:<cause>"`; (b) record the cause on the tracker via `phase-tracker.sh meta <phase> halt "<cause>"` and `phase-tracker.sh update <phase> failed`; (c) emit one `>&2` alert line `HALT phase <N>: <cause> - resume with /multi-agent:resume #<id>`; (d) if `prefs.global.usageLog.enabled` is true, emit the end-of-run usage ping so a run that never reaches Phase 7 is still recorded with the phase it stopped at (`state.currentPhase` + `haltReason`) - the emitter no-ops when logging is off or unconfigured:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
node $HOME/.claude/scripts/usage-report.mjs --state "$STATE_FILE" >/dev/null 2>&1 || true
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Autopilot suppresses *confirmations*, not *halts* - the user must always be able to see why an unattended run stopped without reading the log. The dashboard upserts by run id, so this halt event and a later Phase 7 event (after resume) collapse into one record.
|
|
99
105
|
|
|
100
106
|
### Pipeline Best Practices
|
|
101
107
|
|
|
@@ -196,6 +196,12 @@ $HOME/.claude/scripts/log-metric.sh "$TASK_ID" 7 task.completed \
|
|
|
196
196
|
duration_ms=$TOTAL_DURATION
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
+
**Usage ping (optional, private dashboard).** When `prefs.global.usageLog.enabled` is true, emit one end-of-run activity event to the configured private dashboard. One POST per run (never per phase), fire-and-forget, activity metadata only - who, command, mode, input type, repo, phase reached, outcome, halt cause, review-iteration count, duration, token spend, cost, version. No prompts, code, diffs, or absolute paths. The script no-ops when `usageLog.enabled` is not true or no ingest token resolves, so the call is unconditional and never blocks the run.
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
node $HOME/.claude/scripts/usage-report.mjs --state "$STATE_FILE" >/dev/null 2>&1 || true
|
|
203
|
+
```
|
|
204
|
+
|
|
199
205
|
**Aggregate before reporting**: run `aggregate-metrics.mjs --since=$(date -u -v-30d +%Y-%m-%d)` and embed output in agent-log.md. Use `--json` for Jira. Aggregator handles missing files gracefully.
|
|
200
206
|
|
|
201
207
|
**Per-run outcome metrics (evidence corpus):** also emit `run-metrics.mjs --state <agent-state.json>` and append/persist its JSON. It records the numbers that actually answer "did this run go well" - review iterations (rework loops), first-pass-clean, reviewer signal-to-noise (accepted / raw findings), consensus verdict, build outcome. Accumulating these across real runs is the real-world validation that golden tasks + benchmarks only approximate; keep the corpus so the pipeline's quality can be measured, not asserted.
|
|
@@ -135,7 +135,8 @@ Mode-specific phase sets:
|
|
|
135
135
|
|
|
136
136
|
| Mode | TaskCreate set (in order) |
|
|
137
137
|
|---|---|
|
|
138
|
-
| Full
|
|
138
|
+
| Full interactive (`/multi-agent`) | 0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 (all 8) |
|
|
139
|
+
| `:autopilot`, `:local`, `:local-autopilot` | 0 → 1 → 2 → 3 → 4 → 6 → 7 (7 phases - the interactive Phase 5 test gate is dropped in every autopilot/local variant) |
|
|
139
140
|
| `:dev` | 0 → 3 → 4 → 5 → 6 → 7 (6 phases - 1/2 omitted entirely) |
|
|
140
141
|
| `:dev-autopilot`, `:dev-local`, `:dev-local-autopilot` | 0 → 3 → 4 → 6 → 7 (5 phases - 1/2/5 omitted entirely; the autopilot/local variants drop the interactive Phase 5 test gate) |
|
|
141
142
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"figma_mcp": null,
|
|
13
13
|
"fortify": null,
|
|
14
14
|
"graylog": null,
|
|
15
|
+
"usage_ingest": null,
|
|
15
16
|
"firebase": null,
|
|
16
17
|
"jenkins": null
|
|
17
18
|
},
|
|
@@ -74,6 +75,11 @@
|
|
|
74
75
|
"onExceed": "warn",
|
|
75
76
|
"pricingModel": "opus"
|
|
76
77
|
},
|
|
78
|
+
"usageLog": {
|
|
79
|
+
"enabled": false,
|
|
80
|
+
"endpoint": "https://mmerterden.vercel.app/api/usage/ingest",
|
|
81
|
+
"token": ""
|
|
82
|
+
},
|
|
77
83
|
"derivedSkillSources": [],
|
|
78
84
|
"devToolkit": {
|
|
79
85
|
"enabled": true,
|
|
@@ -188,6 +188,13 @@
|
|
|
188
188
|
"null"
|
|
189
189
|
]
|
|
190
190
|
},
|
|
191
|
+
"usage_ingest": {
|
|
192
|
+
"type": [
|
|
193
|
+
"string",
|
|
194
|
+
"null"
|
|
195
|
+
],
|
|
196
|
+
"description": "Keychain item holding the shared ingest token for the private usage dashboard. When set, usage-report.mjs reads the token from here (never from a synced file), and /multi-agent:update auto-enables usageLog once the token is onboarded. Absent = usage logging stays off."
|
|
197
|
+
},
|
|
191
198
|
"figma_pat": {
|
|
192
199
|
"type": [
|
|
193
200
|
"string",
|
|
@@ -1077,6 +1084,26 @@
|
|
|
1077
1084
|
}
|
|
1078
1085
|
}
|
|
1079
1086
|
},
|
|
1087
|
+
"usageLog": {
|
|
1088
|
+
"type": "object",
|
|
1089
|
+
"additionalProperties": false,
|
|
1090
|
+
"description": "Optional end-of-run usage ping to a private dashboard. When enabled, Phase 7 emits ONE activity event per run (never per phase) via pipeline/scripts/usage-report.mjs: who, command, mode, input type, repo, phase reached, outcome, halt cause, review-iteration count, duration, token spend, cost, version. Never prompts, code, diffs, or absolute paths. Off by default; the emitter no-ops unless enabled is true AND a token resolves (from token below or env MULTI_AGENT_USAGE_TOKEN), so it is inert for anyone who has not configured it.",
|
|
1091
|
+
"properties": {
|
|
1092
|
+
"enabled": {
|
|
1093
|
+
"type": "boolean",
|
|
1094
|
+
"default": false,
|
|
1095
|
+
"description": "Master switch. When false the emitter exits silently and nothing leaves the machine."
|
|
1096
|
+
},
|
|
1097
|
+
"endpoint": {
|
|
1098
|
+
"type": "string",
|
|
1099
|
+
"description": "Ingest URL that receives the activity event. The token is sent in the X-Usage-Token header."
|
|
1100
|
+
},
|
|
1101
|
+
"token": {
|
|
1102
|
+
"type": "string",
|
|
1103
|
+
"description": "Shared ingest token the receiving endpoint validates. May be left empty here and supplied via env MULTI_AGENT_USAGE_TOKEN instead. Local prefs only, never synced."
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
},
|
|
1080
1107
|
"reviewWatch": {
|
|
1081
1108
|
"type": "object",
|
|
1082
1109
|
"additionalProperties": false,
|
|
@@ -82,13 +82,14 @@ Shell scripts invoked during pipeline execution.
|
|
|
82
82
|
- `github-ssh-setup.sh` - first-run SSH key setup helper
|
|
83
83
|
- `sync-parity-check.sh` - manual parity verification helper
|
|
84
84
|
|
|
85
|
-
## Node.js helpers (
|
|
85
|
+
## Node.js helpers (54 `.mjs` files)
|
|
86
86
|
|
|
87
87
|
- `aggregate-metrics.mjs` - collects telemetry aggregates
|
|
88
88
|
- `learning-curve.mjs` - time-bucketed trend over `metrics.jsonl` (first-pass clean rate, review cycles, rework/task, tokens/task, cache ratio); `--bucket`, `--since`, `--json`, `--markdown`
|
|
89
|
-
- `eval-triage.mjs` - runs the
|
|
89
|
+
- `eval-triage.mjs` - runs the 11 triage eval fixtures
|
|
90
|
+
- `eval-mine-corpus.mjs` - manual maintainer CLI: mines `~/.claude/memory/multi-agent/<repo-slug>/triage-corpus.jsonl` from real runs into new triage eval fixtures (dev-only, excluded from the npm package; not part of `npm test`)
|
|
90
91
|
- `gen-skills-index.mjs` - regenerates `pipeline/skills/shared/README.md` skill catalog
|
|
91
|
-
- `migrate-prefs.mjs` - preference migration driver (v2.0.0 through v2.
|
|
92
|
+
- `migrate-prefs.mjs` - preference migration driver (v2.0.0 through v2.6.0)
|
|
92
93
|
- `migrate-state.mjs` - generic migration runner (reads `schemas/migrations/`)
|
|
93
94
|
- `token-budget-report.mjs` - per-phase token usage report
|
|
94
95
|
- `validate-analysis.mjs`, `validate-planning.mjs`, `validate-reviewer.mjs`, `validate-triage.mjs` - per-phase output validators
|
|
@@ -179,8 +179,11 @@ for (const entry of entries) {
|
|
|
179
179
|
// An acknowledged drift is a conscious "port pending" decision, pinned to the
|
|
180
180
|
// upstream version it was made against: it stays visible but does not fail
|
|
181
181
|
// the gate, and the moment upstream moves past the pin it is plain drift
|
|
182
|
-
// again.
|
|
183
|
-
|
|
182
|
+
// again. The pin only counts against an AUTHORITATIVE resolution - a cache
|
|
183
|
+
// that happens to hold the pinned version proves nothing about upstream and
|
|
184
|
+
// must not silence the unverified state.
|
|
185
|
+
const acknowledged =
|
|
186
|
+
drifted && resolved.authoritative && entry.driftAcknowledged === resolved.version;
|
|
184
187
|
const status = acknowledged
|
|
185
188
|
? "drift (acknowledged)"
|
|
186
189
|
: drifted
|
|
@@ -52,6 +52,10 @@ function defaultIndexCandidates() {
|
|
|
52
52
|
const repoRoot = resolve(here, "..", ".."); // <repo> when here is <repo>/pipeline/scripts
|
|
53
53
|
return [
|
|
54
54
|
join(installRoot, "skills", ".skills-index.json"),
|
|
55
|
+
// Codex CLI keeps skills under multi-agent-refs/skills (install/codex.mjs
|
|
56
|
+
// writes the index there); without this candidate every dynamic-skill
|
|
57
|
+
// dispatch on Codex exited 1 with "cannot read index".
|
|
58
|
+
join(installRoot, "multi-agent-refs", "skills", ".skills-index.json"),
|
|
55
59
|
join(repoRoot, "pipeline", "skills", ".skills-index.json"),
|
|
56
60
|
];
|
|
57
61
|
}
|
|
@@ -94,7 +94,11 @@ function readMigratableVersions(target) {
|
|
|
94
94
|
}
|
|
95
95
|
// Schema unreadable: refusing to migrate would be worse than migrating from a
|
|
96
96
|
// version this build cannot enumerate, so fall back to the known history.
|
|
97
|
-
|
|
97
|
+
// Every released schemaVersion below TARGET_VERSION belongs here - the
|
|
98
|
+
// 2.4.0->2.5.0 and 2.5.0->2.6.0 bumps both shipped without extending it,
|
|
99
|
+
// which made a schema-less install throw "unknown schemaVersion" on a prefs
|
|
100
|
+
// file one version behind.
|
|
101
|
+
return new Set(["2.0.0", "2.1.0", "2.2.0", "2.3.0", "2.4.0", "2.5.0"]);
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
function defaultKeychainMapping() {
|
|
@@ -115,6 +115,23 @@ need_jq() {
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
# Live usage ping (best-effort). Emits one per-phase update to the private
|
|
119
|
+
# dashboard via usage-report.mjs, always status=running so per-phase updates
|
|
120
|
+
# never fold the run into rollup counters - the terminal fold comes only from
|
|
121
|
+
# the Phase 7 / halt emit that reads the real run status. The emitter no-ops
|
|
122
|
+
# unless prefs.global.usageLog.enabled; detached so it never blocks a boundary.
|
|
123
|
+
usage_live_ping() {
|
|
124
|
+
local task="$1" phase="$2"
|
|
125
|
+
local script="$HOME/.claude/scripts/usage-report.mjs"
|
|
126
|
+
local prefs="$HOME/.claude/multi-agent-preferences.json"
|
|
127
|
+
[ -n "$task" ] && [ -f "$script" ] || return 0
|
|
128
|
+
# Cheap gate: only spawn the emitter when usage logging is actually on, so a
|
|
129
|
+
# user who never enabled it pays nothing per phase boundary. jq is already a
|
|
130
|
+
# hard dependency of this script.
|
|
131
|
+
jq -e '.global.usageLog.enabled == true' "$prefs" >/dev/null 2>&1 || return 0
|
|
132
|
+
( node "$script" --task-id "$task" --phase "$phase" --status running >/dev/null 2>&1 & ) 2>/dev/null || true
|
|
133
|
+
}
|
|
134
|
+
|
|
118
135
|
# Decode HTML entities in a tile title.
|
|
119
136
|
#
|
|
120
137
|
# `rules.md` forbids entities in "titles, commit messages, task subjects, or body
|
|
@@ -681,6 +698,7 @@ case "$ACTION" in
|
|
|
681
698
|
# subsequent tracker call (the pointer flips on the most recent init).
|
|
682
699
|
echo "$TRACKER_FILE" > "$HOME/.claude/logs/multi-agent/.tracker-current"
|
|
683
700
|
render
|
|
701
|
+
usage_live_ping "$TASK_ID" 0
|
|
684
702
|
if [ "${MULTI_AGENT_QUIET:-0}" != "1" ]; then
|
|
685
703
|
echo "phase-tracker: tracker initialized for task=$TASK_ID" >&2
|
|
686
704
|
echo "phase-tracker: TIP - for concurrent-safe resolution, set:" >&2
|
|
@@ -733,6 +751,7 @@ case "$ACTION" in
|
|
|
733
751
|
release_state_lock
|
|
734
752
|
emit_otel_span "phase.update" "$PID" "$STATUS" "{\"status\": \"$STATUS\"}"
|
|
735
753
|
render
|
|
754
|
+
usage_live_ping "$(basename "$TRACKER_DIR")" "$PID"
|
|
736
755
|
;;
|
|
737
756
|
|
|
738
757
|
sub)
|
|
@@ -353,7 +353,9 @@ function rmExternalDeliveredSkills(skillsDir) {
|
|
|
353
353
|
if (!names) {
|
|
354
354
|
console.log(
|
|
355
355
|
` note: no ${EXTERNAL_SKILLS_MANIFEST} under ${skillsDir} - external skill dirs left in ` +
|
|
356
|
-
`place (cannot tell pipeline-delivered from user-authored;
|
|
356
|
+
`place (cannot tell pipeline-delivered from user-authored; ` +
|
|
357
|
+
`node install.js --claude prunes copies identical to the shipped catalog, ` +
|
|
358
|
+
`--prune-external removes the rest)`,
|
|
357
359
|
);
|
|
358
360
|
return 0;
|
|
359
361
|
}
|