@wenaixi/dsh-superpower 7.3.0 → 7.5.1
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 +112 -105
- package/README.zh.md +216 -0
- package/lib/catalog.d.ts +8 -2
- package/lib/catalog.d.ts.map +1 -1
- package/lib/catalog.js +64 -9
- package/lib/catalog.js.map +1 -1
- package/lib/client.js +120 -75
- package/lib/document.d.ts +8 -2
- package/lib/document.d.ts.map +1 -1
- package/lib/document.js +14 -4
- package/lib/document.js.map +1 -1
- package/lib/superpowers.d.ts +6 -0
- package/lib/superpowers.d.ts.map +1 -1
- package/lib/superpowers.js +25 -2
- package/lib/superpowers.js.map +1 -1
- package/lib/switches.d.ts +17 -18
- package/lib/switches.d.ts.map +1 -1
- package/lib/switches.js +78 -31
- package/lib/switches.js.map +1 -1
- package/package.json +3 -3
- package/skills/brainstorming/SKILL.md +234 -170
- package/skills/brainstorming/spec-document-reviewer-prompt.md +27 -25
- package/skills/brainstorming/visual-companion.md +84 -231
- package/skills/diagnosing-superpowers/SKILL.md +107 -43
- package/skills/diagnosing-superpowers/prompts/analyst-common.md +32 -18
- package/skills/diagnosing-superpowers/prompts/cost-and-time.md +25 -9
- package/skills/diagnosing-superpowers/prompts/plan-adherence.md +26 -12
- package/skills/diagnosing-superpowers/prompts/quality-evidence.md +23 -8
- package/skills/diagnosing-superpowers/prompts/repeated-work.md +25 -14
- package/skills/diagnosing-superpowers/prompts/request-conflicts.md +18 -9
- package/skills/diagnosing-superpowers/prompts/scrub-audit.md +23 -10
- package/skills/diagnosing-superpowers/prompts/scrub.md +25 -12
- package/skills/diagnosing-superpowers/prompts/similar-session.md +30 -22
- package/skills/diagnosing-superpowers/prompts/skill-timeline.md +26 -12
- package/skills/diagnosing-superpowers/prompts/stumbles.md +24 -12
- package/skills/diagnosing-superpowers/references/context-safety.md +15 -7
- package/skills/diagnosing-superpowers/references/github-issues.md +17 -9
- package/skills/diagnosing-superpowers/references/redaction-policy.md +27 -15
- package/skills/diagnosing-superpowers/references/session-discovery.md +31 -20
- package/skills/diagnosing-superpowers/templates/bundle-README.md +66 -40
- package/skills/diagnosing-superpowers/templates/case.md +49 -42
- package/skills/diagnosing-superpowers/templates/issue.md +32 -26
- package/skills/diagnosing-superpowers/templates/report.md +54 -48
- package/skills/dispatching-parallel-agents/SKILL.md +92 -90
- package/skills/executing-plans/SKILL.md +345 -197
- package/skills/finishing-a-development-branch/SKILL.md +107 -82
- package/skills/receiving-code-review/SKILL.md +129 -127
- package/skills/requesting-code-review/SKILL.md +52 -50
- package/skills/requesting-code-review/code-reviewer.md +132 -111
- package/skills/subagent-driven-development/SKILL.md +521 -298
- package/skills/subagent-driven-development/implementer-prompt.md +138 -117
- package/skills/subagent-driven-development/re-review-prompt.md +80 -48
- package/skills/subagent-driven-development/task-reviewer-prompt.md +189 -110
- package/skills/systematic-debugging/CREATION-LOG.md +85 -85
- package/skills/systematic-debugging/SKILL.md +221 -219
- package/skills/systematic-debugging/condition-based-waiting.md +48 -49
- package/skills/systematic-debugging/defense-in-depth.md +46 -46
- package/skills/systematic-debugging/root-cause-tracing.md +63 -63
- package/skills/systematic-debugging/test-academic.md +10 -10
- package/skills/systematic-debugging/test-pressure-1.md +40 -40
- package/skills/systematic-debugging/test-pressure-2.md +58 -58
- package/skills/systematic-debugging/test-pressure-3.md +48 -48
- package/skills/test-driven-development/SKILL.md +161 -153
- package/skills/test-driven-development/writing-good-tests.md +137 -84
- package/skills/using-git-worktrees/SKILL.md +74 -72
- package/skills/using-superpowers/SKILL.md +40 -39
- package/skills/using-superpowers/references/dsh-tools.md +36 -36
- package/skills/verification-before-completion/SKILL.md +85 -83
- package/skills/writing-plans/SKILL.md +123 -84
- package/skills/writing-skills/SKILL.md +419 -417
- package/skills/writing-skills/persuasion-principles.md +118 -118
- package/skills/writing-skills/testing-skills-with-subagents.md +190 -190
- package/skills/brainstorming/scripts/frame-template.html +0 -213
- package/skills/brainstorming/scripts/helper.js +0 -167
- package/skills/brainstorming/scripts/server.cjs +0 -715
- package/skills/brainstorming/scripts/start-server.sh +0 -204
- package/skills/brainstorming/scripts/stop-server.sh +0 -120
|
@@ -1,145 +1,198 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Writing Good Tests
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Load this reference when:** writing or changing tests, adding mocks, or
|
|
4
|
+
adding cleanup/helper methods for tests.
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
+
## Overview
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
A test exists to catch a specific break. Two principles govern everything
|
|
9
|
+
here:
|
|
8
10
|
|
|
9
11
|
```
|
|
10
|
-
1.
|
|
11
|
-
2.
|
|
12
|
+
1. Every test names the break it catches
|
|
13
|
+
2. Every test exercises the real thing
|
|
12
14
|
```
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
Strict TDD produces both naturally: a test written first and watched
|
|
17
|
+
failing against real code has already proven it can fail, and only earns
|
|
18
|
+
a mock when the real dependency proves slow or external.
|
|
15
19
|
|
|
16
|
-
##
|
|
20
|
+
## Principle 1: Name the Break
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
Before writing the test body, answer: **what production change should
|
|
23
|
+
make this test fail — and is that change a bug or a decision?** A test
|
|
24
|
+
earns its place by catching a wrong branch, missing side effect, wrong
|
|
25
|
+
argument, boundary case, or broken contract.
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
**Derive expectations independently.** Use literals and hand-checked
|
|
28
|
+
fixtures; table-driven tests with literal `want` values are the preferred
|
|
29
|
+
shape. An expectation computed by the code under test — or its helpers —
|
|
30
|
+
passes no matter what that code does:
|
|
21
31
|
|
|
22
32
|
```typescript
|
|
23
|
-
// [FAIL]
|
|
33
|
+
// [FAIL] Mirror assertion: the same builder computes both sides — always true
|
|
24
34
|
const expected = buildSearchQuery({ tag: 'urgent' });
|
|
25
35
|
expect(buildSearchQuery({ tag: 'urgent' })).toBe(expected);
|
|
26
36
|
|
|
27
|
-
// [OK]
|
|
37
|
+
// [OK] Hand-derived literal
|
|
28
38
|
expect(buildSearchQuery({ tag: 'urgent' })).toBe('tag:"urgent"');
|
|
29
39
|
```
|
|
30
40
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
**No change detectors.** If only intentional decisions can fail a test —
|
|
42
|
+
a constant's value, exact message wording, private structure — it fires
|
|
43
|
+
on redesign and sleeps through bugs. Test the behavior that depends on
|
|
44
|
+
the decision: not `expect(MAX_RETRIES).toBe(5)` but "a failing call is
|
|
45
|
+
retried 5 times and the 6th attempt never happens."
|
|
46
|
+
|
|
47
|
+
**Behavior, not text.** Asserting that a script, skill, or config
|
|
48
|
+
contains an exact line proves only that the source is the source. Run
|
|
49
|
+
scripts against controlled inputs and assert outputs, side effects, or
|
|
50
|
+
exit codes. Documents that instruct agents are tested by the consuming
|
|
51
|
+
agent's behavior (superpowers:writing-skills); prose for humans earns no
|
|
52
|
+
test at all.
|
|
53
|
+
|
|
54
|
+
**Your code, not the framework.** Test the contract your code makes at
|
|
55
|
+
its boundaries — the route you register, the query you emit, the payload
|
|
56
|
+
you produce. Upstream mechanics are their maintainers' tests to write
|
|
57
|
+
(the classic: asserting your router invokes a registered handler — that
|
|
58
|
+
is the framework's test, not yours). When upstream behavior genuinely
|
|
59
|
+
surprised you, write one narrow characterization test naming the
|
|
60
|
+
assumption. The same boundary applies inside your code: constructors,
|
|
61
|
+
getters, constants, and trivial forwarding earn tests only when they
|
|
62
|
+
validate, normalize, default, derive, enforce, or cause side effects —
|
|
63
|
+
otherwise assert the first consumer-visible result that depends on them.
|
|
64
|
+
|
|
65
|
+
### Gate Function
|
|
38
66
|
|
|
39
67
|
```
|
|
40
|
-
|
|
41
|
-
|
|
68
|
+
BEFORE writing the test body:
|
|
69
|
+
Name the production change that would make this test fail.
|
|
42
70
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
71
|
+
Cannot name one → redesign around an observable behavior
|
|
72
|
+
"The source text changed" → run the artifact and assert its effects
|
|
73
|
+
Only intentional decisions → change detector; test the behavior
|
|
74
|
+
that depends on the decision
|
|
47
75
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
76
|
+
Confirm the expected value is derived without the code under test.
|
|
77
|
+
IF it reuses the code's logic or helpers:
|
|
78
|
+
Replace it with a literal or hand-checked fixture
|
|
51
79
|
```
|
|
52
80
|
|
|
53
|
-
##
|
|
81
|
+
## Principle 2: Exercise the Real Thing
|
|
54
82
|
|
|
55
|
-
**mock
|
|
83
|
+
**The mock earns no assertions.** A mock assertion passes when the mock
|
|
84
|
+
is present and fails when it is absent — it says nothing about the
|
|
85
|
+
component. Assert the real component's behavior; if the mock is what you
|
|
86
|
+
are checking, unmock it or delete the assertion.
|
|
56
87
|
|
|
57
88
|
```typescript
|
|
58
|
-
// [OK]
|
|
89
|
+
// [OK] Real behavior
|
|
59
90
|
expect(screen.getByRole('navigation')).toBeInTheDocument();
|
|
60
91
|
|
|
61
|
-
// [FAIL]
|
|
92
|
+
// [FAIL] Mock existence
|
|
62
93
|
expect(screen.getByTestId('sidebar-mock')).toBeInTheDocument();
|
|
63
94
|
```
|
|
64
95
|
|
|
65
|
-
|
|
96
|
+
**your human partner's correction:** "Are we testing the behavior of a
|
|
97
|
+
mock?"
|
|
66
98
|
|
|
67
|
-
|
|
99
|
+
**Mock at the right level.** Learn every side effect of the real method
|
|
100
|
+
before replacing it; mock the slow or external operation and keep what
|
|
101
|
+
the test depends on real. When unsure, run the test against the real
|
|
102
|
+
implementation first and observe what actually needs to happen.
|
|
68
103
|
|
|
69
104
|
```typescript
|
|
70
|
-
// [FAIL] mock
|
|
105
|
+
// [FAIL] The mock swallows the config write that duplicate detection reads
|
|
71
106
|
vi.mock('ToolCatalog', () => ({
|
|
72
107
|
discoverAndCacheTools: vi.fn().mockResolvedValue(undefined)
|
|
73
108
|
}));
|
|
74
109
|
|
|
75
|
-
// [OK]
|
|
110
|
+
// [OK] Mock only the slow server startup; the config write stays real
|
|
76
111
|
vi.mock('MCPServerManager');
|
|
77
112
|
```
|
|
78
113
|
|
|
79
|
-
|
|
114
|
+
**Make doubles specific.** When arguments, call counts, or ordering are
|
|
115
|
+
part of the contract, assert them — a fake that accepts anything verifies
|
|
116
|
+
nothing. Give each branch (success, error, malformed) its own fixture or
|
|
117
|
+
spy, so the wrong branch cannot satisfy the expectation.
|
|
80
118
|
|
|
81
|
-
|
|
119
|
+
**Mirror real data completely.** Mock the complete structure as it exists
|
|
120
|
+
in reality — all documented fields — not just the ones your test reads.
|
|
121
|
+
Partial mocks fail silently when downstream code reads an omitted field:
|
|
122
|
+
the test passes while integration breaks.
|
|
82
123
|
|
|
83
|
-
|
|
124
|
+
**Production classes carry production methods only.** Cleanup that only
|
|
125
|
+
tests need lives in test utilities, never as a `destroy()` on the
|
|
126
|
+
production class. Ask: is this method called only from tests? Does this
|
|
127
|
+
class own this resource's lifecycle? Wrong answers → test utility.
|
|
84
128
|
|
|
85
|
-
|
|
129
|
+
**Prefer real components over complex mocks.** When mock setup outgrows
|
|
130
|
+
the test logic, mocks miss methods the real components have, or tests
|
|
131
|
+
break when the mock changes, switch to an integration test with real
|
|
132
|
+
components. **your human partner's question:** "Do we need to be using a
|
|
133
|
+
mock here?"
|
|
86
134
|
|
|
87
|
-
###
|
|
135
|
+
### Gate Function
|
|
88
136
|
|
|
89
137
|
```
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
138
|
+
BEFORE adding a mock or test helper:
|
|
139
|
+
List the real method's side effects; keep the ones the test
|
|
140
|
+
depends on real — mock the slow/external level below them.
|
|
93
141
|
|
|
94
|
-
|
|
142
|
+
Mock responses mirror the complete real structure.
|
|
95
143
|
|
|
96
|
-
|
|
144
|
+
A method only tests call lives in test utilities, not production.
|
|
97
145
|
|
|
98
|
-
|
|
99
|
-
|
|
146
|
+
About to assert on the mock itself?
|
|
147
|
+
Unmock it or delete the assertion.
|
|
100
148
|
```
|
|
101
149
|
|
|
102
|
-
##
|
|
150
|
+
## Tests Ship With the Implementation
|
|
103
151
|
|
|
104
|
-
TDD
|
|
152
|
+
The TDD cycle — failing test, minimal implementation, refactor — is what
|
|
153
|
+
"complete" means. Ship the tests the behavior needs and only those:
|
|
154
|
+
trivial code and human prose earn none, and a test written to satisfy
|
|
155
|
+
process costs maintenance forever.
|
|
105
156
|
|
|
106
|
-
##
|
|
157
|
+
## The Mutation Check
|
|
107
158
|
|
|
108
|
-
|
|
159
|
+
Before finishing, mentally mutate the production code; at least one test
|
|
160
|
+
should fail for each realistic mutation:
|
|
109
161
|
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
162
|
+
- Wrong constant or argument
|
|
163
|
+
- Wrong branch handler
|
|
164
|
+
- Missing state change or side effect
|
|
165
|
+
- Empty or default return
|
|
166
|
+
- Missing validation for zero, empty, nil, unauthorized, or malformed input
|
|
115
167
|
|
|
116
|
-
|
|
168
|
+
A mutation nothing catches marks the behavior as unprotected — or the
|
|
169
|
+
test as tautological.
|
|
117
170
|
|
|
118
|
-
##
|
|
171
|
+
## Quick Reference
|
|
119
172
|
|
|
120
|
-
|
|
|
173
|
+
| When you... | Do |
|
|
121
174
|
|-------------|-----|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
| mock
|
|
131
|
-
|
|
|
132
|
-
|
|
133
|
-
##
|
|
134
|
-
|
|
135
|
-
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
-
|
|
144
|
-
- mock
|
|
145
|
-
-
|
|
175
|
+
| Write any test | Name the break it catches — a bug, not a decision |
|
|
176
|
+
| Build an expected value | Derive it by hand; never with the code under test |
|
|
177
|
+
| Test a script or document | Run it / pressure-test its consumer; never grep its text |
|
|
178
|
+
| Reach for a dependency test | Test your boundary contract, not their documented mechanics |
|
|
179
|
+
| Want to assert on a mocked element | Test the real component, or unmock it |
|
|
180
|
+
| Are about to mock a method | Learn its side effects; mock the slow/external level |
|
|
181
|
+
| Build a mock response | Mirror the real structure completely |
|
|
182
|
+
| Need cleanup only tests use | Put it in test utilities |
|
|
183
|
+
| Watch mock setup balloon | Switch to an integration test with real components |
|
|
184
|
+
| Finish a test file | Run the mutation check |
|
|
185
|
+
|
|
186
|
+
## Warning Signs
|
|
187
|
+
|
|
188
|
+
- Setup and assertion share the same object, guaranteeing equality
|
|
189
|
+
- The test can fail only through a panic, crash, or missing selector
|
|
190
|
+
- The test fails on every intentional change, never on accidental breakage
|
|
191
|
+
- Expected values are hidden behind loops, builders, or helpers
|
|
192
|
+
- The test greps source text, or asserts a removed symbol stays removed
|
|
193
|
+
- The test would still matter if only the framework remained
|
|
194
|
+
- The test exists for coverage, checking no side effect or outcome
|
|
195
|
+
- An assertion checks a `*-mock` test ID, or fails if you remove the mock
|
|
196
|
+
- A method is called only from test files
|
|
197
|
+
- Mock setup is more than half the test, or you can't explain why the mock is needed
|
|
198
|
+
- Mocking "just to be safe"
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: using-git-worktrees
|
|
3
|
-
description: "Superpower Skill
|
|
3
|
+
description: "Superpower Skill: Use when starting feature work that needs isolation from current workspace or before executing implementation plans - ensures an isolated workspace exists via native tools or git worktree fallback"
|
|
4
|
+
description_zh: "Superpower Skill:适用于需与当前 worktree 隔离的功能开发或执行实现计划前,通过原生工具优先、git worktree 兜底的方式确保独立 worktree 就绪。"
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
# 使用 Git Worktree
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
# Using Git Worktrees
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Overview
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Ensure work happens in an isolated workspace. Prefer your platform's native worktree tools. Fall back to manual git worktrees only when no native tool is available.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
**Core principle:** Detect existing isolation first. Then use native tools. Then fall back to git. Never fight the harness.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
**Announce at start:** "I'm using the using-git-worktrees skill to set up an isolated workspace."
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
## Step 0: Detect Existing Isolation
|
|
19
|
+
|
|
20
|
+
**Before creating anything, check if you are already in an isolated workspace.**
|
|
19
21
|
|
|
20
22
|
```bash
|
|
21
23
|
GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
|
|
@@ -23,85 +25,85 @@ GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
|
|
|
23
25
|
BRANCH=$(git branch --show-current)
|
|
24
26
|
```
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
**Submodule guard:** `GIT_DIR != GIT_COMMON` is also true inside git submodules. Before concluding "already in a worktree," verify you are not in a submodule:
|
|
27
29
|
|
|
28
30
|
```bash
|
|
29
|
-
#
|
|
31
|
+
# If this returns a path, you're in a submodule, not a worktree — treat as normal repo
|
|
30
32
|
git rev-parse --show-superproject-working-tree 2>/dev/null
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
**If `GIT_DIR != GIT_COMMON` (and not a submodule):** You are already in a linked worktree. Skip to Step 2 (Project Setup). Do NOT create another worktree.
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
37
|
+
Report with branch state:
|
|
38
|
+
- On a branch: "Already in isolated workspace at `<path>` on branch `<name>`."
|
|
39
|
+
- Detached HEAD: "Already in isolated workspace at `<path>` (detached HEAD, externally managed). Branch creation needed at finish time."
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
**If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout.
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
Has the user already indicated their worktree preference in your instructions? If not, ask for consent before creating a worktree:
|
|
42
44
|
|
|
43
|
-
>
|
|
45
|
+
> "Would you like me to set up an isolated worktree? It protects your current branch from changes."
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
Honor any existing declared preference without asking. If the user declines consent, work in place and skip to Step 2.
|
|
46
48
|
|
|
47
|
-
##
|
|
49
|
+
## Step 1: Create Isolated Workspace
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
**You have two mechanisms. Try them in this order.**
|
|
50
52
|
|
|
51
|
-
### 1a.
|
|
53
|
+
### 1a. Native Worktree Tools (preferred)
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
The user has asked for an isolated workspace (Step 0 consent). Do you already have a way to create a worktree? It might be a tool with a name like `EnterWorktree`, `WorktreeCreate`, a `/worktree` command, or a `--worktree` flag. If you do, use it and skip to Step 2.
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
Native tools handle directory placement, branch creation, and cleanup automatically. Using `git worktree add` when you have a native tool creates phantom state your harness can't see or manage.
|
|
56
58
|
|
|
57
|
-
|
|
59
|
+
Only proceed to Step 1b if you have no native worktree tool available.
|
|
58
60
|
|
|
59
|
-
### 1b. Git Worktree
|
|
61
|
+
### 1b. Git Worktree Fallback
|
|
60
62
|
|
|
61
|
-
|
|
63
|
+
**Only use this if Step 1a does not apply** — you have no native worktree tool available. Create a worktree manually using git.
|
|
62
64
|
|
|
63
|
-
####
|
|
65
|
+
#### Directory Selection
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
Follow this priority order. Explicit user preference always beats observed filesystem state.
|
|
66
68
|
|
|
67
|
-
1.
|
|
69
|
+
1. **Check your instructions for a declared worktree directory preference.** If the user has already specified one, use it without asking.
|
|
68
70
|
|
|
69
|
-
2.
|
|
71
|
+
2. **Check for an existing project-local worktree directory:**
|
|
70
72
|
```bash
|
|
71
|
-
ls -d .worktrees 2>/dev/null #
|
|
72
|
-
ls -d worktrees 2>/dev/null #
|
|
73
|
+
ls -d .worktrees 2>/dev/null # Preferred (hidden)
|
|
74
|
+
ls -d worktrees 2>/dev/null # Alternative
|
|
73
75
|
```
|
|
74
|
-
|
|
76
|
+
If found, use it. If both exist, `.worktrees` wins.
|
|
75
77
|
|
|
76
|
-
3.
|
|
78
|
+
3. **If there is no other guidance available**, default to `.worktrees/` at the project root.
|
|
77
79
|
|
|
78
|
-
####
|
|
80
|
+
#### Safety Verification (project-local directories only)
|
|
79
81
|
|
|
80
|
-
|
|
82
|
+
**MUST verify directory is ignored before creating worktree:**
|
|
81
83
|
|
|
82
84
|
```bash
|
|
83
85
|
git check-ignore -q .worktrees 2>/dev/null || git check-ignore -q worktrees 2>/dev/null
|
|
84
86
|
```
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
**If NOT ignored:** Add to .gitignore, commit the change, then proceed.
|
|
87
89
|
|
|
88
|
-
|
|
90
|
+
**Why critical:** Prevents accidentally committing worktree contents to repository.
|
|
89
91
|
|
|
90
|
-
####
|
|
92
|
+
#### Create the Worktree
|
|
91
93
|
|
|
92
94
|
```bash
|
|
93
|
-
#
|
|
95
|
+
# Determine path based on chosen location
|
|
94
96
|
path="$LOCATION/$BRANCH_NAME"
|
|
95
97
|
|
|
96
98
|
git worktree add "$path" -b "$BRANCH_NAME"
|
|
97
99
|
cd "$path"
|
|
98
100
|
```
|
|
99
101
|
|
|
100
|
-
|
|
102
|
+
**Sandbox fallback:** If `git worktree add` fails with a permission error (sandbox denial), tell the user the sandbox blocked worktree creation and you're working in the current directory instead. Then run setup and baseline tests in place.
|
|
101
103
|
|
|
102
|
-
##
|
|
104
|
+
## Step 2: Project Setup
|
|
103
105
|
|
|
104
|
-
|
|
106
|
+
Auto-detect and run appropriate setup:
|
|
105
107
|
|
|
106
108
|
```bash
|
|
107
109
|
# Node.js
|
|
@@ -118,20 +120,20 @@ if [ -f pyproject.toml ]; then poetry install; fi
|
|
|
118
120
|
if [ -f go.mod ]; then go mod download; fi
|
|
119
121
|
```
|
|
120
122
|
|
|
121
|
-
##
|
|
123
|
+
## Step 3: Verify Clean Baseline
|
|
122
124
|
|
|
123
|
-
|
|
125
|
+
Run tests to ensure workspace starts clean:
|
|
124
126
|
|
|
125
127
|
```bash
|
|
126
|
-
#
|
|
128
|
+
# Use project-appropriate command
|
|
127
129
|
npm test / cargo test / pytest / go test ./...
|
|
128
130
|
```
|
|
129
131
|
|
|
130
|
-
|
|
132
|
+
**If tests fail:** Report failures, ask whether to proceed or investigate.
|
|
131
133
|
|
|
132
|
-
|
|
134
|
+
**If tests pass:** Report ready.
|
|
133
135
|
|
|
134
|
-
###
|
|
136
|
+
### Report
|
|
135
137
|
|
|
136
138
|
```
|
|
137
139
|
Worktree ready at <full-path>
|
|
@@ -139,29 +141,29 @@ Tests passing (<N> tests, 0 failures)
|
|
|
139
141
|
Ready to implement <feature-name>
|
|
140
142
|
```
|
|
141
143
|
|
|
142
|
-
##
|
|
144
|
+
## Quick Reference
|
|
143
145
|
|
|
144
|
-
|
|
|
146
|
+
| Situation | Action |
|
|
145
147
|
|-----------|--------|
|
|
146
|
-
|
|
|
147
|
-
|
|
|
148
|
-
|
|
|
149
|
-
|
|
|
150
|
-
| `.worktrees/`
|
|
151
|
-
| `worktrees/`
|
|
152
|
-
|
|
|
153
|
-
|
|
|
154
|
-
|
|
|
155
|
-
|
|
|
156
|
-
|
|
|
157
|
-
|
|
|
158
|
-
|
|
159
|
-
##
|
|
160
|
-
|
|
161
|
-
|
|
|
148
|
+
| Already in linked worktree | Skip creation (Step 0) |
|
|
149
|
+
| In a submodule | Treat as normal repo (Step 0 guard) |
|
|
150
|
+
| Native worktree tool available | Use it (Step 1a) |
|
|
151
|
+
| No native tool | Git worktree fallback (Step 1b) |
|
|
152
|
+
| `.worktrees/` exists | Use it (verify ignored) |
|
|
153
|
+
| `worktrees/` exists | Use it (verify ignored) |
|
|
154
|
+
| Both exist | Use `.worktrees/` |
|
|
155
|
+
| Neither exists | Check instruction file, then default `.worktrees/` |
|
|
156
|
+
| Directory not ignored | Add to .gitignore + commit |
|
|
157
|
+
| Permission error on create | Sandbox fallback, work in place |
|
|
158
|
+
| Tests fail during baseline | Report failures + ask |
|
|
159
|
+
| No package.json/Cargo.toml | Skip dependency install |
|
|
160
|
+
|
|
161
|
+
## Common Rationalizations
|
|
162
|
+
|
|
163
|
+
| Excuse | Reality |
|
|
162
164
|
|--------|---------|
|
|
163
|
-
|
|
|
164
|
-
|
|
|
165
|
-
|
|
|
166
|
-
|
|
|
167
|
-
|
|
|
165
|
+
| "I'm obviously not in a worktree — no need to check" | Run Step 0. Harness-created isolation and submodules both fool eyeballing; the detection commands settle it. |
|
|
166
|
+
| "`git worktree add` is quicker than hunting for a native tool" | A native tool (e.g. `EnterWorktree`) owns placement, branching, and cleanup. Bypassing it is the #1 mistake — it creates phantom state your harness can't see or manage. |
|
|
167
|
+
| "The worktree directory is surely ignored already" | Run `git check-ignore`. An unignored worktree directory commits the whole tree into the repo. |
|
|
168
|
+
| "Any directory name works" | Explicit instructions beat an existing project-local directory, which beats the `.worktrees/` default. |
|
|
169
|
+
| "The workspace is fresh — baseline tests can wait" | A dirty baseline makes every later failure ambiguous. Run the tests now; proceeding past failures is your human partner's call. |
|