@scriptgun/workerc 0.2.0 → 0.4.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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # workerc
2
2
 
3
- Claude Code session management — commands, hooks, and progress tracking.
3
+ Claude Code session management — commands, hooks, agents, and progress tracking.
4
4
 
5
- workerc adds structured session workflows to any project using [Claude Code](https://docs.anthropic.com/en/docs/claude-code). It installs slash commands for managing work sessions, hooks that enforce progress tracking and code quality, and a progress file system that persists context across sessions.
5
+ workerc adds structured session workflows to any project using [Claude Code](https://docs.anthropic.com/en/docs/claude-code). It installs slash commands for managing work sessions, hooks that enforce progress tracking and code quality, agents for specialized tasks, and a progress file system that persists context across sessions.
6
6
 
7
7
  ## Install
8
8
 
@@ -12,16 +12,19 @@ npx @scriptgun/workerc init
12
12
 
13
13
  This interactively sets up:
14
14
 
15
- - **10 slash commands** in `.claude/commands/workerc/`
16
- - **Hooks** in `.claude/hooks/` (tracker + optional lint/type check)
17
- - **Settings** in `.claude/settings.local.json`
15
+ - **14 slash commands** in `.claude/commands/workerc/`
16
+ - **7 hooks** in `.claude/hooks/`
17
+ - **4 agents** in `.claude/agents/` (custom agents preserved on re-init)
18
+ - **Settings** in `.claude/settings.local.json` or `.claude/settings.json`
18
19
  - **Progress directory** at `.claude/progress/`
20
+ - **Optional CLAUDE.md** scaffold
19
21
 
20
22
  ## Commands
21
23
 
22
24
  | Command | Description |
23
25
  |---------|-------------|
24
26
  | `/workerc:new` | Start a new work session with optional spec |
27
+ | `/workerc:plan` | Refine spec with codebase context — turns intent into blueprint |
25
28
  | `/workerc:resume` | Resume an unclaimed session |
26
29
  | `/workerc:status` | Show current session progress |
27
30
  | `/workerc:list` | List all progress files with status |
@@ -31,32 +34,53 @@ This interactively sets up:
31
34
  | `/workerc:handoff` | Pause session with handoff notes |
32
35
  | `/workerc:done` | Mark session complete |
33
36
  | `/workerc:abort` | Abandon session |
37
+ | `/workerc:debug` | Investigate a bug with scientific method debugging |
38
+ | `/workerc:checkpoint` | Create a save point for safe rollback |
39
+ | `/workerc:update` | Update workerc to latest version |
34
40
 
35
41
  ## Hooks
36
42
 
37
43
  ### Always installed
38
44
 
39
- - **post-edit-tracker.sh** — Blocks edits if no progress file is active. Auto-claims pending sessions on first edit. Auto-tracks edited files. Enforces 15s freshness (agent must update progress regularly).
40
- - **session-start-compact.sh** — Re-injects session context after Claude compacts the conversation. Restores progress file, spec, and file list so the agent can continue seamlessly.
45
+ - **post-edit-tracker.sh** — Blocks edits if no progress file is active. Auto-claims pending sessions on first edit. Auto-tracks edited files. Enforces 15s freshness.
46
+ - **session-start-compact.sh** — Re-injects session context after conversation compaction. Restores progress file, spec, and file list.
47
+ - **session-start-startup.sh** — Injects active progress context on every session start, not just compaction.
48
+ - **workerc-check-update.cjs** — Checks npm registry for new workerc versions in background. Caches result for statusline.
49
+ - **workerc-statusline.cjs** — Shows model, current task, directory, and context usage bar with color thresholds.
41
50
 
42
51
  ### Optional (auto-detected)
43
52
 
44
53
  - **post-edit-lint.sh** — Runs linter on every file edit. Detected tools: Biome, ESLint.
45
54
  - **post-edit-types.sh** — Runs type checker on every file edit. Detected tools: TypeScript (`tsc`).
46
55
 
56
+ ## Agents
57
+
58
+ | Agent | Description |
59
+ |-------|-------------|
60
+ | **browser** | Web browsing and automation via Playwright MCP |
61
+ | **commit** | Single-line git commits (`type(scope?): message`) |
62
+ | **finder** | Fast codebase search using Haiku model |
63
+ | **debugger** | Scientific method debugging with persistent debug sessions |
64
+
47
65
  ## How it works
48
66
 
49
- 1. Run `/workerc:new` to start a session — creates a progress file in `.claude/progress/`
50
- 2. The tracker hook auto-claims the session on your first file edit
51
- 3. As you work, the tracker logs edited files and enforces regular progress updates
52
- 4. Use `/workerc:commit` to commit, `/workerc:review` to check against spec
53
- 5. Use `/workerc:handoff` to pause or `/workerc:done` to complete
67
+ 1. Run `/workerc:new` to start a session — creates a progress file and optional spec
68
+ 2. Run `/workerc:plan` to refine the spec with real codebase context
69
+ 3. The tracker hook auto-claims the session on your first file edit
70
+ 4. As you work, the tracker logs edited files and enforces regular progress updates
71
+ 5. The statusline shows your current task, model, and context usage
72
+ 6. Use `/workerc:commit` to commit, `/workerc:review` to check against spec
73
+ 7. Use `/workerc:handoff` to pause or `/workerc:done` to complete
54
74
 
55
75
  Progress files persist across sessions — use `/workerc:resume` to pick up where you left off.
56
76
 
57
77
  ## Re-running init
58
78
 
59
- `workerc init` is idempotent. Running it again updates all commands and hooks without duplicating settings entries.
79
+ `workerc init` is idempotent. Running it again updates all commands, hooks, and agents without duplicating settings entries. Custom agents you've added to `.claude/agents/` are preserved.
80
+
81
+ ## Changelog
82
+
83
+ See [CHANGELOG.md](./CHANGELOG.md) for release history.
60
84
 
61
85
  ## License
62
86
 
package/dist/init.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
1
3
  import * as p from "@clack/prompts";
2
4
  import { detect } from "./detect.js";
3
5
  import { mergeSettings } from "./merge-settings.js";
@@ -120,8 +122,25 @@ export async function init(projectDir) {
120
122
  hookDescriptions.push(`- ${typesHookFilename} (blocks on type errors)`);
121
123
  }
122
124
  hookDescriptions.push("- post-edit-tracker.sh (blocks if progress not updated within 15s)");
125
+ hookDescriptions.push("- workerc-check-update.cjs (checks for workerc updates on session start)");
126
+ hookDescriptions.push("- workerc-statusline.cjs (shows model, task, directory, context usage)");
127
+ hookDescriptions.push("- session-start-startup.sh (injects active progress on session start)");
123
128
  const activeHooksDescription = hookDescriptions.join("\n");
124
- /* Step 6: Write files */
129
+ /* Step 6: CLAUDE.md */
130
+ let enableClaudeMd = false;
131
+ const claudeMdExists = existsSync(join(projectDir, ".claude", "CLAUDE.md"));
132
+ if (!claudeMdExists) {
133
+ const claudeMdAnswer = await p.confirm({
134
+ message: "Scaffold .claude/CLAUDE.md?",
135
+ initialValue: true,
136
+ });
137
+ if (p.isCancel(claudeMdAnswer)) {
138
+ p.cancel("Cancelled");
139
+ process.exit(0);
140
+ }
141
+ enableClaudeMd = claudeMdAnswer;
142
+ }
143
+ /* Step 7: Write files */
125
144
  spinner.start("Writing files");
126
145
  const result = writeFiles({
127
146
  projectDir,
@@ -134,9 +153,10 @@ export async function init(projectDir) {
134
153
  typeExtensions,
135
154
  typesHookFilename,
136
155
  activeHooksDescription,
156
+ enableClaudeMd,
137
157
  });
138
158
  spinner.stop("Files written");
139
- /* Step 7: Merge settings */
159
+ /* Step 8: Merge settings */
140
160
  spinner.start("Updating settings");
141
161
  const settingsFile = mergeSettings({
142
162
  projectDir,
@@ -147,20 +167,26 @@ export async function init(projectDir) {
147
167
  typesHookFilename,
148
168
  });
149
169
  spinner.stop("Settings updated");
150
- /* Step 8: Summary */
170
+ /* Step 9: Summary */
151
171
  p.log.success("workerc installed");
152
- p.log.message([
172
+ const summary = [
153
173
  "",
154
- "Commands (10):",
174
+ `Commands (${result.commands.length}):`,
155
175
  ...result.commands.map((f) => ` .claude/commands/workerc/${f}`),
156
176
  "",
157
177
  "Hooks:",
158
178
  ...result.hooks.map((f) => ` .claude/hooks/${f}`),
159
179
  "",
180
+ `Agents (${result.agents.length} built-in${result.customAgentCount > 0 ? `, ${result.customAgentCount} custom preserved` : ""}):`,
181
+ ...result.agents.map((f) => ` .claude/agents/${f}`),
182
+ "",
160
183
  `Settings: .claude/${settingsFile}`,
161
184
  "Progress: .claude/progress/",
162
- "",
163
- "Get started: run /workerc:new in Claude Code",
164
- ].join("\n"));
185
+ ];
186
+ if (result.claudeMd) {
187
+ summary.push("CLAUDE.md: .claude/CLAUDE.md (customize it)");
188
+ }
189
+ summary.push("", "Get started: run /workerc:new in Claude Code");
190
+ p.log.message(summary.join("\n"));
165
191
  p.outro("done");
166
192
  }
@@ -9,6 +9,9 @@ const WORKERC_HOOK_NAMES = [
9
9
  "post-edit-tracker.sh",
10
10
  "post-edit-lint.sh",
11
11
  "post-edit-types.sh",
12
+ "workerc-check-update.cjs",
13
+ "workerc-statusline.cjs",
14
+ "session-start-startup.sh",
12
15
  ];
13
16
  function isWorkercHook(hook) {
14
17
  return WORKERC_HOOK_NAMES.some((name) => hook.command.includes(name));
@@ -44,7 +47,30 @@ export function mergeSettings(options) {
44
47
  },
45
48
  ],
46
49
  };
47
- settings.hooks.SessionStart = [...existingSessionStart, compactHook];
50
+ const checkUpdateHook = {
51
+ matcher: "",
52
+ hooks: [
53
+ {
54
+ type: "command",
55
+ command: 'node "$CLAUDE_PROJECT_DIR"/.claude/hooks/workerc-check-update.cjs',
56
+ },
57
+ ],
58
+ };
59
+ const startupHook = {
60
+ matcher: "",
61
+ hooks: [
62
+ {
63
+ type: "command",
64
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/session-start-startup.sh',
65
+ },
66
+ ],
67
+ };
68
+ settings.hooks.SessionStart = [
69
+ ...existingSessionStart,
70
+ startupHook,
71
+ compactHook,
72
+ checkUpdateHook,
73
+ ];
48
74
  /* PostToolUse: keep non-workerc hooks, append workerc hooks */
49
75
  const existingPostToolUse = (settings.hooks.PostToolUse ?? []).filter((g) => !isWorkercGroup(g));
50
76
  const newPostToolUse = [];
@@ -81,6 +107,11 @@ export function mergeSettings(options) {
81
107
  ],
82
108
  });
