get-shit-done-cc 1.38.0 → 1.38.2

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
@@ -624,6 +624,7 @@ You're never locked in. The system adapts.
624
624
  | Command | What it does |
625
625
  |---------|--------------|
626
626
  | `/gsd-map-codebase [area]` | Analyze existing codebase before new-project |
627
+ | `/gsd-ingest-docs [dir]` | Scan a repo of mixed ADRs, PRDs, SPECs, and DOCs and bootstrap or merge the full `.planning/` setup in one pass — parallel classification, synthesis with precedence rules, and a three-bucket conflicts report |
627
628
 
628
629
  ### Phase Management
629
630
 
package/bin/install.js CHANGED
@@ -10,6 +10,8 @@ const crypto = require('crypto');
10
10
  const cyan = '\x1b[36m';
11
11
  const green = '\x1b[32m';
12
12
  const yellow = '\x1b[33m';
13
+ const red = '\x1b[31m';
14
+ const bold = '\x1b[1m';
13
15
  const dim = '\x1b[2m';
14
16
  const reset = '\x1b[0m';
15
17
 
@@ -5825,6 +5827,7 @@ function install(isGlobal, runtime = 'claude') {
5825
5827
  let content = fs.readFileSync(srcFile, 'utf8');
5826
5828
  content = content.replace(/'\.claude'/g, configDirReplacement);
5827
5829
  content = content.replace(/\/\.claude\//g, `/${getDirName(runtime)}/`);
5830
+ content = content.replace(/\.claude\//g, `${getDirName(runtime)}/`);
5828
5831
  if (isQwen) {
5829
5832
  content = content.replace(/CLAUDE\.md/g, 'QWEN.md');
5830
5833
  content = content.replace(/\bClaude Code\b/g, 'Qwen Code');
@@ -5950,6 +5953,7 @@ function install(isGlobal, runtime = 'claude') {
5950
5953
  let content = fs.readFileSync(srcFile, 'utf8');
5951
5954
  content = content.replace(/'\.claude'/g, configDirReplacement);
5952
5955
  content = content.replace(/\/\.claude\//g, `/${getDirName(runtime)}/`);
5956
+ content = content.replace(/\.claude\//g, `${getDirName(runtime)}/`);
5953
5957
  content = content.replace(/\{\{GSD_VERSION\}\}/g, pkg.version);
5954
5958
  fs.writeFileSync(destFile, content);
5955
5959
  try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows */ }
@@ -6643,8 +6647,94 @@ function promptLocation(runtimes) {
6643
6647
  * every /gsd-* command that depends on newer query handlers.
6644
6648
  *
6645
6649
  * Skip if --no-sdk. Skip if already on PATH (unless --sdk was explicit).
6646
- * Failures are warnings, not fatal.
6650
+ * Failures are FATAL — we exit non-zero so install does not complete with a
6651
+ * silently broken SDK (issue #2439). Set GSD_ALLOW_OFF_PATH=1 to downgrade the
6652
+ * post-install PATH verification to a warning (exit code 2) for users with an
6653
+ * intentionally restricted PATH who will wire things up manually.
6647
6654
  */
6655
+
6656
+ /**
6657
+ * Resolve `gsd-sdk` on PATH. Uses `command -v` via `sh -c` on POSIX (portable
6658
+ * across sh/bash/zsh) and `where` on Windows. Returns trimmed path or null.
6659
+ */
6660
+ function resolveGsdSdk() {
6661
+ const { spawnSync } = require('child_process');
6662
+ if (process.platform === 'win32') {
6663
+ const r = spawnSync('where', ['gsd-sdk'], { encoding: 'utf-8' });
6664
+ if (r.status === 0 && r.stdout && r.stdout.trim()) {
6665
+ return r.stdout.trim().split('\n')[0].trim();
6666
+ }
6667
+ return null;
6668
+ }
6669
+ const r = spawnSync('sh', ['-c', 'command -v gsd-sdk'], { encoding: 'utf-8' });
6670
+ if (r.status === 0 && r.stdout && r.stdout.trim()) {
6671
+ return r.stdout.trim();
6672
+ }
6673
+ return null;
6674
+ }
6675
+
6676
+ /**
6677
+ * Best-effort detection of the user's shell rc file for PATH remediation hints.
6678
+ */
6679
+ function detectShellRc() {
6680
+ const path = require('path');
6681
+ const shell = process.env.SHELL || '';
6682
+ const home = process.env.HOME || '~';
6683
+ if (/\/zsh$/.test(shell)) return { shell: 'zsh', rc: path.join(home, '.zshrc') };
6684
+ if (/\/bash$/.test(shell)) return { shell: 'bash', rc: path.join(home, '.bashrc') };
6685
+ if (/\/fish$/.test(shell)) return { shell: 'fish', rc: path.join(home, '.config', 'fish', 'config.fish') };
6686
+ return { shell: 'sh', rc: path.join(home, '.profile') };
6687
+ }
6688
+
6689
+ /**
6690
+ * Emit a red fatal banner and exit. Prints actionable PATH remediation when
6691
+ * the global install succeeded but the bin dir is not on PATH.
6692
+ *
6693
+ * If exitCode is 2, this is the "off-PATH" case and GSD_ALLOW_OFF_PATH respect
6694
+ * is applied by the caller; we only print.
6695
+ */
6696
+ function emitSdkFatal(reason, { globalBin, exitCode }) {
6697
+ const { shell, rc } = detectShellRc();
6698
+ const bar = '━'.repeat(72);
6699
+ const redBold = `${red}${bold}`;
6700
+
6701
+ console.error('');
6702
+ console.error(`${redBold}${bar}${reset}`);
6703
+ console.error(`${redBold} ✗ GSD SDK install failed — /gsd-* commands will not work${reset}`);
6704
+ console.error(`${redBold}${bar}${reset}`);
6705
+ console.error(` ${red}Reason:${reset} ${reason}`);
6706
+
6707
+ if (globalBin) {
6708
+ console.error('');
6709
+ console.error(` ${yellow}gsd-sdk was installed to:${reset}`);
6710
+ console.error(` ${cyan}${globalBin}${reset}`);
6711
+ console.error('');
6712
+ console.error(` ${yellow}Your shell's PATH does not include this directory.${reset}`);
6713
+ console.error(` Add it by running:`);
6714
+ if (shell === 'fish') {
6715
+ console.error(` ${cyan}fish_add_path "${globalBin}"${reset}`);
6716
+ console.error(` (or append to ${rc})`);
6717
+ } else {
6718
+ console.error(` ${cyan}echo 'export PATH="${globalBin}:$PATH"' >> ${rc}${reset}`);
6719
+ console.error(` ${cyan}source ${rc}${reset}`);
6720
+ }
6721
+ console.error('');
6722
+ console.error(` Then verify: ${cyan}command -v gsd-sdk${reset}`);
6723
+ if (exitCode === 2) {
6724
+ console.error('');
6725
+ console.error(` ${dim}(GSD_ALLOW_OFF_PATH=1 set → exit ${exitCode} instead of hard failure)${reset}`);
6726
+ }
6727
+ } else {
6728
+ console.error('');
6729
+ console.error(` Build manually to retry:`);
6730
+ console.error(` ${cyan}cd <install-dir>/sdk && npm install && npm run build && npm install -g .${reset}`);
6731
+ }
6732
+
6733
+ console.error(`${redBold}${bar}${reset}`);
6734
+ console.error('');
6735
+ process.exit(exitCode);
6736
+ }
6737
+
6648
6738
  function installSdkIfNeeded() {
6649
6739
  if (hasNoSdk) {
6650
6740
  console.log(`\n ${dim}Skipping GSD SDK install (--no-sdk)${reset}`);
@@ -6656,9 +6746,9 @@ function installSdkIfNeeded() {
6656
6746
  const fs = require('fs');
6657
6747
 
6658
6748
  if (!hasSdk) {
6659
- const probe = spawnSync(process.platform === 'win32' ? 'where' : 'which', ['gsd-sdk'], { stdio: 'ignore' });
6660
- if (probe.status === 0) {
6661
- console.log(` ${green}✓${reset} GSD SDK already installed (gsd-sdk on PATH)`);
6749
+ const resolved = resolveGsdSdk();
6750
+ if (resolved) {
6751
+ console.log(` ${green}✓${reset} GSD SDK already installed (gsd-sdk on PATH at ${resolved})`);
6662
6752
  return;
6663
6753
  }
6664
6754
  }
@@ -6671,17 +6761,8 @@ function installSdkIfNeeded() {
6671
6761
  const sdkDir = path.resolve(__dirname, '..', 'sdk');
6672
6762
  const sdkPackageJson = path.join(sdkDir, 'package.json');
6673
6763
 
6674
- const warnManual = (reason) => {
6675
- console.warn(` ${yellow}⚠${reset} ${reason}`);
6676
- console.warn(` Build manually from the repo sdk/ directory:`);
6677
- console.warn(` ${cyan}cd ${sdkDir} && npm install && npm run build && npm install -g .${reset}`);
6678
- console.warn(` Then restart your shell so the updated PATH is picked up.`);
6679
- console.warn(` Without it, /gsd-* commands will fail with "command not found: gsd-sdk".`);
6680
- };
6681
-
6682
6764
  if (!fs.existsSync(sdkPackageJson)) {
6683
- warnManual(`SDK source tree not found at ${sdkDir}.`);
6684
- return;
6765
+ emitSdkFatal(`SDK source tree not found at ${sdkDir}.`, { globalBin: null, exitCode: 1 });
6685
6766
  }
6686
6767
 
6687
6768
  console.log(`\n ${cyan}Building GSD SDK from source (${sdkDir})…${reset}`);
@@ -6690,36 +6771,43 @@ function installSdkIfNeeded() {
6690
6771
  // 1. Install sdk build-time dependencies (tsc, etc.)
6691
6772
  const installResult = spawnSync(npmCmd, ['install'], { cwd: sdkDir, stdio: 'inherit' });
6692
6773
  if (installResult.status !== 0) {
6693
- warnManual('Failed to `npm install` in sdk/.');
6694
- return;
6774
+ emitSdkFatal('Failed to `npm install` in sdk/.', { globalBin: null, exitCode: 1 });
6695
6775
  }
6696
6776
 
6697
6777
  // 2. Compile TypeScript → sdk/dist/
6698
6778
  const buildResult = spawnSync(npmCmd, ['run', 'build'], { cwd: sdkDir, stdio: 'inherit' });
6699
6779
  if (buildResult.status !== 0) {
6700
- warnManual('Failed to `npm run build` in sdk/.');
6701
- return;
6780
+ emitSdkFatal('Failed to `npm run build` in sdk/.', { globalBin: null, exitCode: 1 });
6702
6781
  }
6703
6782
 
6704
6783
  // 3. Install the built package globally so `gsd-sdk` lands on PATH.
6705
6784
  const globalResult = spawnSync(npmCmd, ['install', '-g', '.'], { cwd: sdkDir, stdio: 'inherit' });
6706
6785
  if (globalResult.status !== 0) {
6707
- warnManual('Failed to `npm install -g .` from sdk/.');
6708
- return;
6786
+ emitSdkFatal('Failed to `npm install -g .` from sdk/.', { globalBin: null, exitCode: 1 });
6709
6787
  }
6710
6788
 
6711
- // Verify gsd-sdk is actually resolvable on PATH. npm's global bin dir is
6712
- // not always on the current shell's PATH (Homebrew prefixes, nvm setups,
6713
- // unconfigured npm prefix), so a zero exit status from `npm install -g`
6714
- // alone is not proof of a working binary.
6715
- const resolverCmd = process.platform === 'win32' ? 'where' : 'which';
6716
- const verify = spawnSync(resolverCmd, ['gsd-sdk'], { encoding: 'utf-8' });
6717
- if (verify.status === 0 && verify.stdout && verify.stdout.trim()) {
6718
- console.log(` ${green}✓${reset} Built and installed GSD SDK from source (gsd-sdk resolved at ${verify.stdout.trim().split('\n')[0]})`);
6719
- } else {
6720
- warnManual('Built and installed GSD SDK from source but gsd-sdk is not on PATH — npm global bin may not be in your PATH.');
6721
- if (verify.stderr) console.warn(` resolver stderr: ${verify.stderr.trim()}`);
6789
+ // 4. Verify gsd-sdk is actually resolvable on PATH. npm's global bin dir is
6790
+ // not always on the current shell's PATH (Homebrew prefixes, nvm setups,
6791
+ // unconfigured npm prefix), so a zero exit status from `npm install -g`
6792
+ // alone is not proof of a working binary (issue #2439 root cause).
6793
+ const resolved = resolveGsdSdk();
6794
+ if (resolved) {
6795
+ console.log(` ${green}✓${reset} Built and installed GSD SDK from source (gsd-sdk resolved at ${resolved})`);
6796
+ return;
6722
6797
  }
6798
+
6799
+ // Off-PATH: resolve npm global bin dir for actionable remediation.
6800
+ const prefixResult = spawnSync(npmCmd, ['config', 'get', 'prefix'], { encoding: 'utf-8' });
6801
+ const prefix = prefixResult.status === 0 ? (prefixResult.stdout || '').trim() : null;
6802
+ const globalBin = prefix
6803
+ ? (process.platform === 'win32' ? prefix : path.join(prefix, 'bin'))
6804
+ : null;
6805
+
6806
+ const allowOffPath = process.env.GSD_ALLOW_OFF_PATH === '1';
6807
+ emitSdkFatal(
6808
+ 'Built and installed GSD SDK, but `gsd-sdk` is not on your PATH.',
6809
+ { globalBin, exitCode: allowOffPath ? 2 : 1 },
6810
+ );
6723
6811
  }
6724
6812
 
6725
6813
  /**
@@ -9,4 +9,4 @@ allowed-tools:
9
9
 
10
10
  Show the following output to the user verbatim, with no extra commentary:
11
11
 
12
- !`gsd-sdk query config-set-model-profile $ARGUMENTS --raw`
12
+ !`if ! command -v gsd-sdk >/dev/null 2>&1; then printf '⚠ gsd-sdk not found in PATH — /gsd-set-profile requires it.\n\nInstall the GSD SDK:\n npm install -g @gsd-build/sdk\n\nOr update GSD to get the latest packages:\n /gsd-update\n'; exit 1; fi; gsd-sdk query config-set-model-profile $ARGUMENTS --raw`
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: gsd:sketch
3
- description: Rapidly sketch UI/design ideas using throwaway HTML mockups with multi-variant exploration
4
- argument-hint: "<design idea to explore> [--quick]"
3
+ description: Sketch UI/design ideas with throwaway HTML mockups, or propose what to sketch next (frontier mode)
4
+ argument-hint: "[design idea to explore] [--quick] [--text] or [frontier]"
5
5
  allowed-tools:
6
6
  - Read
7
7
  - Write
@@ -10,11 +10,20 @@ allowed-tools:
10
10
  - Grep
11
11
  - Glob
12
12
  - AskUserQuestion
13
+ - WebSearch
14
+ - WebFetch
15
+ - mcp__context7__resolve-library-id
16
+ - mcp__context7__query-docs
13
17
  ---
14
18
  <objective>
15
19
  Explore design directions through throwaway HTML mockups before committing to implementation.
16
20
  Each sketch produces 2-3 variants for comparison. Sketches live in `.planning/sketches/` and
17
- integrate with GSD commit patterns, state tracking, and handoff workflows.
21
+ integrate with GSD commit patterns, state tracking, and handoff workflows. Loads spike
22
+ findings to ground mockups in real data shapes and validated interaction patterns.
23
+
24
+ Two modes:
25
+ - **Idea mode** (default) — describe a design idea to sketch
26
+ - **Frontier mode** (no argument or "frontier") — analyzes existing sketch landscape and proposes consistency and frontier sketches
18
27
 
19
28
  Does not require `/gsd-new-project` — auto-creates `.planning/sketches/` if needed.
20
29
  </objective>
@@ -41,5 +50,5 @@ Design idea: $ARGUMENTS
41
50
 
42
51
  <process>
43
52
  Execute the sketch workflow from @~/.claude/get-shit-done/workflows/sketch.md end-to-end.
44
- Preserve all workflow gates (intake, decomposition, variant evaluation, MANIFEST updates, commit patterns).
53
+ Preserve all workflow gates (intake, decomposition, target stack research, variant evaluation, MANIFEST updates, commit patterns).
45
54
  </process>
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: gsd:spike
3
- description: Rapidly spike an idea with throwaway experiments to validate feasibility before planning
4
- argument-hint: "<idea to validate> [--quick]"
3
+ description: Spike an idea through experiential exploration, or propose what to spike next (frontier mode)
4
+ argument-hint: "[idea to validate] [--quick] [--text] or [frontier]"
5
5
  allowed-tools:
6
6
  - Read
7
7
  - Write
@@ -10,11 +10,20 @@ allowed-tools:
10
10
  - Grep
11
11
  - Glob
12
12
  - AskUserQuestion
13
+ - WebSearch
14
+ - WebFetch
15
+ - mcp__context7__resolve-library-id
16
+ - mcp__context7__query-docs
13
17
  ---
14
18
  <objective>
15
- Rapid feasibility validation through focused, throwaway experiments. Each spike answers one
16
- specific question with observable evidence. Spikes live in `.planning/spikes/` and integrate
17
- with GSD commit patterns, state tracking, and handoff workflows.
19
+ Spike an idea through experiential exploration — build focused experiments to feel the pieces
20
+ of a future app, validate feasibility, and produce verified knowledge for the real build.
21
+ Spikes live in `.planning/spikes/` and integrate with GSD commit patterns, state tracking,
22
+ and handoff workflows.
23
+
24
+ Two modes:
25
+ - **Idea mode** (default) — describe an idea to spike
26
+ - **Frontier mode** (no argument or "frontier") — analyzes existing spike landscape and proposes integration and frontier spikes
18
27
 
19
28
  Does not require `/gsd-new-project` — auto-creates `.planning/spikes/` if needed.
20
29
  </objective>
@@ -33,9 +42,10 @@ Idea: $ARGUMENTS
33
42
 
34
43
  **Available flags:**
35
44
  - `--quick` — Skip decomposition/alignment, jump straight to building. Use when you already know what to spike.
45
+ - `--text` — Use plain-text numbered lists instead of AskUserQuestion (for non-Claude runtimes).
36
46
  </context>
37
47
 
38
48
  <process>
39
49
  Execute the spike workflow from @~/.claude/get-shit-done/workflows/spike.md end-to-end.
40
- Preserve all workflow gates (decomposition, risk ordering, verification, MANIFEST updates, commit patterns).
50
+ Preserve all workflow gates (prior spike check, decomposition, research, risk ordering, observability assessment, verification, MANIFEST updates, commit patterns).
41
51
  </process>
@@ -50,7 +50,7 @@ If `PATH_NOT_FOUND` or `MANIFEST_NOT_FOUND`: display error and exit.
50
50
  Run the init query:
51
51
 
52
52
  ```bash
53
- INIT=$(gsd-sdk query init.ingest-docs 2>/dev/null || gsd-sdk query init.default)
53
+ INIT=$(gsd-sdk query init.ingest-docs)
54
54
  ```
55
55
 
56
56
  Parse `project_exists`, `planning_exists`, `has_git`, `project_path` from INIT.
@@ -255,15 +255,16 @@ The sketch-findings skill will auto-load when building the UI.
255
255
 
256
256
  ## ▶ Next Up
257
257
 
258
- **Start building** — implement the validated design
258
+ **Explore frontier sketches** — see what else is worth sketching based on what we've explored
259
259
 
260
- `/gsd-plan-phase`
260
+ `/gsd-sketch` (run with no argument — its frontier mode analyzes the sketch landscape and proposes consistency and frontier sketches)
261
261
 
262
262
  ───────────────────────────────────────────────────────────────
263
263
 
264
264
  **Also available:**
265
+ - `/gsd-plan-phase` — start building the real UI
265
266
  - `/gsd-ui-phase` — generate a UI design contract for a frontend phase
266
- - `/gsd-sketch` — sketch additional design areas
267
+ - `/gsd-sketch [idea]` — sketch a specific new design area
267
268
  - `/gsd-explore` — continue exploring
268
269
 
269
270
  ───────────────────────────────────────────────────────────────
@@ -279,5 +280,6 @@ The sketch-findings skill will auto-load when building the UI.
279
280
  - [ ] Reference files contain design decisions, CSS patterns, HTML structures, anti-patterns
280
281
  - [ ] `.planning/sketches/WRAP-UP-SUMMARY.md` written for project history
281
282
  - [ ] Project CLAUDE.md has auto-load routing line
282
- - [ ] Summary presented with next-step routing
283
+ - [ ] Summary presented
284
+ - [ ] Next-step options presented (including frontier sketch exploration via `/gsd-sketch`)
283
285
  </success_criteria>
@@ -2,6 +2,10 @@
2
2
  Explore design directions through throwaway HTML mockups before committing to implementation.
3
3
  Each sketch produces 2-3 variants for comparison. Saves artifacts to `.planning/sketches/`.
4
4
  Companion to `/gsd-sketch-wrap-up`.
5
+
6
+ Supports two modes:
7
+ - **Idea mode** (default) — user describes a design idea to sketch
8
+ - **Frontier mode** — no argument or "frontier" / "what should I sketch?" — analyzes existing sketch landscape and proposes consistency and frontier sketches
5
9
  </purpose>
6
10
 
7
11
  <required_reading>
@@ -25,9 +29,60 @@ Read all files referenced by the invoking prompt's execution_context before star
25
29
  Parse `$ARGUMENTS` for:
26
30
  - `--quick` flag → set `QUICK_MODE=true`
27
31
  - `--text` flag → set `TEXT_MODE=true`
32
+ - `frontier` or empty → set `FRONTIER_MODE=true`
28
33
  - Remaining text → the design idea to sketch
29
34
 
30
- **Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
35
+ **Text mode:** If TEXT_MODE is enabled, replace AskUserQuestion calls with plain-text numbered lists.
36
+ </step>
37
+
38
+ <step name="route">
39
+ ## Routing
40
+
41
+ - **FRONTIER_MODE is true** → Jump to `frontier_mode`
42
+ - **Otherwise** → Continue to `setup_directory`
43
+ </step>
44
+
45
+ <step name="frontier_mode">
46
+ ## Frontier Mode — Propose What to Sketch Next
47
+
48
+ ### Load the Sketch Landscape
49
+
50
+ If no `.planning/sketches/` directory exists, tell the user there's nothing to analyze and offer to start fresh with an idea instead.
51
+
52
+ Otherwise, load in this order:
53
+
54
+ **a. MANIFEST.md** — the design direction, reference points, and sketch table with winners.
55
+
56
+ **b. Findings skills** — glob `./.claude/skills/sketch-findings-*/SKILL.md` and read any that exist, plus their `references/*.md`. These contain curated design decisions from prior wrap-ups.
57
+
58
+ **c. All sketch READMEs** — read `.planning/sketches/*/README.md` for design questions, winners, and tags.
59
+
60
+ ### Analyze for Consistency Sketches
61
+
62
+ Review winning variants across all sketches. Look for:
63
+
64
+ - **Visual consistency gaps:** Two sketches made independent design choices that haven't been tested together.
65
+ - **State combinations:** Individual states validated but not seen in sequence.
66
+ - **Responsive gaps:** Validated at one viewport but the real app needs multiple.
67
+ - **Theme coherence:** Individual components look good but haven't been composed into a full-page view.
68
+
69
+ If consistency risks exist, present them as concrete proposed sketches with names and design questions. If no meaningful gaps, say so and skip.
70
+
71
+ ### Analyze for Frontier Sketches
72
+
73
+ Think laterally about the design direction from MANIFEST.md and what's been explored:
74
+
75
+ - **Unsketched screens:** UI surfaces assumed but unexplored.
76
+ - **Interaction patterns:** Static layouts validated but transitions, loading, drag-and-drop need feeling.
77
+ - **Edge case UI:** 0 items, 1000 items, errors, slow connections.
78
+ - **Alternative directions:** Fresh takes on "fine but not great" sketches.
79
+ - **Polish passes:** Typography, spacing, micro-interactions, empty states.
80
+
81
+ Present frontier sketches as concrete proposals numbered from the highest existing sketch number.
82
+
83
+ ### Get Alignment and Execute
84
+
85
+ Present all consistency and frontier candidates, then ask which to run. When the user picks sketches, update `.planning/sketches/MANIFEST.md` and proceed directly to building them starting at `build_sketches`.
31
86
  </step>
32
87
 
33
88
  <step name="setup_directory">
@@ -49,27 +104,45 @@ COMMIT_DOCS=$(gsd-sdk query config-get commit_docs 2>/dev/null || echo "true")
49
104
  </step>
50
105
 
51
106
  <step name="mood_intake">
52
- **If `QUICK_MODE` is true:** Skip mood intake. Use whatever the user provided in `$ARGUMENTS` as the design direction. Jump to `decompose`.
107
+ **If `QUICK_MODE` is true:** Skip mood intake. Use whatever the user provided in `$ARGUMENTS` as the design direction. Jump to `load_spike_context`.
53
108
 
54
109
  **Otherwise:**
55
110
 
56
- **Text mode:** If TEXT_MODE is enabled (set in the banner step), replace AskUserQuestion calls with plain-text numbered lists emit the options and ask the user to type the number of their choice.
57
-
58
- Before sketching anything, explore the design intent through conversation. Ask one question at a time — using AskUserQuestion in normal mode, or a plain-text numbered list if TEXT_MODE is active — with a paragraph of context and reasoning for each.
111
+ Before sketching anything, explore the design intent through conversation. Ask one question at a timeusing AskUserQuestion in normal mode, or a plain-text numbered list if TEXT_MODE is active.
59
112
 
60
113
  **Questions to cover (adapt to what the user has already shared):**
61
114
 
62
- 1. **Feel:** "What should this feel like? Give me adjectives, emotions, or a vibe." (e.g., "clean and clinical", "warm and playful", "dense and powerful")
63
- 2. **References:** "What apps, sites, or products have a similar feel to what you're imagining?" (gives concrete visual anchors)
64
- 3. **Core action:** "What's the single most important thing a user does here?" (focuses the sketch on what matters)
115
+ 1. **Feel:** "What should this feel like? Give me adjectives, emotions, or a vibe."
116
+ 2. **References:** "What apps, sites, or products have a similar feel to what you're imagining?"
117
+ 3. **Core action:** "What's the single most important thing a user does here?"
65
118
 
66
- You may need more or fewer questions depending on how much the user shares upfront. After each answer, briefly reflect what you heard and how it shapes your thinking.
119
+ After each answer, briefly reflect what you heard and how it shapes your thinking.
67
120
 
68
121
  When you have enough signal, ask: **"I think I have a good sense of the direction. Ready for me to sketch, or want to keep discussing?"**
69
122
 
70
123
  Only proceed when the user says go.
71
124
  </step>
72
125
 
126
+ <step name="load_spike_context">
127
+ ## Load Spike Context
128
+
129
+ If spikes exist for this project, read them to ground the sketches in reality. Mockups are still pure HTML, but they should reflect what's actually been proven — real data shapes, real component names, real interaction patterns.
130
+
131
+ **a.** Glob for `./.claude/skills/spike-findings-*/SKILL.md` and read any that exist, plus their `references/*.md`. These contain validated patterns and requirements.
132
+
133
+ **b.** Read `.planning/spikes/MANIFEST.md` if it exists — check the Requirements section for non-negotiable design constraints (e.g., "must support streaming", "must render markdown"). These requirements should be visible in the mockup even though the mockup doesn't implement them for real.
134
+
135
+ **c.** Read `.planning/spikes/CONVENTIONS.md` if it exists — the established stack informs what's buildable and what interaction patterns are idiomatic.
136
+
137
+ **How spike context improves sketches:**
138
+ - Use real field names and data shapes from spike findings instead of generic placeholders
139
+ - Show realistic UI states that match what the spikes proved (e.g., if streaming was validated, show a streaming message state)
140
+ - Reference real component names and patterns from the target stack
141
+ - Include interaction states that reflect what the spikes discovered (loading, error, reconnection states)
142
+
143
+ **If no spikes exist**, skip this step.
144
+ </step>
145
+
73
146
  <step name="decompose">
74
147
  Break the idea into 2-5 design questions. Present as a table:
75
148
 
@@ -92,6 +165,28 @@ Bad sketches:
92
165
  Present the table and get alignment before building.
93
166
  </step>
94
167
 
168
+ <step name="research_stack">
169
+ ## Research the Target Stack
170
+
171
+ Before sketching, ground the design in what's actually buildable. Sketches are HTML, but they should reflect real constraints of the target implementation.
172
+
173
+ **a. Identify the target stack.** Check for package.json, Cargo.toml, etc. If the user mentioned a framework (React, SwiftUI, Flutter, etc.), note it.
174
+
175
+ **b. Check component/pattern availability.** Use context7 (resolve-library-id → query-docs) or web search to answer:
176
+ - What layout primitives does the target framework provide?
177
+ - Are there existing component libraries in use? What components are available?
178
+ - What interaction patterns are idiomatic?
179
+
180
+ **c. Note constraints that affect design:**
181
+ - Platform conventions (iOS nav patterns, desktop menu bars, terminal grid constraints)
182
+ - Framework limitations (what's easy vs requires custom work)
183
+ - Existing design tokens or theme systems already in the project
184
+
185
+ **d. Let research inform variants.** At least one variant should follow the path of least resistance for the target stack.
186
+
187
+ **Skip when unnecessary.** Greenfield project with no stack, or user says "just explore visually." The point is grounding, not gatekeeping.
188
+ </step>
189
+
95
190
  <step name="create_manifest">
96
191
  Create or update `.planning/sketches/MANIFEST.md`:
97
192
 
@@ -124,26 +219,24 @@ Build each sketch in order.
124
219
 
125
220
  ### For Each Sketch:
126
221
 
127
- **a.** Find next available number by checking existing `.planning/sketches/NNN-*/` directories.
128
- Format: three-digit zero-padded + hyphenated descriptive name.
222
+ **a.** Find next available number. Format: three-digit zero-padded + hyphenated descriptive name.
129
223
 
130
224
  **b.** Create the sketch directory: `.planning/sketches/NNN-descriptive-name/`
131
225
 
132
226
  **c.** Build `index.html` with 2-3 variants:
133
227
 
134
- **First round — dramatic differences:** Build 2-3 meaningfully different approaches to the design question. Different layouts, different visual structures, different interaction models.
135
-
136
- **Subsequent rounds — refinements:** Once the user has picked a direction or cherry-picked elements, build subtler variations within that direction.
228
+ **First round — dramatic differences:** 2-3 meaningfully different approaches.
229
+ **Subsequent rounds — refinements:** Subtler variations within the chosen direction.
137
230
 
138
231
  Each variant is a page/tab in the same HTML file. Include:
139
232
  - Tab navigation to switch between variants (see `sketch-variant-patterns.md`)
140
233
  - Clear labels: "Variant A: Sidebar Layout", "Variant B: Top Nav", etc.
141
234
  - The sketch toolbar (see `sketch-tooling.md`)
142
235
  - All interactive elements functional (see `sketch-interactivity.md`)
143
- - Real-ish content, not lorem ipsum
236
+ - Real-ish content, not lorem ipsum (use real field names from spike context if available)
144
237
  - Link to `../themes/default.css` for shared theme variables
145
238
 
146
- **All sketches are plain HTML with inline CSS and JS.** No build step, no npm, no framework. Opens instantly in a browser.
239
+ **All sketches are plain HTML with inline CSS and JS.** No build step, no npm, no framework.
147
240
 
148
241
  **d.** Write `README.md`:
149
242
 
@@ -190,16 +283,16 @@ Compare: {what to look for between variants}
190
283
  ──────────────────────────────────────────────────────────────
191
284
 
192
285
  **f.** Handle feedback:
193
- - **Pick a direction:** "I like variant B" → mark winner in README, move to next sketch
194
- - **Cherry-pick elements:** "Rounded edges from A, color treatment from C" → build a synthesis as a new variant, show again
195
- - **Want more exploration:** "None of these feel right, try X instead" → build new variants
286
+ - **Pick a direction:** mark winner, move to next sketch
287
+ - **Cherry-pick elements:** build synthesis as new variant, show again
288
+ - **Want more exploration:** build new variants
196
289
 
197
- Iterate until the user is satisfied with a direction for this sketch.
290
+ Iterate until satisfied.
198
291
 
199
292
  **g.** Finalize:
200
- 1. Mark the winning variant in the README frontmatter (`winner: "B"`)
201
- 2. Add ★ indicator to the winning tab in the HTML
202
- 3. Update `.planning/sketches/MANIFEST.md` with the sketch row
293
+ 1. Mark winning variant in README frontmatter (`winner: "B"`)
294
+ 2. Add ★ indicator to winning tab in HTML
295
+ 3. Update `.planning/sketches/MANIFEST.md`
203
296
 
204
297
  **h.** Commit (if `COMMIT_DOCS` is true):
205
298
  ```bash
@@ -215,7 +308,7 @@ gsd-sdk query commit "docs(sketch-NNN): [winning direction] — [key visual insi
215
308
  </step>
216
309
 
217
310
  <step name="report">
218
- After all sketches complete, present the summary:
311
+ After all sketches complete:
219
312
 
220
313
  ```
221
314
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -243,8 +336,8 @@ After all sketches complete, present the summary:
243
336
  ───────────────────────────────────────────────────────────────
244
337
 
245
338
  **Also available:**
339
+ - `/gsd-sketch` — sketch more (or run with no argument for frontier mode)
246
340
  - `/gsd-plan-phase` — start building the real UI
247
- - `/gsd-explore` — continue exploring the concept
248
341
  - `/gsd-spike` — spike technical feasibility of a design pattern
249
342
 
250
343
  ───────────────────────────────────────────────────────────────
@@ -255,7 +348,9 @@ After all sketches complete, present the summary:
255
348
  <success_criteria>
256
349
  - [ ] `.planning/sketches/` created (auto-creates if needed, no project init required)
257
350
  - [ ] Design direction explored conversationally before any code (unless --quick)
258
- - [ ] Each sketch has 2-3 variants for comparison
351
+ - [ ] Spike context loaded real data shapes, requirements, and conventions inform mockups
352
+ - [ ] Target stack researched — component availability, constraints, idioms (unless greenfield/skipped)
353
+ - [ ] Each sketch has 2-3 variants for comparison (at least one follows path of least resistance)
259
354
  - [ ] User can open and interact with sketches in a browser
260
355
  - [ ] Winning variant selected and marked for each sketch
261
356
  - [ ] All variants preserved (winner marked, not others deleted)