@scriptgun/workerc 0.3.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
@@ -12,9 +12,9 @@ npx @scriptgun/workerc init
12
12
 
13
13
  This interactively sets up:
14
14
 
15
- - **12 slash commands** in `.claude/commands/workerc/`
15
+ - **14 slash commands** in `.claude/commands/workerc/`
16
16
  - **7 hooks** in `.claude/hooks/`
17
- - **4 agents** in `.claude/agents/`
17
+ - **4 agents** in `.claude/agents/` (custom agents preserved on re-init)
18
18
  - **Settings** in `.claude/settings.local.json` or `.claude/settings.json`
19
19
  - **Progress directory** at `.claude/progress/`
20
20
  - **Optional CLAUDE.md** scaffold
@@ -34,6 +34,8 @@ This interactively sets up:
34
34
  | `/workerc:handoff` | Pause session with handoff notes |
35
35
  | `/workerc:done` | Mark session complete |
36
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 |
37
39
  | `/workerc:update` | Update workerc to latest version |
38
40
 
39
41
  ## Hooks
@@ -74,7 +76,7 @@ Progress files persist across sessions — use `/workerc:resume` to pick up wher
74
76
 
75
77
  ## Re-running init
76
78
 
77
- `workerc init` is idempotent. Running it again updates all commands, hooks, and agents 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.
78
80
 
79
81
  ## Changelog
80
82
 
package/dist/init.js CHANGED
@@ -177,7 +177,7 @@ export async function init(projectDir) {
177
177
  "Hooks:",
178
178
  ...result.hooks.map((f) => ` .claude/hooks/${f}`),
179
179
  "",
180
- "Agents:",
180
+ `Agents (${result.agents.length} built-in${result.customAgentCount > 0 ? `, ${result.customAgentCount} custom preserved` : ""}):`,
181
181
  ...result.agents.map((f) => ` .claude/agents/${f}`),
182
182
  "",
183
183
  `Settings: .claude/${settingsFile}`,
@@ -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>
@@ -15,5 +15,6 @@ export declare function writeFiles(options: WriteOptions): {
15
15
  commands: string[];
16
16
  hooks: string[];
17
17
  agents: string[];
18
+ customAgentCount: number;
18
19
  claudeMd: boolean;
19
20
  };
@@ -40,12 +40,18 @@ export function writeFiles(options) {
40
40
  for (const file of commandFiles) {
41
41
  cpSync(join(commandsSrc, file), join(commandsTarget, file));
42
42
  }
43
- /* Copy agent templates verbatim */
43
+ /* Copy agent templates only overwrite workerc's own agents */
44
44
  const agentsSrc = join(templateDir, "agents");
45
45
  const agentFiles = readdirSync(agentsSrc).filter((f) => f.endsWith(".md"));
46
+ const workercAgentNames = new Set(agentFiles);
46
47
  for (const file of agentFiles) {
47
48
  cpSync(join(agentsSrc, file), join(agentsTarget, file));
48
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;
49
55
  /* Copy/template hook files */
50
56
  const writtenHooks = [];
51
57
  /* Tracker — verbatim copy */
@@ -103,5 +109,11 @@ export function writeFiles(options) {
103
109
  claudeMd = true;
104
110
  }
105
111
  }
106
- return { commands: commandFiles, hooks: writtenHooks, agents: agentFiles, claudeMd };
112
+ return {
113
+ commands: commandFiles,
114
+ hooks: writtenHooks,
115
+ agents: agentFiles,
116
+ customAgentCount,
117
+ claudeMd,
118
+ };
107
119
  }
package/package.json CHANGED
@@ -34,5 +34,5 @@
34
34
  },
35
35
  "type": "module",
36
36
  "types": "./dist/init.d.ts",
37
- "version": "0.3.0"
37
+ "version": "0.4.0"
38
38
  }