@nolrm/contextkit 0.9.3 → 0.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -6
- package/lib/commands/install.js +66 -18
- package/lib/commands/update.js +60 -15
- package/lib/integrations/claude-integration.js +156 -26
- package/lib/integrations/cursor-integration.js +123 -7
- package/lib/utils/git-hooks.js +93 -53
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Update `.md` files as your project evolves; the AI follows.
|
|
|
23
23
|
|
|
24
24
|
Works with: **Cursor** • **Claude Code** • **GitHub Copilot** • **Codex CLI** • **Gemini CLI** • **Aider** • **Continue** • **Windsurf**
|
|
25
25
|
|
|
26
|
-
Each platform gets auto-loaded bridge files (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.windsurfrules`, etc.) so your AI tools read project standards automatically.
|
|
26
|
+
Each platform gets auto-loaded bridge files (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.windsurfrules`, etc.) so your AI tools read project standards automatically. Claude Code uses `@` imports in CLAUDE.md to load standards content directly into context — no extra token cost from manual file reads.
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
@@ -111,13 +111,17 @@ Each platform generates bridge files that the AI tool auto-reads. If a bridge fi
|
|
|
111
111
|
|
|
112
112
|
## Use it in your tool
|
|
113
113
|
|
|
114
|
-
**Cursor** — rules auto-load from `.cursor/rules/`
|
|
114
|
+
**Cursor** — rules auto-load from `.cursor/rules/`, slash commands in `.cursor/prompts/`
|
|
115
115
|
```
|
|
116
|
-
|
|
116
|
+
/analyze # scan codebase and generate standards
|
|
117
|
+
/review # code review with checklist
|
|
118
|
+
/fix # diagnose and fix bugs
|
|
117
119
|
```
|
|
118
120
|
|
|
119
|
-
**Claude Code** —
|
|
121
|
+
**Claude Code** — `CLAUDE.md` uses `@` imports to auto-load all standards into context every session (no manual reads needed, saves tokens). Slash commands in `.claude/commands/`.
|
|
120
122
|
```bash
|
|
123
|
+
/analyze # scan codebase and generate standards
|
|
124
|
+
/review # code review with checklist
|
|
121
125
|
claude "create checkout flow for customer"
|
|
122
126
|
```
|
|
123
127
|
|
|
@@ -133,14 +137,93 @@ codex "create checkout flow for customer"
|
|
|
133
137
|
|
|
134
138
|
**CLI** (Chat with AI)
|
|
135
139
|
```bash
|
|
136
|
-
ck ai "create
|
|
140
|
+
ck ai "create a button"
|
|
137
141
|
```
|
|
138
142
|
|
|
139
143
|
---
|
|
140
144
|
|
|
145
|
+
## Slash Commands
|
|
146
|
+
|
|
147
|
+
ContextKit installs reusable slash commands for supported platforms:
|
|
148
|
+
|
|
149
|
+
| Command | What it does |
|
|
150
|
+
|---------|-------------|
|
|
151
|
+
| `/analyze` | Scan codebase and generate standards content |
|
|
152
|
+
| `/review` | Code review with checklist |
|
|
153
|
+
| `/fix` | Diagnose and fix bugs |
|
|
154
|
+
| `/refactor` | Refactor code with safety checks |
|
|
155
|
+
| `/test` | Generate comprehensive tests |
|
|
156
|
+
| `/doc` | Add documentation |
|
|
157
|
+
| `/squad` | Kick off a squad task — write the PO spec |
|
|
158
|
+
| `/squad-architect` | Design the technical plan from the PO spec |
|
|
159
|
+
| `/squad-dev` | Implement code following the architect plan |
|
|
160
|
+
| `/squad-test` | Write and run tests against acceptance criteria |
|
|
161
|
+
| `/squad-review` | Review the full pipeline and give a verdict |
|
|
162
|
+
| `/squad-batch` | Kick off multiple tasks at once (batch PO specs) |
|
|
163
|
+
| `/squad-run` | Auto-run the remaining pipeline for batch tasks |
|
|
164
|
+
|
|
165
|
+
**Claude Code** — available as `/analyze`, `/review`, etc. in `.claude/commands/`
|
|
166
|
+
**Cursor** — available as slash commands in Chat via `.cursor/prompts/`
|
|
167
|
+
|
|
168
|
+
Both platforms delegate to the universal command files in `.contextkit/commands/`, so you maintain one set of workflows.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Squad Workflow
|
|
173
|
+
|
|
174
|
+
The squad workflow turns a single AI session into a structured multi-role pipeline. Each role has its own slash command that reads and writes to a shared handoff file (`.contextkit/squad/handoff.md`), simulating a team of specialists.
|
|
175
|
+
|
|
176
|
+
### Pipeline Roles
|
|
177
|
+
|
|
178
|
+
| Step | Role | Command | What it does |
|
|
179
|
+
|------|------|---------|-------------|
|
|
180
|
+
| 1 | Product Owner | `/squad` | Writes a user story, acceptance criteria, edge cases, and scope |
|
|
181
|
+
| 2 | Architect | `/squad-architect` | Designs the technical approach, files to change, and implementation steps |
|
|
182
|
+
| 3 | Developer | `/squad-dev` | Implements the code following the architect's plan |
|
|
183
|
+
| 4 | Tester | `/squad-test` | Writes and runs tests against the PO's acceptance criteria |
|
|
184
|
+
| 5 | Reviewer | `/squad-review` | Reviews everything and gives a PASS or NEEDS-WORK verdict |
|
|
185
|
+
|
|
186
|
+
### Single-Task Flow
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
/squad "add dark mode support" # PO writes the spec
|
|
190
|
+
/squad-architect # Architect designs the plan
|
|
191
|
+
/squad-dev # Dev implements the code
|
|
192
|
+
/squad-test # Tester writes and runs tests
|
|
193
|
+
/squad-review # Reviewer gives the verdict
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Batch Flow
|
|
197
|
+
|
|
198
|
+
For multiple tasks, use batch mode to spec them all up front, then run the full pipeline automatically:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
/squad-batch "add dark mode" "fix login bug" "refactor checkout"
|
|
202
|
+
# PO writes specs for all three tasks
|
|
203
|
+
|
|
204
|
+
/squad-run
|
|
205
|
+
# Runs Architect → Dev → Test → Review for each task sequentially
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Feedback Loop
|
|
209
|
+
|
|
210
|
+
Any downstream role can raise questions for an upstream role. When this happens, the pipeline pauses and directs you to the right command:
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
Reviewer has questions for Dev → run /squad-dev to clarify
|
|
214
|
+
Tester has questions for Architect → run /squad-architect to clarify
|
|
215
|
+
Architect has questions for PO → run /squad to clarify
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
After clarifications are added, re-run the asking role's command to continue. This prevents misunderstandings from compounding through the pipeline.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
141
222
|
## Git Hooks & Quality Gates
|
|
142
223
|
|
|
143
|
-
ContextKit can optionally install
|
|
224
|
+
ContextKit can optionally install Git hooks during `ck install`. Uses `git config core.hooksPath` to point Git at `.contextkit/hooks/` — no external dependencies like Husky required. Works in any git repo, not just Node.js projects.
|
|
225
|
+
|
|
226
|
+
For **Node.js projects**, a `prepare` script is automatically added to `package.json` so hooks activate for all developers after `npm install` — no need for everyone to run `ck install`.
|
|
144
227
|
|
|
145
228
|
| Hook | What it does |
|
|
146
229
|
|------|-------------|
|
package/lib/commands/install.js
CHANGED
|
@@ -515,12 +515,20 @@ Run \`ck analyze\` to generate this content, or manually add your API pattern be
|
|
|
515
515
|
|
|
516
516
|
// Download commands
|
|
517
517
|
await this.downloadManager.downloadFile(
|
|
518
|
-
`${this.repoUrl}/commands/
|
|
519
|
-
'.contextkit/commands/
|
|
518
|
+
`${this.repoUrl}/commands/analyze.md`,
|
|
519
|
+
'.contextkit/commands/analyze.md'
|
|
520
520
|
);
|
|
521
521
|
await this.downloadManager.downloadFile(
|
|
522
|
-
`${this.repoUrl}/commands/
|
|
523
|
-
'.contextkit/commands/
|
|
522
|
+
`${this.repoUrl}/commands/review.md`,
|
|
523
|
+
'.contextkit/commands/review.md'
|
|
524
|
+
);
|
|
525
|
+
await this.downloadManager.downloadFile(
|
|
526
|
+
`${this.repoUrl}/commands/fix.md`,
|
|
527
|
+
'.contextkit/commands/fix.md'
|
|
528
|
+
);
|
|
529
|
+
await this.downloadManager.downloadFile(
|
|
530
|
+
`${this.repoUrl}/commands/refactor.md`,
|
|
531
|
+
'.contextkit/commands/refactor.md'
|
|
524
532
|
);
|
|
525
533
|
await this.downloadManager.downloadFile(
|
|
526
534
|
`${this.repoUrl}/commands/run-tests.md`,
|
|
@@ -535,18 +543,52 @@ Run \`ck analyze\` to generate this content, or manually add your API pattern be
|
|
|
535
543
|
'.contextkit/commands/quality-check.md'
|
|
536
544
|
);
|
|
537
545
|
await this.downloadManager.downloadFile(
|
|
538
|
-
`${this.repoUrl}/commands/
|
|
539
|
-
'.contextkit/commands/
|
|
546
|
+
`${this.repoUrl}/commands/create-feature.md`,
|
|
547
|
+
'.contextkit/commands/create-feature.md'
|
|
548
|
+
);
|
|
549
|
+
await this.downloadManager.downloadFile(
|
|
550
|
+
`${this.repoUrl}/commands/create-component.md`,
|
|
551
|
+
'.contextkit/commands/create-component.md'
|
|
552
|
+
);
|
|
553
|
+
|
|
554
|
+
// Download squad commands
|
|
555
|
+
await this.downloadManager.downloadFile(
|
|
556
|
+
`${this.repoUrl}/commands/squad.md`,
|
|
557
|
+
'.contextkit/commands/squad.md'
|
|
558
|
+
);
|
|
559
|
+
await this.downloadManager.downloadFile(
|
|
560
|
+
`${this.repoUrl}/commands/squad-architect.md`,
|
|
561
|
+
'.contextkit/commands/squad-architect.md'
|
|
562
|
+
);
|
|
563
|
+
await this.downloadManager.downloadFile(
|
|
564
|
+
`${this.repoUrl}/commands/squad-dev.md`,
|
|
565
|
+
'.contextkit/commands/squad-dev.md'
|
|
566
|
+
);
|
|
567
|
+
await this.downloadManager.downloadFile(
|
|
568
|
+
`${this.repoUrl}/commands/squad-test.md`,
|
|
569
|
+
'.contextkit/commands/squad-test.md'
|
|
570
|
+
);
|
|
571
|
+
await this.downloadManager.downloadFile(
|
|
572
|
+
`${this.repoUrl}/commands/squad-review.md`,
|
|
573
|
+
'.contextkit/commands/squad-review.md'
|
|
574
|
+
);
|
|
575
|
+
await this.downloadManager.downloadFile(
|
|
576
|
+
`${this.repoUrl}/commands/squad-batch.md`,
|
|
577
|
+
'.contextkit/commands/squad-batch.md'
|
|
578
|
+
);
|
|
579
|
+
await this.downloadManager.downloadFile(
|
|
580
|
+
`${this.repoUrl}/commands/squad-run.md`,
|
|
581
|
+
'.contextkit/commands/squad-run.md'
|
|
540
582
|
);
|
|
541
583
|
|
|
542
584
|
// Download hooks (pre-push and commit-msg only, no pre-commit)
|
|
543
585
|
await this.downloadManager.downloadFile(
|
|
544
|
-
`${this.repoUrl}/hooks/pre-push
|
|
545
|
-
'.contextkit/hooks/pre-push
|
|
586
|
+
`${this.repoUrl}/hooks/pre-push`,
|
|
587
|
+
'.contextkit/hooks/pre-push'
|
|
546
588
|
);
|
|
547
589
|
await this.downloadManager.downloadFile(
|
|
548
|
-
`${this.repoUrl}/hooks/commit-msg
|
|
549
|
-
'.contextkit/hooks/commit-msg
|
|
590
|
+
`${this.repoUrl}/hooks/commit-msg`,
|
|
591
|
+
'.contextkit/hooks/commit-msg'
|
|
550
592
|
);
|
|
551
593
|
await this.downloadManager.downloadFile(
|
|
552
594
|
`${this.repoUrl}/hooks/setup-hooks.sh`,
|
|
@@ -581,8 +623,8 @@ Run \`ck analyze\` to generate this content, or manually add your API pattern be
|
|
|
581
623
|
);
|
|
582
624
|
|
|
583
625
|
// Make scripts executable
|
|
584
|
-
await fs.chmod('.contextkit/hooks/pre-push
|
|
585
|
-
await fs.chmod('.contextkit/hooks/commit-msg
|
|
626
|
+
await fs.chmod('.contextkit/hooks/pre-push', '755');
|
|
627
|
+
await fs.chmod('.contextkit/hooks/commit-msg', '755');
|
|
586
628
|
await fs.chmod('.contextkit/hooks/setup-hooks.sh', '755');
|
|
587
629
|
await fs.chmod('.contextkit/types/type-check.sh', '755');
|
|
588
630
|
await fs.chmod('.contextkit/scripts/update.sh', '755');
|
|
@@ -683,11 +725,14 @@ claude "read .contextkit/context.md to see available standards, then create a bu
|
|
|
683
725
|
|
|
684
726
|
### Commands
|
|
685
727
|
- \`.contextkit/commands/analyze.md\` - Analyze & customize standards
|
|
728
|
+
- \`.contextkit/commands/review.md\` - Code review
|
|
729
|
+
- \`.contextkit/commands/fix.md\` - Diagnose and fix bugs
|
|
730
|
+
- \`.contextkit/commands/refactor.md\` - Refactor code structure
|
|
731
|
+
- \`.contextkit/commands/run-tests.md\` - Generate or run tests
|
|
732
|
+
- \`.contextkit/commands/add-documentation.md\` - Add documentation
|
|
733
|
+
- \`.contextkit/commands/quality-check.md\` - Quality checks
|
|
686
734
|
- \`.contextkit/commands/create-component.md\` - Create component
|
|
687
735
|
- \`.contextkit/commands/create-feature.md\` - Create feature
|
|
688
|
-
- \`.contextkit/commands/run-tests.md\` - Run tests
|
|
689
|
-
- \`.contextkit/commands/quality-check.md\` - Quality checks
|
|
690
|
-
- \`.contextkit/commands/add-documentation.md\` - Add documentation
|
|
691
736
|
|
|
692
737
|
### Instructions
|
|
693
738
|
- \`.contextkit/instructions/meta/pre-flight.md\` - Pre-flight checks
|
|
@@ -806,12 +851,15 @@ esac
|
|
|
806
851
|
docs: 'docs'
|
|
807
852
|
},
|
|
808
853
|
commands: {
|
|
809
|
-
|
|
810
|
-
|
|
854
|
+
analyze: '@.contextkit/commands/analyze.md',
|
|
855
|
+
review: '@.contextkit/commands/review.md',
|
|
856
|
+
fix: '@.contextkit/commands/fix.md',
|
|
857
|
+
refactor: '@.contextkit/commands/refactor.md',
|
|
811
858
|
run_tests: '@.contextkit/commands/run-tests.md',
|
|
812
859
|
add_docs: '@.contextkit/commands/add-documentation.md',
|
|
813
860
|
quality_check: '@.contextkit/commands/quality-check.md',
|
|
814
|
-
|
|
861
|
+
create_component: '@.contextkit/commands/create-component.md',
|
|
862
|
+
create_feature: '@.contextkit/commands/create-feature.md'
|
|
815
863
|
}
|
|
816
864
|
};
|
|
817
865
|
|
package/lib/commands/update.js
CHANGED
|
@@ -213,12 +213,20 @@ class UpdateCommand {
|
|
|
213
213
|
|
|
214
214
|
// Download commands
|
|
215
215
|
await this.downloadManager.downloadFile(
|
|
216
|
-
`${this.repoUrl}/commands/
|
|
217
|
-
'.contextkit/commands/
|
|
216
|
+
`${this.repoUrl}/commands/analyze.md`,
|
|
217
|
+
'.contextkit/commands/analyze.md'
|
|
218
218
|
);
|
|
219
219
|
await this.downloadManager.downloadFile(
|
|
220
|
-
`${this.repoUrl}/commands/
|
|
221
|
-
'.contextkit/commands/
|
|
220
|
+
`${this.repoUrl}/commands/review.md`,
|
|
221
|
+
'.contextkit/commands/review.md'
|
|
222
|
+
);
|
|
223
|
+
await this.downloadManager.downloadFile(
|
|
224
|
+
`${this.repoUrl}/commands/fix.md`,
|
|
225
|
+
'.contextkit/commands/fix.md'
|
|
226
|
+
);
|
|
227
|
+
await this.downloadManager.downloadFile(
|
|
228
|
+
`${this.repoUrl}/commands/refactor.md`,
|
|
229
|
+
'.contextkit/commands/refactor.md'
|
|
222
230
|
);
|
|
223
231
|
await this.downloadManager.downloadFile(
|
|
224
232
|
`${this.repoUrl}/commands/run-tests.md`,
|
|
@@ -233,18 +241,52 @@ class UpdateCommand {
|
|
|
233
241
|
'.contextkit/commands/quality-check.md'
|
|
234
242
|
);
|
|
235
243
|
await this.downloadManager.downloadFile(
|
|
236
|
-
`${this.repoUrl}/commands/
|
|
237
|
-
'.contextkit/commands/
|
|
244
|
+
`${this.repoUrl}/commands/create-feature.md`,
|
|
245
|
+
'.contextkit/commands/create-feature.md'
|
|
246
|
+
);
|
|
247
|
+
await this.downloadManager.downloadFile(
|
|
248
|
+
`${this.repoUrl}/commands/create-component.md`,
|
|
249
|
+
'.contextkit/commands/create-component.md'
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
// Download squad commands
|
|
253
|
+
await this.downloadManager.downloadFile(
|
|
254
|
+
`${this.repoUrl}/commands/squad.md`,
|
|
255
|
+
'.contextkit/commands/squad.md'
|
|
256
|
+
);
|
|
257
|
+
await this.downloadManager.downloadFile(
|
|
258
|
+
`${this.repoUrl}/commands/squad-architect.md`,
|
|
259
|
+
'.contextkit/commands/squad-architect.md'
|
|
260
|
+
);
|
|
261
|
+
await this.downloadManager.downloadFile(
|
|
262
|
+
`${this.repoUrl}/commands/squad-dev.md`,
|
|
263
|
+
'.contextkit/commands/squad-dev.md'
|
|
264
|
+
);
|
|
265
|
+
await this.downloadManager.downloadFile(
|
|
266
|
+
`${this.repoUrl}/commands/squad-test.md`,
|
|
267
|
+
'.contextkit/commands/squad-test.md'
|
|
268
|
+
);
|
|
269
|
+
await this.downloadManager.downloadFile(
|
|
270
|
+
`${this.repoUrl}/commands/squad-review.md`,
|
|
271
|
+
'.contextkit/commands/squad-review.md'
|
|
272
|
+
);
|
|
273
|
+
await this.downloadManager.downloadFile(
|
|
274
|
+
`${this.repoUrl}/commands/squad-batch.md`,
|
|
275
|
+
'.contextkit/commands/squad-batch.md'
|
|
276
|
+
);
|
|
277
|
+
await this.downloadManager.downloadFile(
|
|
278
|
+
`${this.repoUrl}/commands/squad-run.md`,
|
|
279
|
+
'.contextkit/commands/squad-run.md'
|
|
238
280
|
);
|
|
239
281
|
|
|
240
282
|
// Download hooks (pre-push and commit-msg only, no pre-commit)
|
|
241
283
|
await this.downloadManager.downloadFile(
|
|
242
|
-
`${this.repoUrl}/hooks/pre-push
|
|
243
|
-
'.contextkit/hooks/pre-push
|
|
284
|
+
`${this.repoUrl}/hooks/pre-push`,
|
|
285
|
+
'.contextkit/hooks/pre-push'
|
|
244
286
|
);
|
|
245
287
|
await this.downloadManager.downloadFile(
|
|
246
|
-
`${this.repoUrl}/hooks/commit-msg
|
|
247
|
-
'.contextkit/hooks/commit-msg
|
|
288
|
+
`${this.repoUrl}/hooks/commit-msg`,
|
|
289
|
+
'.contextkit/hooks/commit-msg'
|
|
248
290
|
);
|
|
249
291
|
await this.downloadManager.downloadFile(
|
|
250
292
|
`${this.repoUrl}/hooks/setup-hooks.sh`,
|
|
@@ -278,8 +320,8 @@ class UpdateCommand {
|
|
|
278
320
|
);
|
|
279
321
|
|
|
280
322
|
// Make scripts executable
|
|
281
|
-
await fs.chmod('.contextkit/hooks/pre-push
|
|
282
|
-
await fs.chmod('.contextkit/hooks/commit-msg
|
|
323
|
+
await fs.chmod('.contextkit/hooks/pre-push', '755');
|
|
324
|
+
await fs.chmod('.contextkit/hooks/commit-msg', '755');
|
|
283
325
|
await fs.chmod('.contextkit/hooks/setup-hooks.sh', '755');
|
|
284
326
|
await fs.chmod('.contextkit/types/type-check.sh', '755');
|
|
285
327
|
await fs.chmod('.contextkit/scripts/update.sh', '755');
|
|
@@ -317,12 +359,15 @@ paths:
|
|
|
317
359
|
|
|
318
360
|
# Commands
|
|
319
361
|
commands:
|
|
320
|
-
|
|
321
|
-
|
|
362
|
+
analyze: "${config.commands?.analyze || '@.contextkit/commands/analyze.md'}"
|
|
363
|
+
review: "${config.commands?.review || '@.contextkit/commands/review.md'}"
|
|
364
|
+
fix: "${config.commands?.fix || '@.contextkit/commands/fix.md'}"
|
|
365
|
+
refactor: "${config.commands?.refactor || '@.contextkit/commands/refactor.md'}"
|
|
322
366
|
run_tests: "${config.commands?.run_tests || '@.contextkit/commands/run-tests.md'}"
|
|
323
367
|
add_docs: "${config.commands?.add_docs || '@.contextkit/commands/add-documentation.md'}"
|
|
324
368
|
quality_check: "${config.commands?.quality_check || '@.contextkit/commands/quality-check.md'}"
|
|
325
|
-
|
|
369
|
+
create_component: "${config.commands?.create_component || '@.contextkit/commands/create-component.md'}"
|
|
370
|
+
create_feature: "${config.commands?.create_feature || '@.contextkit/commands/create-feature.md'}"
|
|
326
371
|
`;
|
|
327
372
|
|
|
328
373
|
await fs.writeFile('.contextkit/config.yml', configContent);
|
|
@@ -12,6 +12,18 @@ class ClaudeIntegration extends BaseIntegration {
|
|
|
12
12
|
'.claude/rules/contextkit-testing.md',
|
|
13
13
|
'.claude/rules/contextkit-code-style.md',
|
|
14
14
|
'.claude/commands/analyze.md',
|
|
15
|
+
'.claude/commands/review.md',
|
|
16
|
+
'.claude/commands/fix.md',
|
|
17
|
+
'.claude/commands/refactor.md',
|
|
18
|
+
'.claude/commands/test.md',
|
|
19
|
+
'.claude/commands/doc.md',
|
|
20
|
+
'.claude/commands/squad.md',
|
|
21
|
+
'.claude/commands/squad-architect.md',
|
|
22
|
+
'.claude/commands/squad-dev.md',
|
|
23
|
+
'.claude/commands/squad-test.md',
|
|
24
|
+
'.claude/commands/squad-review.md',
|
|
25
|
+
'.claude/commands/squad-batch.md',
|
|
26
|
+
'.claude/commands/squad-run.md',
|
|
15
27
|
];
|
|
16
28
|
this.platformDir = '.claude/rules';
|
|
17
29
|
}
|
|
@@ -37,6 +49,33 @@ class ClaudeIntegration extends BaseIntegration {
|
|
|
37
49
|
}
|
|
38
50
|
}
|
|
39
51
|
|
|
52
|
+
getStandardsBlock() {
|
|
53
|
+
return `## Project Standards
|
|
54
|
+
|
|
55
|
+
The following standards are auto-loaded into context via @imports:
|
|
56
|
+
|
|
57
|
+
- @.contextkit/standards/code-style.md — Coding conventions and style rules
|
|
58
|
+
- @.contextkit/standards/testing.md — Testing patterns and requirements
|
|
59
|
+
- @.contextkit/standards/architecture.md — Architecture decisions and patterns
|
|
60
|
+
- @.contextkit/standards/ai-guidelines.md — AI behavior and usage guidelines
|
|
61
|
+
- @.contextkit/standards/workflows.md — Development workflows and processes
|
|
62
|
+
- @.contextkit/standards/glossary.md — Project terminology and shortcuts
|
|
63
|
+
|
|
64
|
+
## Product Context
|
|
65
|
+
|
|
66
|
+
- @.contextkit/product/mission-lite.md — Product mission (condensed)
|
|
67
|
+
- @.contextkit/product/decisions.md — Architecture Decision Records
|
|
68
|
+
- @.contextkit/product/roadmap.md — Development roadmap
|
|
69
|
+
|
|
70
|
+
## Commands
|
|
71
|
+
|
|
72
|
+
- \`.contextkit/commands/analyze.md\` — Analyze and customize standards
|
|
73
|
+
- \`.contextkit/commands/create-component.md\` — Create components
|
|
74
|
+
- \`.contextkit/commands/create-feature.md\` — Create features
|
|
75
|
+
- \`.contextkit/commands/run-tests.md\` — Run tests
|
|
76
|
+
- \`.contextkit/commands/quality-check.md\` — Quality checks`;
|
|
77
|
+
}
|
|
78
|
+
|
|
40
79
|
async generateFiles() {
|
|
41
80
|
// Bridge file: CLAUDE.md (auto-loaded every session)
|
|
42
81
|
const bridgeContent = `# Project Standards (ContextKit)
|
|
@@ -47,7 +86,7 @@ ${this.getStandardsBlock()}
|
|
|
47
86
|
|
|
48
87
|
## Corrections Log
|
|
49
88
|
|
|
50
|
-
-
|
|
89
|
+
- @.contextkit/corrections.md — Track AI performance improvements
|
|
51
90
|
|
|
52
91
|
## Quick Reference
|
|
53
92
|
|
|
@@ -63,14 +102,14 @@ alwaysApply: true
|
|
|
63
102
|
|
|
64
103
|
# ContextKit Standards
|
|
65
104
|
|
|
66
|
-
This project uses ContextKit
|
|
105
|
+
This project uses ContextKit. Project standards are auto-loaded via CLAUDE.md imports.
|
|
67
106
|
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
107
|
+
Key areas to follow:
|
|
108
|
+
- Code style conventions (from code-style.md)
|
|
109
|
+
- Architecture patterns (from architecture.md)
|
|
110
|
+
- AI behavior rules (from ai-guidelines.md)
|
|
111
|
+
- Project terminology (from glossary.md)
|
|
112
|
+
- Product context (from mission-lite.md)
|
|
74
113
|
`;
|
|
75
114
|
await this.writeGeneratedFile('.claude/rules/contextkit-standards.md', standardsRule);
|
|
76
115
|
|
|
@@ -85,8 +124,7 @@ globs:
|
|
|
85
124
|
|
|
86
125
|
# Testing Standards
|
|
87
126
|
|
|
88
|
-
|
|
89
|
-
- \`.contextkit/standards/testing.md\` for test patterns and requirements
|
|
127
|
+
Follow the testing standards auto-loaded via CLAUDE.md (from testing.md).
|
|
90
128
|
- All test cases MUST use numbered descriptions (e.g., \`it("1. renders correctly")\`)
|
|
91
129
|
- Reference \`.contextkit/templates/test.md\` for test template patterns
|
|
92
130
|
`;
|
|
@@ -104,22 +142,105 @@ globs:
|
|
|
104
142
|
|
|
105
143
|
# Code Style
|
|
106
144
|
|
|
107
|
-
|
|
108
|
-
- \`.contextkit/
|
|
109
|
-
- \`.contextkit/templates/
|
|
110
|
-
- \`.contextkit/templates/
|
|
111
|
-
- \`.contextkit/templates/api.md\` for API service patterns
|
|
145
|
+
Follow the code style standards auto-loaded via CLAUDE.md (from code-style.md).
|
|
146
|
+
- Reference \`.contextkit/templates/component.md\` for component patterns
|
|
147
|
+
- Reference \`.contextkit/templates/hook.md\` for custom hook patterns
|
|
148
|
+
- Reference \`.contextkit/templates/api.md\` for API service patterns
|
|
112
149
|
`;
|
|
113
150
|
await this.writeGeneratedFile('.claude/rules/contextkit-code-style.md', codeStyleRule);
|
|
114
151
|
|
|
115
|
-
//
|
|
116
|
-
|
|
152
|
+
// Slash commands — thin wrappers that delegate to .contextkit/commands/
|
|
153
|
+
await this.writeGeneratedFile('.claude/commands/analyze.md', `# Analyze Project
|
|
117
154
|
|
|
118
155
|
Read \`.contextkit/commands/analyze.md\` and execute the analysis workflow for this project.
|
|
119
156
|
|
|
120
157
|
Scan the codebase structure, detect frameworks and patterns, then generate customized standards files in \`.contextkit/standards/\`.
|
|
121
|
-
|
|
122
|
-
|
|
158
|
+
`);
|
|
159
|
+
|
|
160
|
+
await this.writeGeneratedFile('.claude/commands/review.md', `# Code Review
|
|
161
|
+
|
|
162
|
+
Read \`.contextkit/commands/review.md\` and execute the review workflow.
|
|
163
|
+
|
|
164
|
+
Review current changes for correctness, standards compliance, and potential issues.
|
|
165
|
+
`);
|
|
166
|
+
|
|
167
|
+
await this.writeGeneratedFile('.claude/commands/fix.md', `# Fix Bug
|
|
168
|
+
|
|
169
|
+
Read \`.contextkit/commands/fix.md\` and execute the bug fix workflow.
|
|
170
|
+
|
|
171
|
+
Diagnose the root cause, implement the minimal fix, and add a regression test.
|
|
172
|
+
`);
|
|
173
|
+
|
|
174
|
+
await this.writeGeneratedFile('.claude/commands/refactor.md', `# Refactor
|
|
175
|
+
|
|
176
|
+
Read \`.contextkit/commands/refactor.md\` and execute the refactoring workflow.
|
|
177
|
+
|
|
178
|
+
Improve code structure without changing behavior, keeping tests green at every step.
|
|
179
|
+
`);
|
|
180
|
+
|
|
181
|
+
await this.writeGeneratedFile('.claude/commands/test.md', `# Run Tests
|
|
182
|
+
|
|
183
|
+
Read \`.contextkit/commands/run-tests.md\` and execute the testing workflow.
|
|
184
|
+
|
|
185
|
+
Generate or run tests for the specified code, covering happy paths, edge cases, and errors.
|
|
186
|
+
`);
|
|
187
|
+
|
|
188
|
+
await this.writeGeneratedFile('.claude/commands/doc.md', `# Add Documentation
|
|
189
|
+
|
|
190
|
+
Read \`.contextkit/commands/add-documentation.md\` and execute the documentation workflow.
|
|
191
|
+
|
|
192
|
+
Add inline docs, README sections, and usage examples for the specified code.
|
|
193
|
+
`);
|
|
194
|
+
|
|
195
|
+
// Squad slash commands
|
|
196
|
+
await this.writeGeneratedFile('.claude/commands/squad.md', `# Squad — Kickoff
|
|
197
|
+
|
|
198
|
+
Read \`.contextkit/commands/squad.md\` and execute the squad kickoff workflow.
|
|
199
|
+
|
|
200
|
+
Create the handoff file and write the PO spec for the given task. Pass the user's task description as the input.
|
|
201
|
+
`);
|
|
202
|
+
|
|
203
|
+
await this.writeGeneratedFile('.claude/commands/squad-architect.md', `# Squad — Architect
|
|
204
|
+
|
|
205
|
+
Read \`.contextkit/commands/squad-architect.md\` and execute the architect workflow.
|
|
206
|
+
|
|
207
|
+
Read the PO spec from the handoff file, design the technical approach, and write the implementation plan.
|
|
208
|
+
`);
|
|
209
|
+
|
|
210
|
+
await this.writeGeneratedFile('.claude/commands/squad-dev.md', `# Squad — Dev
|
|
211
|
+
|
|
212
|
+
Read \`.contextkit/commands/squad-dev.md\` and execute the dev workflow.
|
|
213
|
+
|
|
214
|
+
Follow the architect's plan to implement the code changes.
|
|
215
|
+
`);
|
|
216
|
+
|
|
217
|
+
await this.writeGeneratedFile('.claude/commands/squad-test.md', `# Squad — Test
|
|
218
|
+
|
|
219
|
+
Read \`.contextkit/commands/squad-test.md\` and execute the test workflow.
|
|
220
|
+
|
|
221
|
+
Write and run tests against the PO's acceptance criteria.
|
|
222
|
+
`);
|
|
223
|
+
|
|
224
|
+
await this.writeGeneratedFile('.claude/commands/squad-review.md', `# Squad — Review
|
|
225
|
+
|
|
226
|
+
Read \`.contextkit/commands/squad-review.md\` and execute the review workflow.
|
|
227
|
+
|
|
228
|
+
Review the full handoff (spec, plan, implementation, tests) and write the final verdict.
|
|
229
|
+
`);
|
|
230
|
+
|
|
231
|
+
await this.writeGeneratedFile('.claude/commands/squad-batch.md', `# Squad Batch — Multi-Task Kickoff
|
|
232
|
+
|
|
233
|
+
Read \`.contextkit/commands/squad-batch.md\` and execute the batch kickoff workflow.
|
|
234
|
+
|
|
235
|
+
Create handoff files for multiple tasks and write PO specs for each one. Pass all task descriptions as the input.
|
|
236
|
+
`);
|
|
237
|
+
|
|
238
|
+
await this.writeGeneratedFile('.claude/commands/squad-run.md', `# Squad Run — Auto-Run Pipeline
|
|
239
|
+
|
|
240
|
+
Read \`.contextkit/commands/squad-run.md\` and execute the pipeline runner workflow.
|
|
241
|
+
|
|
242
|
+
Process all batch tasks through the remaining pipeline steps (Architect, Dev, Test, Review) sequentially.
|
|
243
|
+
`);
|
|
123
244
|
}
|
|
124
245
|
|
|
125
246
|
showUsage() {
|
|
@@ -127,14 +248,23 @@ Scan the codebase structure, detect frameworks and patterns, then generate custo
|
|
|
127
248
|
console.log(chalk.bold(' Claude Code Usage:'));
|
|
128
249
|
console.log(' CLAUDE.md is auto-loaded every session');
|
|
129
250
|
console.log(' .claude/rules/ are loaded based on file context');
|
|
130
|
-
console.log(' Use /analyze slash command for project analysis');
|
|
131
251
|
console.log('');
|
|
132
|
-
console.log(chalk.dim('
|
|
133
|
-
console.log(chalk.dim('
|
|
134
|
-
console.log(chalk.dim('
|
|
135
|
-
console.log(chalk.dim('
|
|
136
|
-
console.log(chalk.dim('
|
|
137
|
-
console.log(chalk.dim('
|
|
252
|
+
console.log(chalk.dim(' Slash commands:'));
|
|
253
|
+
console.log(chalk.dim(' /analyze — Analyze project and generate standards'));
|
|
254
|
+
console.log(chalk.dim(' /review — Review current changes'));
|
|
255
|
+
console.log(chalk.dim(' /fix — Diagnose and fix a bug'));
|
|
256
|
+
console.log(chalk.dim(' /refactor — Refactor code structure'));
|
|
257
|
+
console.log(chalk.dim(' /test — Generate or run tests'));
|
|
258
|
+
console.log(chalk.dim(' /doc — Add documentation'));
|
|
259
|
+
console.log(chalk.dim(''));
|
|
260
|
+
console.log(chalk.dim(' Squad (multi-agent workflow):'));
|
|
261
|
+
console.log(chalk.dim(' /squad "task" — Kickoff: create handoff + PO spec'));
|
|
262
|
+
console.log(chalk.dim(' /squad-architect — Design the implementation plan'));
|
|
263
|
+
console.log(chalk.dim(' /squad-dev — Implement the code'));
|
|
264
|
+
console.log(chalk.dim(' /squad-test — Write and run tests'));
|
|
265
|
+
console.log(chalk.dim(' /squad-review — Review and write verdict'));
|
|
266
|
+
console.log(chalk.dim(' /squad-batch — Batch kickoff: PO specs for multiple tasks'));
|
|
267
|
+
console.log(chalk.dim(' /squad-run — Auto-run pipeline for batch tasks'));
|
|
138
268
|
}
|
|
139
269
|
}
|
|
140
270
|
|
|
@@ -12,6 +12,19 @@ class CursorIntegration extends BaseIntegration {
|
|
|
12
12
|
'.cursor/rules/contextkit-testing.mdc',
|
|
13
13
|
'.cursor/rules/contextkit-components.mdc',
|
|
14
14
|
'.cursor/rules/contextkit-api.mdc',
|
|
15
|
+
'.cursor/prompts/analyze.md',
|
|
16
|
+
'.cursor/prompts/review.md',
|
|
17
|
+
'.cursor/prompts/fix.md',
|
|
18
|
+
'.cursor/prompts/refactor.md',
|
|
19
|
+
'.cursor/prompts/test.md',
|
|
20
|
+
'.cursor/prompts/doc.md',
|
|
21
|
+
'.cursor/prompts/squad.md',
|
|
22
|
+
'.cursor/prompts/squad-architect.md',
|
|
23
|
+
'.cursor/prompts/squad-dev.md',
|
|
24
|
+
'.cursor/prompts/squad-test.md',
|
|
25
|
+
'.cursor/prompts/squad-review.md',
|
|
26
|
+
'.cursor/prompts/squad-batch.md',
|
|
27
|
+
'.cursor/prompts/squad-run.md',
|
|
15
28
|
];
|
|
16
29
|
this.bridgeFiles = [];
|
|
17
30
|
this.platformDir = '.cursor/rules';
|
|
@@ -19,6 +32,7 @@ class CursorIntegration extends BaseIntegration {
|
|
|
19
32
|
|
|
20
33
|
async install() {
|
|
21
34
|
await super.install();
|
|
35
|
+
await fs.ensureDir('.cursor/prompts');
|
|
22
36
|
// Remove old monolithic rule file if present
|
|
23
37
|
await this.removeLegacyFiles();
|
|
24
38
|
}
|
|
@@ -142,20 +156,122 @@ Reference: @.contextkit/standards/architecture.md
|
|
|
142
156
|
- @.contextkit/commands/create-feature.md — Create feature workflow
|
|
143
157
|
`;
|
|
144
158
|
await this.writeGeneratedFile('.cursor/rules/contextkit-api.mdc', apiRule);
|
|
159
|
+
|
|
160
|
+
// Cursor prompts — reusable slash commands in Cursor Chat
|
|
161
|
+
await this.writeGeneratedFile('.cursor/prompts/analyze.md', `# Analyze Project
|
|
162
|
+
|
|
163
|
+
Read \`.contextkit/commands/analyze.md\` and execute the analysis workflow for this project.
|
|
164
|
+
|
|
165
|
+
Scan the codebase structure, detect frameworks and patterns, then generate customized standards files in \`.contextkit/standards/\`.
|
|
166
|
+
`);
|
|
167
|
+
|
|
168
|
+
await this.writeGeneratedFile('.cursor/prompts/review.md', `# Code Review
|
|
169
|
+
|
|
170
|
+
Read \`.contextkit/commands/review.md\` and execute the review workflow.
|
|
171
|
+
|
|
172
|
+
Review current changes for correctness, standards compliance, and potential issues. Flag bugs, security concerns, and standards violations.
|
|
173
|
+
`);
|
|
174
|
+
|
|
175
|
+
await this.writeGeneratedFile('.cursor/prompts/fix.md', `# Fix Bug
|
|
176
|
+
|
|
177
|
+
Read \`.contextkit/commands/fix.md\` and execute the bug fix workflow.
|
|
178
|
+
|
|
179
|
+
Diagnose the root cause, implement the minimal fix, and add a regression test.
|
|
180
|
+
`);
|
|
181
|
+
|
|
182
|
+
await this.writeGeneratedFile('.cursor/prompts/refactor.md', `# Refactor
|
|
183
|
+
|
|
184
|
+
Read \`.contextkit/commands/refactor.md\` and execute the refactoring workflow.
|
|
185
|
+
|
|
186
|
+
Improve code structure without changing behavior, keeping tests green at every step.
|
|
187
|
+
`);
|
|
188
|
+
|
|
189
|
+
await this.writeGeneratedFile('.cursor/prompts/test.md', `# Run Tests
|
|
190
|
+
|
|
191
|
+
Read \`.contextkit/commands/run-tests.md\` and execute the testing workflow.
|
|
192
|
+
|
|
193
|
+
Generate or run tests for the specified code, covering happy paths, edge cases, and errors.
|
|
194
|
+
`);
|
|
195
|
+
|
|
196
|
+
await this.writeGeneratedFile('.cursor/prompts/doc.md', `# Add Documentation
|
|
197
|
+
|
|
198
|
+
Read \`.contextkit/commands/add-documentation.md\` and execute the documentation workflow.
|
|
199
|
+
|
|
200
|
+
Add inline docs, README sections, and usage examples for the specified code.
|
|
201
|
+
`);
|
|
202
|
+
|
|
203
|
+
// Squad prompts
|
|
204
|
+
await this.writeGeneratedFile('.cursor/prompts/squad.md', `# Squad — Kickoff
|
|
205
|
+
|
|
206
|
+
Read \`.contextkit/commands/squad.md\` and execute the squad kickoff workflow.
|
|
207
|
+
|
|
208
|
+
Create the handoff file and write the PO spec for the given task. Pass the user's task description as the input.
|
|
209
|
+
`);
|
|
210
|
+
|
|
211
|
+
await this.writeGeneratedFile('.cursor/prompts/squad-architect.md', `# Squad — Architect
|
|
212
|
+
|
|
213
|
+
Read \`.contextkit/commands/squad-architect.md\` and execute the architect workflow.
|
|
214
|
+
|
|
215
|
+
Read the PO spec from the handoff file, design the technical approach, and write the implementation plan.
|
|
216
|
+
`);
|
|
217
|
+
|
|
218
|
+
await this.writeGeneratedFile('.cursor/prompts/squad-dev.md', `# Squad — Dev
|
|
219
|
+
|
|
220
|
+
Read \`.contextkit/commands/squad-dev.md\` and execute the dev workflow.
|
|
221
|
+
|
|
222
|
+
Follow the architect's plan to implement the code changes.
|
|
223
|
+
`);
|
|
224
|
+
|
|
225
|
+
await this.writeGeneratedFile('.cursor/prompts/squad-test.md', `# Squad — Test
|
|
226
|
+
|
|
227
|
+
Read \`.contextkit/commands/squad-test.md\` and execute the test workflow.
|
|
228
|
+
|
|
229
|
+
Write and run tests against the PO's acceptance criteria.
|
|
230
|
+
`);
|
|
231
|
+
|
|
232
|
+
await this.writeGeneratedFile('.cursor/prompts/squad-review.md', `# Squad — Review
|
|
233
|
+
|
|
234
|
+
Read \`.contextkit/commands/squad-review.md\` and execute the review workflow.
|
|
235
|
+
|
|
236
|
+
Review the full handoff (spec, plan, implementation, tests) and write the final verdict.
|
|
237
|
+
`);
|
|
238
|
+
|
|
239
|
+
await this.writeGeneratedFile('.cursor/prompts/squad-batch.md', `# Squad Batch — Multi-Task Kickoff
|
|
240
|
+
|
|
241
|
+
Read \`.contextkit/commands/squad-batch.md\` and execute the batch kickoff workflow.
|
|
242
|
+
|
|
243
|
+
Create handoff files for multiple tasks and write PO specs for each one. Pass all task descriptions as the input.
|
|
244
|
+
`);
|
|
245
|
+
|
|
246
|
+
await this.writeGeneratedFile('.cursor/prompts/squad-run.md', `# Squad Run — Auto-Run Pipeline
|
|
247
|
+
|
|
248
|
+
Read \`.contextkit/commands/squad-run.md\` and execute the pipeline runner workflow.
|
|
249
|
+
|
|
250
|
+
Process all batch tasks through the remaining pipeline steps (Architect, Dev, Test, Review) sequentially.
|
|
251
|
+
`);
|
|
145
252
|
}
|
|
146
253
|
|
|
147
254
|
showUsage() {
|
|
148
255
|
console.log('');
|
|
149
256
|
console.log(chalk.bold(' Cursor Usage:'));
|
|
150
257
|
console.log(' Rules auto-load based on file context');
|
|
151
|
-
console.log(' In Cursor Chat: @.contextkit/commands/analyze.md');
|
|
152
|
-
console.log(' Or: @.contextkit Create a button component');
|
|
153
258
|
console.log('');
|
|
154
|
-
console.log(chalk.dim('
|
|
155
|
-
console.log(chalk.dim('
|
|
156
|
-
console.log(chalk.dim('
|
|
157
|
-
console.log(chalk.dim('
|
|
158
|
-
console.log(chalk.dim('
|
|
259
|
+
console.log(chalk.dim(' Slash commands (in Cursor Chat):'));
|
|
260
|
+
console.log(chalk.dim(' /analyze — Analyze project and generate standards'));
|
|
261
|
+
console.log(chalk.dim(' /review — Review current changes'));
|
|
262
|
+
console.log(chalk.dim(' /fix — Diagnose and fix a bug'));
|
|
263
|
+
console.log(chalk.dim(' /refactor — Refactor code structure'));
|
|
264
|
+
console.log(chalk.dim(' /test — Generate or run tests'));
|
|
265
|
+
console.log(chalk.dim(' /doc — Add documentation'));
|
|
266
|
+
console.log(chalk.dim(''));
|
|
267
|
+
console.log(chalk.dim(' Squad (multi-agent workflow):'));
|
|
268
|
+
console.log(chalk.dim(' /squad "task" — Kickoff: create handoff + PO spec'));
|
|
269
|
+
console.log(chalk.dim(' /squad-architect — Design the implementation plan'));
|
|
270
|
+
console.log(chalk.dim(' /squad-dev — Implement the code'));
|
|
271
|
+
console.log(chalk.dim(' /squad-test — Write and run tests'));
|
|
272
|
+
console.log(chalk.dim(' /squad-review — Review and write verdict'));
|
|
273
|
+
console.log(chalk.dim(' /squad-batch — Batch kickoff: PO specs for multiple tasks'));
|
|
274
|
+
console.log(chalk.dim(' /squad-run — Auto-run pipeline for batch tasks'));
|
|
159
275
|
}
|
|
160
276
|
}
|
|
161
277
|
|
package/lib/utils/git-hooks.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
1
2
|
const fs = require('fs-extra');
|
|
2
3
|
const chalk = require('chalk');
|
|
3
4
|
|
|
4
5
|
class GitHooksManager {
|
|
5
6
|
constructor() {
|
|
6
|
-
this.
|
|
7
|
+
this.hooksPath = '.contextkit/hooks';
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
async installHooks(packageManager, hookChoices = { prePush: true, commitMsg: true }) {
|
|
@@ -19,8 +20,24 @@ class GitHooksManager {
|
|
|
19
20
|
// Clean up legacy Husky directory if present
|
|
20
21
|
await this.cleanupLegacyHusky();
|
|
21
22
|
|
|
22
|
-
//
|
|
23
|
-
await this.
|
|
23
|
+
// Clean up legacy .git/hooks/ files from previous ContextKit versions
|
|
24
|
+
await this.cleanupLegacyGitHooks();
|
|
25
|
+
|
|
26
|
+
// Remove hooks the user didn't select
|
|
27
|
+
await this.removeUnselectedHooks(hookChoices);
|
|
28
|
+
|
|
29
|
+
// Set core.hooksPath so git uses .contextkit/hooks/ directly
|
|
30
|
+
execSync(`git config core.hooksPath ${this.hooksPath}`, { stdio: 'pipe' });
|
|
31
|
+
console.log(chalk.green(`✅ Git hooks path set to ${this.hooksPath}`));
|
|
32
|
+
|
|
33
|
+
// Add prepare script to package.json for automatic setup on npm install
|
|
34
|
+
await this.addPrepareScript();
|
|
35
|
+
|
|
36
|
+
// Show non-Node setup hint if no package.json
|
|
37
|
+
if (!fs.existsSync('package.json')) {
|
|
38
|
+
console.log(chalk.dim(' 💡 For other developers, add to your setup:'));
|
|
39
|
+
console.log(chalk.dim(` git config core.hooksPath ${this.hooksPath}`));
|
|
40
|
+
}
|
|
24
41
|
|
|
25
42
|
console.log(chalk.green('✅ Git hooks setup complete'));
|
|
26
43
|
|
|
@@ -30,45 +47,49 @@ class GitHooksManager {
|
|
|
30
47
|
}
|
|
31
48
|
}
|
|
32
49
|
|
|
33
|
-
async
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const content = await fs.readFile(legacyPreCommitHook, 'utf8');
|
|
41
|
-
if (content.includes('.contextkit/') || content.includes('.vibe-kit/')) {
|
|
42
|
-
await fs.remove(legacyPreCommitHook);
|
|
43
|
-
console.log(chalk.yellow('🧹 Removed legacy pre-commit hook (replaced by pre-push)'));
|
|
50
|
+
async removeUnselectedHooks(hookChoices) {
|
|
51
|
+
// If user didn't select a hook, remove it from .contextkit/hooks/
|
|
52
|
+
// so core.hooksPath doesn't run hooks they didn't want
|
|
53
|
+
if (!hookChoices.prePush) {
|
|
54
|
+
const hookPath = `${this.hooksPath}/pre-push`;
|
|
55
|
+
if (fs.existsSync(hookPath)) {
|
|
56
|
+
await fs.remove(hookPath);
|
|
44
57
|
}
|
|
45
58
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (hookChoices.commitMsg) {
|
|
52
|
-
await this.addNativeHook('commit-msg', '.contextkit/hooks/commit-msg.sh');
|
|
59
|
+
if (!hookChoices.commitMsg) {
|
|
60
|
+
const hookPath = `${this.hooksPath}/commit-msg`;
|
|
61
|
+
if (fs.existsSync(hookPath)) {
|
|
62
|
+
await fs.remove(hookPath);
|
|
63
|
+
}
|
|
53
64
|
}
|
|
54
65
|
}
|
|
55
66
|
|
|
56
|
-
async
|
|
57
|
-
|
|
67
|
+
async addPrepareScript() {
|
|
68
|
+
if (!fs.existsSync('package.json')) return;
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const pkg = await fs.readJson('package.json');
|
|
72
|
+
const prepareCmd = `git config core.hooksPath ${this.hooksPath}`;
|
|
58
73
|
|
|
59
|
-
|
|
60
|
-
await fs.ensureDir(this.hooksDir);
|
|
74
|
+
if (!pkg.scripts) pkg.scripts = {};
|
|
61
75
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
`;
|
|
76
|
+
// Don't overwrite if prepare already has our command
|
|
77
|
+
if (pkg.scripts.prepare && pkg.scripts.prepare.includes('core.hooksPath')) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
67
80
|
|
|
68
|
-
|
|
69
|
-
|
|
81
|
+
// Append to existing prepare script or create new one
|
|
82
|
+
if (pkg.scripts.prepare) {
|
|
83
|
+
pkg.scripts.prepare = `${pkg.scripts.prepare} && ${prepareCmd}`;
|
|
84
|
+
} else {
|
|
85
|
+
pkg.scripts.prepare = prepareCmd;
|
|
86
|
+
}
|
|
70
87
|
|
|
71
|
-
|
|
88
|
+
await fs.writeJson('package.json', pkg, { spaces: 2 });
|
|
89
|
+
console.log(chalk.green('✅ Added prepare script to package.json'));
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.log(chalk.yellow('⚠️ Could not update package.json prepare script'));
|
|
92
|
+
}
|
|
72
93
|
}
|
|
73
94
|
|
|
74
95
|
async cleanupLegacyHusky() {
|
|
@@ -91,24 +112,21 @@ ${scriptPath} "$@"
|
|
|
91
112
|
|
|
92
113
|
if (hasContextKitHooks) {
|
|
93
114
|
await fs.remove('.husky');
|
|
94
|
-
console.log(chalk.yellow('🧹 Removed legacy .husky/ directory
|
|
115
|
+
console.log(chalk.yellow('🧹 Removed legacy .husky/ directory'));
|
|
95
116
|
console.log(chalk.dim(' 💡 You can also run: npm uninstall husky'));
|
|
96
117
|
}
|
|
97
118
|
}
|
|
98
119
|
|
|
99
|
-
async
|
|
120
|
+
async cleanupLegacyGitHooks() {
|
|
121
|
+
// Remove wrapper hooks from .git/hooks/ left by previous ContextKit versions
|
|
100
122
|
const hooks = ['pre-push', 'commit-msg'];
|
|
101
|
-
|
|
102
123
|
for (const hook of hooks) {
|
|
103
|
-
const hookPath =
|
|
124
|
+
const hookPath = `.git/hooks/${hook}`;
|
|
104
125
|
if (fs.existsSync(hookPath)) {
|
|
105
|
-
// Don't back up our own hooks
|
|
106
126
|
const content = await fs.readFile(hookPath, 'utf8');
|
|
107
|
-
if (content.includes('ContextKit managed hook'))
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
await fs.copy(hookPath, backupPath);
|
|
111
|
-
console.log(chalk.yellow(`📦 Backed up existing hook: ${hook}`));
|
|
127
|
+
if (content.includes('ContextKit managed hook')) {
|
|
128
|
+
await fs.remove(hookPath);
|
|
129
|
+
}
|
|
112
130
|
}
|
|
113
131
|
}
|
|
114
132
|
}
|
|
@@ -116,19 +134,41 @@ ${scriptPath} "$@"
|
|
|
116
134
|
async uninstallHooks() {
|
|
117
135
|
console.log(chalk.yellow('🪝 Removing Git hooks...'));
|
|
118
136
|
|
|
119
|
-
|
|
137
|
+
// Unset core.hooksPath
|
|
138
|
+
try {
|
|
139
|
+
execSync('git config --unset core.hooksPath', { stdio: 'pipe' });
|
|
140
|
+
console.log(chalk.green('✅ Removed core.hooksPath config'));
|
|
141
|
+
} catch (error) {
|
|
142
|
+
// Already unset, that's fine
|
|
143
|
+
}
|
|
120
144
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const backupPath = `${hookPath}.backup`;
|
|
145
|
+
// Remove prepare script from package.json
|
|
146
|
+
await this.removePrepareScript();
|
|
124
147
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
148
|
+
console.log(chalk.green('✅ Git hooks removed'));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async removePrepareScript() {
|
|
152
|
+
if (!fs.existsSync('package.json')) return;
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
const pkg = await fs.readJson('package.json');
|
|
156
|
+
if (!pkg.scripts?.prepare) return;
|
|
157
|
+
|
|
158
|
+
const prepareCmd = `git config core.hooksPath ${this.hooksPath}`;
|
|
159
|
+
|
|
160
|
+
if (pkg.scripts.prepare === prepareCmd) {
|
|
161
|
+
delete pkg.scripts.prepare;
|
|
162
|
+
} else if (pkg.scripts.prepare.includes(prepareCmd)) {
|
|
163
|
+
// Remove our command from a chained prepare script
|
|
164
|
+
pkg.scripts.prepare = pkg.scripts.prepare
|
|
165
|
+
.replace(` && ${prepareCmd}`, '')
|
|
166
|
+
.replace(`${prepareCmd} && `, '');
|
|
131
167
|
}
|
|
168
|
+
|
|
169
|
+
await fs.writeJson('package.json', pkg, { spaces: 2 });
|
|
170
|
+
} catch (error) {
|
|
171
|
+
// Best effort
|
|
132
172
|
}
|
|
133
173
|
}
|
|
134
174
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nolrm/contextkit",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.6",
|
|
4
4
|
"description": "ContextKit - Context Engineering for AI Development. Provide rich context to AI through structured MD files with standards, code guides, and documentation. Works with Cursor, Claude, Aider, VS Code Copilot, and more.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|