gsd-pi 0.3.0 → 0.3.3

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.
Files changed (40) hide show
  1. package/README.md +3 -1
  2. package/dist/cli.js +112 -5
  3. package/dist/loader.js +0 -0
  4. package/dist/resource-loader.d.ts +3 -3
  5. package/dist/resource-loader.js +10 -4
  6. package/dist/tool-bootstrap.d.ts +4 -0
  7. package/dist/tool-bootstrap.js +74 -0
  8. package/dist/wizard.js +15 -5
  9. package/package.json +6 -2
  10. package/patches/@mariozechner+pi-coding-agent+0.57.1.patch +48 -0
  11. package/patches/@mariozechner+pi-tui+0.57.1.patch +47 -0
  12. package/scripts/postinstall.js +8 -0
  13. package/src/resources/extensions/bg-shell/index.ts +57 -8
  14. package/src/resources/extensions/browser-tools/index.ts +80 -7
  15. package/src/resources/extensions/github/gh-api.ts +46 -30
  16. package/src/resources/extensions/gsd/auto.ts +188 -10
  17. package/src/resources/extensions/gsd/commands.ts +13 -6
  18. package/src/resources/extensions/gsd/doctor.ts +7 -0
  19. package/src/resources/extensions/gsd/guided-flow.ts +9 -6
  20. package/src/resources/extensions/gsd/index.ts +32 -2
  21. package/src/resources/extensions/gsd/prompts/discuss.md +73 -27
  22. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  23. package/src/resources/extensions/gsd/prompts/worktree-merge.md +51 -17
  24. package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +38 -0
  25. package/src/resources/extensions/gsd/worktree-command.ts +219 -49
  26. package/src/resources/extensions/gsd/worktree-manager.ts +106 -16
  27. package/src/resources/extensions/mcporter/index.ts +410 -0
  28. package/src/resources/extensions/slash-commands/clear.ts +10 -0
  29. package/src/resources/extensions/slash-commands/index.ts +2 -2
  30. package/src/resources/extensions/voice/index.ts +176 -0
  31. package/src/resources/extensions/voice/speech-recognizer +0 -0
  32. package/src/resources/extensions/voice/speech-recognizer.swift +76 -0
  33. package/dist/modes/interactive/theme/dark.json +0 -85
  34. package/dist/modes/interactive/theme/light.json +0 -84
  35. package/dist/modes/interactive/theme/theme-schema.json +0 -335
  36. package/dist/modes/interactive/theme/theme.d.ts +0 -78
  37. package/dist/modes/interactive/theme/theme.d.ts.map +0 -1
  38. package/dist/modes/interactive/theme/theme.js +0 -949
  39. package/dist/modes/interactive/theme/theme.js.map +0 -1
  40. package/src/resources/extensions/slash-commands/gsd-run.ts +0 -34
@@ -31,13 +31,14 @@ let pendingAutoStart: {
31
31
  pi: ExtensionAPI;
32
32
  basePath: string;
33
33
  milestoneId: string; // the milestone being discussed
34
+ step?: boolean; // preserve step mode through discuss → auto transition
34
35
  } | null = null;
35
36
 
36
37
  /** Called from agent_end to check if auto-mode should start after discuss */
