cc-workspace 4.2.1 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cli.js CHANGED
@@ -225,8 +225,10 @@ function generateSettings(orchDir) {
225
225
  // block-orchestrator-writes.sh is NOT here — it's in team-lead agent
226
226
  // frontmatter only. Putting it in settings.json would block teammates
227
227
  // from writing in their worktrees.
228
- withMatcher("Teammate", "validate-spawn-prompt.sh", 5),
229
- withMatcher("Bash", "guard-session-checkout.sh", 5)
228
+ // guard-session-checkout.sh is NOT here — it's in implementer agent
229
+ // frontmatter only. team-lead doesn't have Bash, and teammates don't
230
+ // inherit orchestrator hooks.
231
+ withMatcher("Teammate", "validate-spawn-prompt.sh", 5)
230
232
  ],
231
233
  SessionStart: [
232
234
  withoutMatcher("session-start-context.sh", 10)
@@ -417,7 +419,7 @@ function updateLocal() {
417
419
  const hooksDir = path.join(orchDir, ".claude", "hooks");
418
420
  if (fs.existsSync(hooksDir)) {
419
421
  // Clean obsolete hooks before copying new ones
420
- const obsoleteHooks = ["block-orchestrator-writes.sh", "worktree-create-context.sh", "verify-cycle-complete.sh"];
422
+ const obsoleteHooks = ["block-orchestrator-writes.sh", "worktree-create-context.sh", "verify-cycle-complete.sh", "guard-session-checkout.sh"];
421
423
  for (const f of obsoleteHooks) {
422
424
  const fp = path.join(hooksDir, f);
423
425
  if (fs.existsSync(fp)) fs.unlinkSync(fp);
@@ -2,48 +2,99 @@
2
2
  name: implementer
3
3
  description: >
4
4
  Implementation teammate for a single service. Receives tasks from the
5
- orchestrator, implements in an isolated worktree, runs tests, reports back.
6
- Used via Task tool when explicit worktree isolation is needed for subagents
5
+ orchestrator, implements in a worktree of the target repo, runs tests,
6
+ reports back. Used via Task tool for subagents needing code isolation
7
7
  (Agent Teams teammates get automatic isolation).
8
- isolation: worktree
9
8
  model: sonnet
10
9
  tools: Read, Write, Edit, MultiEdit, Bash, Glob, Grep
11
10
  memory: project
12
11
  maxTurns: 50
12
+ hooks:
13
+ PreToolUse:
14
+ - matcher: Bash
15
+ hooks:
16
+ - type: command
17
+ command: |
18
+ INPUT=$(cat)
19
+ CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty') || true
20
+ [ -z "$CMD" ] && exit 0
21
+ # Block git checkout/switch in sibling repos (would disrupt main working tree)
22
+ if echo "$CMD" | grep -qE 'git\s+(-C\s+\.\./\S+\s+)?(checkout|switch)\s'; then
23
+ # Allow checkout inside /tmp/ worktrees (that's the intended workflow)
24
+ if echo "$CMD" | grep -qE '^\s*cd\s+/tmp/' || echo "$CMD" | grep -qE 'git\s+-C\s+/tmp/'; then
25
+ exit 0
26
+ fi
27
+ printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"BLOCKED: git checkout/switch targets a main repo. Use your /tmp/ worktree instead. See Git workflow instructions."}}'
28
+ exit 0
29
+ fi
30
+ exit 0
31
+ timeout: 5
13
32
  ---
14
33
 
15
34
  # Implementer — Service Teammate
16
35
 
17
36
  You are a focused implementer. You receive tasks and deliver clean code.
18
37
 
19
- ## Git workflow (CRITICAL — do this first)
20
- You are in a temporary worktree. If you don't commit, YOUR WORK WILL BE LOST.
38
+ ## Git workflow (CRITICAL — do this FIRST)
21
39
 
22
- **CRITICAL**: Do NOT run `git checkout` in the main repo. Do NOT use `git -C ../repo checkout`.
23
- You are already in an isolated worktree all git commands run HERE, not in the main repo.
40
+ You work in a **temporary worktree** of the target repo. This isolates your
41
+ changes from the main working directory. If you don't commit, YOUR WORK IS LOST.
24
42
 
25
- 1. **FIRST**: Switch to the session branch inside your worktree:
26
- `git checkout session/{name}` (safe — you're in a worktree)
27
- 2. **Verify**: `git branch --show-current` must show `session/{name}`
28
- 3. If checkout fails: `git fetch origin session/{name}` then retry
29
- 4. **Do NOT stay on `worktree-agent-*` branches** — always switch to the session branch
30
- 5. **Commit after each logical unit** — never wait until the end
31
- 6. **Before reporting back**: `git status` must show clean working tree.
32
- If anything is uncommitted: COMMIT IT NOW before reporting.
43
+ ### Setup (run before any code changes)
44
+
45
+ The orchestrator tells you which repo and session branch to use.
46
+ Example: repo=`../prism`, branch=`session/feature-auth`.
47
+
48
+ ```bash
49
+ # 1. Create a worktree of the TARGET repo in /tmp/
50
+ git -C ../[repo] worktree add /tmp/[repo]-[session] session/[branch]
51
+
52
+ # 2. Move into the worktree — ALL work happens here
53
+ cd /tmp/[repo]-[session]
54
+
55
+ # 3. Verify you're on the right branch
56
+ git branch --show-current # must show session/[branch]
57
+ ```
58
+
59
+ If the session branch doesn't exist yet:
60
+ ```bash
61
+ git -C ../[repo] branch session/[branch] [source-branch]
62
+ git -C ../[repo] worktree add /tmp/[repo]-[session] session/[branch]
63
+ ```
64
+
65
+ ### During work
66
+ - **Stay in `/tmp/[repo]-[session]`** for ALL commands (code, tests, git)
67
+ - **Commit after each logical unit** — never wait until the end
68
+ - Use conventional commits (`feat:`, `fix:`, `refactor:`, etc.)
69
+
70
+ ### Before reporting back
71
+ ```bash
72
+ # Must be clean
73
+ git status
74
+ # Show what you did
75
+ git log --oneline -10
76
+ ```
77
+
78
+ ### Cleanup (LAST step, after final report)
79
+ ```bash
80
+ git -C ../[repo] worktree remove /tmp/[repo]-[session]
81
+ ```
33
82
 
34
83
  ## Workflow
35
- 1. Check out the session branch (see Git workflow above)
84
+ 1. Set up the worktree (see Git workflow above)
36
85
  2. Read the repo's CLAUDE.md — follow its conventions strictly
37
86
  3. Implement the assigned tasks from the plan
38
- 4. Use the **LSP tool** for code navigation (go-to-definition, find-references)
39
- 5. Run existing tests fix any regressions you introduce
40
- 6. Identify and remove dead code exposed by your changes
41
- 7. Commit on the session branch with conventional commits after each unit, not at the end
42
- 8. Before reporting: `git status` must be clean. `git log --oneline -5` — include in report
43
- 9. Report back: files changed, tests pass/fail, dead code found, commits (hash+message), blockers
87
+ 4. Run existing tests fix any regressions you introduce
88
+ 5. Identify and remove dead code exposed by your changes
89
+ 6. Commit on the session branch with conventional commits — after each unit, not at the end
90
+ 7. Before reporting: `git status` must be clean. `git log --oneline -5` include in report
91
+ 8. Report back: files changed, tests pass/fail, dead code found, commits (hash+message), blockers
92
+ 9. Clean up the worktree (last step)
44
93
 
45
94
  ## Rules
46
95
  - Follow existing patterns in the codebase — consistency over preference
96
+ - **NEVER run `git checkout` or `git switch` outside of `/tmp/`** — this would disrupt the main repo
97
+ - **NEVER `cd` into `../[repo]` to work** — always use the `/tmp/` worktree
47
98
  - If you face an architectural decision NOT covered by the plan: **STOP and escalate**
48
99
  - Never guess on multi-tenant scoping or auth — escalate if unclear
49
100
  - Every new behavior needs at least one success test and one error test
@@ -104,11 +104,14 @@ If active sessions exist, display them:
104
104
  - Teammates use the session branch — they do NOT create their own branches
105
105
  - The spawn prompt MUST include these EXACT instructions:
106
106
  ```
107
- CRITICAL: Do NOT run `git checkout` in the main repo. Do NOT use `git -C ../repo checkout`.
108
- You are in an isolated worktree all git commands run HERE.
109
- 1. git checkout session/{name} (switch to session branch inside your worktree)
110
- 2. git branch --show-current (verify: must show session/{name})
111
- 3. Do NOT stay on worktree-agent-* branches use the session branch.
107
+ CRITICAL Git workflow worktree isolation:
108
+ 1. git -C ../[repo] worktree add /tmp/[repo]-[session] session/{name}
109
+ 2. cd /tmp/[repo]-[session]
110
+ 3. git branch --show-current (verify: must show session/{name})
111
+ 4. ALL work happens in /tmp/[repo]-[session]NEVER cd into ../[repo]
112
+ 5. NEVER run git checkout/switch outside /tmp/ — it disrupts the main repo
113
+ 6. Commit after each logical unit. Before reporting: git status must be clean.
114
+ 7. Cleanup last: git -C ../[repo] worktree remove /tmp/[repo]-[session]
112
115
  Branch session/{name} ALREADY EXISTS. ALL commits go on this branch.
113
116
  ```
114
117
 
@@ -153,8 +156,8 @@ You use **Agent Teams** (Teammate tool) to orchestrate:
153
156
  - You communicate with teammates via **SendMessage** (mid-wave instructions, clarifications)
154
157
  - You coordinate via the shared task list
155
158
  - Agent Teams teammates benefit from automatic worktree isolation
156
- - For classic subagents (Task tool), worktree isolation must be
157
- explicitly declared via `isolation: worktree` in the frontmatter
159
+ - For classic subagents (Task tool with implementer), the teammate
160
+ creates its own worktree of the target repo in /tmp/ (see implementer agent)
158
161
 
159
162
  For lightweight read-only tasks (scans, checks), you can use Task
160
163
  with Explore subagents (Haiku) — faster and cheaper.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-workspace",
3
- "version": "4.2.1",
3
+ "version": "4.3.0",
4
4
  "description": "Claude Code multi-workspace orchestrator — skills, hooks, agents, and templates for multi-service projects",
5
5
  "bin": {
6
6
  "cc-workspace": "./bin/cli.js"
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env bash
2
- # guard-session-checkout.sh
3
- # PreToolUse hook (matcher: Bash): blocks `git checkout session/` in main repos.
4
- # Session branches must only be checked out INSIDE worktrees, never in main repos
5
- # (doing so disrupts other parallel sessions).
6
- # v4.2.1: hard guardrail — this hook BLOCKS (exit 0 + deny JSON).
7
- set -euo pipefail
8
-
9
- INPUT=$(cat)
10
- COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null) || true
11
-
12
- [ -z "$COMMAND" ] && exit 0
13
-
14
- # Only care about git checkout/switch targeting session/ branches
15
- if ! echo "$COMMAND" | grep -qE 'git\s+(checkout|switch)\s+.*session/' 2>/dev/null; then
16
- exit 0
17
- fi
18
-
19
- # Pattern 1: git -C <repo> checkout session/ — always wrong (targets main repo from outside)
20
- if echo "$COMMAND" | grep -qE 'git\s+-C\s+\S+\s+(checkout|switch)\s+.*session/' 2>/dev/null; then
21
- printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"BLOCKED: git checkout session/ with -C targets the main repo directly. This disrupts other parallel sessions. You are in a worktree — run `git checkout session/{name}` from INSIDE your worktree (without -C) instead. If you are not in a worktree, something is wrong with your isolation setup."}}'
22
- exit 0
23
- fi
24
-
25
- # Pattern 2: git checkout session/ without -C — check if we are in a main repo
26
- # In a worktree, .git is a FILE (gitdir pointer). In a main repo, .git is a DIRECTORY.
27
- if [ -d ".git" ] && [ ! -f ".git" ]; then
28
- printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"BLOCKED: git checkout session/ detected in a main repo (not a worktree). Checking out a session branch in the main repo disrupts other parallel sessions. You must work in an isolated worktree. If you are a teammate, your worktree should already exist — run `git checkout session/{name}` from inside it."}}'
29
- exit 0
30
- fi
31
-
32
- # We are in a worktree (.git is a file) — allow the checkout
33
- exit 0