cc-workspace 4.0.3 → 4.0.5
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 +20 -23
- package/bin/cli.js +85 -4
- package/global-skills/agents/implementer.md +1 -2
- package/global-skills/agents/team-lead.md +1 -2
- package/global-skills/agents/workspace-init.md +1 -2
- package/global-skills/bootstrap-repo/SKILL.md +1 -0
- package/global-skills/cross-service-check/SKILL.md +1 -0
- package/global-skills/cycle-retrospective/SKILL.md +1 -0
- package/global-skills/dispatch-feature/references/spawn-templates.md +10 -0
- package/global-skills/merge-prep/SKILL.md +1 -0
- package/global-skills/plan-review/SKILL.md +1 -0
- package/global-skills/refresh-profiles/SKILL.md +1 -0
- package/global-skills/rules/model-routing.md +1 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Claude Code Multi-Workspace Orchestrator v4.0
|
|
1
|
+
# Claude Code Multi-Workspace Orchestrator v4.0.5
|
|
2
2
|
|
|
3
3
|
A system to pilot multi-service projects from Claude Code.
|
|
4
4
|
The orchestrator (Opus) never codes in repos. It clarifies, plans,
|
|
@@ -66,8 +66,10 @@ claude --agent team-lead
|
|
|
66
66
|
npx cc-workspace update
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
Updates
|
|
70
|
-
|
|
69
|
+
Updates all components if the package version is newer:
|
|
70
|
+
- **Global**: skills, rules, agents in `~/.claude/`
|
|
71
|
+
- **Local** (if orchestrator/ found): hooks, settings.json, CLAUDE.md, templates, _TEMPLATE.md
|
|
72
|
+
- **Never overwritten**: workspace.md, constitution.md, plans/
|
|
71
73
|
|
|
72
74
|
### Diagnostic
|
|
73
75
|
|
|
@@ -164,7 +166,7 @@ detects if the target path is in a repo (presence of `.git/`).
|
|
|
164
166
|
|
|
165
167
|
Protection layers:
|
|
166
168
|
1. `disallowedTools: Bash` in agent frontmatter
|
|
167
|
-
2. `
|
|
169
|
+
2. `tools` whitelist in agent frontmatter (note: `allowed-tools` is the skill equivalent)
|
|
168
170
|
3. `PreToolUse` path-aware hook in agent frontmatter
|
|
169
171
|
4. `block-orchestrator-writes.sh` hook in .claude/hooks/
|
|
170
172
|
|
|
@@ -224,7 +226,7 @@ All hooks are **non-blocking** (exit 0 + warning). No hook blocks the session.
|
|
|
224
226
|
| Template | Usage |
|
|
225
227
|
|----------|-------|
|
|
226
228
|
| `workspace.template.md` | Structure for workspace.md (project, service map, relationships, rules, onboarding) |
|
|
227
|
-
| `constitution.template.md` | Structure for constitution.md (
|
|
229
|
+
| `constitution.template.md` | Structure for constitution.md (your engineering principles) |
|
|
228
230
|
| `claude-md.template.md` | Standardized structure for repo CLAUDE.md files (stack, arch, rules, tests, anti-patterns) |
|
|
229
231
|
|
|
230
232
|
---
|
|
@@ -251,17 +253,13 @@ The `orchestrator/` directory is portable:
|
|
|
251
253
|
|
|
252
254
|
## The constitution
|
|
253
255
|
|
|
254
|
-
|
|
256
|
+
`constitution.md` in orchestrator/. You define **all** your engineering
|
|
257
|
+
principles here — security, UX, code quality, process, project-specific rules.
|
|
258
|
+
The `workspace-init` agent helps you write it interactively.
|
|
255
259
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
The orchestrator includes it in every spawn prompt.
|
|
260
|
-
|
|
261
|
-
### Project (to customize)
|
|
262
|
-
|
|
263
|
-
`constitution.md` in orchestrator/. Contains **only** project-specific
|
|
264
|
-
rules (numbered 13+).
|
|
260
|
+
There is no global constitution imposed by the package. Each workspace
|
|
261
|
+
defines its own rules. The orchestrator includes the full constitution
|
|
262
|
+
in every teammate spawn prompt (teammates don't receive it automatically).
|
|
265
263
|
|
|
266
264
|
---
|
|
267
265
|
|
|
@@ -307,7 +305,6 @@ cc-workspace/
|
|
|
307
305
|
├── LICENSE
|
|
308
306
|
│
|
|
309
307
|
└── global-skills/ <- components installed in ~/.claude/
|
|
310
|
-
├── constitution.md <- 12 principles (EN)
|
|
311
308
|
├── templates/
|
|
312
309
|
│ ├── workspace.template.md
|
|
313
310
|
│ ├── constitution.template.md
|
|
@@ -335,12 +332,12 @@ cc-workspace/
|
|
|
335
332
|
|
|
336
333
|
## Idempotence
|
|
337
334
|
|
|
338
|
-
|
|
339
|
-
-
|
|
340
|
-
- Always
|
|
341
|
-
- Always
|
|
342
|
-
-
|
|
343
|
-
- Global components
|
|
335
|
+
Both `init` and `update` are safe to re-run:
|
|
336
|
+
- **Never overwritten**: `workspace.md`, `constitution.md`, `plans/*.md` (user content)
|
|
337
|
+
- **Always regenerated**: `settings.json`, `block-orchestrator-writes.sh` (security), `CLAUDE.md`, `_TEMPLATE.md`
|
|
338
|
+
- **Always copied**: hooks, templates
|
|
339
|
+
- **Always regenerated on init**: `service-profiles.md` (fresh scan)
|
|
340
|
+
- **Global components**: only updated if the version is newer (or `--force`)
|
|
344
341
|
|
|
345
342
|
---
|
|
346
343
|
|
|
@@ -357,7 +354,7 @@ The setup is safe to re-run:
|
|
|
357
354
|
| 7 | **Warning-only hooks** | No more blocking hooks (exit 2 -> exit 0). |
|
|
358
355
|
| 8 | **verify-cycle-complete removed** | No more exit blocking. |
|
|
359
356
|
| 9 | **Orchestrator can write** | In orchestrator/ only. Dynamic path-aware hook. |
|
|
360
|
-
| 10 | **
|
|
357
|
+
| 10 | **Per-workspace constitution** | No global constitution — each workspace defines its own rules. |
|
|
361
358
|
| 11 | **30-line limit removed** | The orchestrator adapts verbosity to context. |
|
|
362
359
|
| 12 | **Structured templates** | workspace.template.md + constitution.template.md + claude-md.template.md. |
|
|
363
360
|
|
package/bin/cli.js
CHANGED
|
@@ -324,7 +324,7 @@ You clarify, plan, delegate, track.
|
|
|
324
324
|
|
|
325
325
|
## Security
|
|
326
326
|
- \`disallowedTools: Bash\` — no direct shell
|
|
327
|
-
- \`
|
|
327
|
+
- \`tools\` : Read, Write, Edit, Glob, Grep, Task(implementer, Explore), Teammate, SendMessage
|
|
328
328
|
- Hook \`PreToolUse\` path-aware: allows orchestrator/, blocks sibling repos
|
|
329
329
|
|
|
330
330
|
> settings.json contains env vars + hooks registration.
|
|
@@ -424,6 +424,80 @@ function planTemplateContent() {
|
|
|
424
424
|
`;
|
|
425
425
|
}
|
|
426
426
|
|
|
427
|
+
// ─── Update local orchestrator/ components ──────────────────
|
|
428
|
+
// Called by `update` when run from a workspace that contains orchestrator/
|
|
429
|
+
// or from inside orchestrator/ itself.
|
|
430
|
+
function updateLocal() {
|
|
431
|
+
const cwd = process.cwd();
|
|
432
|
+
// Detect if we're inside orchestrator/ or in the parent workspace
|
|
433
|
+
let orchDir;
|
|
434
|
+
if (fs.existsSync(path.join(cwd, "workspace.md"))) {
|
|
435
|
+
orchDir = cwd; // inside orchestrator/
|
|
436
|
+
} else if (fs.existsSync(path.join(cwd, "orchestrator", "workspace.md"))) {
|
|
437
|
+
orchDir = path.join(cwd, "orchestrator");
|
|
438
|
+
} else {
|
|
439
|
+
return false; // no local orchestrator found
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
step(`Updating local: ${c.dim}${orchDir}${c.reset}`);
|
|
443
|
+
let count = 0;
|
|
444
|
+
|
|
445
|
+
// ── Hooks (always overwrite — security critical) ──
|
|
446
|
+
const hooksDir = path.join(orchDir, ".claude", "hooks");
|
|
447
|
+
if (fs.existsSync(hooksDir)) {
|
|
448
|
+
generateBlockHook(hooksDir);
|
|
449
|
+
count++;
|
|
450
|
+
const hooksSrc = path.join(SKILLS_DIR, "hooks");
|
|
451
|
+
if (fs.existsSync(hooksSrc)) {
|
|
452
|
+
for (const f of fs.readdirSync(hooksSrc)) {
|
|
453
|
+
if (!f.endsWith(".sh") || f === "verify-cycle-complete.sh") continue;
|
|
454
|
+
copyFile(path.join(hooksSrc, f), path.join(hooksDir, f));
|
|
455
|
+
fs.chmodSync(path.join(hooksDir, f), 0o755);
|
|
456
|
+
count++;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
ok(`${count} hooks updated`);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// ── settings.json (always regenerate — hook registration) ──
|
|
463
|
+
const settingsPath = path.join(orchDir, ".claude", "settings.json");
|
|
464
|
+
if (fs.existsSync(path.join(orchDir, ".claude"))) {
|
|
465
|
+
generateSettings(orchDir);
|
|
466
|
+
ok("settings.json regenerated");
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// ── Templates (always overwrite — reference docs) ──
|
|
470
|
+
const templatesDir = path.join(SKILLS_DIR, "templates");
|
|
471
|
+
const localTemplates = path.join(orchDir, "templates");
|
|
472
|
+
if (fs.existsSync(templatesDir) && fs.existsSync(localTemplates)) {
|
|
473
|
+
let tplCount = 0;
|
|
474
|
+
for (const f of fs.readdirSync(templatesDir)) {
|
|
475
|
+
if (f.endsWith(".md")) {
|
|
476
|
+
copyFile(path.join(templatesDir, f), path.join(localTemplates, f));
|
|
477
|
+
tplCount++;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
ok(`${tplCount} templates updated`);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// ── CLAUDE.md (always overwrite — generated file, not user content) ──
|
|
484
|
+
const claudeMd = path.join(orchDir, "CLAUDE.md");
|
|
485
|
+
fs.writeFileSync(claudeMd, claudeMdContent());
|
|
486
|
+
ok("CLAUDE.md updated");
|
|
487
|
+
|
|
488
|
+
// ── Plan template (always overwrite — structure only) ──
|
|
489
|
+
const planTpl = path.join(orchDir, "plans", "_TEMPLATE.md");
|
|
490
|
+
if (fs.existsSync(path.join(orchDir, "plans"))) {
|
|
491
|
+
fs.writeFileSync(planTpl, planTemplateContent());
|
|
492
|
+
ok("_TEMPLATE.md updated");
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// ── NEVER touch: workspace.md, constitution.md, plans/*.md, service-profiles.md ──
|
|
496
|
+
info(`${c.dim}workspace.md, constitution.md, plans/ — preserved${c.reset}`);
|
|
497
|
+
|
|
498
|
+
return true;
|
|
499
|
+
}
|
|
500
|
+
|
|
427
501
|
// ─── Setup workspace ────────────────────────────────────────
|
|
428
502
|
function setupWorkspace(workspacePath, projectName) {
|
|
429
503
|
const wsAbs = path.resolve(workspacePath);
|
|
@@ -685,10 +759,15 @@ switch (command) {
|
|
|
685
759
|
const force = args.includes("--force");
|
|
686
760
|
log(BANNER);
|
|
687
761
|
const updated = installGlobals(force);
|
|
688
|
-
|
|
762
|
+
const localUpdated = (updated || force) ? updateLocal() : false;
|
|
763
|
+
if (!updated && !force) {
|
|
689
764
|
log(`\n ${c.dim}Already up to date. Use --force to reinstall.${c.reset}\n`);
|
|
690
765
|
} else {
|
|
691
|
-
|
|
766
|
+
if (localUpdated) {
|
|
767
|
+
log(`\n ${c.green}${c.bold}Update complete (globals + local orchestrator/).${c.reset}\n`);
|
|
768
|
+
} else {
|
|
769
|
+
log(`\n ${c.green}${c.bold}Update complete (globals only — no local orchestrator/ found).${c.reset}\n`);
|
|
770
|
+
}
|
|
692
771
|
}
|
|
693
772
|
break;
|
|
694
773
|
}
|
|
@@ -721,7 +800,9 @@ switch (command) {
|
|
|
721
800
|
log(` Installs global skills/rules/agents if version is newer.`);
|
|
722
801
|
log("");
|
|
723
802
|
log(` ${c.cyan}npx cc-workspace update${c.reset} ${c.dim}[--force]${c.reset}`);
|
|
724
|
-
log(` Update global components
|
|
803
|
+
log(` Update global components (skills, rules, agents).`);
|
|
804
|
+
log(` Also updates local orchestrator/ if found (hooks, settings, CLAUDE.md, templates).`);
|
|
805
|
+
log(` Never overwrites: workspace.md, constitution.md, plans/.`);
|
|
725
806
|
log("");
|
|
726
807
|
log(` ${c.cyan}npx cc-workspace doctor${c.reset}`);
|
|
727
808
|
log(` Check all components are installed and consistent.`);
|
|
@@ -7,9 +7,8 @@ description: >
|
|
|
7
7
|
(Agent Teams teammates get automatic isolation).
|
|
8
8
|
isolation: worktree
|
|
9
9
|
model: sonnet
|
|
10
|
-
|
|
10
|
+
tools: Read, Write, Edit, MultiEdit, Bash, Glob, Grep
|
|
11
11
|
memory: project
|
|
12
|
-
effort: medium
|
|
13
12
|
maxTurns: 50
|
|
14
13
|
---
|
|
15
14
|
|
|
@@ -6,10 +6,9 @@ description: >
|
|
|
6
6
|
quality. Never codes in repos — can write in orchestrator/.
|
|
7
7
|
Triggered via claude --agent team-lead.
|
|
8
8
|
model: opus
|
|
9
|
-
|
|
9
|
+
tools: Read, Write, Edit, Glob, Grep, Task(implementer, Explore), Teammate, SendMessage
|
|
10
10
|
disallowedTools: Bash
|
|
11
11
|
memory: project
|
|
12
|
-
effort: high
|
|
13
12
|
maxTurns: 200
|
|
14
13
|
hooks:
|
|
15
14
|
PreToolUse:
|
|
@@ -6,9 +6,8 @@ description: >
|
|
|
6
6
|
Interactively configures workspace.md and constitution.md if [UNCONFIGURED].
|
|
7
7
|
Run once via: claude --agent workspace-init
|
|
8
8
|
model: sonnet
|
|
9
|
-
|
|
9
|
+
tools: Read, Write, Edit, Bash, Glob, Grep, Task(Explore)
|
|
10
10
|
memory: project
|
|
11
|
-
effort: medium
|
|
12
11
|
maxTurns: 80
|
|
13
12
|
---
|
|
14
13
|
|
|
@@ -85,6 +85,8 @@ You are teammate-[service]. Read the CLAUDE.md in your repo first.
|
|
|
85
85
|
|
|
86
86
|
## Explore/Haiku subagent template (read-only)
|
|
87
87
|
|
|
88
|
+
Use `Task` with `subagent_type: Explore` and `model: haiku` for lightweight scans.
|
|
89
|
+
|
|
88
90
|
```
|
|
89
91
|
You are an explorer scanning [target]. Read-only — do NOT modify any files.
|
|
90
92
|
|
|
@@ -94,3 +96,11 @@ You are an explorer scanning [target]. Read-only — do NOT modify any files.
|
|
|
94
96
|
## Report format
|
|
95
97
|
[what to extract and how to format the findings]
|
|
96
98
|
```
|
|
99
|
+
|
|
100
|
+
## Failure handling
|
|
101
|
+
|
|
102
|
+
When a teammate reports back:
|
|
103
|
+
- **Test regression or missing file** (recoverable): fix plan, re-dispatch ONCE
|
|
104
|
+
- **Architectural decision not in plan** (blocking): STOP the wave, escalate to user
|
|
105
|
+
- **No report after extended time**: send a status request via SendMessage
|
|
106
|
+
- **Max re-dispatches per teammate per wave**: 2. After that, escalate to user.
|
|
@@ -5,6 +5,7 @@ description: >
|
|
|
5
5
|
listed in workspace.md. Use when conventions changed, or user says
|
|
6
6
|
"refresh profiles", "update profiles", "re-read CLAUDE.md files".
|
|
7
7
|
context: fork
|
|
8
|
+
agent: Explore
|
|
8
9
|
disable-model-invocation: true
|
|
9
10
|
model: haiku
|
|
10
11
|
allowed-tools: Read, Write, Glob, Grep
|
|
@@ -12,7 +12,7 @@ If you write code for a repo (not a markdown plan), you have failed — delegate
|
|
|
12
12
|
|
|
13
13
|
## Security layers (3 layers in agent frontmatter — no settings.json pollution)
|
|
14
14
|
1. **Agent frontmatter**: `disallowedTools` — refused at model level
|
|
15
|
-
2. **Agent frontmatter**: `
|
|
15
|
+
2. **Agent frontmatter**: `tools` — whitelist of permitted tools (note: `allowed-tools` is for skills only)
|
|
16
16
|
3. **Agent hook**: `PreToolUse` in frontmatter — structured deny response
|
|
17
17
|
|
|
18
18
|
## Routing table
|
|
@@ -24,18 +24,6 @@ If you write code for a repo (not a markdown plan), you have failed — delegate
|
|
|
24
24
|
| Explorers / cross-checks | **Haiku** | `model: haiku` in skill/agent frontmatter |
|
|
25
25
|
| Plan review | **Haiku** | `model: haiku` in skill frontmatter |
|
|
26
26
|
|
|
27
|
-
## Effort levels
|
|
28
|
-
| Role | Effort | Rationale |
|
|
29
|
-
|------|--------|-----------|
|
|
30
|
-
| Orchestrator (team-lead) | **high** | Complex planning, multi-step reasoning |
|
|
31
|
-
| Implementation teammates | **medium** | Focused implementation, clear scope |
|
|
32
|
-
| QA investigators | **medium** | Thorough but bounded analysis |
|
|
33
|
-
| Explorers / cross-checks (Haiku) | **low** | Fast scans, read-only |
|
|
34
|
-
| Plan review (Haiku) | **low** | Structural checks, no deep reasoning |
|
|
35
|
-
|
|
36
|
-
Effort levels are set in agent frontmatter (`effort: high|medium|low|max`).
|
|
37
|
-
Use `max` only for critical debugging or complex architectural decisions.
|
|
38
|
-
|
|
39
27
|
## Custom agent `implementer`
|
|
40
28
|
For Task subagents that need to write code in an isolated worktree,
|
|
41
29
|
use `@implementer` (frontmatter with `isolation: worktree`).
|
package/package.json
CHANGED