@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 +5 -3
- package/dist/init.js +1 -1
- package/dist/templates/commands/checkpoint.md +74 -0
- package/dist/templates/commands/debug.md +183 -0
- package/dist/write-files.d.ts +1 -0
- package/dist/write-files.js +14 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,9 +12,9 @@ npx @scriptgun/workerc init
|
|
|
12
12
|
|
|
13
13
|
This interactively sets up:
|
|
14
14
|
|
|
15
|
-
- **
|
|
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
|
-
|
|
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>
|
package/dist/write-files.d.ts
CHANGED
package/dist/write-files.js
CHANGED
|
@@ -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
|
|
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 {
|
|
112
|
+
return {
|
|
113
|
+
commands: commandFiles,
|
|
114
|
+
hooks: writtenHooks,
|
|
115
|
+
agents: agentFiles,
|
|
116
|
+
customAgentCount,
|
|
117
|
+
claudeMd,
|
|
118
|
+
};
|
|
107
119
|
}
|
package/package.json
CHANGED