claude-raid 0.2.7 → 0.2.8
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 +84 -23
- package/bin/cli.js +4 -2
- package/package.json +1 -1
- package/src/descriptions.js +10 -7
- package/src/init.js +36 -5
- package/src/merge-settings.js +43 -1
- package/src/remove.js +1 -1
- package/src/setup.js +32 -0
- package/src/ui.js +1 -0
- package/src/update.js +26 -3
- package/template/.claude/agents/archer.md +18 -4
- package/template/.claude/agents/rogue.md +18 -4
- package/template/.claude/agents/warrior.md +18 -4
- package/template/.claude/agents/wizard.md +32 -5
- package/template/.claude/dungeon-master-rules.md +120 -31
- package/template/.claude/hooks/raid-lib.sh +45 -4
- package/template/.claude/hooks/raid-pre-compact.sh +8 -4
- package/template/.claude/hooks/raid-session-end.sh +2 -2
- package/template/.claude/hooks/raid-session-start.sh +2 -0
- package/template/.claude/hooks/rtk-bridge.sh +46 -0
- package/template/.claude/hooks/validate-dungeon.sh +11 -3
- package/template/.claude/hooks/validate-file-naming.sh +6 -1
- package/template/.claude/hooks/validate-no-placeholders.sh +13 -2
- package/template/.claude/hooks/validate-write-gate.sh +7 -2
- package/template/.claude/party-rules.md +91 -65
- package/template/.claude/skills/raid-browser/SKILL.md +3 -5
- package/template/.claude/skills/raid-browser-chrome/SKILL.md +1 -1
- package/template/.claude/skills/raid-canonical-design/SKILL.md +309 -162
- package/template/.claude/skills/raid-canonical-implementation/SKILL.md +157 -132
- package/template/.claude/skills/raid-canonical-implementation-plan/SKILL.md +196 -141
- package/template/.claude/skills/raid-canonical-prd/SKILL.md +92 -89
- package/template/.claude/skills/raid-canonical-protocol/SKILL.md +29 -123
- package/template/.claude/skills/raid-canonical-review/SKILL.md +292 -148
- package/template/.claude/skills/raid-debugging/SKILL.md +1 -7
- package/template/.claude/skills/raid-init/SKILL.md +7 -5
- package/template/.claude/skills/raid-tdd/SKILL.md +5 -5
- package/template/.claude/skills/raid-teambuff/SKILL.md +6 -24
- package/template/.claude/skills/raid-verification/SKILL.md +0 -6
- package/template/.claude/skills/raid-wrap-up/SKILL.md +30 -29
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[](#)
|
|
9
9
|
[](#prerequisites)
|
|
10
|
-
[](#)
|
|
11
11
|
|
|
12
12
|
> **Beta** — This project is in active development. Multi-agent sessions are **token-usage intensive** — a full Canonical Quest consumes significantly more tokens than a single-agent workflow. Monitor your usage and start with small tasks to calibrate.
|
|
13
13
|
|
|
@@ -44,6 +44,9 @@ claude-raid start
|
|
|
44
44
|
```bash
|
|
45
45
|
# Preview what gets installed (no changes)
|
|
46
46
|
npx claude-raid summon --dry-run
|
|
47
|
+
|
|
48
|
+
# Install with RTK token compression (optional)
|
|
49
|
+
npx claude-raid summon --rtk
|
|
47
50
|
```
|
|
48
51
|
|
|
49
52
|
### Prerequisites
|
|
@@ -93,31 +96,31 @@ flowchart LR
|
|
|
93
96
|
|
|
94
97
|
Agents research the problem space and produce a complete Product Requirements Document. No code. The Wizard mediates questions between agents and the human.
|
|
95
98
|
|
|
96
|
-
**Output:** `
|
|
99
|
+
**Output:** `spoils/prd.md`
|
|
97
100
|
|
|
98
101
|
### Phase 2 — Design
|
|
99
102
|
|
|
100
103
|
Agents explore design approaches from competing angles. Each brings their lens — the Warrior stress-tests architecture choices, the Archer traces ripple effects, the Rogue attacks assumptions. The design survives only if it withstands all three.
|
|
101
104
|
|
|
102
|
-
**Output:** `phase-2-design.md`
|
|
105
|
+
**Output:** `phases/phase-2-design.md` (evolution log) + `spoils/design.md` (polished deliverable)
|
|
103
106
|
|
|
104
107
|
### Phase 3 — Plan
|
|
105
108
|
|
|
106
109
|
Agents decompose the approved design into discrete, testable tasks. They fight over ordering, scope boundaries, naming, and test coverage until the plan earns consensus.
|
|
107
110
|
|
|
108
|
-
**Output:** `phase-3-plan.md` +
|
|
111
|
+
**Output:** `phases/phase-3-plan.md` + `spoils/tasks/phase-3-plan-task-NN.md`
|
|
109
112
|
|
|
110
113
|
### Phase 4 — Implementation
|
|
111
114
|
|
|
112
115
|
The Wizard assigns tasks in batches. One agent builds each task using strict **TDD** (RED-GREEN-REFACTOR). The others cross-test the implementation — reading code, running tests, and challenging decisions. Every task earns approval before the next batch starts.
|
|
113
116
|
|
|
114
|
-
**Output:** `phase-4-implementation.md` + committed, tested code
|
|
117
|
+
**Output:** `phases/phase-4-implementation.md` + committed, tested code
|
|
115
118
|
|
|
116
119
|
### Phase 5 — Review *(optional)*
|
|
117
120
|
|
|
118
121
|
Two sub-phases: **Pinning** (find issues) and **Fixing** (resolve them). Agents review independently, then fight over findings *and* missing findings. Critical and Important issues must be fixed. The **Black Card** system handles breaking architectural concerns.
|
|
119
122
|
|
|
120
|
-
**Output:** `phase-5-review.md`
|
|
123
|
+
**Output:** `phases/phase-5-review.md` + `spoils/review.md`
|
|
121
124
|
|
|
122
125
|
### Phase 6 — Wrap Up
|
|
123
126
|
|
|
@@ -146,6 +149,8 @@ Four agents, each with a distinct lens. They collaborate through rigor, not agre
|
|
|
146
149
|
</tr>
|
|
147
150
|
</table>
|
|
148
151
|
|
|
152
|
+
All agents run on Claude Opus 4.6.
|
|
153
|
+
|
|
149
154
|
### How They Work Together
|
|
150
155
|
|
|
151
156
|
```mermaid
|
|
@@ -196,14 +201,21 @@ The Dungeon is the team's shared knowledge artifact — a curated board where ag
|
|
|
196
201
|
|
|
197
202
|
```
|
|
198
203
|
.claude/dungeon/{quest-slug}/ # Active quest artifacts
|
|
199
|
-
├──
|
|
200
|
-
├── phase-2-design.md
|
|
201
|
-
├── phase-3-plan.md
|
|
202
|
-
├── phase-
|
|
203
|
-
|
|
204
|
-
├──
|
|
204
|
+
├── phases/ # Evolution logs (scoreboards)
|
|
205
|
+
│ ├── phase-2-design.md
|
|
206
|
+
│ ├── phase-3-plan.md
|
|
207
|
+
│ ├── phase-4-implementation.md
|
|
208
|
+
│ └── phase-5-review.md
|
|
209
|
+
├── spoils/ # Polished deliverables
|
|
210
|
+
│ ├── prd.md
|
|
211
|
+
│ ├── design.md
|
|
212
|
+
│ ├── review.md
|
|
213
|
+
│ └── tasks/
|
|
214
|
+
│ └── phase-3-plan-task-NN.md
|
|
215
|
+
├── backups/ # Pre-compact safety copies
|
|
216
|
+
│ └── phase-N-{name}-backup.md
|
|
205
217
|
├── phase-6-wrap-up.md # Quest storyboard
|
|
206
|
-
├── teambuff-
|
|
218
|
+
├── teambuff-NN.md # Team retrospective reports (on-demand)
|
|
207
219
|
└── teambuff-rulings.md # Active rulings from teambuffs
|
|
208
220
|
|
|
209
221
|
.claude/vault/{quest-slug}/ # Archived completed quests
|
|
@@ -244,7 +256,8 @@ The Dungeon is the team's shared knowledge artifact — a curated board where ag
|
|
|
244
256
|
│ ├── validate-no-placeholders.sh # No TBD/TODO in specs
|
|
245
257
|
│ ├── validate-dungeon.sh # Multi-agent verification on pins
|
|
246
258
|
│ ├── validate-browser-tests-exist.sh # Playwright test detection
|
|
247
|
-
│
|
|
259
|
+
│ ├── validate-browser-cleanup.sh # Browser process cleanup
|
|
260
|
+
│ └── rtk-bridge.sh # Token compression via RTK (opt-in)
|
|
248
261
|
└── skills/
|
|
249
262
|
├── raid-init/ # Quest selection and session setup
|
|
250
263
|
├── raid-canonical-protocol/ # Canonical Quest rules and signals
|
|
@@ -268,24 +281,27 @@ The Dungeon is the team's shared knowledge artifact — a curated board where ag
|
|
|
268
281
|
|
|
269
282
|
The Wizard orchestrates. Warrior, Archer, and Rogue each bring a specialized lens. All agents run on Claude Opus 4.6.
|
|
270
283
|
|
|
271
|
-
### Hooks (
|
|
284
|
+
### Hooks (13)
|
|
272
285
|
|
|
273
286
|
Hooks enforce workflow discipline automatically and **only activate during Raid sessions** — they never interfere with normal coding.
|
|
274
287
|
|
|
275
|
-
**Lifecycle hooks** manage session start/end, quest directory creation, vault archival,
|
|
288
|
+
**Lifecycle hooks** (5) manage session start/end, quest directory creation, vault archival, context compaction backup, and task validation. All source `raid-lib.sh` for shared config.
|
|
276
289
|
|
|
277
|
-
**Quality gate hooks** enforce conventional commits, phase-based write protection, naming conventions, placeholder blocking, multi-agent verification on dungeon pins, and browser
|
|
290
|
+
**Quality gate hooks** (7) enforce conventional commits, phase-based write protection, naming conventions, placeholder blocking, multi-agent verification on dungeon pins, browser test detection, and browser process cleanup.
|
|
291
|
+
|
|
292
|
+
**Optional hooks** (1): `rtk-bridge.sh` provides token compression via RTK — enabled with `--rtk` during summon.
|
|
278
293
|
|
|
279
294
|
All hooks are POSIX-compatible and use `#claude-raid` markers to coexist safely with your existing hooks.
|
|
280
295
|
|
|
281
296
|
### Skills (14)
|
|
282
297
|
|
|
283
|
-
Skills guide agent behavior across the workflow.
|
|
298
|
+
Skills guide agent behavior across the workflow. Five categories:
|
|
284
299
|
|
|
285
300
|
| Category | Skills | Purpose |
|
|
286
301
|
|:--|:--|:--|
|
|
287
302
|
| **Core** | `raid-init` | Quest selection, greeting, session bootstrap |
|
|
288
|
-
| **
|
|
303
|
+
| **Protocol** | `raid-canonical-protocol` | Phase lifecycle rules, transition gates, signals |
|
|
304
|
+
| **Canonical Quest** | 6 phase skills | One skill per phase, chained in order |
|
|
289
305
|
| **Discipline** | `raid-tdd`, `raid-verification`, `raid-debugging` | Quest-agnostic enforcement — invoked within any phase |
|
|
290
306
|
| **Browser** | `raid-browser`, `raid-browser-chrome` | Browser orchestration and live inspection |
|
|
291
307
|
| **Team** | `raid-teambuff` | Emergency team retrospective — freezes quest, all agents reflect on dysfunction, produces binding rulings |
|
|
@@ -301,6 +317,10 @@ Skills guide agent behavior across the workflow. Four categories:
|
|
|
301
317
|
"project": {
|
|
302
318
|
"name": "my-project",
|
|
303
319
|
"language": "typescript",
|
|
320
|
+
"packageManager": "npm",
|
|
321
|
+
"runCommand": "npm run",
|
|
322
|
+
"execCommand": "npx",
|
|
323
|
+
"installCommand": "npm add",
|
|
304
324
|
"testCommand": "npm test",
|
|
305
325
|
"lintCommand": "npm run lint",
|
|
306
326
|
"buildCommand": "npm run build"
|
|
@@ -311,14 +331,20 @@ Skills guide agent behavior across the workflow. Four categories:
|
|
|
311
331
|
"worktrees": ".worktrees"
|
|
312
332
|
},
|
|
313
333
|
"conventions": {
|
|
314
|
-
"fileNaming": "
|
|
334
|
+
"fileNaming": "none",
|
|
315
335
|
"commits": "conventional"
|
|
316
336
|
},
|
|
317
337
|
"raid": {
|
|
318
338
|
"defaultMode": "full",
|
|
339
|
+
"agentEffort": "medium",
|
|
319
340
|
"vault": { "path": ".claude/vault", "enabled": true },
|
|
320
341
|
"lifecycle": {
|
|
321
342
|
"autoSessionManagement": true,
|
|
343
|
+
"teammateNudge": true,
|
|
344
|
+
"taskValidation": true,
|
|
345
|
+
"completionGate": true,
|
|
346
|
+
"phaseTransitionConfirm": true,
|
|
347
|
+
"compactBackup": true,
|
|
322
348
|
"testWindowMinutes": 10
|
|
323
349
|
}
|
|
324
350
|
}
|
|
@@ -342,6 +368,9 @@ Package manager is auto-detected (npm, pnpm, yarn, bun, uv, poetry). Commands ar
|
|
|
342
368
|
|
|
343
369
|
| Key | Default | Description |
|
|
344
370
|
|:--|:--|:--|
|
|
371
|
+
| `project.name` | auto-detected | Project name |
|
|
372
|
+
| `project.language` | auto-detected | Primary language |
|
|
373
|
+
| `project.packageManager` | auto-detected | npm, pnpm, yarn, bun, uv, or poetry |
|
|
345
374
|
| `project.testCommand` | auto-detected | Command to run tests |
|
|
346
375
|
| `project.lintCommand` | auto-detected | Command to run linting |
|
|
347
376
|
| `project.buildCommand` | auto-detected | Command to build |
|
|
@@ -350,8 +379,18 @@ Package manager is auto-detected (npm, pnpm, yarn, bun, uv, poetry). Commands ar
|
|
|
350
379
|
| `paths.worktrees` | `.worktrees` | Git worktree directory |
|
|
351
380
|
| `conventions.fileNaming` | `none` | `kebab-case`, `snake_case`, `camelCase`, or `none` |
|
|
352
381
|
| `conventions.commits` | `conventional` | Commit message format |
|
|
353
|
-
| `conventions.commitMinLength` | `15` | Minimum commit message length |
|
|
354
|
-
| `conventions.maxDepth` | `8` | Maximum file nesting depth |
|
|
382
|
+
| `conventions.commitMinLength` | `15` | Minimum commit message length (set manually) |
|
|
383
|
+
| `conventions.maxDepth` | `8` | Maximum file nesting depth (set manually) |
|
|
384
|
+
| `raid.defaultMode` | `full` | Default quest mode |
|
|
385
|
+
| `raid.agentEffort` | `medium` | Agent reasoning effort level |
|
|
386
|
+
| `raid.vault.enabled` | `true` | Archive completed quests to vault |
|
|
387
|
+
| `raid.vault.path` | `.claude/vault` | Vault directory path |
|
|
388
|
+
| `raid.lifecycle.autoSessionManagement` | `true` | Auto-manage session start/end |
|
|
389
|
+
| `raid.lifecycle.teammateNudge` | `true` | Nudge agents to use teammate mode |
|
|
390
|
+
| `raid.lifecycle.taskValidation` | `true` | Validate task subjects are meaningful |
|
|
391
|
+
| `raid.lifecycle.completionGate` | `true` | Require verification before completion claims |
|
|
392
|
+
| `raid.lifecycle.phaseTransitionConfirm` | `true` | Confirm before phase transitions |
|
|
393
|
+
| `raid.lifecycle.compactBackup` | `true` | Back up dungeon before context compaction |
|
|
355
394
|
| `raid.lifecycle.testWindowMinutes` | `10` | Max age (minutes) of test run for verification |
|
|
356
395
|
|
|
357
396
|
</details>
|
|
@@ -368,13 +407,34 @@ When a browser framework is detected (Next.js, Vite, Angular, etc.), a `browser`
|
|
|
368
407
|
"devCommand": "npm run dev",
|
|
369
408
|
"baseUrl": "http://localhost:3000",
|
|
370
409
|
"defaultPort": 3000,
|
|
371
|
-
"
|
|
410
|
+
"portRange": [3001, 3005],
|
|
411
|
+
"playwrightConfig": "playwright.config.ts",
|
|
412
|
+
"auth": null,
|
|
413
|
+
"startup": null
|
|
372
414
|
}
|
|
373
415
|
}
|
|
374
416
|
```
|
|
375
417
|
|
|
376
418
|
This enables browser-specific hooks and skills — Playwright test detection, browser process cleanup, and live Chrome inspection during reviews.
|
|
377
419
|
|
|
420
|
+
### RTK Token Compression
|
|
421
|
+
|
|
422
|
+
When installed with `--rtk`, an `rtk` section is added to `raid.json`:
|
|
423
|
+
|
|
424
|
+
```json
|
|
425
|
+
{
|
|
426
|
+
"rtk": {
|
|
427
|
+
"enabled": true,
|
|
428
|
+
"bypass": {
|
|
429
|
+
"phases": [],
|
|
430
|
+
"commands": []
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
RTK compresses token usage via a fail-open bridge hook. Bypass specific phases or command prefixes by editing the arrays. Requires the `rtk` binary to be installed separately.
|
|
437
|
+
|
|
378
438
|
---
|
|
379
439
|
|
|
380
440
|
## CLI Reference
|
|
@@ -404,6 +464,7 @@ Installs the full Raid system. Auto-detects project type, copies agents/hooks/sk
|
|
|
404
464
|
- Never overwrites existing files — customized agents are preserved
|
|
405
465
|
- Idempotent — safe to run multiple times
|
|
406
466
|
- `--dry-run` shows exactly what would be created without touching disk
|
|
467
|
+
- `--rtk` enables RTK token compression bridge
|
|
407
468
|
|
|
408
469
|
### `update`
|
|
409
470
|
|
package/bin/cli.js
CHANGED
|
@@ -73,7 +73,8 @@ const COMMANDS = {
|
|
|
73
73
|
console.log(require('../src/init').dryRun(process.cwd()));
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
|
|
76
|
+
const rtkFlag = process.argv.includes('--rtk');
|
|
77
|
+
return require('../src/init').run({ rtkEnabled: rtkFlag });
|
|
77
78
|
},
|
|
78
79
|
update: () => require('../src/update').run(),
|
|
79
80
|
dismantle: () => require('../src/remove').run(),
|
|
@@ -85,7 +86,8 @@ const COMMANDS = {
|
|
|
85
86
|
console.log(require('../src/init').dryRun(process.cwd()));
|
|
86
87
|
return;
|
|
87
88
|
}
|
|
88
|
-
|
|
89
|
+
const rtkFlag = process.argv.includes('--rtk');
|
|
90
|
+
return require('../src/init').run({ rtkEnabled: rtkFlag });
|
|
89
91
|
},
|
|
90
92
|
remove: () => require('../src/remove').run(),
|
|
91
93
|
doctor: () => require('../src/doctor').run(),
|
package/package.json
CHANGED
package/src/descriptions.js
CHANGED
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
// Keep descriptions under 80 chars — they appear in terminal columns.
|
|
5
5
|
|
|
6
6
|
const AGENTS = {
|
|
7
|
-
'wizard.md': 'Dungeon
|
|
8
|
-
'warrior.md': 'Stress-tester —
|
|
9
|
-
'archer.md': 'Pattern-seeker —
|
|
10
|
-
'rogue.md': 'Assumption-destroyer —
|
|
7
|
+
'wizard.md': 'Dungeon Master — opens phases, dispatches team, closes with rulings',
|
|
8
|
+
'warrior.md': 'Stress-tester — tests boundaries, load, edge cases, failure modes',
|
|
9
|
+
'archer.md': 'Pattern-seeker — ripple effects, naming drift, contract violations, dependencies',
|
|
10
|
+
'rogue.md': 'Assumption-destroyer — failing systems, malicious input, race conditions',
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
const HOOKS = {
|
|
14
14
|
lifecycle: [
|
|
15
|
-
{ name: 'raid-lib.sh', desc: 'Shared config — reads raid.json, exports
|
|
15
|
+
{ name: 'raid-lib.sh', desc: 'Shared config — reads raid.json, exports quest state' },
|
|
16
16
|
{ name: 'raid-session-start.sh', desc: 'Activates Raid workflow, creates quest directory' },
|
|
17
17
|
{ name: 'raid-session-end.sh', desc: 'Archives quest dungeon to vault, cleans up' },
|
|
18
18
|
{ name: 'raid-pre-compact.sh', desc: 'Backs up Dungeon before message compaction' },
|
|
@@ -20,18 +20,21 @@ const HOOKS = {
|
|
|
20
20
|
],
|
|
21
21
|
gates: [
|
|
22
22
|
{ name: 'validate-commit.sh', desc: 'Enforces conventional commit format' },
|
|
23
|
-
{ name: 'validate-write-gate.sh', desc: 'Protects session
|
|
23
|
+
{ name: 'validate-write-gate.sh', desc: 'Protects raid-session file, allows quest dir writes' },
|
|
24
24
|
{ name: 'validate-file-naming.sh', desc: 'Enforces naming convention (kebab-case, etc.)' },
|
|
25
25
|
{ name: 'validate-no-placeholders.sh', desc: 'Blocks TBD/TODO in specs, plans, and quest docs' },
|
|
26
26
|
{ name: 'validate-dungeon.sh', desc: 'Validates dungeon entries and black cards' },
|
|
27
27
|
{ name: 'validate-browser-tests-exist.sh', desc: 'Checks Playwright tests exist before commits' },
|
|
28
28
|
{ name: 'validate-browser-cleanup.sh', desc: 'Verifies browser processes cleaned up properly' },
|
|
29
29
|
],
|
|
30
|
+
optional: [
|
|
31
|
+
{ name: 'rtk-bridge.sh', desc: 'Token compression via RTK (optional, opt-in)' },
|
|
32
|
+
],
|
|
30
33
|
};
|
|
31
34
|
|
|
32
35
|
const SKILLS = {
|
|
33
36
|
// Core
|
|
34
|
-
'raid-init': 'Quest selection, greeting,
|
|
37
|
+
'raid-init': 'Quest selection, greeting, raid initialization',
|
|
35
38
|
// Canonical Quest chain
|
|
36
39
|
'raid-canonical-protocol': 'Canonical Quest protocol and rules',
|
|
37
40
|
'raid-canonical-prd': 'Phase 1: PRD creation (optional)',
|
package/src/init.js
CHANGED
|
@@ -32,7 +32,7 @@ function copyRecursive(src, dest, skipped) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
function install(cwd) {
|
|
35
|
+
function install(cwd, opts = {}) {
|
|
36
36
|
const claudeDir = path.join(cwd, '.claude');
|
|
37
37
|
const result = { skipped: [], alreadyInstalled: false, detected: null };
|
|
38
38
|
|
|
@@ -131,6 +131,15 @@ function install(cwd) {
|
|
|
131
131
|
startup: null,
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
|
+
if (opts.rtkEnabled) {
|
|
135
|
+
raidConfig.rtk = {
|
|
136
|
+
enabled: true,
|
|
137
|
+
bypass: {
|
|
138
|
+
phases: [],
|
|
139
|
+
commands: [],
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
134
143
|
fs.writeFileSync(raidConfigPath, JSON.stringify(raidConfig, null, 2) + '\n');
|
|
135
144
|
}
|
|
136
145
|
|
|
@@ -161,14 +170,14 @@ function install(cwd) {
|
|
|
161
170
|
return result;
|
|
162
171
|
}
|
|
163
172
|
|
|
164
|
-
async function run() {
|
|
173
|
+
async function run(opts = {}) {
|
|
165
174
|
const cwd = process.cwd();
|
|
166
175
|
const { bold, dim } = colors;
|
|
167
176
|
|
|
168
177
|
console.log('\n' + banner());
|
|
169
178
|
console.log(header('Summoning the Party...') + '\n');
|
|
170
179
|
|
|
171
|
-
const result = install(cwd);
|
|
180
|
+
const result = install(cwd, opts);
|
|
172
181
|
|
|
173
182
|
if (result.alreadyInstalled) {
|
|
174
183
|
console.log(' The party is already here. Use ' + bold('claude-raid update') + ' to reforge.');
|
|
@@ -222,7 +231,20 @@ async function run() {
|
|
|
222
231
|
}
|
|
223
232
|
|
|
224
233
|
// Setup wizard
|
|
225
|
-
await runSetup();
|
|
234
|
+
const setupResult = await runSetup(opts);
|
|
235
|
+
|
|
236
|
+
// Apply RTK config if enabled interactively
|
|
237
|
+
if (setupResult.actions.includes('rtk-enabled')) {
|
|
238
|
+
const raidConfigPath = path.join(cwd, '.claude', 'raid.json');
|
|
239
|
+
if (fs.existsSync(raidConfigPath)) {
|
|
240
|
+
const config = JSON.parse(fs.readFileSync(raidConfigPath, 'utf8'));
|
|
241
|
+
if (!config.rtk) {
|
|
242
|
+
config.rtk = { enabled: true, bypass: { phases: [], commands: [] } };
|
|
243
|
+
fs.writeFileSync(raidConfigPath, JSON.stringify(config, null, 2) + '\n');
|
|
244
|
+
mergeSettings(cwd);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
226
248
|
|
|
227
249
|
// Reference card
|
|
228
250
|
const { referenceCard } = require('./ui');
|
|
@@ -273,6 +295,15 @@ function dryRun(cwd) {
|
|
|
273
295
|
}
|
|
274
296
|
lines.push('');
|
|
275
297
|
|
|
298
|
+
// Hooks — Optional
|
|
299
|
+
if (HOOKS.optional && HOOKS.optional.length > 0) {
|
|
300
|
+
lines.push(header('Hooks \u2014 Optional') + '\n');
|
|
301
|
+
for (const h of HOOKS.optional) {
|
|
302
|
+
lines.push(' ' + colors.bold(h.name.padEnd(28)) + h.desc + tag('hooks/' + h.name));
|
|
303
|
+
}
|
|
304
|
+
lines.push('');
|
|
305
|
+
}
|
|
306
|
+
|
|
276
307
|
// Skills
|
|
277
308
|
lines.push(header('Skills') + '\n');
|
|
278
309
|
for (const [folder, desc] of Object.entries(SKILLS)) {
|
|
@@ -301,7 +332,7 @@ function dryRun(cwd) {
|
|
|
301
332
|
}
|
|
302
333
|
lines.push('');
|
|
303
334
|
|
|
304
|
-
lines.push(' Run without --dry-run to
|
|
335
|
+
lines.push(' Run without --dry-run to summon.');
|
|
305
336
|
|
|
306
337
|
return lines.join('\n');
|
|
307
338
|
}
|
package/src/merge-settings.js
CHANGED
|
@@ -11,6 +11,19 @@ const RAID_PERMISSIONS = ['Read', 'Glob', 'Grep', 'Bash', 'Write', 'Edit'];
|
|
|
11
11
|
|
|
12
12
|
const RAID_HOOK_MARKER = '#claude-raid';
|
|
13
13
|
|
|
14
|
+
const RTK_HOOK_MARKER = '#claude-raid-rtk';
|
|
15
|
+
|
|
16
|
+
const RTK_HOOKS = {
|
|
17
|
+
PreToolUse: [
|
|
18
|
+
{
|
|
19
|
+
matcher: 'Bash',
|
|
20
|
+
hooks: [
|
|
21
|
+
{ type: 'command', command: `bash .claude/hooks/rtk-bridge.sh ${RTK_HOOK_MARKER}` },
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
|
|
14
27
|
const RAID_HOOKS = {
|
|
15
28
|
PostToolUse: [
|
|
16
29
|
{
|
|
@@ -78,6 +91,10 @@ function isRaidHookEntry(entry) {
|
|
|
78
91
|
return entry.hooks && entry.hooks.some(h => h.command && h.command.includes(RAID_HOOK_MARKER));
|
|
79
92
|
}
|
|
80
93
|
|
|
94
|
+
function isRtkHookEntry(entry) {
|
|
95
|
+
return entry.hooks && entry.hooks.some(h => h.command && h.command.includes(RTK_HOOK_MARKER));
|
|
96
|
+
}
|
|
97
|
+
|
|
81
98
|
function mergeSettings(cwd) {
|
|
82
99
|
const settingsPath = path.join(cwd, '.claude', 'settings.json');
|
|
83
100
|
let existing = {};
|
|
@@ -112,6 +129,31 @@ function mergeSettings(cwd) {
|
|
|
112
129
|
existing.hooks[event].push(...raidEntries);
|
|
113
130
|
}
|
|
114
131
|
|
|
132
|
+
// RTK hooks — read raid.json to check if enabled
|
|
133
|
+
const raidJsonPath = path.join(cwd, '.claude', 'raid.json');
|
|
134
|
+
let rtkEnabled = false;
|
|
135
|
+
try {
|
|
136
|
+
const raidConfig = JSON.parse(fs.readFileSync(raidJsonPath, 'utf8'));
|
|
137
|
+
rtkEnabled = raidConfig.rtk && raidConfig.rtk.enabled === true;
|
|
138
|
+
} catch {
|
|
139
|
+
// No raid.json or invalid — RTK stays disabled
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Strip existing RTK hooks first (clean slate for toggle behavior)
|
|
143
|
+
for (const event of Object.keys(existing.hooks)) {
|
|
144
|
+
existing.hooks[event] = existing.hooks[event].filter(entry => !isRtkHookEntry(entry));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Append RTK hooks if enabled (after core hooks, ensuring last position)
|
|
148
|
+
if (rtkEnabled) {
|
|
149
|
+
for (const [event, rtkEntries] of Object.entries(RTK_HOOKS)) {
|
|
150
|
+
if (!Array.isArray(existing.hooks[event])) {
|
|
151
|
+
existing.hooks[event] = [];
|
|
152
|
+
}
|
|
153
|
+
existing.hooks[event].push(...rtkEntries);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
115
157
|
fs.writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + '\n');
|
|
116
158
|
}
|
|
117
159
|
|
|
@@ -142,7 +184,7 @@ function removeRaidSettings(cwd) {
|
|
|
142
184
|
|
|
143
185
|
if (settings.hooks) {
|
|
144
186
|
for (const event of Object.keys(settings.hooks)) {
|
|
145
|
-
settings.hooks[event] = settings.hooks[event].filter(entry => !isRaidHookEntry(entry));
|
|
187
|
+
settings.hooks[event] = settings.hooks[event].filter(entry => !isRaidHookEntry(entry) && !isRtkHookEntry(entry));
|
|
146
188
|
if (settings.hooks[event].length === 0) delete settings.hooks[event];
|
|
147
189
|
}
|
|
148
190
|
if (Object.keys(settings.hooks).length === 0) delete settings.hooks;
|
package/src/remove.js
CHANGED
|
@@ -41,7 +41,7 @@ function performRemove(cwd) {
|
|
|
41
41
|
const hooksDir = path.join(claudeDir, 'hooks');
|
|
42
42
|
if (fs.existsSync(hooksDir)) {
|
|
43
43
|
const hooks = fs.readdirSync(hooksDir).filter(f =>
|
|
44
|
-
(f.startsWith('validate-') || f.startsWith('raid-')) && f.endsWith('.sh')
|
|
44
|
+
(f.startsWith('validate-') || f.startsWith('raid-') || f === 'rtk-bridge.sh') && f.endsWith('.sh')
|
|
45
45
|
);
|
|
46
46
|
for (const hook of hooks) {
|
|
47
47
|
rmSafe(path.join(hooksDir, hook));
|
package/src/setup.js
CHANGED
|
@@ -217,6 +217,28 @@ function checkJq(exec) {
|
|
|
217
217
|
};
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
+
function checkRtk(exec) {
|
|
221
|
+
const found = exec('command -v rtk');
|
|
222
|
+
if (!found) {
|
|
223
|
+
return {
|
|
224
|
+
id: 'rtk',
|
|
225
|
+
ok: false,
|
|
226
|
+
label: 'RTK',
|
|
227
|
+
detail: 'not installed (optional — reduces context usage by 60-90%)',
|
|
228
|
+
hint: 'Install: curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh',
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
const raw = exec('rtk --version');
|
|
232
|
+
const ver = parseVersion(raw);
|
|
233
|
+
const tag = ver ? `v${ver.major}.${ver.minor}.${ver.patch}` : (raw || 'unknown').trim();
|
|
234
|
+
return {
|
|
235
|
+
id: 'rtk',
|
|
236
|
+
ok: true,
|
|
237
|
+
label: 'RTK',
|
|
238
|
+
detail: `${tag} — token compression available`,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
220
242
|
function checkPlatform(platform) {
|
|
221
243
|
if (platform === 'win32') {
|
|
222
244
|
return {
|
|
@@ -321,6 +343,7 @@ function runChecks(opts = {}) {
|
|
|
321
343
|
checkTeammateMode(homedir),
|
|
322
344
|
checkSplitPane(exec),
|
|
323
345
|
checkPlaywright(exec, cwd),
|
|
346
|
+
checkRtk(exec),
|
|
324
347
|
];
|
|
325
348
|
|
|
326
349
|
return {
|
|
@@ -390,6 +413,15 @@ async function runSetup(opts = {}) {
|
|
|
390
413
|
|
|
391
414
|
stdout.write('\n ' + formatCheckLine(splitPane).join('\n ') + '\n');
|
|
392
415
|
|
|
416
|
+
// RTK prompt — only if RTK is on PATH and not already configured via --rtk
|
|
417
|
+
const rtkCheck = checks.find(c => c.id === 'rtk');
|
|
418
|
+
if (rtkCheck && rtkCheck.ok && !opts.rtkEnabled) {
|
|
419
|
+
const rtkConfirm = await ask('\n RTK detected — enable token compression? [Y/n] ', stdin, stdout);
|
|
420
|
+
if (rtkConfirm.toLowerCase() !== 'n') {
|
|
421
|
+
actions.push('rtk-enabled');
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
393
425
|
// Recalculate allOk (required checks only: node + claude)
|
|
394
426
|
|
|
395
427
|
allOk = checks.filter(c => REQUIRED_IDS.includes(c.id)).every(c => c.ok);
|
package/src/ui.js
CHANGED
|
@@ -143,6 +143,7 @@ function referenceCard() {
|
|
|
143
143
|
'',
|
|
144
144
|
' Config: ' + colors.bold('.claude/raid.json') + ' ' + colors.dim('project settings'),
|
|
145
145
|
' Rules: ' + colors.bold('.claude/party-rules.md') + ' ' + colors.dim('editable party rules'),
|
|
146
|
+
' RTK: ' + colors.bold('.claude/raid.json \u2192 rtk') + ' ' + colors.dim('opt-in token compression'),
|
|
146
147
|
]);
|
|
147
148
|
|
|
148
149
|
const nextStep = box('Next Step', [
|
package/src/update.js
CHANGED
|
@@ -31,7 +31,7 @@ function copyForceRecursive(src, dest) {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
function performUpdate(cwd) {
|
|
34
|
+
function performUpdate(cwd, opts = {}) {
|
|
35
35
|
const claudeDir = path.join(cwd, '.claude');
|
|
36
36
|
const skippedAgents = [];
|
|
37
37
|
|
|
@@ -144,6 +144,20 @@ function performUpdate(cwd) {
|
|
|
144
144
|
|
|
145
145
|
mergeSettings(cwd);
|
|
146
146
|
|
|
147
|
+
// RTK hint — if RTK is detected but not configured in raid.json
|
|
148
|
+
let rtkHint = false;
|
|
149
|
+
if (opts.rtkDetected) {
|
|
150
|
+
const raidConfigPath = path.join(claudeDir, 'raid.json');
|
|
151
|
+
if (fs.existsSync(raidConfigPath)) {
|
|
152
|
+
try {
|
|
153
|
+
const raidConfig = JSON.parse(fs.readFileSync(raidConfigPath, 'utf8'));
|
|
154
|
+
if (!raidConfig.rtk) {
|
|
155
|
+
rtkHint = true;
|
|
156
|
+
}
|
|
157
|
+
} catch {}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
147
161
|
let message = 'The Raid has been updated to the latest version.';
|
|
148
162
|
if (migratedFields.length > 0) {
|
|
149
163
|
message += `\nMigrated raid.json: added ${migratedFields.join(', ')}`;
|
|
@@ -158,15 +172,19 @@ function performUpdate(cwd) {
|
|
|
158
172
|
message += '\nUse `claude-raid dismantle` then `claude-raid summon` to reset.';
|
|
159
173
|
}
|
|
160
174
|
|
|
161
|
-
return { success: true, message, skippedAgents, migratedFields };
|
|
175
|
+
return { success: true, message, skippedAgents, migratedFields, rtkHint };
|
|
162
176
|
}
|
|
163
177
|
|
|
164
178
|
function run() {
|
|
165
179
|
const cwd = process.cwd();
|
|
180
|
+
const { execSync } = require('child_process');
|
|
181
|
+
let rtkDetected = false;
|
|
182
|
+
try { execSync('command -v rtk', { stdio: 'pipe' }); rtkDetected = true; } catch {}
|
|
183
|
+
|
|
166
184
|
console.log('\n' + banner());
|
|
167
185
|
console.log(header('Reforging the Arsenal...') + '\n');
|
|
168
186
|
|
|
169
|
-
const result = performUpdate(cwd);
|
|
187
|
+
const result = performUpdate(cwd, { rtkDetected });
|
|
170
188
|
|
|
171
189
|
if (!result.success) {
|
|
172
190
|
console.log(' ' + colors.red('✖') + ' No party found. Run ' + colors.bold('claude-raid summon') + ' first.');
|
|
@@ -177,6 +195,11 @@ function run() {
|
|
|
177
195
|
if (result.skippedAgents.length > 0) {
|
|
178
196
|
console.log(' ' + colors.dim('Preserved customized warriors: ' + result.skippedAgents.join(', ')));
|
|
179
197
|
}
|
|
198
|
+
|
|
199
|
+
if (result.rtkHint) {
|
|
200
|
+
console.log(' ' + colors.dim('Tip: RTK detected — add "rtk": { "enabled": true } to raid.json'));
|
|
201
|
+
console.log(' ' + colors.dim('or re-run summon with --rtk to enable token compression.'));
|
|
202
|
+
}
|
|
180
203
|
}
|
|
181
204
|
|
|
182
205
|
module.exports = { performUpdate, run };
|
|
@@ -5,17 +5,31 @@ description: >
|
|
|
5
5
|
catches naming drift, contract violations, and implicit dependencies. Independently
|
|
6
6
|
verifies every claim. Zero trust in reports — reads code, traces chains. Zero ego —
|
|
7
7
|
concedes with evidence, moves on. Collaborates through rigor, not agreement.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
<example>
|
|
11
|
+
Context: The Wizard is in Phase 2 (Design) and needs ripple effect analysis on a proposed change.
|
|
12
|
+
user: "TURN_DISPATCH: Phase 2, Round 1. Quest: migrate from REST to GraphQL. Your angle: trace how this change ripples through existing consumers, shared types, error contracts, and middleware."
|
|
13
|
+
assistant: "I'll map every consumer of the REST endpoints, trace the type contracts downstream, identify naming conventions that will drift, and pin each ripple with its exact consequence."
|
|
14
|
+
<commentary>The Wizard dispatches Archer when a design or change needs systemic coherence analysis — tracing how changes propagate through the codebase and catching inconsistencies.</commentary>
|
|
15
|
+
</example>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
<example>
|
|
19
|
+
Context: The Wizard is in Phase 5 (Review) and needs pattern consistency validation.
|
|
20
|
+
user: "TURN_DISPATCH: Phase 5, Round 1. Your angle: review the implementation for naming drift, contract violations, and inconsistencies with existing codebase patterns."
|
|
21
|
+
assistant: "I'll compare the new code against established conventions, trace every interface for contract compliance, and flag where naming or structure diverges from the rest of the codebase."
|
|
22
|
+
<commentary>During review, Archer validates that the implementation maintains systemic coherence — no naming drift, no broken contracts, no implicit dependencies introduced.</commentary>
|
|
23
|
+
</example>
|
|
8
24
|
model: claude-opus-4-6
|
|
9
25
|
tools: SendMessage, TaskCreate, TaskUpdate, Read, Grep, Glob, Bash, Write, Edit
|
|
10
26
|
effort: medium
|
|
11
27
|
color: green
|
|
12
28
|
memory: project
|
|
13
29
|
skills:
|
|
14
|
-
- raid-canonical-prd
|
|
15
30
|
- raid-tdd
|
|
16
31
|
- raid-verification
|
|
17
32
|
- raid-debugging
|
|
18
|
-
- raid-wrap-up
|
|
19
33
|
---
|
|
20
34
|
|
|
21
35
|
# The Archer — Raid Teammate
|
|
@@ -35,8 +49,8 @@ Does this fit? You trace how changes ripple through the system. You catch naming
|
|
|
35
49
|
|
|
36
50
|
## Learning
|
|
37
51
|
|
|
38
|
-
- When @Warrior
|
|
39
|
-
- When @Rogue
|
|
52
|
+
- When you read @Warrior's Dungeon findings and discover a structural issue you missed, update your mental model.
|
|
53
|
+
- When you read @Rogue's Dungeon findings and discover a failure scenario through a path you traced, integrate the attack vector.
|
|
40
54
|
|
|
41
55
|
## Unique Standards
|
|
42
56
|
|