@simplysm/sd-claude 13.0.76 → 13.0.77
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/claude/refs/sd-code-conventions.md +11 -3
- package/claude/refs/sd-solid.md +11 -2
- package/claude/rules/sd-claude-rules.md +6 -10
- package/claude/sd-statusline.js +7 -7
- package/claude/skills/sd-api-name-review/SKILL.md +103 -17
- package/claude/skills/sd-brainstorm/SKILL.md +32 -47
- package/claude/skills/sd-check/SKILL.md +14 -16
- package/claude/skills/sd-commit/SKILL.md +1 -3
- package/claude/skills/sd-debug/SKILL.md +5 -11
- package/claude/skills/sd-debug/condition-based-waiting.md +5 -11
- package/claude/skills/sd-debug/root-cause-tracing.md +18 -33
- package/claude/skills/sd-explore/SKILL.md +86 -44
- package/claude/skills/sd-plan/SKILL.md +0 -1
- package/claude/skills/sd-plan-dev/SKILL.md +48 -82
- package/claude/skills/sd-review/SKILL.md +107 -80
- package/claude/skills/sd-review/api-reviewer-prompt.md +23 -43
- package/claude/skills/sd-review/code-reviewer-prompt.md +26 -35
- package/claude/skills/sd-review/convention-checker-prompt.md +23 -26
- package/claude/skills/sd-review/refactoring-analyzer-prompt.md +92 -0
- package/claude/skills/sd-skill/SKILL.md +10 -16
- package/claude/skills/sd-skill/writing-guide.md +7 -11
- package/claude/skills/sd-tdd/SKILL.md +15 -20
- package/claude/skills/sd-use/SKILL.md +3 -4
- package/claude/skills/sd-worktree/SKILL.md +58 -113
- package/package.json +1 -1
- package/claude/skills/sd-review/code-simplifier-prompt.md +0 -95
- package/claude/skills/sd-review/structure-analyzer-prompt.md +0 -97
- package/claude/skills/sd-worktree/sd-worktree.mjs +0 -152
|
@@ -6,128 +6,73 @@ model: haiku
|
|
|
6
6
|
|
|
7
7
|
# sd-worktree
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
- Check `git status` — if merge conflicts exist, STOP and report
|
|
50
|
-
- Do NOT proceed to `clean` until merge is confirmed successful
|
|
51
|
-
|
|
52
|
-
**Violation of these rules causes IRREVERSIBLE DATA LOSS.**
|
|
53
|
-
|
|
54
|
-
## Overview
|
|
55
|
-
|
|
56
|
-
Create, merge, and clean up git worktrees under `.worktrees/`. Uses the current branch of the main working tree as the source branch.
|
|
57
|
-
|
|
58
|
-
**Important**: Claude Code's working directory (cd) shifts between main and worktree, so always verify the cd location before and after each command.
|
|
59
|
-
|
|
60
|
-
## Target Worktree Resolution
|
|
61
|
-
|
|
62
|
-
For all commands, the target worktree name is resolved in this order:
|
|
63
|
-
|
|
64
|
-
1. Explicitly provided in args → use as-is
|
|
65
|
-
2. Current cd is inside `.worktrees/<name>/` → use that `<name>` (auto-detected)
|
|
66
|
-
3. Neither applies → ask the user
|
|
67
|
-
|
|
68
|
-
## Commands
|
|
69
|
-
|
|
70
|
-
### add — Create a worktree
|
|
71
|
-
|
|
72
|
-
Take a work description from args, determine a kebab-case name, then run:
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# Run from main
|
|
76
|
-
node .claude/skills/sd-worktree/sd-worktree.mjs add <name>
|
|
77
|
-
cd .worktrees/<name> # Move into the worktree
|
|
9
|
+
Branch-isolated workflow using git worktrees.
|
|
10
|
+
|
|
11
|
+
## Flow
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
flowchart TD
|
|
15
|
+
START([sd-worktree invoked]) --> ADD
|
|
16
|
+
|
|
17
|
+
subgraph ADD [add]
|
|
18
|
+
A1["git worktree add .worktrees/NAME -b NAME"]
|
|
19
|
+
A1 -->|fail| HALT
|
|
20
|
+
A1 -->|ok| A2[detect package manager]
|
|
21
|
+
A2 --> A3["pm install (cwd: .worktrees/NAME)"]
|
|
22
|
+
A3 -->|fail| HALT
|
|
23
|
+
A3 -->|ok| A4["cd .worktrees/NAME"]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
A4 --> WORK["work + commit inside worktree"]
|
|
27
|
+
WORK --> MERGE
|
|
28
|
+
|
|
29
|
+
subgraph MERGE [merge]
|
|
30
|
+
M0["cd PROJECT_ROOT"]
|
|
31
|
+
M0 --> M1["git merge NAME --no-ff (cwd: PROJECT_ROOT)"]
|
|
32
|
+
M1 -->|fail| HALT
|
|
33
|
+
M1 -->|ok| M2[merge complete]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
M2 --> CLEAN
|
|
37
|
+
|
|
38
|
+
subgraph CLEAN [clean]
|
|
39
|
+
C1{"cwd inside worktree?"}
|
|
40
|
+
C1 -->|yes| HALT
|
|
41
|
+
C1 -->|no| C2["rm -rf .worktrees/NAME (bash)"]
|
|
42
|
+
C2 --> C3["git worktree prune"]
|
|
43
|
+
C3 --> C4["git branch -d NAME"]
|
|
44
|
+
C4 -->|fail| HALT
|
|
45
|
+
C4 -->|ok| C5[done]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
HALT([HALT - AskUserQuestion])
|
|
78
49
|
```
|
|
79
50
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
### rebase — Rebase onto main branch
|
|
51
|
+
## Rules
|
|
83
52
|
|
|
84
|
-
|
|
85
|
-
# Can be run from inside the worktree
|
|
86
|
-
node .claude/skills/sd-worktree/sd-worktree.mjs rebase [name]
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
- Rebases the worktree branch onto the latest commit of the main branch
|
|
90
|
-
- Errors if uncommitted changes exist → commit or stash first
|
|
91
|
-
- Use when you want a clean history before merging
|
|
92
|
-
- **If rebase fails or conflicts → STOP. Report to user. Do NOT auto-resolve.**
|
|
53
|
+
### HALT
|
|
93
54
|
|
|
94
|
-
|
|
55
|
+
When any step reaches **fail** or **HALT**:
|
|
95
56
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
```
|
|
57
|
+
1. Show the error message to the user as-is
|
|
58
|
+
2. Ask the user how to proceed via `AskUserQuestion`
|
|
59
|
+
3. Do **nothing** until the user responds
|
|
100
60
|
|
|
101
|
-
|
|
102
|
-
- Errors if uncommitted changes exist → commit or stash first
|
|
103
|
-
- After merge, always `cd <project-root>` (required for subsequent clean)
|
|
61
|
+
Manual git merge, git stash, git reset, git clean, or **any workaround is forbidden**. Yolo mode does NOT override HALT.
|
|
104
62
|
|
|
105
|
-
|
|
106
|
-
1. Before merge: check BOTH main and worktree for uncommitted changes
|
|
107
|
-
2. If the script exits with non-zero → show "Please proceed with the merge manually." message (in system language) and STOP.
|
|
108
|
-
3. After merge: run `git status` in main to confirm no conflicts
|
|
109
|
-
4. If conflicts or errors → show "Please proceed with the merge manually." message (in system language) and STOP.
|
|
110
|
-
5. Only proceed to `clean` after confirming merge was fully successful
|
|
63
|
+
### Worktree location
|
|
111
64
|
|
|
112
|
-
|
|
65
|
+
All worktrees MUST be created under **`.worktrees/`** (project root).
|
|
113
66
|
|
|
114
|
-
|
|
115
|
-
# Must cd to main first (worktree directory will be deleted)
|
|
116
|
-
cd <project-root>
|
|
117
|
-
node .claude/skills/sd-worktree/sd-worktree.mjs clean <name>
|
|
118
|
-
```
|
|
67
|
+
### Package manager detection
|
|
119
68
|
|
|
120
|
-
|
|
121
|
-
|
|
69
|
+
| File | PM |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `pnpm-lock.yaml` | pnpm |
|
|
72
|
+
| `yarn.lock` | yarn |
|
|
73
|
+
| `package-lock.json` | npm |
|
|
74
|
+
| `bun.lockb` / `bun.lock` | bun |
|
|
122
75
|
|
|
123
|
-
|
|
76
|
+
### clean: use rm -rf
|
|
124
77
|
|
|
125
|
-
|
|
126
|
-
(main: 13.x) → /sd-worktree add modal-migration
|
|
127
|
-
→ cd .worktrees/modal-migration
|
|
128
|
-
(worktree) → ... work ...
|
|
129
|
-
(worktree) → /sd-worktree rebase # (optional) rebase onto latest main
|
|
130
|
-
(worktree) → /sd-worktree merge
|
|
131
|
-
(worktree) → cd <project-root>
|
|
132
|
-
(main: 13.x) → /sd-worktree clean modal-migration
|
|
133
|
-
```
|
|
78
|
+
`git worktree remove` almost always fails on Windows due to file locks. Use `rm -rf` (bash) + `git worktree prune` instead.
|
package/package.json
CHANGED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
# Code Simplifier Prompt
|
|
2
|
-
|
|
3
|
-
Template for `Agent(general-purpose)`. Fill in `[TARGET_PATH]`.
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
You are analyzing code for structural simplification opportunities.
|
|
7
|
-
Your question: "Can this code be simpler without changing its behavior?"
|
|
8
|
-
|
|
9
|
-
## Target
|
|
10
|
-
|
|
11
|
-
Analyze ALL source files at [TARGET_PATH].
|
|
12
|
-
|
|
13
|
-
## Step 1: List all source files
|
|
14
|
-
|
|
15
|
-
Use Glob to list all .ts/.tsx files under the target path (exclude node_modules, dist).
|
|
16
|
-
|
|
17
|
-
## Step 2: Understand the structure
|
|
18
|
-
|
|
19
|
-
Read the following reference files for project conventions:
|
|
20
|
-
- `CLAUDE.md` — project overview and conventions
|
|
21
|
-
- `.claude/rules/sd-refs-linker.md` — reference guide linking to detailed docs per topic (read relevant refs based on the target code)
|
|
22
|
-
|
|
23
|
-
Then:
|
|
24
|
-
- Map module dependencies and abstraction layers
|
|
25
|
-
- Compare whether similar-role files use consistent patterns
|
|
26
|
-
- Identify complexity hotspots: deep nesting, long functions, complex conditionals
|
|
27
|
-
|
|
28
|
-
## Step 3: Find refactoring opportunities
|
|
29
|
-
|
|
30
|
-
Look for:
|
|
31
|
-
- Unnecessary complexity: over-abstraction, needless indirection, complex generics that could be simpler
|
|
32
|
-
- Duplication: same logic repeated across files, similar functions that could be unified
|
|
33
|
-
- Readability: hard-to-follow control flow, unclear variable names, implicit behavior
|
|
34
|
-
- File structure: too many files for simple concepts, or too many responsibilities in one file
|
|
35
|
-
- Coupling: changes that would cascade widely, tightly coupled modules
|
|
36
|
-
|
|
37
|
-
## CRITICAL — Scope boundaries
|
|
38
|
-
|
|
39
|
-
Do NOT report ANY of the following. These are OUT OF SCOPE:
|
|
40
|
-
- Bugs, security issues, logic errors, race conditions → that's code review
|
|
41
|
-
- Naming consistency, API design, type quality (including `any` types) → that's API review
|
|
42
|
-
- Code language violations (Korean comments, non-English strings) → that's lint
|
|
43
|
-
- Documentation gaps (missing JSDoc, missing comments, undocumented behavior) → that's documentation
|
|
44
|
-
- Style preferences (property shorthand, `else` after `return`, import ordering, formatting)
|
|
45
|
-
- Performance optimization (unless the fix is ALSO a structural improvement)
|
|
46
|
-
- Magic numbers with clear adjacent comments
|
|
47
|
-
- Small interface duplication (< 10 fields) where extraction adds indirection without real benefit
|
|
48
|
-
- Issues in code OUTSIDE the target path
|
|
49
|
-
|
|
50
|
-
**Test each finding:** "Is this about CODE STRUCTURE, or about something else (bugs, conventions, docs, performance)?" If something else → drop it.
|
|
51
|
-
|
|
52
|
-
## Step 4: Self-verify before reporting
|
|
53
|
-
|
|
54
|
-
Before including ANY finding:
|
|
55
|
-
|
|
56
|
-
1. **Structure test**: Is this genuinely about code structure? Or is it a bug, convention, or documentation issue disguised as refactoring?
|
|
57
|
-
2. **Impact test**: Would a developer actually struggle with this structure? Or is it just "could be slightly different"?
|
|
58
|
-
3. **Scope check**: Is the issue IN the target code, or in how other code uses it?
|
|
59
|
-
|
|
60
|
-
**Quality over quantity: 3 verified structural findings > 10 mixed findings.**
|
|
61
|
-
|
|
62
|
-
## Constraints
|
|
63
|
-
|
|
64
|
-
- Analysis only. Do NOT modify any files.
|
|
65
|
-
- Do NOT provide corrected code blocks. Describe issues and suggestions in words only.
|
|
66
|
-
- Only report structural issues with real evidence from the code.
|
|
67
|
-
- Focus on substance: structural problems that genuinely make the code harder to understand or modify.
|
|
68
|
-
|
|
69
|
-
## Output Format
|
|
70
|
-
|
|
71
|
-
Use this exact format for every finding:
|
|
72
|
-
|
|
73
|
-
### [HIGH|MEDIUM|LOW] title
|
|
74
|
-
|
|
75
|
-
- **File**: path/to/file.ts:42
|
|
76
|
-
- **Evidence**: what you observed (include code snippet)
|
|
77
|
-
- **Issue**: what the structural problem is
|
|
78
|
-
- **Suggestion**: how to improve it (in words, not code)
|
|
79
|
-
|
|
80
|
-
Impact levels:
|
|
81
|
-
- HIGH: Major structural problem. Significantly harder to understand or modify safely.
|
|
82
|
-
- MEDIUM: Notable structural concern. Unnecessary complexity or meaningful duplication.
|
|
83
|
-
- LOW: Improvement opportunity. Cleaner structure exists but current code is workable.
|
|
84
|
-
|
|
85
|
-
Start your report with:
|
|
86
|
-
|
|
87
|
-
## Code Simplification Results
|
|
88
|
-
|
|
89
|
-
### Summary
|
|
90
|
-
- Files reviewed: N
|
|
91
|
-
- Findings: X HIGH, Y MEDIUM, Z LOW
|
|
92
|
-
|
|
93
|
-
### Findings
|
|
94
|
-
[findings here]
|
|
95
|
-
```
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
# Structure Analyzer Prompt
|
|
2
|
-
|
|
3
|
-
Template for `Agent(general-purpose)`. Fill in `[TARGET_PATH]`.
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
You are analyzing code for structural organization and responsibility separation.
|
|
7
|
-
Your question: "Is the code organized in a way that makes responsibilities clear and changes localized?"
|
|
8
|
-
|
|
9
|
-
## Target
|
|
10
|
-
|
|
11
|
-
Analyze ALL source files at [TARGET_PATH].
|
|
12
|
-
|
|
13
|
-
## Step 1: List all source files
|
|
14
|
-
|
|
15
|
-
Use Glob to list all .ts/.tsx files under the target path (exclude node_modules, dist).
|
|
16
|
-
This is your analysis scope — every file in this list must be examined.
|
|
17
|
-
|
|
18
|
-
## Step 2: Understand the architecture
|
|
19
|
-
|
|
20
|
-
Read the following reference files for project conventions:
|
|
21
|
-
- `CLAUDE.md` — project overview and conventions
|
|
22
|
-
- `.claude/rules/sd-refs-linker.md` — reference guide linking to detailed docs per topic (read relevant refs based on the target code)
|
|
23
|
-
|
|
24
|
-
Then:
|
|
25
|
-
- Read index.ts to map the module structure and public exports
|
|
26
|
-
- Identify module boundaries: what each module/file owns
|
|
27
|
-
- Map abstraction levels: which code is high-level vs low-level
|
|
28
|
-
- Identify responsibility groupings: which functions/classes belong together
|
|
29
|
-
|
|
30
|
-
## Step 3: Find structural improvement opportunities
|
|
31
|
-
|
|
32
|
-
Look for:
|
|
33
|
-
- Responsibility mixing: a single module handling concerns that should be separate
|
|
34
|
-
- Abstraction level mismatch: high-level orchestration mixed with low-level implementation details in the same function/module
|
|
35
|
-
- Module organization: related functionality scattered across unrelated files, or unrelated functionality grouped together
|
|
36
|
-
- Leaking abstractions: internal implementation details exposed through public API that force consumers to know about internals
|
|
37
|
-
- Coupling hotspots: modules where a change would cascade to many other files
|
|
38
|
-
|
|
39
|
-
## CRITICAL — Scope boundaries
|
|
40
|
-
|
|
41
|
-
Do NOT report ANY of the following. These are OUT OF SCOPE:
|
|
42
|
-
- Bugs, security, logic errors, race conditions → that's code review
|
|
43
|
-
- Naming consistency, API design, type quality → that's API review
|
|
44
|
-
- Code complexity, duplication within a single function → that's code simplification
|
|
45
|
-
- Circular dependencies, wrong dependency direction, boundary violations → that's code review (architectural defects)
|
|
46
|
-
- Style preferences, comment style, import ordering
|
|
47
|
-
- Dependencies that are clearly intentional and well-established patterns in the codebase
|
|
48
|
-
- Issues in code OUTSIDE the target path
|
|
49
|
-
|
|
50
|
-
**Key distinction:** Architectural DEFECTS (circular deps, boundary violations) are for code review. Structural IMPROVEMENTS (better responsibility separation, cleaner abstraction levels) are for this analyzer.
|
|
51
|
-
|
|
52
|
-
## Step 4: Self-verify before reporting
|
|
53
|
-
|
|
54
|
-
Before including ANY finding:
|
|
55
|
-
|
|
56
|
-
1. **Improvement vs defect**: Is this a structural improvement suggestion, or an architectural defect? If defect → not in scope.
|
|
57
|
-
2. **Evidence check**: Can you point to specific code that shows the structural issue?
|
|
58
|
-
3. **Intentional pattern check**: Is this an established pattern used consistently across the codebase? If yes → by-design, drop it.
|
|
59
|
-
4. **Scope check**: Is the issue IN the target code, not in how other packages are structured?
|
|
60
|
-
|
|
61
|
-
**Quality over quantity: 3 verified structural findings > 10 maybe-findings.**
|
|
62
|
-
|
|
63
|
-
## Constraints
|
|
64
|
-
|
|
65
|
-
- Analysis only. Do NOT modify any files.
|
|
66
|
-
- Do NOT provide corrected code blocks. Describe improvements in words only.
|
|
67
|
-
- Only report issues with concrete evidence (specific code references).
|
|
68
|
-
- If the structure is consistent across the codebase, treat it as intentional.
|
|
69
|
-
|
|
70
|
-
## Output Format
|
|
71
|
-
|
|
72
|
-
Use this exact format for every finding:
|
|
73
|
-
|
|
74
|
-
### [HIGH|MEDIUM|LOW] title
|
|
75
|
-
|
|
76
|
-
- **File**: path/to/file.ts:42
|
|
77
|
-
- **Evidence**: what you observed (include code snippet)
|
|
78
|
-
- **Issue**: what the structural concern is
|
|
79
|
-
- **Suggestion**: how to improve the structure (in words, not code)
|
|
80
|
-
|
|
81
|
-
Impact levels:
|
|
82
|
-
- HIGH: Major structural issue. Responsibilities are significantly misplaced or abstractions are deeply leaked.
|
|
83
|
-
- MEDIUM: Notable structural concern. Better organization would meaningfully improve maintainability.
|
|
84
|
-
- LOW: Improvement opportunity. Cleaner structure exists but current organization is workable.
|
|
85
|
-
|
|
86
|
-
Start your report with:
|
|
87
|
-
|
|
88
|
-
## Structure Analysis Results
|
|
89
|
-
|
|
90
|
-
### Summary
|
|
91
|
-
- Files reviewed: N
|
|
92
|
-
- Module structure: brief description
|
|
93
|
-
- Findings: X HIGH, Y MEDIUM, Z LOW
|
|
94
|
-
|
|
95
|
-
### Findings
|
|
96
|
-
[findings here]
|
|
97
|
-
```
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { execSync } from "node:child_process";
|
|
3
|
-
import { existsSync, rmSync } from "node:fs";
|
|
4
|
-
import { resolve, sep } from "node:path";
|
|
5
|
-
|
|
6
|
-
const [cmd, ...args] = process.argv.slice(2);
|
|
7
|
-
|
|
8
|
-
function run(command, opts) {
|
|
9
|
-
execSync(command, { encoding: "utf-8", stdio: "inherit", ...opts });
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function getOutput(command) {
|
|
13
|
-
return execSync(command, { encoding: "utf-8" }).trim();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Main working tree path (accurate even when run inside a worktree)
|
|
17
|
-
const mainWorktree = getOutput("git worktree list --porcelain")
|
|
18
|
-
.split("\n")[0]
|
|
19
|
-
.replace("worktree ", "");
|
|
20
|
-
|
|
21
|
-
function detectPackageManager() {
|
|
22
|
-
if (existsSync(resolve(mainWorktree, "pnpm-lock.yaml"))) return "pnpm";
|
|
23
|
-
if (existsSync(resolve(mainWorktree, "yarn.lock"))) return "yarn";
|
|
24
|
-
if (existsSync(resolve(mainWorktree, "package-lock.json"))) return "npm";
|
|
25
|
-
if (
|
|
26
|
-
existsSync(resolve(mainWorktree, "bun.lockb")) ||
|
|
27
|
-
existsSync(resolve(mainWorktree, "bun.lock"))
|
|
28
|
-
)
|
|
29
|
-
return "bun";
|
|
30
|
-
return "npm";
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function detectWorktreeName() {
|
|
34
|
-
const cwd = process.cwd();
|
|
35
|
-
const worktreesDir = resolve(mainWorktree, ".worktrees");
|
|
36
|
-
if (cwd.startsWith(worktreesDir + sep)) {
|
|
37
|
-
return cwd.slice(worktreesDir.length + 1).split(sep)[0];
|
|
38
|
-
}
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getMainBranch() {
|
|
43
|
-
return getOutput(`git -C "${mainWorktree}" rev-parse --abbrev-ref HEAD`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
switch (cmd) {
|
|
47
|
-
case "add": {
|
|
48
|
-
const name = args[0];
|
|
49
|
-
if (!name) {
|
|
50
|
-
console.error("Usage: sd-worktree.mjs add <kebab-case-name>");
|
|
51
|
-
process.exit(1);
|
|
52
|
-
}
|
|
53
|
-
const worktreePath = resolve(mainWorktree, ".worktrees", name);
|
|
54
|
-
if (existsSync(worktreePath)) {
|
|
55
|
-
console.error(`Already exists: ${worktreePath}`);
|
|
56
|
-
process.exit(1);
|
|
57
|
-
}
|
|
58
|
-
const branch = getMainBranch();
|
|
59
|
-
console.log(`Creating worktree: .worktrees/${name} (from ${branch})`);
|
|
60
|
-
run(`git worktree add "${worktreePath}" -b "${name}"`);
|
|
61
|
-
const pm = detectPackageManager();
|
|
62
|
-
console.log(`Installing dependencies (${pm})...`);
|
|
63
|
-
run(`${pm} install`, { cwd: worktreePath });
|
|
64
|
-
console.log(`\nReady: ${worktreePath}`);
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
case "merge": {
|
|
69
|
-
const name = args[0] ?? detectWorktreeName();
|
|
70
|
-
if (!name) {
|
|
71
|
-
console.error("Usage: sd-worktree.mjs merge [name] (or run inside .worktrees/<name>)");
|
|
72
|
-
process.exit(1);
|
|
73
|
-
}
|
|
74
|
-
// Check for uncommitted changes
|
|
75
|
-
const worktreePath_m = resolve(mainWorktree, ".worktrees", name);
|
|
76
|
-
if (existsSync(worktreePath_m)) {
|
|
77
|
-
const status = getOutput(`git -C "${worktreePath_m}" status --porcelain`);
|
|
78
|
-
if (status) {
|
|
79
|
-
console.error(`Error: worktree '${name}' has uncommitted changes:\n${status}`);
|
|
80
|
-
console.error("Commit or stash changes before merging.");
|
|
81
|
-
process.exit(1);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
const branch = getMainBranch();
|
|
85
|
-
console.log(`Merging '${name}' into '${branch}'...`);
|
|
86
|
-
run(`git merge "${name}" --no-ff`, { cwd: mainWorktree });
|
|
87
|
-
console.log(`\nMerged '${name}' into '${branch}'.`);
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
case "rebase": {
|
|
92
|
-
const name = args[0] ?? detectWorktreeName();
|
|
93
|
-
if (!name) {
|
|
94
|
-
console.error("Usage: sd-worktree.mjs rebase [name] (or run inside .worktrees/<name>)");
|
|
95
|
-
process.exit(1);
|
|
96
|
-
}
|
|
97
|
-
const worktreePath_r = resolve(mainWorktree, ".worktrees", name);
|
|
98
|
-
if (!existsSync(worktreePath_r)) {
|
|
99
|
-
console.error(`Error: worktree '${name}' does not exist.`);
|
|
100
|
-
process.exit(1);
|
|
101
|
-
}
|
|
102
|
-
// Check for uncommitted changes
|
|
103
|
-
const statusR = getOutput(`git -C "${worktreePath_r}" status --porcelain`);
|
|
104
|
-
if (statusR) {
|
|
105
|
-
console.error(`Error: worktree '${name}' has uncommitted changes:\n${statusR}`);
|
|
106
|
-
console.error("Commit or stash changes before rebasing.");
|
|
107
|
-
process.exit(1);
|
|
108
|
-
}
|
|
109
|
-
const branchR = getMainBranch();
|
|
110
|
-
console.log(`Rebasing '${name}' onto '${branchR}'...`);
|
|
111
|
-
run(`git rebase "${branchR}"`, { cwd: worktreePath_r });
|
|
112
|
-
console.log(`\nRebased '${name}' onto '${branchR}'.`);
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
case "clean": {
|
|
117
|
-
const name = args[0] ?? detectWorktreeName();
|
|
118
|
-
if (!name) {
|
|
119
|
-
console.error("Usage: sd-worktree.mjs clean [name] (or run inside .worktrees/<name>)");
|
|
120
|
-
process.exit(1);
|
|
121
|
-
}
|
|
122
|
-
// Block execution from inside the worktree
|
|
123
|
-
const worktreePath = resolve(mainWorktree, ".worktrees", name);
|
|
124
|
-
const cwd = process.cwd();
|
|
125
|
-
if (cwd === worktreePath || cwd.startsWith(worktreePath + "/")) {
|
|
126
|
-
console.error(`Error: Cannot clean '${name}' from inside its worktree.`);
|
|
127
|
-
console.error(
|
|
128
|
-
`Run: cd "${mainWorktree}" && node .claude/skills/sd-worktree/sd-worktree.mjs clean ${name}`,
|
|
129
|
-
);
|
|
130
|
-
process.exit(1);
|
|
131
|
-
}
|
|
132
|
-
if (existsSync(worktreePath)) {
|
|
133
|
-
console.log(`Removing worktree: .worktrees/${name}`);
|
|
134
|
-
try {
|
|
135
|
-
run(`git worktree remove --force "${worktreePath}"`, { cwd: mainWorktree });
|
|
136
|
-
} catch {
|
|
137
|
-
// Manual cleanup when git worktree remove fails (e.g., due to node_modules)
|
|
138
|
-
console.log("git worktree remove failed, cleaning up manually...");
|
|
139
|
-
rmSync(worktreePath, { recursive: true, force: true });
|
|
140
|
-
run("git worktree prune", { cwd: mainWorktree });
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
console.log(`Deleting branch: ${name}`);
|
|
144
|
-
run(`git branch -d "${name}"`, { cwd: mainWorktree });
|
|
145
|
-
console.log(`\nCleaned up '${name}'.`);
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
default:
|
|
150
|
-
console.error("Usage: sd-worktree.mjs <add|merge|rebase|clean> [name]");
|
|
151
|
-
process.exit(1);
|
|
152
|
-
}
|