37
38
  export function checkAutoStartAfterDiscuss(): boolean {
38
39
  if (!pendingAutoStart) return false;
39
40
 
40
- const { ctx, pi, basePath, milestoneId } = pendingAutoStart;
41
+ const { ctx, pi, basePath, milestoneId, step } = pendingAutoStart;
41
42
 
42
43
  // Don't fire until the discuss phase has actually produced a context file
43
44
  // for the milestone being discussed. agent_end fires after every LLM turn,
@@ -47,7 +48,7 @@ export function checkAutoStartAfterDiscuss(): boolean {
47
48
  if (!contextFile) return false; // no context yet — keep waiting
48
49
 
49
50
  pendingAutoStart = null;
50
- startAuto(ctx, pi, basePath, false).catch(() => {});
51
+ startAuto(ctx, pi, basePath, false, { step }).catch(() => {});
51
52
  return true;
52
53
  }
53
54
 
@@ -435,7 +436,9 @@ export async function showSmartEntry(
435
436
  ctx: ExtensionCommandContext,
436
437
  pi: ExtensionAPI,
437
438
  basePath: string,
439
+ options?: { step?: boolean },
438
440
  ): Promise<void> {
441
+ const stepMode = options?.step;
439
442
 
440
443
  // ── Ensure git repo exists — GSD needs it for branch-per-slice ──────
441
444
  try {
@@ -501,14 +504,14 @@ export async function showSmartEntry(
501
504
 
502
505
  if (isFirst) {
503
506
  // First ever — skip wizard, just ask directly
504
- pendingAutoStart = { ctx, pi, basePath, milestoneId: nextId };
507
+ pendingAutoStart = { ctx, pi, basePath, milestoneId: nextId, step: stepMode };
505
508
  dispatchWorkflow(pi, buildDiscussPrompt(nextId,
506
509
  `New project, milestone ${nextId}. Do NOT read or explore .gsd/ — it's empty scaffolding.`,
507
510
  basePath
508
511
  ));
509
512
  } else {
510
513
  const choice = await showNextAction(ctx as any, {
511
- title: "GSD — Get Stuff Done",
514
+ title: "GSD — Get Shit Done",
512
515
  summary: ["No active milestone."],
513
516
  actions: [
514
517
  {
@@ -522,7 +525,7 @@ export async function showSmartEntry(
522
525
  });
523
526
 
524
527
  if (choice === "new_milestone") {
525
- pendingAutoStart = { ctx, pi, basePath, milestoneId: nextId };
528
+ pendingAutoStart = { ctx, pi, basePath, milestoneId: nextId, step: stepMode };
526
529
  dispatchWorkflow(pi, buildDiscussPrompt(nextId,
527
530
  `New milestone ${nextId}.`,
528
531
  basePath
@@ -560,7 +563,7 @@ export async function showSmartEntry(
560
563
  const milestoneIds = findMilestoneIds(basePath);
561
564
  const nextId = `M${String(milestoneIds.length + 1).padStart(3, "0")}`;
562
565
 
563
- pendingAutoStart = { ctx, pi, basePath, milestoneId: nextId };
566
+ pendingAutoStart = { ctx, pi, basePath, milestoneId: nextId, step: stepMode };
564
567
  dispatchWorkflow(pi, buildDiscussPrompt(nextId,
565
568
  `New milestone ${nextId}.`,
566
569
  basePath
@@ -63,13 +63,43 @@ export default function (pi: ExtensionAPI) {
63
63
  registerGSDCommand(pi);
64
64
  registerWorktreeCommand(pi);
65
65
 
66
- // ── Dynamic-cwd bash tool ──────────────────────────────────────────────
66
+ // ── /exit kill the process immediately ──────────────────────────────
67
+ pi.registerCommand("exit", {
68
+ description: "Exit GSD immediately",
69
+ handler: async (_ctx) => {
70
+ process.exit(0);
71
+ },
72
+ });
73
+
74
+ // ── Dynamic-cwd bash tool with default timeout ────────────────────────
67
75
  // The built-in bash tool captures cwd at startup. This replacement uses
68
76
  // a spawnHook to read process.cwd() dynamically so that process.chdir()
69
77
  // (used by /worktree switch) propagates to shell commands.
70
- const dynamicBash = createBashTool(process.cwd(), {
78
+ //
79
+ // The upstream SDK's bash tool has no default timeout — if the LLM omits
80
+ // the timeout parameter, commands run indefinitely, causing hangs on
81
+ // Windows where process killing is unreliable (see #40). We wrap execute
82
+ // to inject a 120-second default when no timeout is provided.
83
+ const DEFAULT_BASH_TIMEOUT_SECS = 120;
84
+ const baseBash = createBashTool(process.cwd(), {
71
85
  spawnHook: (ctx) => ({ ...ctx, cwd: process.cwd() }),
72
86
  });
87
+ const dynamicBash = {
88
+ ...baseBash,
89
+ execute: async (
90
+ toolCallId: string,
91
+ params: { command: string; timeout?: number },
92
+ signal?: AbortSignal,
93
+ onUpdate?: any,
94
+ ctx?: any,
95
+ ) => {
96
+ const paramsWithTimeout = {
97
+ ...params,
98
+ timeout: params.timeout ?? DEFAULT_BASH_TIMEOUT_SECS,
99
+ };
100
+ return baseBash.execute(toolCallId, paramsWithTimeout, signal, onUpdate, ctx);
101
+ },
102
+ };
73
103
  pi.registerTool(dynamicBash as any);
74
104
 
75
105
  // ── session_start: render branded GSD header ───────────────────────────
@@ -1,14 +1,23 @@
1
1
  {{preamble}}
2
2
 
3
- Say exactly: "What's the vision?" nothing else. Wait for the user's answer.
3
+ Ask: "What's the vision?" once, and then use whatever the user replies with as the vision input to continue.
4
4
 
5
- ## Discussion Phase
5
+ Special handling: if the user message is not a project description (for example, they ask about status, branch state, or other clarifications), treat it as the vision input and proceed with discussion logic instead of repeating "What's the vision?".
6
6
 
7
- After they describe it, your job is to understand the project deeply enough to define the project's capability contract before planning slices.
7
+ ## Reflection Step
8
+
9
+ After the user describes their idea, **do not ask questions yet**. First, prove you understood by reflecting back:
10
+
11
+ 1. Summarize what you understood in your own words — concretely, not abstractly.
12
+ 2. Include a complexity/scale read: "This sounds like [task/project/product] scale — roughly N milestone(s)."
13
+ 3. Include scope honesty — a bullet list of the major capabilities you're hearing: "Here's what I'm hearing: [bullet list of major capabilities]."
14
+ 4. Ask: "Did I get that right, or did I miss something?" — plain text, not `ask_user_questions`. Let them correct freely.
15
+
16
+ This prevents runaway questioning by forcing comprehension proof before anything else. Do not skip this step. Do not combine it with the first question round.
8
17
 
9
18
  ## Vision Mapping
10
19
 
11
- Before diving into detailed Q&A, read the user's description and classify its scale:
20
+ After reflection is confirmed, classify the scale:
12
21
 
13
22
  - **Task** — a focused piece of work (single milestone, few slices)
14
23
  - **Project** — a coherent product with multiple major capabilities (multi-milestone likely)
@@ -19,40 +28,69 @@ Before diving into detailed Q&A, read the user's description and classify its sc
19
28
  2. Present this to the user for confirmation or adjustment
20
29
  3. Only then begin the deep Q&A — and scope the Q&A to the full vision, not just M001
21
30
 
22
- **For Task scale:** Proceed directly to the discussion flow below (single milestone).
31
+ **For Task scale:** Proceed directly to questioning.
23
32
 
24
33
  **Anti-reduction rule:** If the user describes a big vision, plan the big vision. Do not ask "what's the minimum viable version?" or try to reduce scope unless the user explicitly asks for an MVP or minimal version. When something is complex or risky, phase it into a later milestone — do not cut it. The user's ambition is the target, and your job is to sequence it intelligently, not shrink it.
25
34
 
26
- ---
35
+ ## Mandatory Investigation Before First Question Round
36
+
37
+ Before asking your first question, do a mandatory investigation pass. This is not optional.
38
+
39
+ 1. **Scout the codebase** — `ls`, `find`, `rg`, or `scout` for broad unfamiliar areas. Understand what already exists, what patterns are established, what constraints current code imposes.
40
+ 2. **Check library docs** — `resolve_library` / `get_library_docs` for any tech the user mentioned. Get current facts about capabilities, constraints, API shapes, version-specific behavior.
41
+ 3. **Web search** — `search-the-web` if the domain is unfamiliar, if you need current best practices, or if the user referenced external services/APIs you need facts about. Use `fetch_page` for full content when snippets aren't enough.
42
+
43
+ This happens ONCE, before the first round. The goal: your first questions should reflect what's actually true, not what you assume.
44
+
45
+ For subsequent rounds, continue investigating between rounds — check docs, search, or scout as needed to make each round's questions smarter. But the first-round investigation is mandatory and explicit.
46
+
47
+ ## Questioning Philosophy
48
+
49
+ You are a thinking partner, not an interviewer.
27
50
 
28
- **If the user provides a file path or pastes a large document** (spec, design doc, product plan, chat export), read it fully before asking questions. Use it as the starting point — don't ask them to re-explain what's already in the document. Your questions should fill gaps and resolve ambiguities the document doesn't cover.
51
+ **Start open, follow energy.** Let the user's enthusiasm guide where you dig deeper. If they light up about a particular aspect, explore it. If they're vague about something, that's where you probe.
29
52
 
30
- **Investigate between question rounds to make your questions smarter.** Before each round of questions, do enough lightweight research that your questions are grounded in reality not guesses about what exists or what's possible.
53
+ **Challenge vagueness, make abstract concrete.** When the user says something abstract ("it should be smart" / "it needs to handle edge cases" / "good UX"), push for specifics. What does "smart" mean in practice? Which edge cases? What does good UX look like for this specific interaction?
31
54
 
32
- - Check library docs (`resolve_library` / `get_library_docs`) when the user mentions tech you need current facts aboutcapabilities, constraints, API shapes, version-specific behavior
33
- - Do web searches (`search-the-web`) to verify the landscape — what solutions exist, what's changed recently, what's the current best practice. Use `freshness` for recency-sensitive queries, `domain` to target specific sites. Use `fetch_page` to read the full content of promising URLs when snippets aren't enough.
34
- - Scout the codebase (`ls`, `find`, `rg`, or `scout` for broad unfamiliar areas) to understand what already exists, what patterns are established, what constraints current code imposes
55
+ **Questions must be about the experience, not the implementation.** Never ask "what auth provider?" — ask "when someone logs in, what should that feel like?" Never ask "what database?" ask "when they come back tomorrow, what should they see?" Implementation is your job. Understanding what they want to experience is the discussion's job.
35
56
 
36
- Don't go deep just enough that your next question reflects what's actually true rather than what you assume.
57
+ **Freeform rule:** When the user selects "Other" or clearly wants to explain something freely, stop using `ask_user_questions` and switch to plain text follow-ups. Let them talk. Resume structured questions when appropriate.
37
58
 
38
- **Use this to actively surface:**
39
- - The biggest technical unknowns what could fail, what hasn't been proven, what might invalidate the plan
40
- - Integration surfacesexternal systems, APIs, libraries, or internal modules this work touches
41
- - What needs to be proven before committing the things that, if they don't work, mean the plan is wrong
42
- - Product reality requirements: primary user loop, launchability expectations, continuity expectations, and failure visibility expectations
43
- - Items that are complex, risky, or lower priority phase these into later milestones rather than deferring or cutting them. Only truly unwanted capabilities become anti-features.
59
+ **Anti-patterns never do these:**
60
+ - **Checklist walking** going through a predetermined list of topics regardless of what the user said
61
+ - **Canned questions**asking generic questions that could apply to any project
62
+ - **Corporate speak** "What are your key success metrics?" / "Who are the stakeholders?"
63
+ - **Interrogation** rapid-fire questions without acknowledging or building on answers
64
+ - **Rushing**trying to get through questions quickly to move to planning
65
+ - **Shallow acceptance** — accepting vague answers without probing ("Sounds good!" then moving on)
66
+ - **Premature constraints** — asking about tech stack, deployment targets, or architecture before understanding what they're building
67
+ - **Asking about technical skill** — never ask "how technical are you?" or "are you familiar with X?" — adapt based on how they communicate
44
68
 
45
- **Then use ask_user_questions** to dig into gray areas — architecture choices, scope boundaries, tech preferences, what's in vs out. 1-3 questions per round.
69
+ ## Depth Enforcement
46
70
 
47
- If a `GSD Skill Preferences` block is present in system context, use it to decide which skills to load and follow during discuss/planning work, but do not let it override the required discuss flow or artifact requirements.
71
+ Do NOT offer to proceed until ALL of the following are satisfied. Track these internally as a background checklist:
48
72
 
49
- **Self-regulate depth by scale:**
50
- - **Task scale:** After about 5-10 questions total (2-3 rounds), or when you feel you have a solid understanding, offer to proceed.
51
- - **Project/Product scale:** After about 15-25 questions total (5-8 rounds), or when you feel you have a solid understanding, offer to proceed.
73
+ - [ ] **What they're building** — concrete enough that you could explain it to a stranger
74
+ - [ ] **Why it needs to exist** the problem it solves or the desire it fulfills
75
+ - [ ] **Who it's for** even if just themselves
76
+ - [ ] **What "done" looks like** — observable outcomes, not abstract goals
77
+ - [ ] **The biggest technical unknowns / risks** — what could fail, what hasn't been proven
78
+ - [ ] **What external systems/services this touches** — APIs, databases, third-party services, hardware
52
79
 
53
- Include a question like:
54
- "I think I have a good picture. Ready to confirm requirements and milestone plan, or are there more things to discuss?"
55
- with options: "Ready to confirm requirements and milestone plan (Recommended)", "I have more to discuss"
80
+ **Minimum round counts before the wrap-up gate is allowed:**
81
+ - **Task scale:** at least 2 full rounds (6+ questions asked and answered)
82
+ - **Project/Product scale:** at least 4 full rounds (12+ questions asked and answered)
83
+
84
+ Do not count the reflection step as a question round. Rounds start after reflection is confirmed.
85
+
86
+ ## Wrap-up Gate
87
+
88
+ Only after the depth checklist is fully satisfied AND minimum rounds are hit, offer to proceed.
89
+
90
+ The wrap-up gate must include a scope reflection:
91
+ "Here's what I'm planning to build: [list of capabilities with rough complexity]. Does this match your vision, or did I miss something?"
92
+
93
+ Then offer options: "Ready to confirm requirements and milestone plan (Recommended)", "I have more to discuss"
56
94
 
57
95
  If the user wants to keep going, keep asking. If they're ready, proceed.
58
96
 
@@ -105,7 +143,9 @@ Rules:
105
143
 
106
144
  For multi-milestone projects, requirements should span the full vision. Requirements owned by later milestones get provisional ownership. The full requirement set captures the user's complete vision — milestones are the sequencing strategy, not the scope boundary.
107
145
 
108
- If the project is new or has no `REQUIREMENTS.md`, confirm candidate requirements with the user before writing the roadmap. Keep the confirmation lightweight: confirm, defer, reject, or add.
146
+ If the project is new or has no `REQUIREMENTS.md`, confirm candidate requirements with the user before writing the roadmap.
147
+
148
+ **Print the requirements in chat before asking for confirmation.** Do not say "here are the requirements" and then only write them to a file. The user must see them in the terminal. Print a markdown table with columns: ID, Title, Status, Owner, Source. Group by status (Active, Deferred, Out of Scope). After the table, ask: "Confirm, adjust, or add?"
109
149
 
110
150
  ## Scope Assessment
111
151
 
@@ -115,6 +155,12 @@ If Vision Mapping classified the work as Task but discussion revealed Project-sc
115
155
 
116
156
  ## Output Phase
117
157
 
158
+ ### Roadmap Preview
159
+
160
+ Before writing any files, **print the planned roadmap in chat** so the user can see and approve it. Print a markdown table with columns: Slice, Title, Risk, Depends, Demo. One row per slice. Below the table, print the milestone definition of done as a bullet list.
161
+
162
+ Ask: "Ready to write the plan, or want to adjust?" Only proceed to writing files after the user confirms.
163
+
118
164
  ### Naming Convention
119
165
 
120
166
  Directories use bare IDs. Files use ID-SUFFIX format. Titles live inside file content, not in names.
@@ -1,4 +1,4 @@
1
- ## GSD — Get Stuff Done
1
+ ## GSD — Get Shit Done
2
2
 
3
3
  You are **GSD** — a coding agent that gets shit done.
4
4
 
@@ -1,8 +1,16 @@
1
- You are merging GSD artifacts from worktree **{{worktreeName}}** (branch `{{worktreeBranch}}`) into target branch `{{mainBranch}}`.
1
+ You are merging changes from worktree **{{worktreeName}}** (branch `{{worktreeBranch}}`) into target branch `{{mainBranch}}`.
2
+
3
+ ## Working Directory
4
+
5
+ Your current working directory has been set to the **main project tree** at `{{mainTreePath}}`. You are on the `{{mainBranch}}` branch. All git and file commands run from here.
6
+
7
+ - **Main tree (CWD):** `{{mainTreePath}}` — this is where you run `git merge`, read main-branch files, and commit
8
+ - **Worktree directory:** `{{worktreePath}}` — the worktree's working copy; read files here to inspect worktree versions before merging
9
+ - **Worktree branch:** `{{worktreeBranch}}`
2
10
 
3
11
  ## Context
4
12
 
5
- The worktree was created as a parallel workspace. It may contain new milestones, updated roadmaps, new plans, research, decisions, or other GSD artifacts that need to be reconciled with the main branch.
13
+ The worktree was created as a parallel workspace. It may contain code changes, new milestones, updated roadmaps, new plans, research, decisions, or other artifacts that need to be merged into the target branch.
6
14
 
7
15
  ### Commit History (worktree)
8
16
 
@@ -10,7 +18,7 @@ The worktree was created as a parallel workspace. It may contain new milestones,
10
18
  {{commitLog}}
11
19
  ```
12
20
 
13
- ### GSD Artifact Changes
21
+ ### Changed Files
14
22
 
15
23
  **Added files:**
16
24
  {{addedFiles}}
@@ -21,10 +29,16 @@ The worktree was created as a parallel workspace. It may contain new milestones,
21
29
  **Removed files:**
22
30
  {{removedFiles}}
23
31
 
24
- ### Full Diff
32
+ ### Code Diff
33
+
34
+ ```diff
35
+ {{codeDiff}}
36
+ ```
37
+
38
+ ### GSD Artifact Diff
25
39
 
26
40
  ```diff
27
- {{fullDiff}}
41
+ {{gsdDiff}}
28
42
  ```
29
43
 
30
44
  ## Your Task
@@ -33,7 +47,15 @@ Analyze the changes and guide the merge. Follow these steps exactly:
33
47
 
34
48
  ### Step 1: Categorize Changes
35
49
 
36
- Classify each changed GSD artifact:
50
+ Classify each changed file:
51
+
52
+ **Code changes:**
53
+ - **New source files** — new modules, components, utilities, tests
54
+ - **Modified source files** — changes to existing code
55
+ - **Config changes** — package.json, tsconfig, build config, etc.
56
+ - **Deleted files** — removed source or config files
57
+
58
+ **GSD artifact changes:**
37
59
  - **New milestones** — entirely new M###/ directories with roadmaps
38
60
  - **New slices/tasks** — new planning artifacts within existing milestones
39
61
  - **Updated roadmaps** — modifications to existing M###-ROADMAP.md files
@@ -47,7 +69,12 @@ Classify each changed GSD artifact:
47
69
 
48
70
  For each **modified** file, check whether the main branch version has also changed since the worktree branched off. Flag any files where both branches have diverged — these need manual reconciliation.
49
71
 
50
- Read the current main-branch version of each modified file and compare it against both the worktree version and the common ancestor to identify:
72
+ To compare versions:
73
+ - **Main-branch version:** read the file at its normal path (your CWD is the main tree)
74
+ - **Worktree version:** read the file at `{{worktreePath}}/<relative-path>`
75
+ - Use `git merge-base {{mainBranch}} {{worktreeBranch}}` to find the common ancestor if needed
76
+
77
+ Classify each modified file:
51
78
  - **Clean merges** — main hasn't changed, worktree changes can apply directly
52
79
  - **Conflicts** — both branches changed the same file; needs reconciliation
53
80
  - **Stale changes** — worktree modified a file that main has since replaced or removed
@@ -58,28 +85,35 @@ Present a merge plan to the user:
58
85
 
59
86
  1. For **clean merges**: list files that will merge without conflict
60
87
  2. For **conflicts**: show both versions side-by-side and propose a reconciled version
61
- 3. For **new artifacts**: confirm they should be added to the main branch
62
- 4. For **removed artifacts**: confirm the removals are intentional
88
+ 3. For **new files**: confirm they should be added to the main branch
89
+ 4. For **removed files**: confirm the removals are intentional
63
90
 
64
91
  Ask the user to confirm the merge plan before proceeding.
65
92
 
66
93
  ### Step 4: Execute Merge
67
94
 
68
- Once confirmed:
95
+ Once confirmed, run all commands from `{{mainTreePath}}` (your CWD):
69
96
 
70
- 1. If there are conflicts requiring manual reconciliation, apply the reconciled versions to the main branch working tree
71
- 2. Run `git merge --squash {{worktreeBranch}}` to bring in all changes
72
- 3. Review the staged changes if any reconciled files need adjustment, apply them now
73
- 4. Commit with message: `merge(worktree/{{worktreeName}}): <summary of what was merged>`
74
- 5. Report what was merged
97
+ 1. Ensure you are on the target branch: `git checkout {{mainBranch}}`
98
+ 2. If there are conflicts requiring manual reconciliation, apply the reconciled versions first
99
+ 3. Run `git merge --squash {{worktreeBranch}}` to bring in all changes
100
+ 4. Review the staged changes if any reconciled files need adjustment, apply them now
101
+ 5. Commit with message: `merge(worktree/{{worktreeName}}): <summary of what was merged>`
102
+ 6. Report what was merged
75
103
 
76
104
  ### Step 5: Cleanup Prompt
77
105
 
78
106
  After a successful merge, ask the user whether to:
79
- - **Remove the worktree** — delete `.gsd/worktrees/{{worktreeName}}/` and the `{{worktreeBranch}}` branch
107
+ - **Remove the worktree** — delete the worktree directory and the `{{worktreeBranch}}` branch
80
108
  - **Keep the worktree** — leave it for continued parallel work
81
109
 
82
- If the user chooses to remove it, run `/worktree remove {{worktreeName}}`.
110
+ If the user chooses to remove it, run these commands from `{{mainTreePath}}`:
111
+ ```
112
+ git worktree remove {{worktreePath}}
113
+ git branch -D {{worktreeBranch}}
114
+ ```
115
+
116
+ **Do NOT use `/worktree remove` — the command handler may not have the correct state after the merge.** Use the git commands directly.
83
117
 
84
118
  ## Important
85
119
 
@@ -0,0 +1,38 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+
4
+ let passed = 0;
5
+ let failed = 0;
6
+
7
+ function assert(condition: boolean, message: string): void {
8
+ if (condition) passed++;
9
+ else {
10
+ failed++;
11
+ console.error(` FAIL: ${message}`);
12
+ }
13
+ }
14
+
15
+ const promptPath = join(process.cwd(), 'src/resources/extensions/gsd/prompts/discuss.md');
16
+ const discussPrompt = readFileSync(promptPath, 'utf-8');
17
+
18
+ console.log('\n=== discuss prompt: resilient vision framing ===');
19
+ {
20
+ const hardenedPattern = /Say exactly:\s*"What's the vision\?"/;
21
+ assert(!hardenedPattern.test(discussPrompt), 'prompt no longer uses exact-verbosity lock');
22
+ assert(
23
+ discussPrompt.includes('Ask: "What\'s the vision?" once'),
24
+ 'prompt asks for vision exactly once',
25
+ );
26
+ assert(
27
+ discussPrompt.includes('Special handling'),
28
+ 'prompt documents special handling for non-vision user messages',
29
+ );
30
+ assert(
31
+ discussPrompt.includes('instead of repeating "What\'s the vision?"'),
32
+ 'prompt forbids repeating the vision question',
33
+ );
34
+ }
35
+
36
+ console.log(`\nResults: ${passed} passed, ${failed} failed`);
37
+ if (failed > 0) process.exit(1);
38
+ console.log('All tests passed ✓');