claude-code-pilot 2.0.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.
Files changed (257) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -0
  3. package/bin/install.js +431 -0
  4. package/docs/agent-guides/architecture.md +107 -0
  5. package/ecc/agents/architect.md +211 -0
  6. package/ecc/agents/code-reviewer.md +237 -0
  7. package/ecc/agents/doc-updater.md +107 -0
  8. package/ecc/agents/e2e-runner.md +107 -0
  9. package/ecc/agents/security-reviewer.md +108 -0
  10. package/ecc/agents/tdd-guide.md +91 -0
  11. package/ecc/commands/checkpoint.md +74 -0
  12. package/ecc/commands/evolve.md +178 -0
  13. package/ecc/commands/learn.md +70 -0
  14. package/ecc/commands/model-route.md +26 -0
  15. package/ecc/commands/quality-gate.md +29 -0
  16. package/ecc/commands/resume-session.md +155 -0
  17. package/ecc/commands/save-session.md +275 -0
  18. package/ecc/commands/sessions.md +305 -0
  19. package/ecc/commands/verify.md +59 -0
  20. package/ecc/contexts/dev.md +20 -0
  21. package/ecc/contexts/research.md +26 -0
  22. package/ecc/contexts/review.md +22 -0
  23. package/ecc/examples/CLAUDE.md +100 -0
  24. package/ecc/examples/django-api-CLAUDE.md +308 -0
  25. package/ecc/examples/go-microservice-CLAUDE.md +267 -0
  26. package/ecc/examples/rust-api-CLAUDE.md +285 -0
  27. package/ecc/examples/saas-nextjs-CLAUDE.md +166 -0
  28. package/ecc/examples/user-CLAUDE.md +109 -0
  29. package/ecc/rules/common/agents.md +49 -0
  30. package/ecc/rules/common/coding-style.md +48 -0
  31. package/ecc/rules/common/development-workflow.md +37 -0
  32. package/ecc/rules/common/git-workflow.md +24 -0
  33. package/ecc/rules/common/hooks.md +30 -0
  34. package/ecc/rules/common/patterns.md +31 -0
  35. package/ecc/rules/common/performance.md +55 -0
  36. package/ecc/rules/common/security.md +29 -0
  37. package/ecc/rules/common/testing.md +29 -0
  38. package/ecc/rules/golang/coding-style.md +32 -0
  39. package/ecc/rules/golang/hooks.md +17 -0
  40. package/ecc/rules/golang/patterns.md +45 -0
  41. package/ecc/rules/golang/security.md +34 -0
  42. package/ecc/rules/golang/testing.md +31 -0
  43. package/ecc/rules/kotlin/coding-style.md +86 -0
  44. package/ecc/rules/kotlin/patterns.md +146 -0
  45. package/ecc/rules/kotlin/security.md +82 -0
  46. package/ecc/rules/kotlin/testing.md +128 -0
  47. package/ecc/rules/perl/coding-style.md +46 -0
  48. package/ecc/rules/perl/hooks.md +22 -0
  49. package/ecc/rules/perl/patterns.md +76 -0
  50. package/ecc/rules/perl/security.md +69 -0
  51. package/ecc/rules/perl/testing.md +54 -0
  52. package/ecc/rules/php/coding-style.md +35 -0
  53. package/ecc/rules/php/hooks.md +24 -0
  54. package/ecc/rules/php/patterns.md +32 -0
  55. package/ecc/rules/php/security.md +33 -0
  56. package/ecc/rules/php/testing.md +34 -0
  57. package/ecc/rules/python/coding-style.md +42 -0
  58. package/ecc/rules/python/hooks.md +19 -0
  59. package/ecc/rules/python/patterns.md +39 -0
  60. package/ecc/rules/python/security.md +30 -0
  61. package/ecc/rules/python/testing.md +38 -0
  62. package/ecc/rules/swift/coding-style.md +47 -0
  63. package/ecc/rules/swift/hooks.md +20 -0
  64. package/ecc/rules/swift/patterns.md +66 -0
  65. package/ecc/rules/swift/security.md +33 -0
  66. package/ecc/rules/swift/testing.md +45 -0
  67. package/ecc/rules/typescript/coding-style.md +199 -0
  68. package/ecc/rules/typescript/hooks.md +22 -0
  69. package/ecc/rules/typescript/patterns.md +52 -0
  70. package/ecc/rules/typescript/security.md +28 -0
  71. package/ecc/rules/typescript/testing.md +18 -0
  72. package/ecc/scripts/hooks/check-hook-enabled.js +12 -0
  73. package/ecc/scripts/hooks/evaluate-session.js +100 -0
  74. package/ecc/scripts/hooks/pre-compact.js +48 -0
  75. package/ecc/scripts/hooks/run-with-flags-shell.sh +32 -0
  76. package/ecc/scripts/hooks/run-with-flags.js +120 -0
  77. package/ecc/scripts/hooks/session-end-marker.js +15 -0
  78. package/ecc/scripts/hooks/session-end.js +258 -0
  79. package/ecc/scripts/hooks/session-start.js +97 -0
  80. package/ecc/scripts/hooks/suggest-compact.js +80 -0
  81. package/ecc/scripts/lib/hook-flags.js +74 -0
  82. package/ecc/scripts/lib/package-manager.d.ts +119 -0
  83. package/ecc/scripts/lib/package-manager.js +431 -0
  84. package/ecc/scripts/lib/project-detect.js +428 -0
  85. package/ecc/scripts/lib/resolve-formatter.js +185 -0
  86. package/ecc/scripts/lib/session-aliases.d.ts +136 -0
  87. package/ecc/scripts/lib/session-aliases.js +481 -0
  88. package/ecc/scripts/lib/session-manager.d.ts +131 -0
  89. package/ecc/scripts/lib/session-manager.js +444 -0
  90. package/ecc/scripts/lib/shell-split.js +86 -0
  91. package/ecc/scripts/lib/utils.d.ts +183 -0
  92. package/ecc/scripts/lib/utils.js +543 -0
  93. package/ecc/skills/continuous-learning-v2/SKILL.md +365 -0
  94. package/ecc/skills/continuous-learning-v2/agents/observer-loop.sh +144 -0
  95. package/ecc/skills/continuous-learning-v2/agents/observer.md +198 -0
  96. package/ecc/skills/continuous-learning-v2/agents/start-observer.sh +194 -0
  97. package/ecc/skills/continuous-learning-v2/config.json +8 -0
  98. package/ecc/skills/continuous-learning-v2/hooks/observe.sh +246 -0
  99. package/ecc/skills/continuous-learning-v2/scripts/detect-project.sh +218 -0
  100. package/ecc/skills/continuous-learning-v2/scripts/instinct-cli.py +1148 -0
  101. package/ecc/skills/continuous-learning-v2/scripts/test_parse_instinct.py +984 -0
  102. package/ecc/skills/strategic-compact/SKILL.md +103 -0
  103. package/ecc/skills/strategic-compact/suggest-compact.sh +54 -0
  104. package/ecc/skills/verification-loop-SKILL.md +126 -0
  105. package/gsd/LICENSE +21 -0
  106. package/gsd/agents/gsd-codebase-mapper.md +772 -0
  107. package/gsd/agents/gsd-debugger.md +1257 -0
  108. package/gsd/agents/gsd-executor.md +489 -0
  109. package/gsd/agents/gsd-integration-checker.md +445 -0
  110. package/gsd/agents/gsd-nyquist-auditor.md +178 -0
  111. package/gsd/agents/gsd-phase-researcher.md +555 -0
  112. package/gsd/agents/gsd-plan-checker.md +708 -0
  113. package/gsd/agents/gsd-planner.md +1309 -0
  114. package/gsd/agents/gsd-project-researcher.md +631 -0
  115. package/gsd/agents/gsd-research-synthesizer.md +249 -0
  116. package/gsd/agents/gsd-roadmapper.md +652 -0
  117. package/gsd/agents/gsd-verifier.md +581 -0
  118. package/gsd/commands-gsd/add-phase.md +43 -0
  119. package/gsd/commands-gsd/add-tests.md +41 -0
  120. package/gsd/commands-gsd/add-todo.md +47 -0
  121. package/gsd/commands-gsd/audit-milestone.md +36 -0
  122. package/gsd/commands-gsd/check-todos.md +45 -0
  123. package/gsd/commands-gsd/cleanup.md +18 -0
  124. package/gsd/commands-gsd/complete-milestone.md +136 -0
  125. package/gsd/commands-gsd/debug.md +168 -0
  126. package/gsd/commands-gsd/discuss-phase.md +90 -0
  127. package/gsd/commands-gsd/execute-phase.md +41 -0
  128. package/gsd/commands-gsd/health.md +22 -0
  129. package/gsd/commands-gsd/help.md +22 -0
  130. package/gsd/commands-gsd/insert-phase.md +32 -0
  131. package/gsd/commands-gsd/join-discord.md +18 -0
  132. package/gsd/commands-gsd/list-phase-assumptions.md +46 -0
  133. package/gsd/commands-gsd/map-codebase.md +71 -0
  134. package/gsd/commands-gsd/new-milestone.md +44 -0
  135. package/gsd/commands-gsd/new-project.md +42 -0
  136. package/gsd/commands-gsd/pause-work.md +38 -0
  137. package/gsd/commands-gsd/plan-milestone-gaps.md +34 -0
  138. package/gsd/commands-gsd/plan-phase.md +45 -0
  139. package/gsd/commands-gsd/progress.md +24 -0
  140. package/gsd/commands-gsd/quick.md +45 -0
  141. package/gsd/commands-gsd/reapply-patches.md +123 -0
  142. package/gsd/commands-gsd/remove-phase.md +31 -0
  143. package/gsd/commands-gsd/research-phase.md +190 -0
  144. package/gsd/commands-gsd/resume-work.md +40 -0
  145. package/gsd/commands-gsd/set-profile.md +34 -0
  146. package/gsd/commands-gsd/settings.md +36 -0
  147. package/gsd/commands-gsd/update.md +37 -0
  148. package/gsd/commands-gsd/validate-phase.md +35 -0
  149. package/gsd/commands-gsd/verify-work.md +38 -0
  150. package/gsd/get-shit-done/bin/gsd-tools.cjs +592 -0
  151. package/gsd/get-shit-done/bin/lib/commands.cjs +548 -0
  152. package/gsd/get-shit-done/bin/lib/config.cjs +169 -0
  153. package/gsd/get-shit-done/bin/lib/core.cjs +492 -0
  154. package/gsd/get-shit-done/bin/lib/frontmatter.cjs +299 -0
  155. package/gsd/get-shit-done/bin/lib/init.cjs +710 -0
  156. package/gsd/get-shit-done/bin/lib/milestone.cjs +241 -0
  157. package/gsd/get-shit-done/bin/lib/phase.cjs +901 -0
  158. package/gsd/get-shit-done/bin/lib/roadmap.cjs +298 -0
  159. package/gsd/get-shit-done/bin/lib/state.cjs +721 -0
  160. package/gsd/get-shit-done/bin/lib/template.cjs +222 -0
  161. package/gsd/get-shit-done/bin/lib/verify.cjs +820 -0
  162. package/gsd/get-shit-done/references/checkpoints.md +776 -0
  163. package/gsd/get-shit-done/references/continuation-format.md +249 -0
  164. package/gsd/get-shit-done/references/decimal-phase-calculation.md +65 -0
  165. package/gsd/get-shit-done/references/git-integration.md +248 -0
  166. package/gsd/get-shit-done/references/git-planning-commit.md +38 -0
  167. package/gsd/get-shit-done/references/model-profile-resolution.md +34 -0
  168. package/gsd/get-shit-done/references/model-profiles.md +93 -0
  169. package/gsd/get-shit-done/references/phase-argument-parsing.md +61 -0
  170. package/gsd/get-shit-done/references/planning-config.md +200 -0
  171. package/gsd/get-shit-done/references/questioning.md +162 -0
  172. package/gsd/get-shit-done/references/tdd.md +263 -0
  173. package/gsd/get-shit-done/references/ui-brand.md +160 -0
  174. package/gsd/get-shit-done/references/verification-patterns.md +612 -0
  175. package/gsd/get-shit-done/templates/DEBUG.md +164 -0
  176. package/gsd/get-shit-done/templates/UAT.md +247 -0
  177. package/gsd/get-shit-done/templates/VALIDATION.md +76 -0
  178. package/gsd/get-shit-done/templates/codebase/architecture.md +255 -0
  179. package/gsd/get-shit-done/templates/codebase/concerns.md +310 -0
  180. package/gsd/get-shit-done/templates/codebase/conventions.md +307 -0
  181. package/gsd/get-shit-done/templates/codebase/integrations.md +280 -0
  182. package/gsd/get-shit-done/templates/codebase/stack.md +186 -0
  183. package/gsd/get-shit-done/templates/codebase/structure.md +285 -0
  184. package/gsd/get-shit-done/templates/codebase/testing.md +480 -0
  185. package/gsd/get-shit-done/templates/config.json +37 -0
  186. package/gsd/get-shit-done/templates/context.md +297 -0
  187. package/gsd/get-shit-done/templates/continue-here.md +78 -0
  188. package/gsd/get-shit-done/templates/debug-subagent-prompt.md +91 -0
  189. package/gsd/get-shit-done/templates/discovery.md +146 -0
  190. package/gsd/get-shit-done/templates/milestone-archive.md +123 -0
  191. package/gsd/get-shit-done/templates/milestone.md +115 -0
  192. package/gsd/get-shit-done/templates/phase-prompt.md +569 -0
  193. package/gsd/get-shit-done/templates/planner-subagent-prompt.md +117 -0
  194. package/gsd/get-shit-done/templates/project.md +184 -0
  195. package/gsd/get-shit-done/templates/requirements.md +231 -0
  196. package/gsd/get-shit-done/templates/research-project/ARCHITECTURE.md +204 -0
  197. package/gsd/get-shit-done/templates/research-project/FEATURES.md +147 -0
  198. package/gsd/get-shit-done/templates/research-project/PITFALLS.md +200 -0
  199. package/gsd/get-shit-done/templates/research-project/STACK.md +120 -0
  200. package/gsd/get-shit-done/templates/research-project/SUMMARY.md +170 -0
  201. package/gsd/get-shit-done/templates/research.md +552 -0
  202. package/gsd/get-shit-done/templates/retrospective.md +54 -0
  203. package/gsd/get-shit-done/templates/roadmap.md +202 -0
  204. package/gsd/get-shit-done/templates/state.md +176 -0
  205. package/gsd/get-shit-done/templates/summary-complex.md +59 -0
  206. package/gsd/get-shit-done/templates/summary-minimal.md +41 -0
  207. package/gsd/get-shit-done/templates/summary-standard.md +48 -0
  208. package/gsd/get-shit-done/templates/summary.md +248 -0
  209. package/gsd/get-shit-done/templates/user-setup.md +311 -0
  210. package/gsd/get-shit-done/templates/verification-report.md +322 -0
  211. package/gsd/get-shit-done/workflows/add-phase.md +112 -0
  212. package/gsd/get-shit-done/workflows/add-tests.md +351 -0
  213. package/gsd/get-shit-done/workflows/add-todo.md +158 -0
  214. package/gsd/get-shit-done/workflows/audit-milestone.md +332 -0
  215. package/gsd/get-shit-done/workflows/check-todos.md +177 -0
  216. package/gsd/get-shit-done/workflows/cleanup.md +152 -0
  217. package/gsd/get-shit-done/workflows/complete-milestone.md +764 -0
  218. package/gsd/get-shit-done/workflows/diagnose-issues.md +219 -0
  219. package/gsd/get-shit-done/workflows/discovery-phase.md +289 -0
  220. package/gsd/get-shit-done/workflows/discuss-phase.md +676 -0
  221. package/gsd/get-shit-done/workflows/execute-phase.md +459 -0
  222. package/gsd/get-shit-done/workflows/execute-plan.md +449 -0
  223. package/gsd/get-shit-done/workflows/health.md +159 -0
  224. package/gsd/get-shit-done/workflows/help.md +489 -0
  225. package/gsd/get-shit-done/workflows/insert-phase.md +130 -0
  226. package/gsd/get-shit-done/workflows/list-phase-assumptions.md +178 -0
  227. package/gsd/get-shit-done/workflows/map-codebase.md +316 -0
  228. package/gsd/get-shit-done/workflows/new-milestone.md +384 -0
  229. package/gsd/get-shit-done/workflows/new-project.md +1111 -0
  230. package/gsd/get-shit-done/workflows/pause-work.md +122 -0
  231. package/gsd/get-shit-done/workflows/plan-milestone-gaps.md +274 -0
  232. package/gsd/get-shit-done/workflows/plan-phase.md +560 -0
  233. package/gsd/get-shit-done/workflows/progress.md +382 -0
  234. package/gsd/get-shit-done/workflows/quick.md +601 -0
  235. package/gsd/get-shit-done/workflows/remove-phase.md +155 -0
  236. package/gsd/get-shit-done/workflows/research-phase.md +74 -0
  237. package/gsd/get-shit-done/workflows/resume-project.md +307 -0
  238. package/gsd/get-shit-done/workflows/set-profile.md +81 -0
  239. package/gsd/get-shit-done/workflows/settings.md +214 -0
  240. package/gsd/get-shit-done/workflows/transition.md +544 -0
  241. package/gsd/get-shit-done/workflows/update.md +240 -0
  242. package/gsd/get-shit-done/workflows/validate-phase.md +167 -0
  243. package/gsd/get-shit-done/workflows/verify-phase.md +243 -0
  244. package/gsd/get-shit-done/workflows/verify-work.md +583 -0
  245. package/gsd/hooks/gsd-check-update.js +81 -0
  246. package/gsd/hooks/gsd-context-monitor.js +141 -0
  247. package/gsd/hooks/gsd-statusline.js +115 -0
  248. package/kit/CLAUDE.md +43 -0
  249. package/kit/commands/kit/update.md +46 -0
  250. package/kit/commands/setup-refresh.md +50 -0
  251. package/kit/commands/setup.md +579 -0
  252. package/kit/commands/tool-guide.md +44 -0
  253. package/kit/hooks/kit-check-update.js +54 -0
  254. package/kit/mcp.json +10 -0
  255. package/kit/rules/code-style.md +24 -0
  256. package/manifest.json +30 -0
  257. package/package.json +36 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Othmane Hanyf
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # Claude Code Pilot
2
+
3
+ Universal Claude Code configuration for **any project**. Bundles two complementary systems:
4
+
5
+ - **GSD** (Get Shit Done) v1.22.4 — *Methodology*. Spec-driven development with fresh 200k contexts per task. Prevents context rot.
6
+ - **ECC** (Everything Claude Code) v1.8.0 — *Toolbox*. Session persistence, continuous learning, verification, quality gates. Prevents knowledge loss.
7
+
8
+ One command to install. `/setup` wizard auto-configures everything.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ cd your-project
14
+ npx claude-code-pilot
15
+ claude
16
+ > /setup
17
+ ```
18
+
19
+ ## The Workflow
20
+
21
+ ```
22
+ npx claude-code-pilot ← install (once)
23
+ claude → /setup ← wizard scans codebase, generates CLAUDE.md
24
+
25
+ # Development
26
+ /gsd:discuss-phase 1 ← GSD: capture requirements
27
+ /gsd:plan-phase 1 ← GSD: atomic plans
28
+ /checkpoint create "before-impl" ← ECC: snapshot
29
+ /gsd:execute-phase 1 ← GSD: build with fresh contexts
30
+ /verify ← ECC: build → types → lint → tests → security
31
+ /gsd:verify-work 1 ← GSD: does it match the spec?
32
+ /save-session ← ECC: persist for next session
33
+ /learn ← ECC: extract reusable patterns
34
+
35
+ # Next session
36
+ /resume-session ← ECC: load previous context
37
+ /evolve ← ECC: promote instincts → skills
38
+ /kit:update ← update everything
39
+ ```
40
+
41
+ ## What's Included (254 files after install)
42
+
43
+ ### GSD — Methodology (32 commands, 12 agents)
44
+ | Command | What |
45
+ |---------|------|
46
+ | `/gsd:new-project` | Initialize with roadmap and milestones |
47
+ | `/gsd:discuss-phase N` | Capture requirements |
48
+ | `/gsd:plan-phase N` | Atomic plans (max 3 tasks per subagent) |
49
+ | `/gsd:execute-phase N` | Build in fresh 200k contexts |
50
+ | `/gsd:verify-work N` | Goal-backward verification |
51
+ | `/gsd:quick "task"` | Same quality, lighter process |
52
+ | `/gsd:progress` | Milestone progress |
53
+ | `/gsd:help` | All 32 commands |
54
+
55
+ 12 specialized subagents: executor, planner, verifier, debugger, codebase-mapper, roadmapper, etc.
56
+
57
+ ### ECC — Toolbox (9 commands, 6 agents, 3 skills)
58
+ | Command | What |
59
+ |---------|------|
60
+ | `/verify` | 6-phase quality check (build, types, lint, tests, security, diff) |
61
+ | `/checkpoint` | Git-backed snapshots with before/after comparison |
62
+ | `/save-session` | Persist what worked, what didn't, exact next step |
63
+ | `/resume-session` | Load previous session context |
64
+ | `/learn` | Extract reusable patterns from session |
65
+ | `/evolve` | Promote learned instincts into skills/commands/agents |
66
+ | `/quality-gate` | On-demand quality pipeline |
67
+ | `/model-route` | Recommend model tier (Haiku/Sonnet/Opus) |
68
+ | `/sessions` | List, load, alias saved sessions |
69
+
70
+ 6 agents: architect, code-reviewer, security-reviewer, tdd-guide, e2e-runner, doc-updater.
71
+
72
+ 3 skills: continuous-learning-v2 (instinct system), strategic-compact, verification-loop.
73
+
74
+ ### Kit — Infrastructure
75
+ | Feature | What |
76
+ |---------|------|
77
+ | `/setup` wizard | Scans codebase, generates CLAUDE.md, installs language rules |
78
+ | `/setup:refresh` | Updates config after project changes |
79
+ | `/kit:update` | Updates kit + GSD + ECC |
80
+ | Safety hooks | Blocks rm -rf, DROP TABLE, push --force; protects .env/lock files |
81
+ | Notifications | Desktop alerts (task complete, idle, permission needed) |
82
+ | Context modes | dev.md, research.md, review.md |
83
+ | Language rules | 9 common + 7 language-specific sets (activated by /setup) |
84
+
85
+ ## How GSD and ECC Work Together
86
+
87
+ | | GSD | ECC |
88
+ |---|---|---|
89
+ | **Purpose** | Structure *how* to work | Ensure *quality* of work |
90
+ | **Core** | Phases, milestones, subagents | Verification, learning, persistence |
91
+ | **Verification** | "Does it match the spec?" | "Is it production-ready?" |
92
+ | **Context** | Fresh 200k per task | Strategic compact, pre-compact save |
93
+ | **Knowledge** | Plans in files | Instincts that evolve into skills |
94
+ | **Persistence** | Atomic commits | Session files with full context |
95
+
96
+ ## Hooks (13 total)
97
+
98
+ | Hook | Event | Source |
99
+ |------|-------|--------|
100
+ | Command blocker | PreToolUse:Bash | Kit |
101
+ | File protection | PreToolUse:Write\|Edit | Kit |
102
+ | Context monitor | PostToolUse | GSD |
103
+ | GSD update check | SessionStart | GSD |
104
+ | Kit update check | SessionStart | Kit |
105
+ | Session loader | SessionStart | ECC |
106
+ | Session saver | Stop | ECC |
107
+ | Pre-compact save | PreCompact | ECC |
108
+ | Strategic compact | PreToolUse:Edit\|Write | ECC |
109
+ | Task completed | Stop | Kit |
110
+ | Idle prompt | Notification | Kit |
111
+ | Permission needed | Notification | Kit |
112
+ | Statusline | Always | GSD |
113
+
114
+ ## Language Rules
115
+
116
+ The installer copies 9 common rules (always active) and 7 language-specific rule sets into `available-rules/`. The `/setup` wizard detects your language and activates the matching set.
117
+
118
+ Available: TypeScript, Python, Go, Swift, Kotlin, PHP, Perl.
119
+
120
+ ## Self-Updating
121
+
122
+ On every session start, the kit checks npm for new versions. When available, the agent sees: *"⬆️ Pilot update available. Run /kit:update."*
123
+
124
+ ```bash
125
+ # From Claude Code:
126
+ /kit:update
127
+
128
+ # From terminal:
129
+ npx claude-code-pilot@latest --update
130
+ ```
131
+
132
+ Updates preserve your CLAUDE.md, architecture docs, and settings customizations.
133
+
134
+ ## CLI
135
+
136
+ ```
137
+ npx claude-code-pilot [options]
138
+
139
+ -l, --local Install to .claude/ (default)
140
+ -g, --global Install to ~/.claude/
141
+ -u, --update Update existing installation
142
+ --uninstall Remove kit files (preserves CLAUDE.md)
143
+ -h, --help Show help
144
+ ```
145
+
146
+ ## Credits
147
+
148
+ - **GSD** by [TÂCHES](https://github.com/glittercowboy/get-shit-done) (MIT)
149
+ - **ECC** by [Affaan Mustafa](https://github.com/affaan-m/everything-claude-code) (MIT)
150
+ - **find-skills** by [Vercel Labs](https://github.com/vercel-labs/skills)
151
+ - **Context7** by [Upstash](https://github.com/upstash/context7)
package/bin/install.js ADDED
@@ -0,0 +1,431 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+ const { execSync } = require('child_process');
7
+
8
+ const cyan = '\x1b[36m', green = '\x1b[32m', yellow = '\x1b[33m', dim = '\x1b[2m', reset = '\x1b[0m';
9
+
10
+ const pkg = require('../package.json');
11
+ const manifest = require('../manifest.json');
12
+
13
+ const args = process.argv.slice(2);
14
+ const hasGlobal = args.includes('--global') || args.includes('-g');
15
+ const hasLocal = args.includes('--local') || args.includes('-l');
16
+ const hasUpdate = args.includes('--update') || args.includes('-u');
17
+ const hasUninstall = args.includes('--uninstall');
18
+ const hasHelp = args.includes('--help') || args.includes('-h');
19
+
20
+ const banner = '\n' +
21
+ cyan + ' ╔═╗┬┬ ┌─┐┌┬┐\n' +
22
+ ' ╠═╝││ │ │ │ \n' +
23
+ ' ╩ ┴┴─┘└─┘ ┴ ' + reset + '\n\n' +
24
+ ' Claude Code Pilot ' + dim + 'v' + pkg.version + reset + '\n' +
25
+ ' GSD ' + dim + 'v' + manifest.bundled.gsd.version + reset +
26
+ ' + ECC ' + dim + 'v' + manifest.bundled.ecc.version + reset + '\n';
27
+
28
+ console.log(banner);
29
+
30
+ if (hasHelp) {
31
+ console.log(` ${yellow}Usage:${reset} npx claude-code-pilot [options]\n
32
+ ${yellow}Options:${reset}
33
+ ${cyan}-l, --local${reset} Install to current project (default)
34
+ ${cyan}-g, --global${reset} Install to ~/.claude/
35
+ ${cyan}-u, --update${reset} Update existing installation
36
+ ${cyan}--uninstall${reset} Remove kit files
37
+ ${cyan}-h, --help${reset} Show help\n`);
38
+ process.exit(0);
39
+ }
40
+
41
+ // --- Paths ---
42
+ const src = path.join(__dirname, '..');
43
+ const isGlobal = hasGlobal;
44
+ const targetDir = isGlobal
45
+ ? (process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude'))
46
+ : path.join(process.cwd(), '.claude');
47
+ const locationLabel = isGlobal ? targetDir.replace(os.homedir(), '~') : '.claude/';
48
+ const pathPrefix = isGlobal ? `${targetDir.replace(/\\/g, '/')}/` : './.claude/';
49
+ const projectRoot = isGlobal ? os.homedir() : process.cwd();
50
+
51
+ // --- Utilities ---
52
+ function readSettings(p) {
53
+ if (fs.existsSync(p)) { try { return JSON.parse(fs.readFileSync(p, 'utf8')); } catch { return {}; } }
54
+ return {};
55
+ }
56
+ function writeSettings(p, s) { fs.writeFileSync(p, JSON.stringify(s, null, 2) + '\n'); }
57
+
58
+ function copyDir(srcDir, destDir, opts = {}) {
59
+ if (!fs.existsSync(srcDir)) return 0;
60
+ const { replacePaths = false, clean = false } = opts;
61
+ if (clean && fs.existsSync(destDir)) fs.rmSync(destDir, { recursive: true });
62
+ fs.mkdirSync(destDir, { recursive: true });
63
+ let count = 0;
64
+ for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
65
+ const s = path.join(srcDir, entry.name);
66
+ const d = path.join(destDir, entry.name);
67
+ if (entry.isDirectory()) {
68
+ count += copyDir(s, d, opts);
69
+ } else {
70
+ if (replacePaths && (entry.name.endsWith('.md') || entry.name.endsWith('.sh'))) {
71
+ let text = fs.readFileSync(s, 'utf8');
72
+ text = text.replace(/~\/\.claude\//g, pathPrefix);
73
+ text = text.replace(/\$HOME\/\.claude\//g, pathPrefix);
74
+ fs.writeFileSync(d, text);
75
+ } else {
76
+ fs.copyFileSync(s, d);
77
+ }
78
+ count++;
79
+ }
80
+ }
81
+ return count;
82
+ }
83
+
84
+ function copyFile(s, d, replace = false) {
85
+ fs.mkdirSync(path.dirname(d), { recursive: true });
86
+ if (replace) {
87
+ let text = fs.readFileSync(s, 'utf8');
88
+ text = text.replace(/~\/\.claude\//g, pathPrefix);
89
+ text = text.replace(/\$HOME\/\.claude\//g, pathPrefix);
90
+ // Replace CLAUDE_PLUGIN_ROOT with actual path
91
+ text = text.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, pathPrefix.replace(/\/$/, ''));
92
+ fs.writeFileSync(d, text);
93
+ } else {
94
+ fs.copyFileSync(s, d);
95
+ }
96
+ }
97
+
98
+ function addHookIfMissing(settings, event, matcher, fingerprint, hookCmd, description) {
99
+ if (!settings.hooks) settings.hooks = {};
100
+ if (!settings.hooks[event]) settings.hooks[event] = [];
101
+ const exists = settings.hooks[event].some(e =>
102
+ e.hooks?.some(h => h.command?.includes(fingerprint))
103
+ );
104
+ if (!exists) {
105
+ const entry = { hooks: [{ type: 'command', command: hookCmd }] };
106
+ if (matcher !== null) entry.matcher = matcher;
107
+ if (description) entry.description = description;
108
+ settings.hooks[event].push(entry);
109
+ return true;
110
+ }
111
+ return false;
112
+ }
113
+
114
+ // --- Install ---
115
+ function install() {
116
+ const mode = hasUpdate ? 'Updating' : 'Installing';
117
+ console.log(` ${mode} to ${cyan}${locationLabel}${reset}\n`);
118
+ fs.mkdirSync(targetDir, { recursive: true });
119
+
120
+ // ═══════════════════════════════════════
121
+ // Kit Core
122
+ // ═══════════════════════════════════════
123
+ console.log(` ${dim}Kit core...${reset}`);
124
+ const kitSrc = path.join(src, 'kit');
125
+ copyDir(path.join(kitSrc, 'commands'), path.join(targetDir, 'commands'), { replacePaths: true });
126
+ copyDir(path.join(kitSrc, 'hooks'), path.join(targetDir, 'hooks'));
127
+ console.log(` ${green}✓${reset} Kit commands + hooks`);
128
+
129
+ // ═══════════════════════════════════════
130
+ // GSD
131
+ // ═══════════════════════════════════════
132
+ console.log(`\n ${dim}GSD v${manifest.bundled.gsd.version}...${reset}`);
133
+ const gsdSrc = path.join(src, 'gsd');
134
+
135
+ const cmdCount = copyDir(path.join(gsdSrc, 'commands-gsd'), path.join(targetDir, 'commands', 'gsd'), { replacePaths: true, clean: true });
136
+ console.log(` ${green}✓${reset} GSD commands (${cmdCount})`);
137
+
138
+ copyDir(path.join(gsdSrc, 'get-shit-done'), path.join(targetDir, 'get-shit-done'), { replacePaths: true, clean: true });
139
+ console.log(` ${green}✓${reset} GSD core (workflows, references, templates)`);
140
+
141
+ copyDir(path.join(gsdSrc, 'agents'), path.join(targetDir, 'agents'), { replacePaths: true });
142
+ console.log(` ${green}✓${reset} GSD agents (12)`);
143
+
144
+ // GSD hooks
145
+ const gsdHooksSrc = path.join(gsdSrc, 'hooks');
146
+ if (fs.existsSync(gsdHooksSrc)) {
147
+ const hooksDest = path.join(targetDir, 'hooks');
148
+ fs.mkdirSync(hooksDest, { recursive: true });
149
+ for (const f of fs.readdirSync(gsdHooksSrc).filter(f => f.endsWith('.js'))) {
150
+ fs.copyFileSync(path.join(gsdHooksSrc, f), path.join(hooksDest, f));
151
+ }
152
+ console.log(` ${green}✓${reset} GSD hooks (statusline, context monitor, update check)`);
153
+ }
154
+
155
+ // ═══════════════════════════════════════
156
+ // ECC
157
+ // ═══════════════════════════════════════
158
+ console.log(`\n ${dim}ECC v${manifest.bundled.ecc.version}...${reset}`);
159
+ const eccSrc = path.join(src, 'ecc');
160
+
161
+ // ECC commands (flat — alongside kit commands)
162
+ const eccCmdSrc = path.join(eccSrc, 'commands');
163
+ if (fs.existsSync(eccCmdSrc)) {
164
+ for (const f of fs.readdirSync(eccCmdSrc).filter(f => f.endsWith('.md'))) {
165
+ copyFile(path.join(eccCmdSrc, f), path.join(targetDir, 'commands', f), true);
166
+ }
167
+ const eccCmdCount = fs.readdirSync(eccCmdSrc).filter(f => f.endsWith('.md')).length;
168
+ console.log(` ${green}✓${reset} ECC commands (${eccCmdCount}: sessions, verify, learn, checkpoint, ...)`);
169
+ }
170
+
171
+ // ECC skills
172
+ const eccSkillsSrc = path.join(eccSrc, 'skills');
173
+ if (fs.existsSync(eccSkillsSrc)) {
174
+ copyDir(eccSkillsSrc, path.join(targetDir, 'skills'), { replacePaths: true });
175
+ console.log(` ${green}✓${reset} ECC skills (continuous-learning, strategic-compact, verification-loop)`);
176
+ }
177
+
178
+ // ECC contexts
179
+ const eccCtxSrc = path.join(eccSrc, 'contexts');
180
+ if (fs.existsSync(eccCtxSrc)) {
181
+ copyDir(eccCtxSrc, path.join(targetDir, 'contexts'));
182
+ console.log(` ${green}✓${reset} ECC context modes (dev, research, review)`);
183
+ }
184
+
185
+ // ECC agents (alongside GSD agents)
186
+ const eccAgentsSrc = path.join(eccSrc, 'agents');
187
+ if (fs.existsSync(eccAgentsSrc)) {
188
+ for (const f of fs.readdirSync(eccAgentsSrc).filter(f => f.endsWith('.md'))) {
189
+ copyFile(path.join(eccAgentsSrc, f), path.join(targetDir, 'agents', f), true);
190
+ }
191
+ const eccAgentCount = fs.readdirSync(eccAgentsSrc).filter(f => f.endsWith('.md')).length;
192
+ console.log(` ${green}✓${reset} ECC agents (${eccAgentCount}: architect, code-reviewer, security, tdd, ...)`);
193
+ }
194
+
195
+ // ECC scripts (hooks + lib — preserve relative paths)
196
+ const eccScriptsSrc = path.join(eccSrc, 'scripts');
197
+ if (fs.existsSync(eccScriptsSrc)) {
198
+ copyDir(eccScriptsSrc, path.join(targetDir, 'ecc-scripts'));
199
+ console.log(` ${green}✓${reset} ECC scripts (session lifecycle, project detection, utils)`);
200
+ }
201
+
202
+ // Patch ECC getClaudeDir() for local installs (CWD-relative)
203
+ if (!isGlobal) {
204
+ const utilsPath = path.join(targetDir, 'ecc-scripts', 'lib', 'utils.js');
205
+ if (fs.existsSync(utilsPath)) {
206
+ let utilsContent = fs.readFileSync(utilsPath, 'utf8');
207
+ utilsContent = utilsContent.replace(
208
+ /function getClaudeDir\(\)\s*\{[^}]*\}/,
209
+ "function getClaudeDir() {\n return path.join(process.cwd(), '.claude');\n}"
210
+ );
211
+ fs.writeFileSync(utilsPath, utilsContent);
212
+ console.log(` ${green}✓${reset} ECC: patched getClaudeDir() for local install`);
213
+ }
214
+ }
215
+
216
+ // ECC rules (common always, language-specific all copied — /setup activates relevant ones)
217
+ const eccRulesSrc = path.join(eccSrc, 'rules');
218
+ if (fs.existsSync(eccRulesSrc)) {
219
+ copyDir(path.join(eccRulesSrc, 'common'), path.join(targetDir, 'rules', 'common'), { replacePaths: true });
220
+ // Copy language rules into available-rules/ (activated by /setup based on detection)
221
+ for (const lang of fs.readdirSync(eccRulesSrc).filter(d => d !== 'common')) {
222
+ const langSrc = path.join(eccRulesSrc, lang);
223
+ if (fs.statSync(langSrc).isDirectory()) {
224
+ copyDir(langSrc, path.join(targetDir, 'available-rules', lang), { replacePaths: true });
225
+ }
226
+ }
227
+ console.log(` ${green}✓${reset} ECC rules (common + 7 language sets in available-rules/)`);
228
+ }
229
+
230
+ // ECC examples
231
+ const eccExSrc = path.join(eccSrc, 'examples');
232
+ if (fs.existsSync(eccExSrc)) {
233
+ copyDir(eccExSrc, path.join(targetDir, 'ecc-examples'), { replacePaths: true });
234
+ console.log(` ${green}✓${reset} ECC example CLAUDE.md files (reference)`);
235
+ }
236
+
237
+ // ═══════════════════════════════════════
238
+ // CommonJS + package.json
239
+ // ═══════════════════════════════════════
240
+ fs.writeFileSync(path.join(targetDir, 'package.json'), '{"type":"commonjs"}\n');
241
+
242
+ // ═══════════════════════════════════════
243
+ // Root files (only fresh install or bootstrap)
244
+ // ═══════════════════════════════════════
245
+ console.log(`\n ${dim}Root files...${reset}`);
246
+ const claudeMdSrc = path.join(kitSrc, 'CLAUDE.md');
247
+ const claudeMdDest = path.join(projectRoot, 'CLAUDE.md');
248
+ if (fs.existsSync(claudeMdSrc)) {
249
+ if (!fs.existsSync(claudeMdDest) ||
250
+ fs.readFileSync(claudeMdDest, 'utf8').includes('Run `/setup` to auto-configure')) {
251
+ fs.copyFileSync(claudeMdSrc, claudeMdDest);
252
+ console.log(` ${green}✓${reset} CLAUDE.md (bootstrap)`);
253
+ } else {
254
+ console.log(` ${dim}⏭️ CLAUDE.md (customized — preserved)${reset}`);
255
+ }
256
+ }
257
+
258
+ const mcpSrc = path.join(kitSrc, 'mcp.json');
259
+ const mcpDest = path.join(projectRoot, '.mcp.json');
260
+ if (fs.existsSync(mcpSrc) && !fs.existsSync(mcpDest)) {
261
+ fs.copyFileSync(mcpSrc, mcpDest);
262
+ console.log(` ${green}✓${reset} .mcp.json (Context7)`);
263
+ }
264
+
265
+ const archSrc = path.join(src, 'docs', 'agent-guides', 'architecture.md');
266
+ const archDest = path.join(projectRoot, 'docs', 'agent-guides', 'architecture.md');
267
+ if (fs.existsSync(archSrc) && !fs.existsSync(archDest)) {
268
+ fs.mkdirSync(path.dirname(archDest), { recursive: true });
269
+ fs.copyFileSync(archSrc, archDest);
270
+ console.log(` ${green}✓${reset} docs/agent-guides/architecture.md`);
271
+ }
272
+
273
+ // ═══════════════════════════════════════
274
+ // Settings (merge — never overwrite)
275
+ // ═══════════════════════════════════════
276
+ console.log(`\n ${dim}Configuring settings...${reset}`);
277
+ const settingsPath = path.join(targetDir, 'settings.json');
278
+ const settings = readSettings(settingsPath);
279
+
280
+ // --- Safety hooks ---
281
+ let added;
282
+ added = addHookIfMissing(settings, 'PreToolUse', 'Bash', 'Blocked: forbidden',
283
+ `bash -c 'CMD=$(jq -r ".tool_input.command" <<< "$(cat)"); for p in "rm -rf /" "rm -rf ~" "DROP TABLE" "TRUNCATE" "push.*--force"; do if echo "$CMD" | grep -qiE "$p"; then echo "Blocked: forbidden pattern \\"$p\\" detected" >&2; exit 2; fi; done; exit 0'`);
284
+ if (added) console.log(` ${green}✓${reset} Safety: dangerous command blocker`);
285
+
286
+ added = addHookIfMissing(settings, 'PreToolUse', 'Write|Edit', 'Protected file',
287
+ `bash -c 'FILE=$(jq -r ".tool_input.file_path // empty" <<< "$(cat)"); for p in ".env" "package-lock.json" "pnpm-lock.yaml" "yarn.lock" "bun.lock" ".git/"; do if [[ "$FILE" == *"$p"* ]]; then echo "Protected file: $p" >&2; exit 2; fi; done; exit 0'`);
288
+ if (added) console.log(` ${green}✓${reset} Safety: file protection`);
289
+
290
+ // --- GSD hooks ---
291
+ added = addHookIfMissing(settings, 'PostToolUse', null, 'gsd-context-monitor',
292
+ `node ${pathPrefix}hooks/gsd-context-monitor.js`, 'GSD context window monitor');
293
+ if (added) console.log(` ${green}✓${reset} GSD: context monitor`);
294
+
295
+ added = addHookIfMissing(settings, 'SessionStart', null, 'gsd-check-update',
296
+ `node ${pathPrefix}hooks/gsd-check-update.js`, 'GSD version check');
297
+ if (added) console.log(` ${green}✓${reset} GSD: update check`);
298
+
299
+ // --- Kit hooks ---
300
+ added = addHookIfMissing(settings, 'SessionStart', null, 'kit-check-update',
301
+ `node ${pathPrefix}hooks/kit-check-update.js`, 'Pilot version check');
302
+ if (added) console.log(` ${green}✓${reset} Kit: update check`);
303
+
304
+ // --- ECC hooks ---
305
+ added = addHookIfMissing(settings, 'SessionStart', null, 'ecc-scripts/hooks/session-start',
306
+ `node ${pathPrefix}ecc-scripts/hooks/session-start.js`, 'ECC session context loader');
307
+ if (added) console.log(` ${green}✓${reset} ECC: session start (loads previous context)`);
308
+
309
+ added = addHookIfMissing(settings, 'Stop', null, 'ecc-scripts/hooks/session-end',
310
+ `node ${pathPrefix}ecc-scripts/hooks/session-end.js`, 'ECC session persistence');
311
+ if (added) console.log(` ${green}✓${reset} ECC: session end (saves session state)`);
312
+
313
+ added = addHookIfMissing(settings, 'PreCompact', null, 'ecc-scripts/hooks/pre-compact',
314
+ `node ${pathPrefix}ecc-scripts/hooks/pre-compact.js`, 'ECC pre-compact state save');
315
+ if (added) console.log(` ${green}✓${reset} ECC: pre-compact (saves state before compaction)`);
316
+
317
+ added = addHookIfMissing(settings, 'PreToolUse', 'Edit|Write', 'suggest-compact',
318
+ `node ${pathPrefix}ecc-scripts/hooks/suggest-compact.js`, 'ECC strategic compact suggestions');
319
+ if (added) console.log(` ${green}✓${reset} ECC: strategic compact suggestions`);
320
+
321
+ // --- Notifications ---
322
+ added = addHookIfMissing(settings, 'Stop', '', 'Task completed',
323
+ `bash -c 'if command -v terminal-notifier &>/dev/null; then terminal-notifier -title "Claude Code" -message "Task completed" -sound default; elif command -v osascript &>/dev/null; then osascript -e "display notification \\"Task completed\\" with title \\"Claude Code\\" sound name \\"Glass\\""; elif command -v notify-send &>/dev/null; then notify-send -u normal "Claude Code" "Task completed"; fi'`);
324
+ if (added) console.log(` ${green}✓${reset} Notification: task completed`);
325
+
326
+ added = addHookIfMissing(settings, 'Notification', 'idle_prompt', 'Ready for input',
327
+ `bash -c 'if command -v terminal-notifier &>/dev/null; then terminal-notifier -title "Claude Code" -message "Ready for input" -sound default; elif command -v osascript &>/dev/null; then osascript -e "display notification \\"Ready for input\\" with title \\"Claude Code\\" sound name \\"Glass\\""; elif command -v notify-send &>/dev/null; then notify-send -u normal "Claude Code" "Ready for input"; fi'`);
328
+ if (added) console.log(` ${green}✓${reset} Notification: idle prompt`);
329
+
330
+ added = addHookIfMissing(settings, 'Notification', 'permission_prompt', 'Permission needed',
331
+ `bash -c 'if command -v terminal-notifier &>/dev/null; then terminal-notifier -title "Claude Code" -message "Permission needed" -sound Submarine; elif command -v osascript &>/dev/null; then osascript -e "display notification \\"Permission needed\\" with title \\"Claude Code\\" sound name \\"Submarine\\""; elif command -v notify-send &>/dev/null; then notify-send -u critical "Claude Code" "Permission needed"; fi'`);
332
+ if (added) console.log(` ${green}✓${reset} Notification: permission prompt`);
333
+
334
+ // --- Statusline ---
335
+ if (!settings.statusLine) {
336
+ settings.statusLine = { type: 'command', command: `node ${pathPrefix}hooks/gsd-statusline.js` };
337
+ console.log(` ${green}✓${reset} GSD statusline`);
338
+ }
339
+
340
+ // --- Permissions ---
341
+ if (!settings.permissions) settings.permissions = {};
342
+ if (!settings.permissions.deny) settings.permissions.deny = [];
343
+ for (const p of ['Bash(rm -rf *)', 'Bash(git push --force*)', 'Bash(*DROP TABLE*)']) {
344
+ if (!settings.permissions.deny.includes(p)) settings.permissions.deny.push(p);
345
+ }
346
+
347
+ writeSettings(settingsPath, settings);
348
+ console.log(` ${green}✓${reset} Settings written`);
349
+
350
+ // ═══════════════════════════════════════
351
+ // Version files
352
+ // ═══════════════════════════════════════
353
+ const gsdVersionDir = path.join(targetDir, 'get-shit-done');
354
+ fs.mkdirSync(gsdVersionDir, { recursive: true });
355
+ fs.writeFileSync(path.join(gsdVersionDir, 'VERSION'), manifest.bundled.gsd.version);
356
+
357
+ const kitVersionDir = path.join(targetDir, 'kit-version');
358
+ fs.mkdirSync(kitVersionDir, { recursive: true });
359
+ fs.writeFileSync(path.join(kitVersionDir, 'VERSION'), pkg.version);
360
+ fs.writeFileSync(path.join(kitVersionDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
361
+ console.log(` ${green}✓${reset} Version files (kit v${pkg.version}, GSD v${manifest.bundled.gsd.version}, ECC v${manifest.bundled.ecc.version})`);
362
+
363
+ // ═══════════════════════════════════════
364
+ // External: find-skills
365
+ // ═══════════════════════════════════════
366
+ console.log(`\n ${dim}External dependencies...${reset}`);
367
+ try {
368
+ execSync('npx skills add https://github.com/vercel-labs/skills --skill find-skills -g -a claude-code -y', { stdio: 'pipe', timeout: 30000 });
369
+ console.log(` ${green}✓${reset} find-skills`);
370
+ } catch {
371
+ console.log(` ${yellow}⚠${reset} find-skills failed — run: npx skills add https://github.com/vercel-labs/skills --skill find-skills -g -a claude-code -y`);
372
+ }
373
+
374
+ // Notifications check
375
+ console.log('');
376
+ try { execSync('which terminal-notifier', { stdio: 'pipe' }); console.log(` ${green}✓${reset} Notifications: terminal-notifier`); }
377
+ catch { try { execSync('which osascript', { stdio: 'pipe' }); console.log(` ${green}✓${reset} Notifications: osascript`); }
378
+ catch { try { execSync('which notify-send', { stdio: 'pipe' }); console.log(` ${green}✓${reset} Notifications: notify-send`); }
379
+ catch { console.log(` ${yellow}⚠${reset} No notification tool found`); } } }
380
+
381
+ // ═══════════════════════════════════════
382
+ // Summary
383
+ // ═══════════════════════════════════════
384
+ const totalAgents = fs.existsSync(path.join(targetDir, 'agents'))
385
+ ? fs.readdirSync(path.join(targetDir, 'agents')).filter(f => f.endsWith('.md')).length : 0;
386
+
387
+ const action = hasUpdate ? 'Updated' : 'Installed';
388
+ console.log(`
389
+ ${green}${action}!${reset} Kit v${pkg.version}
390
+
391
+ ${cyan}GSD${reset} v${manifest.bundled.gsd.version} — 32 commands, 12 agents, spec-driven development
392
+ ${cyan}ECC${reset} v${manifest.bundled.ecc.version} — Sessions, learning, verification, quality gates
393
+ ${cyan}Kit${reset} — Safety hooks, notifications, auto-updates, /setup wizard
394
+
395
+ ${totalAgents} agents total. Context monitoring. Session persistence.
396
+ Language rules ready in available-rules/ (activated by /setup).
397
+
398
+ Next:
399
+ ${cyan}claude${reset}
400
+ ${cyan}/setup${reset} ← auto-configure this project
401
+ ${cyan}/kit:update${reset} ← update to latest version
402
+
403
+ GSD: ECC:
404
+ ${cyan}/gsd:new-project${reset} ${cyan}/save-session${reset}
405
+ ${cyan}/gsd:quick "task"${reset} ${cyan}/verify${reset}
406
+ ${cyan}/gsd:discuss-phase 1${reset} ${cyan}/checkpoint create "v1"${reset}
407
+ ${cyan}/gsd:help${reset} ${cyan}/learn${reset}
408
+ `);
409
+ }
410
+
411
+ // --- Uninstall ---
412
+ function uninstall() {
413
+ console.log(` Uninstalling from ${cyan}${locationLabel}${reset}\n`);
414
+ const dirs = ['commands', 'get-shit-done', 'agents', 'hooks', 'rules', 'skills',
415
+ 'contexts', 'ecc-scripts', 'ecc-examples', 'available-rules', 'kit-version'];
416
+ let removed = 0;
417
+ for (const d of dirs) {
418
+ const p = path.join(targetDir, d);
419
+ if (fs.existsSync(p)) {
420
+ fs.rmSync(p, { recursive: true });
421
+ removed++;
422
+ console.log(` ${green}✓${reset} Removed ${d}/`);
423
+ }
424
+ }
425
+ console.log(removed ? `\n ${green}Done!${reset} CLAUDE.md and settings.json preserved.\n` : ` ${yellow}⚠${reset} Nothing to remove\n`);
426
+ }
427
+
428
+ // --- Main ---
429
+ if (hasUninstall) { uninstall(); }
430
+ else if (!hasGlobal && !hasLocal) { console.log(` ${dim}Defaulting to local install (.claude/)${reset}\n`); install(); }
431
+ else { install(); }