83
109
  settings.hooks.PostToolUse = [...existingPostToolUse, ...newPostToolUse];
110
+ /* Statusline: always overwrite with workerc's */
111
+ settings.statusLine = {
112
+ type: "command",
113
+ command: 'node "$CLAUDE_PROJECT_DIR"/.claude/hooks/workerc-statusline.cjs',
114
+ };
84
115
  writeFileSync(settingsPath, JSON.stringify(settings, null, "\t") + "\n");
85
116
  return filename;
86
117
  }
@@ -0,0 +1,17 @@
1
+ ## Behavior
2
+ - concise responses
3
+ - read relevant docs before work
4
+ - root cause > quick fix
5
+
6
+ ## Code Style
7
+ <!-- customize for your project -->
8
+
9
+ ## Repo
10
+ <!-- describe your repo structure, package manager, build tools -->
11
+
12
+ ## Agents
13
+ | agent | purpose |
14
+ |-------|---------|
15
+ | browser | web automation via Playwright MCP |
16
+ | commit | git commits |
17
+ | finder | fast codebase search |
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: browser
3
+ description: Web browsing and automation
4
+ tools: Read, Bash
5
+ ---
6
+
7
+ Use Playwright MCP for browser automation.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: commit
3
+ description: Create git commits
4
+ tools: Read, Bash, Grep, Glob
5
+ ---
6
+
7
+ Single line commits: `type(scope?): message`
8
+ No description body, no co-author.
@@ -0,0 +1,256 @@
1
+ ---
2
+ name: debugger
3
+ description: Investigates bugs using scientific method with persistent debug sessions
4
+ tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch
5
+ ---
6
+
7
+ <role>
8
+ You investigate bugs using systematic scientific method. You maintain a persistent debug file that survives context resets.
9
+
10
+ User = Reporter (knows symptoms), You = Investigator (find the cause).
11
+
12
+ Never ask the user what's causing the bug or which file has the problem. Ask about their experience. Investigate the cause yourself.
13
+ </role>
14
+
15
+ <philosophy>
16
+
17
+ ## Meta-Debugging: Your Own Code
18
+
19
+ When debugging code you wrote, you're fighting your own mental model.
20
+
21
+ - **Treat your code as foreign** — read it as if someone else wrote it
22
+ - **Question your design decisions** — they're hypotheses, not facts
23
+ - **Admit your mental model might be wrong** — code behavior is truth, your model is a guess
24
+ - **Prioritize code you touched** — if you modified 100 lines and something breaks, those are prime suspects
25
+
26
+ The hardest admission: "I implemented this wrong."
27
+
28
+ ## Foundation Principles
29
+
30
+ - **What do you know for certain?** Observable facts, not assumptions
31
+ - **What are you assuming?** Have you verified it?
32
+ - **Strip away everything you think you know.** Build from observable facts.
33
+
34
+ ## Cognitive Biases
35
+
36
+ | Bias | Trap | Antidote |
37
+ |------|------|----------|
38
+ | Confirmation | Only seek supporting evidence | "What would prove me wrong?" |
39
+ | Anchoring | First explanation becomes your anchor | Generate 3+ hypotheses before investigating any |
40
+ | Sunk Cost | 2 hours on one path, keep going | Every 30 min: "If I started fresh, would I take this path?" |
41
+
42
+ ## Core Disciplines
43
+
44
+ - **Change one variable** at a time. Multiple changes = no idea what mattered.
45
+ - **Complete reading.** Read entire functions, not just "relevant" lines.
46
+ - **Embrace not knowing.** "I don't know" = good. "It must be X" = dangerous.
47
+
48
+ </philosophy>
49
+
50
+ <hypothesis_testing>
51
+
52
+ ## Falsifiability
53
+
54
+ A good hypothesis can be proven wrong. If you can't design an experiment to disprove it, it's not useful.
55
+
56
+ **Bad:** "Something is wrong with the state"
57
+ **Good:** "User state resets because component remounts on route change"
58
+
59
+ The difference: specificity.
60
+
61
+ ## Process
62
+
63
+ For each hypothesis:
64
+ 1. **Prediction:** If H is true, I will observe X
65
+ 2. **Test:** Execute one specific test
66
+ 3. **Observe:** Record what actually happened
67
+ 4. **Conclude:** Support or refute?
68
+
69
+ **One hypothesis at a time.** If you change three things and it works, you don't know which fixed it.
70
+
71
+ ## Evidence Quality
72
+
73
+ **Strong:** Directly observable, repeatable, unambiguous, independent
74
+ **Weak:** Hearsay, non-repeatable, ambiguous, confounded
75
+
76
+ Act when you can answer YES to all:
77
+ 1. Understand the mechanism? (not just "what" but "why")
78
+ 2. Reproduce reliably?
79
+ 3. Have evidence, not just theory?
80
+ 4. Ruled out alternatives?
81
+
82
+ ## When Disproven
83
+
84
+ 1. Acknowledge explicitly with evidence
85
+ 2. Extract the learning — what did this rule out?
86
+ 3. Form new hypotheses based on what you now know
87
+ 4. Don't get attached — being wrong quickly beats being wrong slowly
88
+
89
+ </hypothesis_testing>
90
+
91
+ <investigation_techniques>
92
+
93
+ ## Binary Search
94
+
95
+ **When:** Large codebase, many possible failure points.
96
+
97
+ Cut problem space in half repeatedly:
98
+ 1. Identify boundaries (where works, where fails)
99
+ 2. Test midpoint
100
+ 3. Determine which half contains the bug
101
+ 4. Repeat until exact line
102
+
103
+ ## Minimal Reproduction
104
+
105
+ **When:** Complex system, many moving parts.
106
+
107
+ 1. Copy failing code to new file
108
+ 2. Remove one piece at a time
109
+ 3. Still reproduces? Keep it removed. Doesn't? Put it back.
110
+ 4. Repeat until bare minimum
111
+ 5. Bug is now obvious
112
+
113
+ ## Working Backwards
114
+
115
+ **When:** You know correct output, don't know why you're not getting it.
116
+
117
+ 1. Define desired output precisely
118
+ 2. What function produces this? Test with expected input.
119
+ 3. Correct output? Bug is earlier. Wrong output? Bug is here.
120
+ 4. Repeat backwards through call stack
121
+
122
+ ## Differential Debugging
123
+
124
+ **When:** Used to work, now doesn't. Works in one env but not another.
125
+
126
+ List differences (code, env, config, data), test each in isolation.
127
+
128
+ ## Git Bisect
129
+
130
+ **When:** Feature worked in past, broke at unknown commit.
131
+
132
+ ```bash
133
+ git bisect start
134
+ git bisect bad
135
+ git bisect good abc123
136
+ ```
137
+
138
+ 100 commits → ~7 tests to find breaking commit.
139
+
140
+ ## Technique Selection
141
+
142
+ | Situation | Technique |
143
+ |-----------|-----------|
144
+ | Large codebase | Binary search |
145
+ | Confused | Rubber duck, add logging first |
146
+ | Complex system | Minimal reproduction |
147
+ | Know desired output | Working backwards |
148
+ | Used to work | Differential debugging, git bisect |
149
+ | Many possible causes | Comment out everything |
150
+
151
+ </investigation_techniques>
152
+
153
+ <debug_file>
154
+
155
+ ## Location
156
+
157
+ Debug files live in `.claude/progress/debug-{slug}.md`
158
+
159
+ ## Structure
160
+
161
+ ```markdown
162
+ # Debug: {title}
163
+ <!-- session: {SESSION_ID} -->
164
+ <!-- spec: None -->
165
+
166
+ ## Current Focus
167
+ hypothesis: {current theory}
168
+ test: {how testing it}
169
+ next: {immediate next step}
170
+
171
+ ## Symptoms
172
+ expected: {what should happen}
173
+ actual: {what actually happens}
174
+ errors: {error messages}
175
+ reproduction: {how to trigger}
176
+
177
+ ## Eliminated
178
+ - {theory}: {evidence that disproved it}
179
+
180
+ ## Evidence
181
+ - {what examined}: {what observed} → {implication}
182
+
183
+ ## Log
184
+ - [ ] ({timestamp}) (debug) {action taken}
185
+
186
+ ## Files
187
+ ```
188
+
189
+ ## Rules
190
+
191
+ | Section | Rule |
192
+ |---------|------|
193
+ | Current Focus | OVERWRITE before every action |
194
+ | Symptoms | IMMUTABLE after gathering |
195
+ | Eliminated | APPEND only |
196
+ | Evidence | APPEND only |
197
+ | Log | APPEND only |
198
+
199
+ Update the file BEFORE taking action, not after. If context resets, the file shows what was about to happen.
200
+
201
+ </debug_file>
202
+
203
+ <execution_flow>
204
+
205
+ **Step 1: Start or resume**
206
+
207
+ Check `.claude/progress/debug-*.md` for active sessions matching this session ID.
208
+
209
+ If resuming: read file, announce status, continue from Current Focus.
210
+ If new: create debug file immediately.
211
+
212
+ **Step 2: Gather symptoms**
213
+
214
+ Ask about: expected behavior, actual behavior, error messages, when it started.
215
+ Update file after EACH answer.
216
+
217
+ **Step 3: Investigate**
218
+
219
+ 1. Gather initial evidence (search codebase, read files, run tests)
220
+ 2. Form SPECIFIC, FALSIFIABLE hypothesis
221
+ 3. Test ONE hypothesis at a time
222
+ 4. Append to Evidence and Eliminated as you go
223
+ 5. Repeat until root cause confirmed
224
+
225
+ **Step 4: Fix**
226
+
227
+ - Make SMALLEST change that addresses root cause
228
+ - Update debug file with fix details
229
+
230
+ **Step 5: Verify**
231
+
232
+ - Test against original Symptoms
233
+ - If fails: back to Step 3
234
+ - If passes: log resolution
235
+
236
+ **Step 6: Done**
237
+
238
+ Log completion in debug file. Print root cause and fix summary.
239
+
240
+ </execution_flow>
241
+
242
+ <when_to_restart>
243
+
244
+ Consider starting over when:
245
+ 1. 2+ hours with no progress — you're tunnel-visioned
246
+ 2. 3+ "fixes" that didn't work — your mental model is wrong
247
+ 3. You can't explain the current behavior — don't add changes on top of confusion
248
+ 4. The fix works but you don't know why — this isn't fixed, this is luck
249
+
250
+ Restart protocol:
251
+ 1. Write down what you know for certain
252
+ 2. Write down what you've ruled out
253
+ 3. List new hypotheses (different from before)
254
+ 4. Begin again from evidence gathering
255
+
256
+ </when_to_restart>
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: finder
3
+ description: Fast codebase search
4
+ tools: Read, Grep, Glob
5
+ model: haiku
6
+ ---
7
+
8
+ Returns file paths with line numbers.
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: workerc:checkpoint
3
+ description: Create a save point — snapshot current state for safe rollback
4
+ allowed-tools:
5
+ - Read
6
+ - Bash
7
+ - Glob
8
+ - AskUserQuestion
9
+ ---
10
+
11
+ <objective>
12
+ Create a named checkpoint of the current working state. Uses git to snapshot changes so you can rollback if the next steps go wrong. Logs checkpoint in progress file.
13
+ </objective>
14
+
15
+ <process>
16
+
17
+ **Step 1: Find session progress file**
18
+
19
+ Read all `.claude/progress/*.md`. Find the one with `<!-- session: CURRENT_SESSION_ID -->` on line 2.
20
+
21
+ If none found: print "No active progress file for this session." and STOP.
22
+
23
+ **Step 2: Check git state**
24
+
25
+ Run `git status --short` and `git diff --stat`.
26
+
27
+ If no changes (clean working tree):
28
+ - Print: "Nothing to checkpoint — working tree is clean."
29
+ - STOP
30
+
31
+ **Step 3: Name the checkpoint**
32
+
33
+ Ask:
34
+ ```
35
+ AskUserQuestion(
36
+ header: "Checkpoint",
37
+ question: "Name this checkpoint? (describes what's safe so far)",
38
+ options: [
39
+ { label: "Auto-name", description: "Generate from progress file context" },
40
+ { label: "I'll name it", description: "I'll provide a name" }
41
+ ],
42
+ multiSelect: false
43
+ )
44
+ ```
45
+
46
+ **If "Auto-name":** Generate from latest progress log entries (e.g. "auth-middleware-working").
47
+ **If "I'll name it":** Wait for user input.
48
+
49
+ Generate tag name: `checkpoint/{slug}/{YYYYMMDD-HHMM}` (e.g. `checkpoint/auth-middleware-working/20260210-1530`).
50
+
51
+ **Step 4: Create checkpoint**
52
+
53
+ Stage all current changes and create a temporary commit + tag:
54
+
55
+ ```bash
56
+ git stash push -m "workerc-checkpoint: {name}"
57
+ git stash apply
58
+ ```
59
+
60
+ This creates a stash entry that acts as a named snapshot. The working tree stays exactly as it was.
61
+
62
+ Log in progress file:
63
+ `- [x] ({YYYY-MM-DD HH:MM}) (checkpoint) {name}`
64
+
65
+ Print:
66
+ ```
67
+ Checkpoint created: {name}
68
+ Stash: git stash list | grep "workerc-checkpoint: {name}"
69
+ Rollback: git stash pop (applies last stash) or git checkout -- . (discard changes)
70
+ ```
71
+
72
+ STOP.
73
+
74
+ </process>
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: workerc:debug
3
+ description: Investigate a bug using scientific method with persistent debug session
4
+ allowed-tools:
5
+ - Read
6
+ - Write
7
+ - Edit
8
+ - Glob
9
+ - Grep
10
+ - Bash
11
+ - AskUserQuestion
12
+ - WebSearch
13
+ ---
14
+
15
+ <objective>
16
+ Start or resume a debug session. Uses scientific method: gather symptoms, form hypotheses, test one at a time, find root cause, fix, verify. Maintains a persistent debug file that survives context resets.
17
+ </objective>
18
+
19
+ <process>
20
+
21
+ **Step 1: Check for active debug sessions**
22
+
23
+ Look for files matching `.claude/progress/debug-*.md` that are NOT marked `[DONE]` or `[ABORTED]`.
24
+
25
+ If active sessions exist AND user didn't describe a new issue:
26
+ - List them with current hypothesis and next action
27
+ - Ask:
28
+ ```
29
+ AskUserQuestion(
30
+ header: "Debug",
31
+ question: "Resume existing session or start new?",
32
+ options: [
33
+ { label: "Resume", description: "Continue the active debug session" },
34
+ { label: "New", description: "Start investigating a new bug" }
35
+ ],
36
+ multiSelect: false
37
+ )
38
+ ```
39
+
40
+ If no active sessions or user chose "New": continue to Step 2.
41
+ If "Resume": read the debug file, announce status and current hypothesis, continue from where Current Focus left off.
42
+
43
+ **Step 2: Gather symptoms**
44
+
45
+ Ask the user:
46
+ ```
47
+ AskUserQuestion(
48
+ header: "Bug",
49
+ question: "What's happening?",
50
+ options: [
51
+ { label: "Describe it", description: "I'll explain the symptoms" },
52
+ { label: "Error message", description: "I have a specific error" }
53
+ ],
54
+ multiSelect: false
55
+ )
56
+ ```
57
+
58
+ Wait for user input. Then ask follow-ups as needed:
59
+ - What did you expect to happen?
60
+ - When did it start? Did it ever work?
61
+ - Can you reproduce it consistently?
62
+
63
+ **Step 3: Create debug file**
64
+
65
+ Generate slug from the bug description (lowercase, hyphens, max 30 chars).
66
+
67
+ Write `.claude/progress/debug-{slug}.md`:
68
+ ```markdown
69
+ # Debug: {title}
70
+ <!-- session: pending -->
71
+ <!-- spec: None -->
72
+
73
+ ## Current Focus
74
+ hypothesis: gathering symptoms
75
+ test: n/a
76
+ next: investigate codebase around error
77
+
78
+ ## Symptoms
79
+ expected: {what should happen}
80
+ actual: {what actually happens}
81
+ errors: {error messages or "none"}
82
+ reproduction: {how to trigger}
83
+
84
+ ## Eliminated
85
+
86
+ ## Evidence
87
+
88
+ ## Log
89
+ - [ ] ({YYYY-MM-DD HH:MM}) (debug) Session started: {title}
90
+
91
+ ## Files
92
+ ```
93
+
94
+ **Step 4: Investigate**
95
+
96
+ Follow the debugger methodology:
97
+
98
+ **4a. Gather initial evidence**
99
+ - Search codebase for error text, relevant files, related code
100
+ - Read the most relevant files COMPLETELY
101
+ - Run the app/tests to observe behavior
102
+ - APPEND each finding to `## Evidence`
103
+
104
+ **4b. Form hypothesis**
105
+ - Based on evidence, form a SPECIFIC, FALSIFIABLE hypothesis
106
+ - Update `## Current Focus` with hypothesis, test, and next action
107
+ - Log: `- [ ] ({timestamp}) (debug) Hypothesis: {hypothesis}`
108
+
109
+ **4c. Test hypothesis**
110
+ - Execute ONE test at a time
111
+ - Change ONE variable at a time
112
+ - Append result to `## Evidence`
113
+
114
+ **4d. Evaluate**
115
+ - **Confirmed:** Root cause found — proceed to Step 5
116
+ - **Eliminated:** Append to `## Eliminated` with evidence, form new hypothesis, repeat 4b
117
+
118
+ Key principles:
119
+ - One hypothesis at a time
120
+ - Falsifiable predictions: "If H is true, I will observe X"
121
+ - Strong evidence: directly observable, repeatable, unambiguous
122
+ - Don't act on "I think it might be X" — wait for proof
123
+
124
+ **Step 5: Present root cause and fix plan**
125
+
126
+ ```
127
+ ## Root Cause Found
128
+
129
+ **Cause:** {specific root cause with evidence}
130
+
131
+ **Evidence:**
132
+ - {key finding 1}
133
+ - {key finding 2}
134
+
135
+ **Proposed fix:** {minimal change to address root cause}
136
+
137
+ **Files to change:**
138
+ - {file}: {what to change}
139
+ ```
140
+
141
+ Ask:
142
+ ```
143
+ AskUserQuestion(
144
+ header: "Fix",
145
+ question: "How should we proceed?",
146
+ options: [
147
+ { label: "Fix it", description: "Apply the minimal fix" },
148
+ { label: "Different fix", description: "I want a different approach" },
149
+ { label: "Just diagnose", description: "Don't fix, I'll handle it" }
150
+ ],
151
+ multiSelect: false
152
+ )
153
+ ```
154
+
155
+ **If "Fix it":** Apply the smallest change that addresses root cause. Proceed to Step 6.
156
+ **If "Different fix":** Wait for user's approach, apply that instead. Proceed to Step 6.
157
+ **If "Just diagnose":** Log root cause, mark session done, STOP.
158
+
159
+ **Step 6: Verify**
160
+
161
+ - Test against original Symptoms
162
+ - Run related tests if they exist
163
+ - Verify the fix doesn't break adjacent functionality
164
+
165
+ **If verification fails:** Log failure, go back to Step 4 with new evidence.
166
+
167
+ **If verification passes:**
168
+
169
+ Update debug file:
170
+ - Log: `- [x] ({timestamp}) (debug) Root cause: {cause}`
171
+ - Log: `- [x] ({timestamp}) (debug) Fix verified: {what was fixed}`
172
+
173
+ Print:
174
+ ```
175
+ Bug fixed and verified.
176
+ Root cause: {cause}
177
+ Fix: {what changed}
178
+ Files: {list}
179
+ ```
180
+
181
+ STOP.
182
+
183
+ </process>
@@ -0,0 +1,167 @@
1
+ ---
2
+ name: workerc:plan
3
+ description: Refine spec with codebase context — turns intent into implementation blueprint
4
+ allowed-tools:
5
+ - Read
6
+ - Edit
7
+ - Glob
8
+ - Grep
9
+ - Bash
10
+ - AskUserQuestion
11
+ ---
12
+
13
+ <objective>
14
+ Read the current spec + progress, explore the codebase around relevant areas, present recommendations with options to the user, then rewrite the spec with concrete implementation details.
15
+ Turns vague intent into a precise blueprint with real file paths, patterns, types, and edge cases.
16
+ </objective>
17
+
18
+ <process>
19
+
20
+ **Step 1: Find session and spec**
21
+
22
+ Read all `.claude/progress/*.md`. Find the one with `<!-- session: CURRENT_SESSION_ID -->` on line 2.
23
+
24
+ If none found: print "No active progress file for this session." and STOP.
25
+
26
+ Read line 3 for spec path.
27
+
28
+ If spec is "None" or missing:
29
+ - Print: "No spec linked to this session. Create one with /workerc:new or /workerc:scope first."
30
+ - STOP
31
+
32
+ Read the full spec file. Read the full progress file.
33
+
34
+ **Step 2: Understand the goal**
35
+
36
+ From the spec's `## Goal` and `## Scope` sections, identify:
37
+ - What the user wants to build/change
38
+ - What's explicitly in/out of scope
39
+ - Any decisions already made (in `## Decisions`)
40
+
41
+ Print a one-line summary of the goal to confirm understanding.
42
+
43
+ **Step 3: Explore the codebase**
44
+
45
+ Based on the goal and scope, explore the codebase to gather real context:
46
+
47
+ - **Find relevant files:** Use Glob and Grep to find files related to the goal. Look for existing patterns, types, utilities, middleware, routes, tests — anything the implementation should follow or integrate with.
48
+ - **Read key files:** Read the most relevant 3-5 files to understand existing patterns, naming conventions, directory structure, and coding style.
49
+ - **Map dependencies:** Identify what the new code needs to import, extend, or integrate with.
50
+ - **Check for prior art:** Look for similar features already implemented that can serve as a template.
51
+
52
+ **Step 4: Present recommendations**
53
+
54
+ Based on what you discovered, present a structured recommendation:
55
+
56
+ ```
57
+ ## Recommendation
58
+
59
+ ### Approach
60
+ {1-3 sentences describing the recommended approach}
61
+
62
+ ### Key files
63
+ - `path/to/file.ts` — {why this file matters}
64
+ - `path/to/pattern.ts` — {pattern to follow}
65
+
66
+ ### Implementation steps
67
+ 1. {step 1}
68
+ 2. {step 2}
69
+ ...
70
+
71
+ ### Patterns to follow
72
+ - {existing pattern from codebase}
73
+
74
+ ### Edge cases
75
+ - {edge case 1}
76
+ - {edge case 2}
77
+
78
+ ### Open questions
79
+ - {anything unclear that needs user input}
80
+ ```
81
+
82
+ Then ask the user:
83
+
84
+ ```
85
+ AskUserQuestion(
86
+ header: "Plan",
87
+ question: "How should we proceed with this plan?",
88
+ options: [
89
+ { label: "Looks good", description: "Write this into the spec" },
90
+ { label: "Adjust", description: "I want to change some things" },
91
+ { label: "Different approach", description: "I have a different idea" }
92
+ ],
93
+ multiSelect: false
94
+ )
95
+ ```
96
+
97
+ **If "Adjust":**
98
+ - Wait for user's adjustments
99
+ - Incorporate their feedback
100
+ - Re-present the updated recommendation
101
+ - Ask again
102
+
103
+ **If "Different approach":**
104
+ - Wait for user's alternative
105
+ - Re-explore codebase with new direction
106
+ - Go back to Step 4
107
+
108
+ **If "Looks good":**
109
+ - Proceed to Step 5
110
+
111
+ **Step 5: Rewrite the spec**
112
+
113
+ Update the spec file with concrete implementation details. Preserve existing sections and add/expand:
114
+
115
+ ```markdown
116
+ # {Title}
117
+
118
+ ## Goal
119
+ {original goal, unchanged}
120
+
121
+ ## Scope
122
+ {original scope, unchanged}
123
+
124
+ ## Implementation Plan
125
+
126
+ ### Approach
127
+ {the approved approach}
128
+
129
+ ### Steps
130
+ - [ ] {step 1} — `path/to/file.ts`
131
+ - [ ] {step 2} — `path/to/file.ts`
132
+ ...
133
+
134
+ ### Patterns
135
+ {existing patterns to follow, with file:line references}
136
+
137
+ ### Types / Interfaces
138
+ {key types the implementation needs, with references to where they're defined}
139
+
140
+ ### Edge Cases
141
+ {edge cases to handle}
142
+
143
+ ## Decisions
144
+ {any new decisions from the planning process, appended to existing}
145
+
146
+ ## Discovered
147
+ {anything discovered during exploration — gotchas, constraints, existing bugs}
148
+
149
+ ## Rejected
150
+ {approaches considered but rejected, with reasons}
151
+ ```
152
+
153
+ **Step 6: Log and confirm**
154
+
155
+ Add to progress log:
156
+ `- [x] ({YYYY-MM-DD HH:MM}) (plan) Refined spec with implementation details`
157
+
158
+ Print:
159
+ ```
160
+ Spec updated: {spec path}
161
+ {N} implementation steps planned
162
+ Ready to build — the spec is now your blueprint.
163
+ ```
164
+
165
+ STOP.
166
+
167
+ </process>
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: workerc:update
3
+ description: Update workerc to the latest version
4
+ allowed-tools:
5
+ - Bash
6
+ ---
7
+
8
+ <objective>
9
+ Update workerc to the latest version and re-run init.
10
+ </objective>
11
+
12
+ <process>
13
+
14
+ **Step 1: Run update**
15
+
16
+ ```bash
17
+ npx @scriptgun/workerc@latest init
18
+ ```
19
+
20
+ This will re-detect tools, re-write hooks, and update settings.
21
+ The init wizard is interactive — follow the prompts.
22
+
23
+ **Step 2: Confirm**
24
+
25
+ Print: "workerc updated. Restart Claude Code to pick up new hooks."
26
+
27
+ STOP.
28
+
29
+ </process>
@@ -0,0 +1,81 @@
1
+ #!/bin/bash
2
+ # SessionStart hook: Inject active progress context on fresh session start
3
+ # Fires on: every session start (matcher "" in settings)
4
+ # Complements session-start-compact.sh which only fires on compaction
5
+
6
+ INPUT=$(cat)
7
+ SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty')
8
+
9
+ [ -z "$SESSION_ID" ] && exit 0
10
+
11
+ TRACKER_DIR="$(cd "$(dirname "$0")/../progress" 2>/dev/null && pwd)"
12
+ [ -z "$TRACKER_DIR" ] || [ ! -d "$TRACKER_DIR" ] && exit 0
13
+
14
+ PROJECT_DIR="$(cd "$(dirname "$0")/../.." 2>/dev/null && pwd)"
15
+
16
+ # Find this session's active tracker
17
+ MY_TRACKER=""
18
+ for t in "$TRACKER_DIR"/*.md; do
19
+ [ -f "$t" ] || continue
20
+ LINE1=$(head -1 "$t")
21
+ echo "$LINE1" | grep -q "\[DONE\]" && continue
22
+ echo "$LINE1" | grep -q "\[ABORTED\]" && continue
23
+ LINE2=$(sed -n '2p' "$t")
24
+ if echo "$LINE2" | grep -q "<!-- session: $SESSION_ID -->"; then
25
+ MY_TRACKER="$t"
26
+ break
27
+ fi
28
+ done
29
+
30
+ [ -z "$MY_TRACKER" ] && exit 0
31
+
32
+ # Read tracker
33
+ TRACKER_CONTENT=$(cat "$MY_TRACKER")
34
+ TRACKER_NAME=$(basename "$MY_TRACKER")
35
+ TRACKER_REL=".claude/progress/$TRACKER_NAME"
36
+
37
+ # Extract spec path (line 3: <!-- spec: path -->)
38
+ SPEC_PATH=""
39
+ SPEC_CONTENT=""
40
+ SPEC_LINE=$(sed -n '3p' "$MY_TRACKER")
41
+ if echo "$SPEC_LINE" | grep -q "<!-- spec:"; then
42
+ SPEC_PATH=$(echo "$SPEC_LINE" | sed -n 's/<!-- spec: \(.*\) -->/\1/p')
43
+ fi
44
+
45
+ if [ -n "$SPEC_PATH" ] && [ "$SPEC_PATH" != "None" ]; then
46
+ FULL_SPEC="$PROJECT_DIR/$SPEC_PATH"
47
+ if [ -f "$FULL_SPEC" ]; then
48
+ SPEC_CONTENT=$(cat "$FULL_SPEC")
49
+ fi
50
+ fi
51
+
52
+ DONE_COUNT=$(grep -c '^\- \[x\]' "$MY_TRACKER" 2>/dev/null || echo "0")
53
+
54
+ CONTEXT="# ACTIVE SESSION CONTEXT
55
+
56
+ You have an active work session. Session ID: $SESSION_ID
57
+
58
+ ## Progress: $TRACKER_REL ($DONE_COUNT entries completed)
59
+ $TRACKER_CONTENT
60
+
61
+ ## REQUIRED: Read your context files before working:
62
+ 1. Read file $PROJECT_DIR/$TRACKER_REL"
63
+
64
+ if [ -n "$SPEC_PATH" ] && [ "$SPEC_PATH" != "None" ]; then
65
+ CONTEXT="$CONTEXT
66
+ 2. Read file $PROJECT_DIR/$SPEC_PATH"
67
+ fi
68
+
69
+ CONTEXT="$CONTEXT
70
+ 3. Review ## Files to rebuild code context
71
+ 4. Continue working from where you left off"
72
+
73
+ if [ -n "$SPEC_CONTENT" ]; then
74
+ CONTEXT="$CONTEXT
75
+
76
+ ## Spec: $SPEC_PATH
77
+ $SPEC_CONTENT"
78
+ fi
79
+
80
+ jq -n --arg ctx "$CONTEXT" '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":$ctx}}'
81
+ exit 0
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+ /* SessionStart hook: check for workerc updates in background */
3
+ /* Spawns a detached child so the hook exits immediately */
4
+
5
+ const fs = require("fs")
6
+ const path = require("path")
7
+ const os = require("os")
8
+ const { spawn } = require("child_process")
9
+
10
+ const homeDir = os.homedir()
11
+ const cacheDir = path.join(homeDir, ".claude", "cache")
12
+ const cacheFile = path.join(cacheDir, "workerc-update-check.json")
13
+
14
+ if (!fs.existsSync(cacheDir)) {
15
+ fs.mkdirSync(cacheDir, { recursive: true })
16
+ }
17
+
18
+ const child = spawn(
19
+ process.execPath,
20
+ [
21
+ "-e",
22
+ `
23
+ const fs = require("fs")
24
+ const { execSync } = require("child_process")
25
+
26
+ const cacheFile = ${JSON.stringify(cacheFile)}
27
+
28
+ let installed = "0.0.0"
29
+ try {
30
+ const out = execSync("npm ls @scriptgun/workerc --json 2>/dev/null || npx workerc --version 2>/dev/null", {
31
+ encoding: "utf8",
32
+ timeout: 10000,
33
+ windowsHide: true,
34
+ }).trim()
35
+ /* Try JSON parse (npm ls), fall back to raw version string */
36
+ try {
37
+ const json = JSON.parse(out)
38
+ installed = json.dependencies?.["@scriptgun/workerc"]?.version || "0.0.0"
39
+ } catch (_) {
40
+ if (/^\\d+\\.\\d+/.test(out)) installed = out
41
+ }
42
+ } catch (_) {}
43
+
44
+ let latest = null
45
+ try {
46
+ latest = execSync("npm view @scriptgun/workerc version", {
47
+ encoding: "utf8",
48
+ timeout: 10000,
49
+ windowsHide: true,
50
+ }).trim()
51
+ } catch (_) {}
52
+
53
+ const result = {
54
+ update_available: latest && installed !== latest,
55
+ installed,
56
+ latest: latest || "unknown",
57
+ checked: Math.floor(Date.now() / 1000),
58
+ }
59
+
60
+ fs.writeFileSync(cacheFile, JSON.stringify(result))
61
+ `,
62
+ ],
63
+ { stdio: "ignore", windowsHide: true }
64
+ )
65
+
66
+ child.unref()
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ /* Statusline hook: model | task | directory | context usage */
3
+ /* Reads current task from workerc progress files */
4
+
5
+ const fs = require("fs")
6
+ const path = require("path")
7
+ const os = require("os")
8
+
9
+ let input = ""
10
+ process.stdin.setEncoding("utf8")
11
+ process.stdin.on("data", (chunk) => (input += chunk))
12
+ process.stdin.on("end", () => {
13
+ try {
14
+ const data = JSON.parse(input)
15
+ const model = data.model?.display_name || "Claude"
16
+ const dir = data.workspace?.current_dir || process.cwd()
17
+ const session = data.session_id || ""
18
+ const remaining = data.context_window?.remaining_percentage
19
+
20
+ /* Context window bar (scaled to 80% real limit) */
21
+ let ctx = ""
22
+ if (remaining != null) {
23
+ const rem = Math.round(remaining)
24
+ const rawUsed = Math.max(0, Math.min(100, 100 - rem))
25
+ const used = Math.min(100, Math.round((rawUsed / 80) * 100))
26
+ const filled = Math.floor(used / 10)
27
+ const bar = "\u2588".repeat(filled) + "\u2591".repeat(10 - filled)
28
+
29
+ if (used < 63) {
30
+ ctx = ` \x1b[32m${bar} ${used}%\x1b[0m`
31
+ } else if (used < 81) {
32
+ ctx = ` \x1b[33m${bar} ${used}%\x1b[0m`
33
+ } else if (used < 95) {
34
+ ctx = ` \x1b[38;5;208m${bar} ${used}%\x1b[0m`
35
+ } else {
36
+ ctx = ` \x1b[5;31m\uD83D\uDC80 ${bar} ${used}%\x1b[0m`
37
+ }
38
+ }
39
+
40
+ /* Current task from workerc progress files */
41
+ let task = ""
42
+ const projectDir = data.workspace?.current_dir || process.cwd()
43
+ const progressDir = path.join(projectDir, ".claude", "progress")
44
+
45
+ if (session && fs.existsSync(progressDir)) {
46
+ const files = fs.readdirSync(progressDir).filter((f) => f.endsWith(".md"))
47
+
48
+ for (const file of files) {
49
+ const filePath = path.join(progressDir, file)
50
+ try {
51
+ const content = fs.readFileSync(filePath, "utf8")
52
+ const lines = content.split("\n")
53
+
54
+ /* Line 1: title, skip if DONE/ABORTED */
55
+ if (/\[DONE\]|\[ABORTED\]/.test(lines[0] || "")) continue
56
+ /* Line 2: <!-- session: ID --> */
57
+ if (!(lines[1] || "").includes(`<!-- session: ${session} -->`)) continue
58
+
59
+ /* Extract title from "# Title" */
60
+ const titleMatch = (lines[0] || "").match(/^#\s+(.+)/)
61
+ if (titleMatch) task = titleMatch[1].replace(/\s*\[.*?\]\s*/g, "").trim()
62
+ break
63
+ } catch (_) {}
64
+ }
65
+ }
66
+
67
+ /* workerc update available? */
68
+ let updateNotice = ""
69
+ const cacheFile = path.join(os.homedir(), ".claude", "cache", "workerc-update-check.json")
70
+ if (fs.existsSync(cacheFile)) {
71
+ try {
72
+ const cache = JSON.parse(fs.readFileSync(cacheFile, "utf8"))
73
+ if (cache.update_available) {
74
+ updateNotice = "\x1b[33m\u2B06 workerc update\x1b[0m \u2502 "
75
+ }
76
+ } catch (_) {}
77
+ }
78
+
79
+ /* Output */
80
+ const dirname = path.basename(dir)
81
+ if (task) {
82
+ process.stdout.write(
83
+ `${updateNotice}\x1b[2m${model}\x1b[0m \u2502 \x1b[1m${task}\x1b[0m \u2502 \x1b[2m${dirname}\x1b[0m${ctx}`
84
+ )
85
+ } else {
86
+ process.stdout.write(
87
+ `${updateNotice}\x1b[2m${model}\x1b[0m \u2502 \x1b[2m${dirname}\x1b[0m${ctx}`
88
+ )
89
+ }
90
+ } catch (_) {
91
+ /* Silent fail */
92
+ }
93
+ })
@@ -9,8 +9,12 @@ export interface WriteOptions {
9
9
  typeExtensions: string;
10
10
  typesHookFilename: string;
11
11
  activeHooksDescription: string;
12
+ enableClaudeMd: boolean;
12
13
  }
13
14
  export declare function writeFiles(options: WriteOptions): {
14
15
  commands: string[];
15
16
  hooks: string[];
17
+ agents: string[];
18
+ customAgentCount: number;
19
+ claudeMd: boolean;
16
20
  };
@@ -28,9 +28,11 @@ export function writeFiles(options) {
28
28
  const claudeDir = join(options.projectDir, ".claude");
29
29
  const commandsTarget = join(claudeDir, "commands", "workerc");
30
30
  const hooksTarget = join(claudeDir, "hooks");
31
+ const agentsTarget = join(claudeDir, "agents");
31
32
  const progressDir = join(claudeDir, "progress");
32
33
  ensureDir(commandsTarget);
33
34
  ensureDir(hooksTarget);
35
+ ensureDir(agentsTarget);
34
36
  ensureDir(progressDir);
35
37
  /* Copy command templates verbatim */
36
38
  const commandsSrc = join(templateDir, "commands");
@@ -38,12 +40,36 @@ export function writeFiles(options) {
38
40
  for (const file of commandFiles) {
39
41
  cpSync(join(commandsSrc, file), join(commandsTarget, file));
40
42
  }
43
+ /* Copy agent templates — only overwrite workerc's own agents */
44
+ const agentsSrc = join(templateDir, "agents");
45
+ const agentFiles = readdirSync(agentsSrc).filter((f) => f.endsWith(".md"));
46
+ const workercAgentNames = new Set(agentFiles);
47
+ for (const file of agentFiles) {
48
+ cpSync(join(agentsSrc, file), join(agentsTarget, file));
49
+ }
50
+ /* Count custom agents preserved (exist in target but not in workerc templates) */
51
+ const existingAgents = existsSync(agentsTarget)
52
+ ? readdirSync(agentsTarget).filter((f) => f.endsWith(".md"))
53
+ : [];
54
+ const customAgentCount = existingAgents.filter((f) => !workercAgentNames.has(f)).length;
41
55
  /* Copy/template hook files */
42
56
  const writtenHooks = [];
43
57
  /* Tracker — verbatim copy */
44
58
  cpSync(join(templateDir, "hooks", "post-edit-tracker.sh"), join(hooksTarget, "post-edit-tracker.sh"));
45
59
  chmodSync(join(hooksTarget, "post-edit-tracker.sh"), 0o755);
46
60
  writtenHooks.push("post-edit-tracker.sh");
61
+ /* Check-update — verbatim copy */
62
+ cpSync(join(templateDir, "hooks", "workerc-check-update.cjs"), join(hooksTarget, "workerc-check-update.cjs"));
63
+ chmodSync(join(hooksTarget, "workerc-check-update.cjs"), 0o755);
64
+ writtenHooks.push("workerc-check-update.cjs");
65
+ /* Statusline — verbatim copy */
66
+ cpSync(join(templateDir, "hooks", "workerc-statusline.cjs"), join(hooksTarget, "workerc-statusline.cjs"));
67
+ chmodSync(join(hooksTarget, "workerc-statusline.cjs"), 0o755);
68
+ writtenHooks.push("workerc-statusline.cjs");
69
+ /* Startup — verbatim copy */
70
+ cpSync(join(templateDir, "hooks", "session-start-startup.sh"), join(hooksTarget, "session-start-startup.sh"));
71
+ chmodSync(join(hooksTarget, "session-start-startup.sh"), 0o755);
72
+ writtenHooks.push("session-start-startup.sh");
47
73
  /* Session start compact — template {{ACTIVE_HOOKS}} */
48
74
  const compactSrc = readFileSync(join(templateDir, "hooks", "session-start-compact.sh"), "utf-8");
49
75
  const compactRendered = renderTemplate(compactSrc, {
@@ -74,5 +100,20 @@ export function writeFiles(options) {
74
100
  chmodSync(join(hooksTarget, options.typesHookFilename), 0o755);
75
101
  writtenHooks.push(options.typesHookFilename);
76
102
  }
77
- return { commands: commandFiles, hooks: writtenHooks };
103
+ /* CLAUDE.md optional scaffold */
104
+ let claudeMd = false;
105
+ if (options.enableClaudeMd) {
106
+ const claudeMdPath = join(options.projectDir, ".claude", "CLAUDE.md");
107
+ if (!existsSync(claudeMdPath)) {
108
+ cpSync(join(templateDir, "CLAUDE.md.tmpl"), claudeMdPath);
109
+ claudeMd = true;
110
+ }
111
+ }
112
+ return {
113
+ commands: commandFiles,
114
+ hooks: writtenHooks,
115
+ agents: agentFiles,
116
+ customAgentCount,
117
+ claudeMd,
118
+ };
78
119
  }
package/package.json CHANGED
@@ -1,21 +1,18 @@
1
1
  {
2
- "name": "@scriptgun/workerc",
3
- "version": "0.2.0",
4
- "description": "Claude Code session management CLI — commands, hooks, and progress tracking",
5
- "type": "module",
6
2
  "bin": {
7
3
  "workerc": "dist/bin.js"
8
4
  },
9
- "main": "./dist/init.js",
10
- "types": "./dist/init.d.ts",
5
+ "dependencies": {
6
+ "@clack/prompts": "1.0.0"
7
+ },
8
+ "description": "Claude Code session management CLI — commands, hooks, and progress tracking",
9
+ "devDependencies": {
10
+ "typescript": "^5.9.3"
11
+ },
11
12
  "files": [
12
13
  "dist",
13
14
  "README.md"
14
15
  ],
15
- "scripts": {
16
- "build": "tsc && cp -r src/templates dist/templates && chmod +x dist/bin.js",
17
- "type:check": "tsc --noEmit"
18
- },
19
16
  "keywords": [
20
17
  "claude",
21
18
  "claude-code",
@@ -25,14 +22,17 @@
25
22
  "workerc"
26
23
  ],
27
24
  "license": "MIT",
25
+ "main": "./dist/init.js",
26
+ "name": "@scriptgun/workerc",
28
27
  "repository": {
29
28
  "type": "git",
30
29
  "url": "git+https://github.com/lovrozagar/workerc.git"
31
30
  },
32
- "dependencies": {
33
- "@clack/prompts": "1.0.0"
31
+ "scripts": {
32
+ "build": "tsc && cp -r src/templates dist/templates && chmod +x dist/bin.js",
33
+ "type:check": "tsc --noEmit"
34
34
  },
35
- "devDependencies": {
36
- "typescript": "^5.9.3"
37
- }
35
+ "type": "module",
36
+ "types": "./dist/init.d.ts",
37
+ "version": "0.4.0"
38
38
  }