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.
- package/LICENSE +21 -0
- package/README.md +151 -0
- package/bin/install.js +431 -0
- package/docs/agent-guides/architecture.md +107 -0
- package/ecc/agents/architect.md +211 -0
- package/ecc/agents/code-reviewer.md +237 -0
- package/ecc/agents/doc-updater.md +107 -0
- package/ecc/agents/e2e-runner.md +107 -0
- package/ecc/agents/security-reviewer.md +108 -0
- package/ecc/agents/tdd-guide.md +91 -0
- package/ecc/commands/checkpoint.md +74 -0
- package/ecc/commands/evolve.md +178 -0
- package/ecc/commands/learn.md +70 -0
- package/ecc/commands/model-route.md +26 -0
- package/ecc/commands/quality-gate.md +29 -0
- package/ecc/commands/resume-session.md +155 -0
- package/ecc/commands/save-session.md +275 -0
- package/ecc/commands/sessions.md +305 -0
- package/ecc/commands/verify.md +59 -0
- package/ecc/contexts/dev.md +20 -0
- package/ecc/contexts/research.md +26 -0
- package/ecc/contexts/review.md +22 -0
- package/ecc/examples/CLAUDE.md +100 -0
- package/ecc/examples/django-api-CLAUDE.md +308 -0
- package/ecc/examples/go-microservice-CLAUDE.md +267 -0
- package/ecc/examples/rust-api-CLAUDE.md +285 -0
- package/ecc/examples/saas-nextjs-CLAUDE.md +166 -0
- package/ecc/examples/user-CLAUDE.md +109 -0
- package/ecc/rules/common/agents.md +49 -0
- package/ecc/rules/common/coding-style.md +48 -0
- package/ecc/rules/common/development-workflow.md +37 -0
- package/ecc/rules/common/git-workflow.md +24 -0
- package/ecc/rules/common/hooks.md +30 -0
- package/ecc/rules/common/patterns.md +31 -0
- package/ecc/rules/common/performance.md +55 -0
- package/ecc/rules/common/security.md +29 -0
- package/ecc/rules/common/testing.md +29 -0
- package/ecc/rules/golang/coding-style.md +32 -0
- package/ecc/rules/golang/hooks.md +17 -0
- package/ecc/rules/golang/patterns.md +45 -0
- package/ecc/rules/golang/security.md +34 -0
- package/ecc/rules/golang/testing.md +31 -0
- package/ecc/rules/kotlin/coding-style.md +86 -0
- package/ecc/rules/kotlin/patterns.md +146 -0
- package/ecc/rules/kotlin/security.md +82 -0
- package/ecc/rules/kotlin/testing.md +128 -0
- package/ecc/rules/perl/coding-style.md +46 -0
- package/ecc/rules/perl/hooks.md +22 -0
- package/ecc/rules/perl/patterns.md +76 -0
- package/ecc/rules/perl/security.md +69 -0
- package/ecc/rules/perl/testing.md +54 -0
- package/ecc/rules/php/coding-style.md +35 -0
- package/ecc/rules/php/hooks.md +24 -0
- package/ecc/rules/php/patterns.md +32 -0
- package/ecc/rules/php/security.md +33 -0
- package/ecc/rules/php/testing.md +34 -0
- package/ecc/rules/python/coding-style.md +42 -0
- package/ecc/rules/python/hooks.md +19 -0
- package/ecc/rules/python/patterns.md +39 -0
- package/ecc/rules/python/security.md +30 -0
- package/ecc/rules/python/testing.md +38 -0
- package/ecc/rules/swift/coding-style.md +47 -0
- package/ecc/rules/swift/hooks.md +20 -0
- package/ecc/rules/swift/patterns.md +66 -0
- package/ecc/rules/swift/security.md +33 -0
- package/ecc/rules/swift/testing.md +45 -0
- package/ecc/rules/typescript/coding-style.md +199 -0
- package/ecc/rules/typescript/hooks.md +22 -0
- package/ecc/rules/typescript/patterns.md +52 -0
- package/ecc/rules/typescript/security.md +28 -0
- package/ecc/rules/typescript/testing.md +18 -0
- package/ecc/scripts/hooks/check-hook-enabled.js +12 -0
- package/ecc/scripts/hooks/evaluate-session.js +100 -0
- package/ecc/scripts/hooks/pre-compact.js +48 -0
- package/ecc/scripts/hooks/run-with-flags-shell.sh +32 -0
- package/ecc/scripts/hooks/run-with-flags.js +120 -0
- package/ecc/scripts/hooks/session-end-marker.js +15 -0
- package/ecc/scripts/hooks/session-end.js +258 -0
- package/ecc/scripts/hooks/session-start.js +97 -0
- package/ecc/scripts/hooks/suggest-compact.js +80 -0
- package/ecc/scripts/lib/hook-flags.js +74 -0
- package/ecc/scripts/lib/package-manager.d.ts +119 -0
- package/ecc/scripts/lib/package-manager.js +431 -0
- package/ecc/scripts/lib/project-detect.js +428 -0
- package/ecc/scripts/lib/resolve-formatter.js +185 -0
- package/ecc/scripts/lib/session-aliases.d.ts +136 -0
- package/ecc/scripts/lib/session-aliases.js +481 -0
- package/ecc/scripts/lib/session-manager.d.ts +131 -0
- package/ecc/scripts/lib/session-manager.js +444 -0
- package/ecc/scripts/lib/shell-split.js +86 -0
- package/ecc/scripts/lib/utils.d.ts +183 -0
- package/ecc/scripts/lib/utils.js +543 -0
- package/ecc/skills/continuous-learning-v2/SKILL.md +365 -0
- package/ecc/skills/continuous-learning-v2/agents/observer-loop.sh +144 -0
- package/ecc/skills/continuous-learning-v2/agents/observer.md +198 -0
- package/ecc/skills/continuous-learning-v2/agents/start-observer.sh +194 -0
- package/ecc/skills/continuous-learning-v2/config.json +8 -0
- package/ecc/skills/continuous-learning-v2/hooks/observe.sh +246 -0
- package/ecc/skills/continuous-learning-v2/scripts/detect-project.sh +218 -0
- package/ecc/skills/continuous-learning-v2/scripts/instinct-cli.py +1148 -0
- package/ecc/skills/continuous-learning-v2/scripts/test_parse_instinct.py +984 -0
- package/ecc/skills/strategic-compact/SKILL.md +103 -0
- package/ecc/skills/strategic-compact/suggest-compact.sh +54 -0
- package/ecc/skills/verification-loop-SKILL.md +126 -0
- package/gsd/LICENSE +21 -0
- package/gsd/agents/gsd-codebase-mapper.md +772 -0
- package/gsd/agents/gsd-debugger.md +1257 -0
- package/gsd/agents/gsd-executor.md +489 -0
- package/gsd/agents/gsd-integration-checker.md +445 -0
- package/gsd/agents/gsd-nyquist-auditor.md +178 -0
- package/gsd/agents/gsd-phase-researcher.md +555 -0
- package/gsd/agents/gsd-plan-checker.md +708 -0
- package/gsd/agents/gsd-planner.md +1309 -0
- package/gsd/agents/gsd-project-researcher.md +631 -0
- package/gsd/agents/gsd-research-synthesizer.md +249 -0
- package/gsd/agents/gsd-roadmapper.md +652 -0
- package/gsd/agents/gsd-verifier.md +581 -0
- package/gsd/commands-gsd/add-phase.md +43 -0
- package/gsd/commands-gsd/add-tests.md +41 -0
- package/gsd/commands-gsd/add-todo.md +47 -0
- package/gsd/commands-gsd/audit-milestone.md +36 -0
- package/gsd/commands-gsd/check-todos.md +45 -0
- package/gsd/commands-gsd/cleanup.md +18 -0
- package/gsd/commands-gsd/complete-milestone.md +136 -0
- package/gsd/commands-gsd/debug.md +168 -0
- package/gsd/commands-gsd/discuss-phase.md +90 -0
- package/gsd/commands-gsd/execute-phase.md +41 -0
- package/gsd/commands-gsd/health.md +22 -0
- package/gsd/commands-gsd/help.md +22 -0
- package/gsd/commands-gsd/insert-phase.md +32 -0
- package/gsd/commands-gsd/join-discord.md +18 -0
- package/gsd/commands-gsd/list-phase-assumptions.md +46 -0
- package/gsd/commands-gsd/map-codebase.md +71 -0
- package/gsd/commands-gsd/new-milestone.md +44 -0
- package/gsd/commands-gsd/new-project.md +42 -0
- package/gsd/commands-gsd/pause-work.md +38 -0
- package/gsd/commands-gsd/plan-milestone-gaps.md +34 -0
- package/gsd/commands-gsd/plan-phase.md +45 -0
- package/gsd/commands-gsd/progress.md +24 -0
- package/gsd/commands-gsd/quick.md +45 -0
- package/gsd/commands-gsd/reapply-patches.md +123 -0
- package/gsd/commands-gsd/remove-phase.md +31 -0
- package/gsd/commands-gsd/research-phase.md +190 -0
- package/gsd/commands-gsd/resume-work.md +40 -0
- package/gsd/commands-gsd/set-profile.md +34 -0
- package/gsd/commands-gsd/settings.md +36 -0
- package/gsd/commands-gsd/update.md +37 -0
- package/gsd/commands-gsd/validate-phase.md +35 -0
- package/gsd/commands-gsd/verify-work.md +38 -0
- package/gsd/get-shit-done/bin/gsd-tools.cjs +592 -0
- package/gsd/get-shit-done/bin/lib/commands.cjs +548 -0
- package/gsd/get-shit-done/bin/lib/config.cjs +169 -0
- package/gsd/get-shit-done/bin/lib/core.cjs +492 -0
- package/gsd/get-shit-done/bin/lib/frontmatter.cjs +299 -0
- package/gsd/get-shit-done/bin/lib/init.cjs +710 -0
- package/gsd/get-shit-done/bin/lib/milestone.cjs +241 -0
- package/gsd/get-shit-done/bin/lib/phase.cjs +901 -0
- package/gsd/get-shit-done/bin/lib/roadmap.cjs +298 -0
- package/gsd/get-shit-done/bin/lib/state.cjs +721 -0
- package/gsd/get-shit-done/bin/lib/template.cjs +222 -0
- package/gsd/get-shit-done/bin/lib/verify.cjs +820 -0
- package/gsd/get-shit-done/references/checkpoints.md +776 -0
- package/gsd/get-shit-done/references/continuation-format.md +249 -0
- package/gsd/get-shit-done/references/decimal-phase-calculation.md +65 -0
- package/gsd/get-shit-done/references/git-integration.md +248 -0
- package/gsd/get-shit-done/references/git-planning-commit.md +38 -0
- package/gsd/get-shit-done/references/model-profile-resolution.md +34 -0
- package/gsd/get-shit-done/references/model-profiles.md +93 -0
- package/gsd/get-shit-done/references/phase-argument-parsing.md +61 -0
- package/gsd/get-shit-done/references/planning-config.md +200 -0
- package/gsd/get-shit-done/references/questioning.md +162 -0
- package/gsd/get-shit-done/references/tdd.md +263 -0
- package/gsd/get-shit-done/references/ui-brand.md +160 -0
- package/gsd/get-shit-done/references/verification-patterns.md +612 -0
- package/gsd/get-shit-done/templates/DEBUG.md +164 -0
- package/gsd/get-shit-done/templates/UAT.md +247 -0
- package/gsd/get-shit-done/templates/VALIDATION.md +76 -0
- package/gsd/get-shit-done/templates/codebase/architecture.md +255 -0
- package/gsd/get-shit-done/templates/codebase/concerns.md +310 -0
- package/gsd/get-shit-done/templates/codebase/conventions.md +307 -0
- package/gsd/get-shit-done/templates/codebase/integrations.md +280 -0
- package/gsd/get-shit-done/templates/codebase/stack.md +186 -0
- package/gsd/get-shit-done/templates/codebase/structure.md +285 -0
- package/gsd/get-shit-done/templates/codebase/testing.md +480 -0
- package/gsd/get-shit-done/templates/config.json +37 -0
- package/gsd/get-shit-done/templates/context.md +297 -0
- package/gsd/get-shit-done/templates/continue-here.md +78 -0
- package/gsd/get-shit-done/templates/debug-subagent-prompt.md +91 -0
- package/gsd/get-shit-done/templates/discovery.md +146 -0
- package/gsd/get-shit-done/templates/milestone-archive.md +123 -0
- package/gsd/get-shit-done/templates/milestone.md +115 -0
- package/gsd/get-shit-done/templates/phase-prompt.md +569 -0
- package/gsd/get-shit-done/templates/planner-subagent-prompt.md +117 -0
- package/gsd/get-shit-done/templates/project.md +184 -0
- package/gsd/get-shit-done/templates/requirements.md +231 -0
- package/gsd/get-shit-done/templates/research-project/ARCHITECTURE.md +204 -0
- package/gsd/get-shit-done/templates/research-project/FEATURES.md +147 -0
- package/gsd/get-shit-done/templates/research-project/PITFALLS.md +200 -0
- package/gsd/get-shit-done/templates/research-project/STACK.md +120 -0
- package/gsd/get-shit-done/templates/research-project/SUMMARY.md +170 -0
- package/gsd/get-shit-done/templates/research.md +552 -0
- package/gsd/get-shit-done/templates/retrospective.md +54 -0
- package/gsd/get-shit-done/templates/roadmap.md +202 -0
- package/gsd/get-shit-done/templates/state.md +176 -0
- package/gsd/get-shit-done/templates/summary-complex.md +59 -0
- package/gsd/get-shit-done/templates/summary-minimal.md +41 -0
- package/gsd/get-shit-done/templates/summary-standard.md +48 -0
- package/gsd/get-shit-done/templates/summary.md +248 -0
- package/gsd/get-shit-done/templates/user-setup.md +311 -0
- package/gsd/get-shit-done/templates/verification-report.md +322 -0
- package/gsd/get-shit-done/workflows/add-phase.md +112 -0
- package/gsd/get-shit-done/workflows/add-tests.md +351 -0
- package/gsd/get-shit-done/workflows/add-todo.md +158 -0
- package/gsd/get-shit-done/workflows/audit-milestone.md +332 -0
- package/gsd/get-shit-done/workflows/check-todos.md +177 -0
- package/gsd/get-shit-done/workflows/cleanup.md +152 -0
- package/gsd/get-shit-done/workflows/complete-milestone.md +764 -0
- package/gsd/get-shit-done/workflows/diagnose-issues.md +219 -0
- package/gsd/get-shit-done/workflows/discovery-phase.md +289 -0
- package/gsd/get-shit-done/workflows/discuss-phase.md +676 -0
- package/gsd/get-shit-done/workflows/execute-phase.md +459 -0
- package/gsd/get-shit-done/workflows/execute-plan.md +449 -0
- package/gsd/get-shit-done/workflows/health.md +159 -0
- package/gsd/get-shit-done/workflows/help.md +489 -0
- package/gsd/get-shit-done/workflows/insert-phase.md +130 -0
- package/gsd/get-shit-done/workflows/list-phase-assumptions.md +178 -0
- package/gsd/get-shit-done/workflows/map-codebase.md +316 -0
- package/gsd/get-shit-done/workflows/new-milestone.md +384 -0
- package/gsd/get-shit-done/workflows/new-project.md +1111 -0
- package/gsd/get-shit-done/workflows/pause-work.md +122 -0
- package/gsd/get-shit-done/workflows/plan-milestone-gaps.md +274 -0
- package/gsd/get-shit-done/workflows/plan-phase.md +560 -0
- package/gsd/get-shit-done/workflows/progress.md +382 -0
- package/gsd/get-shit-done/workflows/quick.md +601 -0
- package/gsd/get-shit-done/workflows/remove-phase.md +155 -0
- package/gsd/get-shit-done/workflows/research-phase.md +74 -0
- package/gsd/get-shit-done/workflows/resume-project.md +307 -0
- package/gsd/get-shit-done/workflows/set-profile.md +81 -0
- package/gsd/get-shit-done/workflows/settings.md +214 -0
- package/gsd/get-shit-done/workflows/transition.md +544 -0
- package/gsd/get-shit-done/workflows/update.md +240 -0
- package/gsd/get-shit-done/workflows/validate-phase.md +167 -0
- package/gsd/get-shit-done/workflows/verify-phase.md +243 -0
- package/gsd/get-shit-done/workflows/verify-work.md +583 -0
- package/gsd/hooks/gsd-check-update.js +81 -0
- package/gsd/hooks/gsd-context-monitor.js +141 -0
- package/gsd/hooks/gsd-statusline.js +115 -0
- package/kit/CLAUDE.md +43 -0
- package/kit/commands/kit/update.md +46 -0
- package/kit/commands/setup-refresh.md +50 -0
- package/kit/commands/setup.md +579 -0
- package/kit/commands/tool-guide.md +44 -0
- package/kit/hooks/kit-check-update.js +54 -0
- package/kit/mcp.json +10 -0
- package/kit/rules/code-style.md +24 -0
- package/manifest.json +30 -0
- 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(); }
|