shokunin 1.2.0 → 1.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/README.md +19 -12
- package/bin/install.js +46 -1
- package/package.json +1 -1
- package/skills/ship/SKILL.md +1 -1
- package/skills/start/SKILL.md +45 -7
package/README.md
CHANGED
|
@@ -57,11 +57,15 @@ Every feature starts with a clean workspace.
|
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
This creates:
|
|
60
|
-
- A git worktree at
|
|
60
|
+
- A git worktree at `.worktrees/PROJ-123-add-user-authentication/`
|
|
61
61
|
- A branch `PROJ-123/add-user-authentication`
|
|
62
62
|
- A plan scaffold at `.claude/plans/PROJ-123.md`
|
|
63
63
|
|
|
64
|
-
Open a new terminal, `cd` into the worktree, and start Claude Code
|
|
64
|
+
Open a new terminal, `cd` into the worktree, and start Claude Code:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cd .worktrees/PROJ-123-add-user-authentication && claude
|
|
68
|
+
```
|
|
65
69
|
|
|
66
70
|
### 2. `/shokunin:plan` — Measure Twice, Cut Once
|
|
67
71
|
|
|
@@ -180,10 +184,13 @@ with session management and token refresh.
|
|
|
180
184
|
Shokunin uses git worktrees to support working on multiple features simultaneously.
|
|
181
185
|
|
|
182
186
|
```
|
|
183
|
-
~/src/myproject/
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
+
~/src/myproject/
|
|
188
|
+
.worktrees/ gitignored
|
|
189
|
+
PROJ-123-add-auth/ worktree (Claude session B)
|
|
190
|
+
PROJ-456-fix-dashboard/ worktree (Claude session C)
|
|
191
|
+
PROJ-789-api-refactor/ worktree (Claude session D)
|
|
192
|
+
src/
|
|
193
|
+
package.json
|
|
187
194
|
```
|
|
188
195
|
|
|
189
196
|
Each worktree is a separate directory with its own branch and Claude Code session. Run `/shokunin:wip` from any session to see all features in flight:
|
|
@@ -191,11 +198,11 @@ Each worktree is a separate directory with its own branch and Claude Code sessio
|
|
|
191
198
|
```
|
|
192
199
|
Shokunin — Work in Progress
|
|
193
200
|
|
|
194
|
-
| Worktree
|
|
195
|
-
|
|
196
|
-
|
|
|
197
|
-
|
|
|
198
|
-
| . (main)
|
|
201
|
+
| Worktree | Branch | Ticket | Status | Progress |
|
|
202
|
+
|-----------------------------------|--------------------------|----------|-------------|-----------|
|
|
203
|
+
| .worktrees/PROJ-123-add-auth | PROJ-123/add-auth | PROJ-123 | in-progress | 4/7 tasks |
|
|
204
|
+
| .worktrees/PROJ-456-fix-dash | PROJ-456/fix-dash | PROJ-456 | review | 5/5 tasks |
|
|
205
|
+
| . (main) | main | — | — | — |
|
|
199
206
|
```
|
|
200
207
|
|
|
201
208
|
## Git Strategy
|
|
@@ -204,7 +211,7 @@ Shokunin — Work in Progress
|
|
|
204
211
|
- **During development:** WIP commits (`wip: <task name>`) — safe, cheap, squashed later
|
|
205
212
|
- **At ship time:** All commits squashed into one: `PROJ-123: feat: description`
|
|
206
213
|
- **PRs:** Created via `gh pr create`, merged manually on GitHub
|
|
207
|
-
- **Cleanup:** `git worktree remove
|
|
214
|
+
- **Cleanup:** `git worktree remove .worktrees/<ticket>-<slug>` after merge
|
|
208
215
|
|
|
209
216
|
## Quick Flow
|
|
210
217
|
|
package/bin/install.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const readline = require('readline');
|
|
6
|
+
const { execSync } = require('child_process');
|
|
6
7
|
|
|
7
8
|
const SKILLS = ['start', 'plan', 'build', 'review', 'ship', 'wip', 'docs'];
|
|
8
9
|
const AGENTS = ['code-reviewer'];
|
|
@@ -50,6 +51,7 @@ async function promptUser(question) {
|
|
|
50
51
|
async function main() {
|
|
51
52
|
const args = process.argv.slice(2);
|
|
52
53
|
const force = args.includes('--force');
|
|
54
|
+
const noCommit = args.includes('--no-commit');
|
|
53
55
|
|
|
54
56
|
const projectRoot = findProjectRoot(process.cwd());
|
|
55
57
|
const packageRoot = path.resolve(__dirname, '..');
|
|
@@ -133,12 +135,49 @@ async function main() {
|
|
|
133
135
|
}
|
|
134
136
|
}
|
|
135
137
|
|
|
138
|
+
// Add .worktrees/ to .gitignore
|
|
139
|
+
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
140
|
+
let gitignoreUpdated = false;
|
|
141
|
+
const worktreeEntry = '.worktrees/';
|
|
142
|
+
if (fs.existsSync(gitignorePath)) {
|
|
143
|
+
const content = fs.readFileSync(gitignorePath, 'utf8');
|
|
144
|
+
if (!content.includes(worktreeEntry)) {
|
|
145
|
+
fs.appendFileSync(gitignorePath, `\n# Shokunin worktrees\n${worktreeEntry}\n`);
|
|
146
|
+
gitignoreUpdated = true;
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
fs.writeFileSync(gitignorePath, `# Shokunin worktrees\n${worktreeEntry}\n`);
|
|
150
|
+
gitignoreUpdated = true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Auto-commit skills to git so worktrees inherit them
|
|
154
|
+
const hasChanges = installed > 0 || updated > 0;
|
|
155
|
+
let committed = false;
|
|
156
|
+
|
|
157
|
+
if ((hasChanges || gitignoreUpdated) && !noCommit) {
|
|
158
|
+
const isGitRepo = fs.existsSync(path.join(projectRoot, '.git'));
|
|
159
|
+
if (isGitRepo) {
|
|
160
|
+
try {
|
|
161
|
+
execSync('git add .claude/skills/ .claude/agents/', { cwd: projectRoot, stdio: 'pipe' });
|
|
162
|
+
if (gitignoreUpdated) {
|
|
163
|
+
execSync('git add .gitignore', { cwd: projectRoot, stdio: 'pipe' });
|
|
164
|
+
}
|
|
165
|
+
execSync('git commit -m "chore: install shokunin engineering process skills"', { cwd: projectRoot, stdio: 'pipe' });
|
|
166
|
+
committed = true;
|
|
167
|
+
} catch {
|
|
168
|
+
// Commit may fail if nothing staged (already tracked) or no git user configured
|
|
169
|
+
committed = false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
136
174
|
// Summary
|
|
137
175
|
console.log('');
|
|
138
176
|
console.log(' Done!');
|
|
139
177
|
if (installed > 0) console.log(` Installed: ${installed}`);
|
|
140
178
|
if (updated > 0) console.log(` Updated: ${updated}`);
|
|
141
179
|
if (skipped > 0) console.log(` Unchanged: ${skipped}`);
|
|
180
|
+
if (committed) console.log(' Committed to git (skills available in worktrees)');
|
|
142
181
|
console.log('');
|
|
143
182
|
console.log(' Skills installed:');
|
|
144
183
|
for (const skill of SKILLS) {
|
|
@@ -152,8 +191,14 @@ async function main() {
|
|
|
152
191
|
console.log(' /shokunin:review # Code review');
|
|
153
192
|
console.log(' /shokunin:ship # Squash, PR, ship it');
|
|
154
193
|
console.log('');
|
|
194
|
+
if (!committed && hasChanges) {
|
|
195
|
+
console.log(' [!] Skills were not committed to git.');
|
|
196
|
+
console.log(' Run: git add .claude/skills/ .claude/agents/ && git commit');
|
|
197
|
+
console.log(' (Skills must be committed for worktrees to inherit them)');
|
|
198
|
+
console.log('');
|
|
199
|
+
}
|
|
155
200
|
console.log(' Prerequisites:');
|
|
156
|
-
console.log(' - gh CLI installed and authenticated (for /ship)');
|
|
201
|
+
console.log(' - gh CLI installed and authenticated (for /shokunin:ship)');
|
|
157
202
|
console.log(' - Add Bash(gh *) to ~/.claude/settings.json allow list');
|
|
158
203
|
console.log('');
|
|
159
204
|
}
|
package/package.json
CHANGED
package/skills/ship/SKILL.md
CHANGED
package/skills/start/SKILL.md
CHANGED
|
@@ -23,22 +23,60 @@ You are the initialisation phase of the shokunin engineering process. Set up a c
|
|
|
23
23
|
|
|
24
24
|
- **Branch name:** `<ticket>/<slugified-description>` — lowercase, hyphens, no special chars
|
|
25
25
|
- Example: `PROJ-123/add-user-authentication`
|
|
26
|
-
- **Worktree directory:**
|
|
27
|
-
- Example:
|
|
26
|
+
- **Worktree directory:** `.worktrees/<ticket>-<slug>`
|
|
27
|
+
- Example: `.worktrees/PROJ-123-add-user-authentication`
|
|
28
28
|
|
|
29
|
-
### 3.
|
|
29
|
+
### 3. Ensure .worktrees/ is Gitignored
|
|
30
|
+
|
|
31
|
+
Check if `.worktrees/` is in `.gitignore`. If not, add it:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
grep -q '^\.worktrees/' .gitignore 2>/dev/null || echo '.worktrees/' >> .gitignore
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Create the `.worktrees/` directory if it doesn't exist:
|
|
30
38
|
|
|
31
39
|
```bash
|
|
32
|
-
|
|
40
|
+
mkdir -p .worktrees
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 4. Create Worktree
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git worktree add -b <branch-name> .worktrees/<ticket>-<slug> main
|
|
33
47
|
```
|
|
34
48
|
|
|
35
49
|
If the branch already exists, ask the user if they want to resume work on it or start fresh.
|
|
36
50
|
|
|
37
|
-
###
|
|
51
|
+
### 5. Ensure Skills Exist in Worktree
|
|
52
|
+
|
|
53
|
+
Check if `.claude/skills/` exists in the new worktree. If it doesn't (e.g. skills weren't committed to main), copy them from the source repo:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Check if skills exist in the worktree
|
|
57
|
+
ls <worktree-dir>/.claude/skills/plan/SKILL.md
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
If missing, copy the entire `.claude/skills/` and `.claude/agents/` directories from the current repo into the worktree:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
cp -r .claude/skills <worktree-dir>/.claude/skills
|
|
64
|
+
cp -r .claude/agents <worktree-dir>/.claude/agents
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then commit them on the feature branch so they persist:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
cd <worktree-dir>
|
|
71
|
+
git add .claude/skills/ .claude/agents/
|
|
72
|
+
git commit -m "chore: add shokunin skills to feature branch"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 7. Create Plan Scaffold
|
|
38
76
|
|
|
39
77
|
Create the directory `.claude/plans/` in the worktree if it doesn't exist.
|
|
40
78
|
|
|
41
|
-
Write `.claude/plans/<ticket>.md` with this scaffold:
|
|
79
|
+
Write `.claude/plans/<ticket>.md` in the worktree with this scaffold:
|
|
42
80
|
|
|
43
81
|
```markdown
|
|
44
82
|
# Feature: <feature description>
|
|
@@ -61,7 +99,7 @@ Write `.claude/plans/<ticket>.md` with this scaffold:
|
|
|
61
99
|
<To be captured during /plan>
|
|
62
100
|
```
|
|
63
101
|
|
|
64
|
-
###
|
|
102
|
+
### 8. Print Next Steps
|
|
65
103
|
|
|
66
104
|
Tell the user:
|
|
67
105
|
|