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 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 `../PROJ-123-add-user-authentication/`
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/ main repo
184
- +-- ../PROJ-123-add-auth/ worktree (Claude session B)
185
- +-- ../PROJ-456-fix-dashboard/ worktree (Claude session C)
186
- +-- ../PROJ-789-api-refactor/ worktree (Claude session D)
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 | Branch | Ticket | Status | Progress |
195
- |-------------------------|--------------------------|----------|-------------|-----------|
196
- | ../PROJ-123-add-auth | PROJ-123/add-auth | PROJ-123 | in-progress | 4/7 tasks |
197
- | ../PROJ-456-fix-dash | PROJ-456/fix-dash | PROJ-456 | review | 5/5 tasks |
198
- | . (main) | 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` after merge
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shokunin",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Lightweight engineering process skills for Claude Code — craftsmanship in AI-assisted development",
5
5
  "bin": {
6
6
  "shokunin": "bin/install.js"
@@ -115,7 +115,7 @@ After the PR is created, tell the user:
115
115
  PR created: <URL>
116
116
 
117
117
  After the PR is merged, clean up the worktree:
118
- git worktree remove <worktree-dir>
118
+ git worktree remove .worktrees/<ticket>-<slug>
119
119
  ```
120
120
 
121
121
  ## Important
@@ -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:** `../<ticket>-<slug>`
27
- - Example: `../PROJ-123-add-user-authentication`
26
+ - **Worktree directory:** `.worktrees/<ticket>-<slug>`
27
+ - Example: `.worktrees/PROJ-123-add-user-authentication`
28
28
 
29
- ### 3. Create Worktree
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
- git worktree add -b <branch-name> <worktree-dir> main
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
- ### 4. Create Plan Scaffold
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
- ### 5. Print Next Steps
102
+ ### 8. Print Next Steps
65
103
 
66
104
  Tell the user:
67
105