@mmerterden/multi-agent-pipeline 11.5.0 → 12.1.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 +75 -0
- package/docs/adr/0007-multi-tool-adapter-framework.md +2 -2
- package/docs/adr/0008-installer-modularization-and-secret-leak-defense.md +2 -0
- package/docs/adr/README.md +1 -0
- package/docs/features.md +2 -2
- package/install/claude.mjs +51 -1
- package/install/index.mjs +34 -1
- package/package.json +2 -2
- package/pipeline/commands/multi-agent/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/analysis/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/autopilot/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/build-optimize/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/channels/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/create-jira/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/dev/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/dev-autopilot/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/dev-local/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/dev-local-autopilot/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/diff-explain/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/finish/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +29 -3
- package/pipeline/commands/multi-agent/help/SKILL.md +3 -2
- package/pipeline/commands/multi-agent/issue/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/jira/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/kill/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/language/SKILL.md +20 -1
- package/pipeline/commands/multi-agent/local/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/local-autopilot/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/log/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/manual-test/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/prune-logs/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/purge/SKILL.md +27 -24
- package/pipeline/commands/multi-agent/refactor/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/resume/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/review/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/review-issue/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/review-jira/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/scan/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/search/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/setup/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/stack/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/status/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/sync/SKILL.md +20 -2
- package/pipeline/commands/multi-agent/test/SKILL.md +1 -0
- package/pipeline/commands/multi-agent/uninstall/SKILL.md +87 -0
- package/pipeline/commands/multi-agent/update/SKILL.md +1 -0
- package/pipeline/lib/multi-repo-pipeline.sh +6 -1
- package/pipeline/multi-agent-refs/cross-cli-contract.md +5 -5
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +12 -1
- package/pipeline/scripts/_cost.mjs +35 -0
- package/pipeline/scripts/agent-guard.py +8 -3
- package/pipeline/scripts/cost-budget-check.mjs +2 -1
- package/pipeline/scripts/cost-lib.sh +43 -0
- package/pipeline/scripts/fixtures/install-layout.tsv +4 -2
- package/pipeline/scripts/gc-tmp.sh +67 -8
- package/pipeline/scripts/gc-worktrees.sh +140 -0
- package/pipeline/scripts/localize-commands.mjs +130 -0
- package/pipeline/scripts/phase-tracker.sh +10 -19
- package/pipeline/scripts/prune-logs.sh +100 -15
- package/pipeline/scripts/purge.sh +235 -0
- package/pipeline/scripts/render-agent-log-cost.sh +7 -13
- package/pipeline/scripts/render-cost-summary.sh +4 -7
- package/pipeline/scripts/run-aggregator.mjs +2 -3
- package/pipeline/scripts/smoke-description-tr.sh +82 -0
- package/pipeline/scripts/smoke-gc-tmp.sh +50 -4
- package/pipeline/scripts/smoke-gc-worktrees.sh +125 -0
- package/pipeline/scripts/smoke-prune-logs.sh +57 -7
- package/pipeline/scripts/smoke-purge.sh +138 -0
- package/pipeline/scripts/smoke-source-parity.sh +85 -0
- package/pipeline/scripts/smoke-update-check.sh +13 -0
- package/pipeline/scripts/uninstall.mjs +41 -6
- package/pipeline/scripts/update-check.sh +9 -0
- package/pipeline/skills/.skill-manifest.json +7 -7
- package/pipeline/skills/.skills-index.json +9 -9
- package/pipeline/skills/shared/README.md +19 -10
- package/pipeline/skills/shared/core/multi-agent/SKILL.md +1 -0
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +2 -2
- package/pipeline/skills/shared/core/multi-agent-uninstall/SKILL.md +74 -0
- package/pipeline/skills/skills-index.md +1 -1
- package/pipeline/commands/multi-agent/delete/SKILL.md +0 -67
- package/pipeline/skills/shared/core/multi-agent-delete/SKILL.md +0 -66
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# smoke-prune-logs.sh - prune-logs.sh removes per-task log dirs, honors the
|
|
3
|
-
# project/task/age filters, is dry-run by default,
|
|
4
|
-
# trail or metrics corpus
|
|
3
|
+
# project/task/age filters, is dry-run by default, NEVER deletes the audit
|
|
4
|
+
# trail or metrics corpus (even under adversarial dir names), refuses unsafe
|
|
5
|
+
# log roots, and spares active task dirs.
|
|
5
6
|
#
|
|
6
7
|
# Exit 0 = all pass, 1 = any failure.
|
|
7
8
|
|
|
@@ -40,7 +41,7 @@ seed() {
|
|
|
40
41
|
|
|
41
42
|
echo "→ 1. dry-run lists task dirs and deletes nothing"
|
|
42
43
|
seed
|
|
43
|
-
out=$(PRUNE_LOG_ROOT="$LR" bash "$PL" 2>&1)
|
|
44
|
+
out=$(PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" 2>&1)
|
|
44
45
|
echo "$out" | grep -q "DRY-RUN" && pass "dry-run banner shown" || fail "dry-run banner missing"
|
|
45
46
|
[ -f "$LR/my-ios-app/PROJ-1/agent-state.json" ] && pass "dry-run kept task dirs" || fail "dry-run deleted a task dir"
|
|
46
47
|
echo "$out" | grep -qi "preserved" && pass "dry-run states audit/metrics are preserved" || fail "no preservation note"
|
|
@@ -48,7 +49,7 @@ echo "$out" | grep -qi "preserved" && pass "dry-run states audit/metrics are pre
|
|
|
48
49
|
echo ""
|
|
49
50
|
echo "→ 2. --yes deletes task dirs but preserves audit + metrics + .counter"
|
|
50
51
|
seed
|
|
51
|
-
PRUNE_LOG_ROOT="$LR" bash "$PL" --yes >/dev/null 2>&1
|
|
52
|
+
PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --yes >/dev/null 2>&1
|
|
52
53
|
[ -f "$LR/audit.jsonl" ] && pass "audit.jsonl preserved" || fail "audit.jsonl was deleted"
|
|
53
54
|
[ -f "$LR/metrics.jsonl" ] && pass "metrics.jsonl preserved" || fail "metrics.jsonl was deleted"
|
|
54
55
|
[ -f "$LR/my-ios-app/.counter" ] && pass ".counter preserved" || fail ".counter was deleted"
|
|
@@ -58,21 +59,21 @@ PRUNE_LOG_ROOT="$LR" bash "$PL" --yes >/dev/null 2>&1
|
|
|
58
59
|
echo ""
|
|
59
60
|
echo "→ 3. --project scopes deletion to one project"
|
|
60
61
|
seed
|
|
61
|
-
PRUNE_LOG_ROOT="$LR" bash "$PL" --project=my-ios-app --yes >/dev/null 2>&1
|
|
62
|
+
PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --project=my-ios-app --yes >/dev/null 2>&1
|
|
62
63
|
[ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "my-ios-app task removed" || fail "my-ios-app task survived"
|
|
63
64
|
[ -f "$LR/other/PROJ-9/agent-log.md" ] && pass "other project untouched" || fail "other project was deleted"
|
|
64
65
|
|
|
65
66
|
echo ""
|
|
66
67
|
echo "→ 4. --task scopes deletion to one task dir"
|
|
67
68
|
seed
|
|
68
|
-
PRUNE_LOG_ROOT="$LR" bash "$PL" --task=PROJ-1 --yes >/dev/null 2>&1
|
|
69
|
+
PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --task=PROJ-1 --yes >/dev/null 2>&1
|
|
69
70
|
[ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "PROJ-1 removed" || fail "PROJ-1 survived"
|
|
70
71
|
[ -f "$LR/my-ios-app/PROJ-2/tracker-state.json" ] && pass "PROJ-2 untouched" || fail "PROJ-2 was deleted"
|
|
71
72
|
|
|
72
73
|
echo ""
|
|
73
74
|
echo "→ 5. --older-than excludes fresh task dirs"
|
|
74
75
|
seed
|
|
75
|
-
out=$(PRUNE_LOG_ROOT="$LR" bash "$PL" --older-than=1 2>&1)
|
|
76
|
+
out=$(PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --older-than=1 2>&1)
|
|
76
77
|
echo "$out" | grep -q "nothing" && pass "freshly-created dirs excluded by --older-than=1" || fail "--older-than did not exclude fresh dirs"
|
|
77
78
|
|
|
78
79
|
echo ""
|
|
@@ -82,6 +83,55 @@ PRUNE_LOG_ROOT="$LR" bash "$PL" --bogus >/dev/null 2>&1
|
|
|
82
83
|
PRUNE_LOG_ROOT="/nonexistent-$$-dir" bash "$PL" >/dev/null 2>&1
|
|
83
84
|
[ "$?" = "0" ] && pass "missing log root exits 0 (no-op)" || fail "missing log root did not exit 0"
|
|
84
85
|
|
|
86
|
+
echo ""
|
|
87
|
+
echo "→ 7. adversarial dirs named like preserved files survive --yes"
|
|
88
|
+
rm -rf "${LR:?}"/*
|
|
89
|
+
mkdir -p "$LR/audit.jsonl" "$LR/proj/metrics.jsonl" "$LR/proj/metrics-summary.md" "$LR/proj/.counter" "$LR/proj/PROJ-5"
|
|
90
|
+
echo '{}' >"$LR/audit.jsonl/agent-state.json"
|
|
91
|
+
echo '{}' >"$LR/proj/metrics.jsonl/agent-log.md"
|
|
92
|
+
echo '{}' >"$LR/proj/metrics-summary.md/tracker-state.json"
|
|
93
|
+
echo '{}' >"$LR/proj/.counter/agent-state.json"
|
|
94
|
+
echo '{}' >"$LR/proj/PROJ-5/agent-state.json"
|
|
95
|
+
PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --yes >/dev/null 2>&1
|
|
96
|
+
[ -d "$LR/audit.jsonl" ] && pass "dir named audit.jsonl spared" || fail "dir named audit.jsonl deleted"
|
|
97
|
+
[ -d "$LR/proj/metrics.jsonl" ] && pass "dir named metrics.jsonl spared" || fail "dir named metrics.jsonl deleted"
|
|
98
|
+
[ -d "$LR/proj/metrics-summary.md" ] && pass "dir named metrics-summary.md spared" || fail "dir named metrics-summary.md deleted"
|
|
99
|
+
[ -d "$LR/proj/.counter" ] && pass "dir named .counter spared" || fail "dir named .counter deleted"
|
|
100
|
+
[ ! -e "$LR/proj/PROJ-5" ] && pass "normal task dir beside them still removed" || fail "normal task dir survived"
|
|
101
|
+
|
|
102
|
+
echo ""
|
|
103
|
+
echo "→ 8. unsafe log roots are refused (exit 2, dry-run only)"
|
|
104
|
+
PRUNE_LOG_ROOT="$HOME" bash "$PL" >/dev/null 2>&1
|
|
105
|
+
[ "$?" = "2" ] && pass "\$HOME as log root refused" || fail "\$HOME as log root not refused"
|
|
106
|
+
GITROOT="$(mktemp -d)"
|
|
107
|
+
mkdir -p "$GITROOT/.git"
|
|
108
|
+
PRUNE_LOG_ROOT="$GITROOT" bash "$PL" --yes >/dev/null 2>&1
|
|
109
|
+
rc=$?
|
|
110
|
+
rm -rf "$GITROOT"
|
|
111
|
+
[ "$rc" = "2" ] && pass "git work tree as log root refused" || fail "git work tree as log root not refused"
|
|
112
|
+
|
|
113
|
+
echo ""
|
|
114
|
+
echo "→ 9. default grace spares freshly-touched (active) task dirs"
|
|
115
|
+
seed
|
|
116
|
+
out=$(PRUNE_LOG_ROOT="$LR" bash "$PL" --yes 2>&1)
|
|
117
|
+
rc=$?
|
|
118
|
+
[ "$rc" = "0" ] && pass "grace run exits 0" || fail "grace run exited $rc"
|
|
119
|
+
[ -f "$LR/my-ios-app/PROJ-1/agent-state.json" ] && pass "active task dir spared by default grace" || fail "default grace deleted an active task dir"
|
|
120
|
+
echo "$out" | grep -qi "spared" && pass "output mentions spared active dirs" || fail "no spared-active note in output"
|
|
121
|
+
PRUNE_LOG_ROOT="$LR" bash "$PL" --task=PROJ-1 --yes >/dev/null 2>&1
|
|
122
|
+
[ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "explicit --task bypasses the grace" || fail "--task did not bypass the grace"
|
|
123
|
+
|
|
124
|
+
echo ""
|
|
125
|
+
echo "→ 10. traversal-shaped --task/--project values are rejected"
|
|
126
|
+
PRUNE_LOG_ROOT="$LR" bash "$PL" "--task=../evil" >/dev/null 2>&1
|
|
127
|
+
[ "$?" = "2" ] && pass "--task=../evil exits 2" || fail "--task=../evil accepted"
|
|
128
|
+
PRUNE_LOG_ROOT="$LR" bash "$PL" "--task=.counter" >/dev/null 2>&1
|
|
129
|
+
[ "$?" = "2" ] && pass "--task=.counter (leading dot) exits 2" || fail "--task=.counter accepted"
|
|
130
|
+
PRUNE_LOG_ROOT="$LR" bash "$PL" "--project=a/b" >/dev/null 2>&1
|
|
131
|
+
[ "$?" = "2" ] && pass "--project=a/b exits 2" || fail "--project=a/b accepted"
|
|
132
|
+
PRUNE_LOG_ROOT="$LR" bash "$PL" "--task=" >/dev/null 2>&1
|
|
133
|
+
[ "$?" = "2" ] && pass "empty --task exits 2" || fail "empty --task accepted"
|
|
134
|
+
|
|
85
135
|
echo ""
|
|
86
136
|
echo "══ prune-logs smoke: $PASS passed, $FAIL failed ══"
|
|
87
137
|
[ "$FAIL" -eq 0 ]
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# smoke-purge.sh - purge.sh wipes .worktrees/ worktrees (registered and
|
|
3
|
+
# orphaned), their local branches, and the project task counter; is dry-run
|
|
4
|
+
# by default; preserves the main worktree, protected branches, and the
|
|
5
|
+
# audit/metrics corpus; and never follows symlinks out of .worktrees/.
|
|
6
|
+
#
|
|
7
|
+
# Exit 0 = all pass, 1 = any failure.
|
|
8
|
+
|
|
9
|
+
set -uo pipefail
|
|
10
|
+
|
|
11
|
+
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
12
|
+
PG="$ROOT/pipeline/scripts/purge.sh"
|
|
13
|
+
PASS=0
|
|
14
|
+
FAIL=0
|
|
15
|
+
pass() {
|
|
16
|
+
PASS=$((PASS + 1))
|
|
17
|
+
echo " ✓ $1"
|
|
18
|
+
}
|
|
19
|
+
fail() {
|
|
20
|
+
FAIL=$((FAIL + 1))
|
|
21
|
+
echo " ✗ $1"
|
|
22
|
+
}
|
|
23
|
+
[ -f "$PG" ] || {
|
|
24
|
+
echo "FAIL: purge.sh missing" >&2
|
|
25
|
+
exit 1
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
SB="$(cd "$(mktemp -d)" && pwd -P)"
|
|
29
|
+
trap 'rm -rf "$SB"' EXIT
|
|
30
|
+
|
|
31
|
+
REPO="$SB/repo"
|
|
32
|
+
LR="$SB/logs"
|
|
33
|
+
VICTIM="$SB/victim"
|
|
34
|
+
|
|
35
|
+
seed() {
|
|
36
|
+
rm -rf "$REPO" "$LR" "$VICTIM"
|
|
37
|
+
mkdir -p "$REPO" "$LR/repo" "$VICTIM"
|
|
38
|
+
echo keep >"$VICTIM/keep.txt"
|
|
39
|
+
git -C "$REPO" init -q -b main
|
|
40
|
+
git -C "$REPO" -c user.email=t@t.t -c user.name=t commit -q --allow-empty -m init
|
|
41
|
+
git -C "$REPO" worktree add -q -b feature/PROJ-1-x "$REPO/.worktrees/PROJ-1" >/dev/null 2>&1
|
|
42
|
+
git -C "$REPO" worktree add -q -b bugfix/PROJ-2-y "$REPO/.worktrees/PROJ-2" >/dev/null 2>&1
|
|
43
|
+
mkdir -p "$REPO/.worktrees/PROJ-9" # orphan: dir git no longer registers
|
|
44
|
+
echo '{}' >"$REPO/.worktrees/PROJ-9/agent-state.json"
|
|
45
|
+
ln -s "$VICTIM" "$REPO/.worktrees/evil-link" # symlink escape attempt
|
|
46
|
+
echo '7' >"$LR/repo/.counter"
|
|
47
|
+
echo audit >"$LR/audit.jsonl"
|
|
48
|
+
echo metric >"$LR/metrics.jsonl"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
has_branch() {
|
|
52
|
+
git -C "$REPO" show-ref --verify -q "refs/heads/$1"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
echo "→ 1. dry-run lists everything and deletes nothing"
|
|
56
|
+
seed
|
|
57
|
+
out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" 2>&1)
|
|
58
|
+
rc=$?
|
|
59
|
+
[ "$rc" = "0" ] && pass "dry-run exits 0" || fail "dry-run exited $rc"
|
|
60
|
+
echo "$out" | grep -q "DRY-RUN" && pass "dry-run banner shown" || fail "dry-run banner missing"
|
|
61
|
+
echo "$out" | grep -q "PROJ-1" && pass "worktree PROJ-1 listed" || fail "worktree PROJ-1 not listed"
|
|
62
|
+
echo "$out" | grep -q "feature/PROJ-1-x" && pass "branch listed" || fail "branch not listed"
|
|
63
|
+
echo "$out" | grep -q ".counter" && pass "counter listed" || fail "counter not listed"
|
|
64
|
+
[ -d "$REPO/.worktrees/PROJ-1" ] && pass "dry-run kept worktrees" || fail "dry-run deleted a worktree"
|
|
65
|
+
[ -f "$LR/repo/.counter" ] && pass "dry-run kept the counter" || fail "dry-run deleted the counter"
|
|
66
|
+
has_branch feature/PROJ-1-x && pass "dry-run kept branches" || fail "dry-run deleted a branch"
|
|
67
|
+
|
|
68
|
+
echo ""
|
|
69
|
+
echo "→ 2. --yes wipes worktrees + branches + counter, preserves the rest"
|
|
70
|
+
seed
|
|
71
|
+
PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --yes >/dev/null 2>&1
|
|
72
|
+
rc=$?
|
|
73
|
+
[ "$rc" = "0" ] && pass "--yes exits 0" || fail "--yes exited $rc"
|
|
74
|
+
[ ! -e "$REPO/.worktrees/PROJ-1" ] && pass "registered worktree PROJ-1 removed" || fail "PROJ-1 survived"
|
|
75
|
+
[ ! -e "$REPO/.worktrees/PROJ-2" ] && pass "registered worktree PROJ-2 removed" || fail "PROJ-2 survived"
|
|
76
|
+
[ ! -e "$REPO/.worktrees/PROJ-9" ] && pass "orphan worktree dir removed" || fail "orphan PROJ-9 survived"
|
|
77
|
+
! has_branch feature/PROJ-1-x && pass "branch feature/PROJ-1-x deleted" || fail "feature/PROJ-1-x survived"
|
|
78
|
+
! has_branch bugfix/PROJ-2-y && pass "branch bugfix/PROJ-2-y deleted" || fail "bugfix/PROJ-2-y survived"
|
|
79
|
+
has_branch main && pass "main branch preserved" || fail "main branch was deleted"
|
|
80
|
+
git -C "$REPO" rev-parse --is-inside-work-tree >/dev/null 2>&1 && pass "main worktree still a git repo" || fail "main worktree destroyed"
|
|
81
|
+
wt_count=$(git -C "$REPO" worktree list 2>/dev/null | wc -l | tr -d ' ')
|
|
82
|
+
[ "$wt_count" = "1" ] && pass "only the main worktree remains registered" || fail "expected 1 registered worktree, got $wt_count"
|
|
83
|
+
[ ! -e "$LR/repo/.counter" ] && pass "task counter removed" || fail "task counter survived"
|
|
84
|
+
[ -f "$LR/audit.jsonl" ] && pass "audit.jsonl preserved" || fail "audit.jsonl was deleted"
|
|
85
|
+
[ -f "$LR/metrics.jsonl" ] && pass "metrics.jsonl preserved" || fail "metrics.jsonl was deleted"
|
|
86
|
+
[ -f "$VICTIM/keep.txt" ] && pass "symlink target outside repo untouched" || fail "symlink target was deleted"
|
|
87
|
+
|
|
88
|
+
echo ""
|
|
89
|
+
echo "→ 3. protected branch carried by a worktree survives, worktree still removed"
|
|
90
|
+
seed
|
|
91
|
+
git -C "$REPO" worktree add -q -b develop "$REPO/.worktrees/DEV-1" >/dev/null 2>&1
|
|
92
|
+
PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --yes >/dev/null 2>&1
|
|
93
|
+
[ ! -e "$REPO/.worktrees/DEV-1" ] && pass "develop worktree removed" || fail "develop worktree survived"
|
|
94
|
+
has_branch develop && pass "develop branch preserved" || fail "develop branch was deleted"
|
|
95
|
+
|
|
96
|
+
echo ""
|
|
97
|
+
echo "→ 4. clean repo and non-repo are no-ops (exit 0)"
|
|
98
|
+
CLEAN="$SB/clean"
|
|
99
|
+
mkdir -p "$CLEAN"
|
|
100
|
+
git -C "$CLEAN" init -q -b main
|
|
101
|
+
out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$CLEAN" 2>&1)
|
|
102
|
+
rc=$?
|
|
103
|
+
{ [ "$rc" = "0" ] && echo "$out" | grep -q "nothing to do"; } && pass "clean repo is a no-op" || fail "clean repo not a clean no-op (rc=$rc)"
|
|
104
|
+
PLAIN="$SB/plain"
|
|
105
|
+
mkdir -p "$PLAIN"
|
|
106
|
+
out=$(bash "$PG" --repo "$PLAIN" 2>&1)
|
|
107
|
+
rc=$?
|
|
108
|
+
{ [ "$rc" = "0" ] && echo "$out" | grep -q "not a git work tree"; } && pass "non-repo dir is a no-op" || fail "non-repo dir not a clean no-op (rc=$rc)"
|
|
109
|
+
|
|
110
|
+
echo ""
|
|
111
|
+
echo "→ 5. usage errors exit 2"
|
|
112
|
+
bash "$PG" --bogus >/dev/null 2>&1
|
|
113
|
+
[ "$?" = "2" ] && pass "unknown argument exits 2" || fail "unknown argument did not exit 2"
|
|
114
|
+
bash "$PG" --repo >/dev/null 2>&1
|
|
115
|
+
[ "$?" = "2" ] && pass "--repo without a path exits 2" || fail "--repo without a path did not exit 2"
|
|
116
|
+
|
|
117
|
+
echo ""
|
|
118
|
+
echo "→ 6. --delete-remote without a remote warns but does not fail"
|
|
119
|
+
seed
|
|
120
|
+
out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --delete-remote 2>&1)
|
|
121
|
+
echo "$out" | grep -q "remote branch origin/feature/PROJ-1-x" && pass "dry-run lists remote branch deletion" || fail "dry-run missing remote branch line"
|
|
122
|
+
out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --delete-remote --yes 2>&1)
|
|
123
|
+
rc=$?
|
|
124
|
+
[ "$rc" = "0" ] && pass "--delete-remote --yes exits 0 without a remote" || fail "--delete-remote --yes exited $rc"
|
|
125
|
+
echo "$out" | grep -qi "warning" && pass "missing remote surfaces a warning" || fail "no warning for missing remote"
|
|
126
|
+
|
|
127
|
+
echo ""
|
|
128
|
+
echo "→ 7. purge from inside a linked worktree still anchors on the main repo"
|
|
129
|
+
seed
|
|
130
|
+
out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO/.worktrees/PROJ-1" --yes 2>&1)
|
|
131
|
+
rc=$?
|
|
132
|
+
[ "$rc" = "0" ] && pass "run from linked worktree exits 0" || fail "run from linked worktree exited $rc"
|
|
133
|
+
[ ! -e "$REPO/.worktrees/PROJ-1" ] && pass "worktrees removed when invoked from inside one" || fail "worktrees survived"
|
|
134
|
+
git -C "$REPO" rev-parse --is-inside-work-tree >/dev/null 2>&1 && pass "main repo intact" || fail "main repo destroyed"
|
|
135
|
+
|
|
136
|
+
echo ""
|
|
137
|
+
echo "══ purge smoke: $PASS passed, $FAIL failed ══"
|
|
138
|
+
[ "$FAIL" -eq 0 ]
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# smoke-source-parity.sh - guard the two divergent SOURCE trees of the same
|
|
3
|
+
# feature set from drifting out of alignment.
|
|
4
|
+
#
|
|
5
|
+
# The pipeline ships each sub-command twice, in parallel trees:
|
|
6
|
+
# 1. pipeline/commands/multi-agent/<name>/ (Claude slash commands)
|
|
7
|
+
# 2. pipeline/skills/shared/core/multi-agent-<name>/ (Copilot skills)
|
|
8
|
+
# Both are meant to cover the SAME feature SET. A feature present in one tree
|
|
9
|
+
# but absent from the other is the single biggest maintainability liability
|
|
10
|
+
# here: users on one CLI silently lose a capability the other CLI advertises.
|
|
11
|
+
#
|
|
12
|
+
# This is a STRUCTURAL set-parity check only. It auto-discovers feature names
|
|
13
|
+
# from the directory listings (nothing is hardcoded), strips the
|
|
14
|
+
# 'multi-agent-' prefix from the skills tree, and FAILS if the symmetric
|
|
15
|
+
# difference of the two name sets is non-empty. It deliberately does NOT diff
|
|
16
|
+
# prose / behavior content between a matched command and its skill - content
|
|
17
|
+
# drift is a separate concern (see smoke-sync-parity.sh / sync-parity-check).
|
|
18
|
+
|
|
19
|
+
set -uo pipefail
|
|
20
|
+
|
|
21
|
+
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
22
|
+
CMDS_DIR="$REPO_ROOT/pipeline/commands/multi-agent"
|
|
23
|
+
SKILLS_DIR="$REPO_ROOT/pipeline/skills/shared/core"
|
|
24
|
+
|
|
25
|
+
PASS=0
|
|
26
|
+
FAIL=0
|
|
27
|
+
pass() { PASS=$((PASS+1)); echo " ✓ $1"; }
|
|
28
|
+
fail() { FAIL=$((FAIL+1)); echo " ✗ $1"; }
|
|
29
|
+
|
|
30
|
+
if [ ! -d "$CMDS_DIR" ]; then
|
|
31
|
+
echo "FAIL: commands tree missing at $CMDS_DIR" >&2
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
if [ ! -d "$SKILLS_DIR" ]; then
|
|
35
|
+
echo "FAIL: skills tree missing at $SKILLS_DIR" >&2
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
echo "→ 1. discover feature names in each source tree"
|
|
40
|
+
|
|
41
|
+
# Claude slash commands: every immediate sub-directory is a feature.
|
|
42
|
+
CMD_FEATURES=$(find "$CMDS_DIR" -mindepth 1 -maxdepth 1 -type d \
|
|
43
|
+
-exec basename {} \; | sort -u)
|
|
44
|
+
|
|
45
|
+
# Copilot skills: multi-agent-<name> sub-directories; strip the prefix.
|
|
46
|
+
# Non-prefixed skill dirs (e.g. apple-archive-compliance) are standalone
|
|
47
|
+
# skills without a slash-command twin, so they are intentionally excluded.
|
|
48
|
+
SKILL_FEATURES=$(find "$SKILLS_DIR" -mindepth 1 -maxdepth 1 -type d \
|
|
49
|
+
-name 'multi-agent-*' -exec basename {} \; \
|
|
50
|
+
| sed 's/^multi-agent-//' | sort -u)
|
|
51
|
+
|
|
52
|
+
CMD_COUNT=$(printf '%s\n' "$CMD_FEATURES" | grep -c . || true)
|
|
53
|
+
SKILL_COUNT=$(printf '%s\n' "$SKILL_FEATURES" | grep -c . || true)
|
|
54
|
+
pass "commands tree: $CMD_COUNT features"
|
|
55
|
+
pass "skills tree: $SKILL_COUNT features"
|
|
56
|
+
|
|
57
|
+
echo ""
|
|
58
|
+
echo "→ 2. set symmetric difference must be empty"
|
|
59
|
+
|
|
60
|
+
# In commands tree but missing from skills tree.
|
|
61
|
+
ONLY_CMD=$(comm -23 \
|
|
62
|
+
<(printf '%s\n' "$CMD_FEATURES") \
|
|
63
|
+
<(printf '%s\n' "$SKILL_FEATURES"))
|
|
64
|
+
# In skills tree but missing from commands tree.
|
|
65
|
+
ONLY_SKILL=$(comm -13 \
|
|
66
|
+
<(printf '%s\n' "$CMD_FEATURES") \
|
|
67
|
+
<(printf '%s\n' "$SKILL_FEATURES"))
|
|
68
|
+
|
|
69
|
+
if [ -z "$ONLY_CMD" ]; then
|
|
70
|
+
pass "no command-only features (all present as skills)"
|
|
71
|
+
else
|
|
72
|
+
fail "features in commands/ but NOT in skills tree:"
|
|
73
|
+
printf ' - %s\n' $ONLY_CMD
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
if [ -z "$ONLY_SKILL" ]; then
|
|
77
|
+
pass "no skill-only features (all present as commands)"
|
|
78
|
+
else
|
|
79
|
+
fail "features in skills tree but NOT in commands/:"
|
|
80
|
+
printf ' - %s\n' $ONLY_SKILL
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
echo ""
|
|
84
|
+
echo "══ source-parity smoke: $PASS passed, $FAIL failed ══"
|
|
85
|
+
[ "$FAIL" -eq 0 ]
|
|
@@ -67,6 +67,19 @@ else
|
|
|
67
67
|
record_fail "local-ahead should be silent (got '$out', rc=$rc)"
|
|
68
68
|
fi
|
|
69
69
|
|
|
70
|
+
# 3b2. No --local, no repo clone -> falls back to the install-time version
|
|
71
|
+
# marker (npx-only installs have no clone to read a version from)
|
|
72
|
+
marker_home="$tmpdir/marker-home"
|
|
73
|
+
mkdir -p "$marker_home/.claude"
|
|
74
|
+
printf '10.0.0\n' > "$marker_home/.claude/.pipeline-version"
|
|
75
|
+
printf '%s|99.0.0\n' "$now" > "$CACHE"
|
|
76
|
+
out=$(HOME="$marker_home" UPDATE_CHECK_CACHE="$CACHE" bash "$SCRIPT" 2>/dev/null); rc=$?
|
|
77
|
+
if [ "$rc" -eq 0 ] && [ "$out" = "10.0.0|99.0.0" ]; then
|
|
78
|
+
record_pass "no clone -> .pipeline-version marker fallback works"
|
|
79
|
+
else
|
|
80
|
+
record_fail "marker fallback should print '10.0.0|99.0.0' (got '$out', rc=$rc)"
|
|
81
|
+
fi
|
|
82
|
+
|
|
70
83
|
# 3c. Offline + stale cache -> silent exit 0 (advisory: never blocks)
|
|
71
84
|
printf '0|10.0.0\n' > "$CACHE"
|
|
72
85
|
out=$(UPDATE_CHECK_CACHE="$CACHE" http_proxy="http://127.0.0.1:1" https_proxy="http://127.0.0.1:1" \
|
|
@@ -12,21 +12,26 @@
|
|
|
12
12
|
* node uninstall.mjs # interactive, removes from all installed targets
|
|
13
13
|
* node uninstall.mjs --yes # skip prompts, remove from all
|
|
14
14
|
* node uninstall.mjs --claude # only Claude Code
|
|
15
|
+
* node uninstall.mjs --all-data # ALSO remove pipeline settings + logs/state/metrics
|
|
15
16
|
* node uninstall.mjs --cursor --target=/path/to/repo # legacy adapter-file cleanup
|
|
16
17
|
* node uninstall.mjs --dry-run # report what would be removed, change nothing
|
|
17
18
|
*
|
|
18
19
|
* Targeted by:
|
|
19
|
-
* - `/multi-agent:
|
|
20
|
-
* - `multi-agent-
|
|
20
|
+
* - `/multi-agent:uninstall` slash command (Claude Code)
|
|
21
|
+
* - `multi-agent-uninstall` skill (Copilot CLI)
|
|
21
22
|
* - `npx @mmerterden/multi-agent-pipeline uninstall` (direct CLI)
|
|
22
23
|
*
|
|
23
|
-
* Always preserved:
|
|
24
|
-
* - $HOME/.claude/CLAUDE.md (user customizations)
|
|
25
|
-
* - $HOME/.claude/multi-agent-preferences.json
|
|
24
|
+
* Always preserved (both modes):
|
|
26
25
|
* - Personal access tokens in the OS credential store
|
|
26
|
+
* - $HOME/.claude/CLAUDE.md (user customizations)
|
|
27
|
+
* - $HOME/.claude/rules/ (user-owned; installed write-if-missing)
|
|
27
28
|
* - User content outside the `<!-- multi-agent-pipeline:begin/end -->` markers
|
|
28
29
|
* in shared rules files (copilot-instructions.md)
|
|
29
30
|
*
|
|
31
|
+
* Preserved by default, removed with --all-data:
|
|
32
|
+
* - $HOME/.claude/multi-agent-preferences.json (pipeline settings)
|
|
33
|
+
* - $HOME/.claude/logs/multi-agent/ (task logs, state, metrics, audit trail)
|
|
34
|
+
*
|
|
30
35
|
* @module pipeline/scripts/runtime/uninstall
|
|
31
36
|
*/
|
|
32
37
|
|
|
@@ -86,6 +91,9 @@ const forCodex = flags.includes("--codex") || flags.includes("--all") || !explic
|
|
|
86
91
|
|
|
87
92
|
const dryRun = flags.includes("--dry-run");
|
|
88
93
|
const skipPrompt = flags.includes("--yes") || flags.includes("-y");
|
|
94
|
+
// Full cleanup: also remove pipeline settings + the multi-agent log root
|
|
95
|
+
// (task logs, state, metrics, audit). Tokens, CLAUDE.md and rules/ stay.
|
|
96
|
+
const allData = flags.includes("--all-data");
|
|
89
97
|
|
|
90
98
|
const adapterTarget = (() => {
|
|
91
99
|
const raw = flags.find((f) => f.startsWith("--target="));
|
|
@@ -312,11 +320,17 @@ async function main() {
|
|
|
312
320
|
if (forAntigravity) console.log(` - Antigravity (${adapterTarget}/.agent/rules + .agent/workflows + AGENTS.md block + .agent/mcp_config.json)`);
|
|
313
321
|
if (forCodex) console.log(" - OpenAI Codex CLI (~/.codex/prompts/multi-agent.md + AGENTS.md block + config.toml mcp block)");
|
|
314
322
|
console.log("");
|
|
323
|
+
if (allData) {
|
|
324
|
+
console.log(" FULL CLEANUP (--all-data) also removes:");
|
|
325
|
+
console.log(" - ~/.claude/multi-agent-preferences.json (pipeline settings)");
|
|
326
|
+
console.log(" - ~/.claude/logs/multi-agent/ (task logs, state, metrics, audit trail)");
|
|
327
|
+
console.log("");
|
|
328
|
+
}
|
|
315
329
|
console.log(" PRESERVED (never touched):");
|
|
316
330
|
console.log(" - Personal access tokens in OS credential store (Keychain / Credential Manager / libsecret)");
|
|
317
331
|
console.log(" - ~/.claude/CLAUDE.md (your customizations)");
|
|
318
332
|
console.log(" - ~/.claude/rules/ (user-owned; installed write-if-missing, never overwritten)");
|
|
319
|
-
console.log(" - ~/.claude/multi-agent-preferences.json (your settings)");
|
|
333
|
+
if (!allData) console.log(" - ~/.claude/multi-agent-preferences.json (your settings)");
|
|
320
334
|
console.log(" - Your own content in copilot-instructions.md above the pipeline section");
|
|
321
335
|
console.log("");
|
|
322
336
|
|
|
@@ -335,6 +349,7 @@ async function main() {
|
|
|
335
349
|
rmIfExists(join(CLAUDE, "multi-agent-refs"));
|
|
336
350
|
rmIfExists(join(CLAUDE, "schemas"));
|
|
337
351
|
rmIfExists(join(CLAUDE, "lib"));
|
|
352
|
+
rmIfExists(join(CLAUDE, ".pipeline-version"));
|
|
338
353
|
// NOTE: ~/.claude/rules/ is USER-OWNED. install lays baseline rules down
|
|
339
354
|
// write-if-missing and NEVER overwrites them (install/claude.mjs
|
|
340
355
|
// installRules, skipExisting) so users can evolve their global rules
|
|
@@ -363,6 +378,7 @@ async function main() {
|
|
|
363
378
|
// Pipeline-managed trees the installer lays down alongside scripts/.
|
|
364
379
|
rmIfExists(join(COP, "schemas"));
|
|
365
380
|
rmIfExists(join(COP, "lib"));
|
|
381
|
+
rmIfExists(join(COP, ".pipeline-version"));
|
|
366
382
|
const skills = join(COP, "skills");
|
|
367
383
|
let n = rmMatchingDirs(skills, (name) => name === "multi-agent" || name.startsWith("multi-agent-"));
|
|
368
384
|
n += rmMatchingDirs(skills, (name) => name === "figma-ios" || name === "figma-android" || name === "figma-common" || name === "figma-to-component");
|
|
@@ -377,6 +393,16 @@ async function main() {
|
|
|
377
393
|
stripManagedBlock(join(COP, "copilot-instructions.md"));
|
|
378
394
|
}
|
|
379
395
|
|
|
396
|
+
// Full cleanup: pipeline settings + the multi-agent log root. Both are
|
|
397
|
+
// pipeline-generated data (not user-authored like CLAUDE.md / rules), so
|
|
398
|
+
// --all-data removes them; the default run leaves them in place.
|
|
399
|
+
if (allData && HOME) {
|
|
400
|
+
console.log("");
|
|
401
|
+
console.log(" [Full cleanup] Removing pipeline settings + logs...");
|
|
402
|
+
rmIfExists(join(HOME, ".claude", "multi-agent-preferences.json"));
|
|
403
|
+
rmIfExists(join(HOME, ".claude", "logs", "multi-agent"));
|
|
404
|
+
}
|
|
405
|
+
|
|
380
406
|
// Legacy adapter-file cleanup (adapters removed in v10.7.0). These blocks
|
|
381
407
|
// delete files a pre-v10.7.0 install generated; they never touch user files
|
|
382
408
|
// outside the multi-agent-* namespace / managed markers.
|
|
@@ -423,6 +449,15 @@ async function main() {
|
|
|
423
449
|
|
|
424
450
|
console.log("");
|
|
425
451
|
console.log(" ✓ Pipeline removed.");
|
|
452
|
+
if (!allData) {
|
|
453
|
+
console.log("");
|
|
454
|
+
console.log(" Kept your pipeline settings + logs. To remove those too, re-run with --all-data.");
|
|
455
|
+
} else {
|
|
456
|
+
console.log("");
|
|
457
|
+
console.log(" Full cleanup done. Still on disk (user-owned, remove by hand if you want a bare system):");
|
|
458
|
+
console.log(" - ~/.claude/CLAUDE.md");
|
|
459
|
+
console.log(" - ~/.claude/rules/");
|
|
460
|
+
}
|
|
426
461
|
console.log("");
|
|
427
462
|
console.log(" Personal access tokens were NOT touched. Inspect with:");
|
|
428
463
|
console.log(" macOS: security find-generic-password -s \"<service>\" -w");
|
|
@@ -46,6 +46,15 @@ if [ -z "$LOCAL_VERSION" ]; then
|
|
|
46
46
|
fi
|
|
47
47
|
done
|
|
48
48
|
fi
|
|
49
|
+
# npx-only installs have no repo clone; the installer stamps the version here.
|
|
50
|
+
if [ -z "$LOCAL_VERSION" ]; then
|
|
51
|
+
for marker in "$HOME/.claude/.pipeline-version" "$HOME/.copilot/.pipeline-version"; do
|
|
52
|
+
if [ -f "$marker" ]; then
|
|
53
|
+
LOCAL_VERSION=$(head -1 "$marker" 2>/dev/null | tr -d '[:space:]')
|
|
54
|
+
[ -n "$LOCAL_VERSION" ] && break
|
|
55
|
+
fi
|
|
56
|
+
done
|
|
57
|
+
fi
|
|
49
58
|
[ -z "$LOCAL_VERSION" ] && exit 0 # cannot determine local version -> silent no-op
|
|
50
59
|
|
|
51
60
|
now=$(date +%s)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-07-
|
|
3
|
+
"generatedAt": "2026-07-20T07:34:26Z",
|
|
4
4
|
"skillCount": 189,
|
|
5
5
|
"entries": [
|
|
6
6
|
{
|
|
@@ -35,10 +35,6 @@
|
|
|
35
35
|
"path": "shared/core/multi-agent-create-jira/SKILL.md",
|
|
36
36
|
"sha256": "40caf0489ad8322cd00d792a244e772d4ddb6ccfd7c3807729d6b17590e7f81c"
|
|
37
37
|
},
|
|
38
|
-
{
|
|
39
|
-
"path": "shared/core/multi-agent-delete/SKILL.md",
|
|
40
|
-
"sha256": "aa48d1e0fe111b9dc1b681025f16880410d47266f12f522df1835857e6cb9551"
|
|
41
|
-
},
|
|
42
38
|
{
|
|
43
39
|
"path": "shared/core/multi-agent-dev-autopilot/SKILL.md",
|
|
44
40
|
"sha256": "82b1cf4a4bbd84fcfef54fcdbcdefa27f2747df6d4fac5c86b42e861013c6d58"
|
|
@@ -153,19 +149,23 @@
|
|
|
153
149
|
},
|
|
154
150
|
{
|
|
155
151
|
"path": "shared/core/multi-agent-sync/SKILL.md",
|
|
156
|
-
"sha256": "
|
|
152
|
+
"sha256": "de38486056c99a599d93ae5166a2071875331a7d77f1e34f66d8b72657a73c2f"
|
|
157
153
|
},
|
|
158
154
|
{
|
|
159
155
|
"path": "shared/core/multi-agent-test/SKILL.md",
|
|
160
156
|
"sha256": "f90c34f71ea6cd5cccbfa128597eaaa221a0ca5f62924eb9cfb6b1ed2d07de04"
|
|
161
157
|
},
|
|
158
|
+
{
|
|
159
|
+
"path": "shared/core/multi-agent-uninstall/SKILL.md",
|
|
160
|
+
"sha256": "775bcaf9248659986c3c5ef1c4f07d3d85784bd10c73cb33c47648bdfc8d834c"
|
|
161
|
+
},
|
|
162
162
|
{
|
|
163
163
|
"path": "shared/core/multi-agent-update/SKILL.md",
|
|
164
164
|
"sha256": "4f31addb21ab5ec31a1288dc4ee56f102d0936473a964f8a6f4075a9c44889cd"
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
"path": "shared/core/multi-agent/SKILL.md",
|
|
168
|
-
"sha256": "
|
|
168
|
+
"sha256": "fe03eb27cae0489178cc327b3ca370e998638b6de08d4caa8c755dd53f45a30e"
|
|
169
169
|
},
|
|
170
170
|
{
|
|
171
171
|
"path": "shared/external/accessibility-compliance-accessibility-audit/SKILL.md",
|
|
@@ -794,15 +794,6 @@
|
|
|
794
794
|
"triggerPaths": [],
|
|
795
795
|
"relativePath": "shared/core/multi-agent-create-jira/SKILL.md"
|
|
796
796
|
},
|
|
797
|
-
{
|
|
798
|
-
"name": "multi-agent-delete",
|
|
799
|
-
"description": "Uninstall the pipeline from Claude Code + Copilot CLI. Keychain access tokens are left untouched. Asks for double confirmation.",
|
|
800
|
-
"platform": null,
|
|
801
|
-
"group": "core",
|
|
802
|
-
"triggerKeywords": [],
|
|
803
|
-
"triggerPaths": [],
|
|
804
|
-
"relativePath": "shared/core/multi-agent-delete/SKILL.md"
|
|
805
|
-
},
|
|
806
797
|
{
|
|
807
798
|
"name": "multi-agent-dev",
|
|
808
799
|
"description": "Fast development mode: Init → Dev (Opus) → Test → Commit → Report. Analysis, planning, and review phases are skipped.",
|
|
@@ -1073,6 +1064,15 @@
|
|
|
1073
1064
|
"triggerPaths": [],
|
|
1074
1065
|
"relativePath": "shared/core/multi-agent-test/SKILL.md"
|
|
1075
1066
|
},
|
|
1067
|
+
{
|
|
1068
|
+
"name": "multi-agent-uninstall",
|
|
1069
|
+
"description": "Uninstall the pipeline from Claude Code + Copilot CLI. Keychain access tokens are always left untouched; --all-data also clears pipeline settings and logs. Asks for double confirmation.",
|
|
1070
|
+
"platform": null,
|
|
1071
|
+
"group": "core",
|
|
1072
|
+
"triggerKeywords": [],
|
|
1073
|
+
"triggerPaths": [],
|
|
1074
|
+
"relativePath": "shared/core/multi-agent-uninstall/SKILL.md"
|
|
1075
|
+
},
|
|
1076
1076
|
{
|
|
1077
1077
|
"name": "multi-agent-update",
|
|
1078
1078
|
"description": "Update the pipeline to the latest version: git pull, install, migrate.",
|