@gitwhy-cli/whyspec 0.1.16 → 0.1.18
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/dist/adapters/claude-code.d.ts +5 -10
- package/dist/adapters/claude-code.d.ts.map +1 -1
- package/dist/adapters/claude-code.js +55 -115
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adapters/codex.d.ts.map +1 -1
- package/dist/adapters/codex.js +12 -9
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/types.d.ts +3 -1
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js +15 -13
- package/dist/adapters/types.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +42 -28
- package/dist/commands/init.js.map +1 -1
- package/package.json +1 -1
- package/skills/whyspec-capture/SKILL.md +110 -23
- package/skills/whyspec-debug/SKILL.md +193 -309
- package/skills/whyspec-execute/SKILL.md +123 -31
- package/skills/whyspec-plan/SKILL.md +213 -52
- package/skills/whyspec-search/SKILL.md +88 -20
- package/skills/whyspec-show/SKILL.md +76 -26
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import { GeneratedFile } from "./types.js";
|
|
1
|
+
import { GeneratedFile, WhySpecCommand } from "./types.js";
|
|
2
2
|
/**
|
|
3
|
-
* Generate
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - YAML frontmatter (name, description)
|
|
7
|
-
* - Placeholder instructions showing the CLI-as-oracle pattern
|
|
8
|
-
*
|
|
9
|
-
* @param projectRoot - Optional project root prefix for paths (default: "")
|
|
10
|
-
* @returns Array of GeneratedFile objects
|
|
3
|
+
* Generate compact instructions for each WhySpec command.
|
|
4
|
+
* Used by adapters that embed skill content (Codex, Claude commands).
|
|
5
|
+
* The canonical full-length skills live in skills/whyspec-{cmd}/SKILL.md.
|
|
11
6
|
*/
|
|
12
|
-
export declare function
|
|
7
|
+
export declare function getSkillInstructions(command: WhySpecCommand): string;
|
|
13
8
|
export declare function generateClaudeCodeCommands(projectRoot?: string): GeneratedFile[];
|
|
14
9
|
//# sourceMappingURL=claude-code.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAIb,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CA+IpE;AAED,wBAAgB,0BAA0B,CACxC,WAAW,GAAE,MAAW,GACvB,aAAa,EAAE,CAqBjB"}
|
|
@@ -1,47 +1,45 @@
|
|
|
1
1
|
import { WHYSPEC_COMMANDS, COMMAND_DESCRIPTIONS, COMMAND_ARGUMENT_HINTS, } from "./types.js";
|
|
2
2
|
/**
|
|
3
|
-
* Generate
|
|
4
|
-
*
|
|
5
|
-
* The
|
|
6
|
-
* even before Agent 5 enriches it.
|
|
3
|
+
* Generate compact instructions for each WhySpec command.
|
|
4
|
+
* Used by adapters that embed skill content (Codex, Claude commands).
|
|
5
|
+
* The canonical full-length skills live in skills/whyspec-{cmd}/SKILL.md.
|
|
7
6
|
*/
|
|
8
|
-
function getSkillInstructions(command) {
|
|
7
|
+
export function getSkillInstructions(command) {
|
|
9
8
|
switch (command) {
|
|
10
9
|
case "plan":
|
|
11
|
-
return
|
|
10
|
+
return `Plan a change — create intent.md, design.md, and tasks.md with the Decision Bridge.
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
When ready to implement, run \`/whyspec:execute\`
|
|
14
13
|
|
|
15
14
|
## Workflow
|
|
16
15
|
|
|
17
|
-
1.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- "How will you know it works?"
|
|
16
|
+
1. Parse what the user typed. If they gave a meaningful description, act immediately — do NOT
|
|
17
|
+
ask generic questions like "What problem does this solve?" or "What constraints exist?"
|
|
18
|
+
Only ask if ARGUMENTS is empty or genuinely ambiguous.
|
|
21
19
|
|
|
22
20
|
2. Call the CLI to create the change folder:
|
|
23
21
|
\`\`\`bash
|
|
24
22
|
whyspec plan --json "<change-name>"
|
|
25
23
|
\`\`\`
|
|
26
24
|
|
|
27
|
-
3.
|
|
25
|
+
3. Explore the codebase to understand the affected area before writing plan files.
|
|
28
26
|
|
|
29
27
|
4. Create three files in the change folder:
|
|
30
28
|
- **intent.md** — Why this change exists, decisions to make, constraints, success criteria
|
|
31
29
|
- **design.md** — Technical approach, trade-off matrix, architecture, questions to resolve
|
|
32
30
|
- **tasks.md** — Verification criteria (defined FIRST), then implementation checklist
|
|
33
31
|
|
|
34
|
-
5. The "Decisions to Make" section in
|
|
35
|
-
These will be resolved by /whyspec-capture after implementation.
|
|
32
|
+
5. The "Decisions to Make" section in intent.md is the BEFORE side of the Decision Bridge.
|
|
36
33
|
|
|
37
34
|
## Important
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
- Every
|
|
35
|
+
- Act first, ask only when stuck. The user told you what they want.
|
|
36
|
+
- Ground plans in the actual codebase — read relevant files before writing.
|
|
37
|
+
- Every unsettled design choice must be a checkbox in "Decisions to Make".
|
|
38
|
+
- Scale the plan to the change — a typo fix gets 3 lines, not a trade-off matrix.`;
|
|
41
39
|
case "execute":
|
|
42
|
-
return
|
|
40
|
+
return `Implement a change — read the plan, work through tasks, commit atomically.
|
|
43
41
|
|
|
44
|
-
|
|
42
|
+
When all tasks are done, run \`/whyspec:capture\`
|
|
45
43
|
|
|
46
44
|
## Workflow
|
|
47
45
|
|
|
@@ -50,103 +48,78 @@ Use this skill when the developer wants to implement a planned change.
|
|
|
50
48
|
whyspec execute --json "<change-name>"
|
|
51
49
|
\`\`\`
|
|
52
50
|
|
|
53
|
-
2.
|
|
51
|
+
2. Read intent.md and design.md BEFORE coding — understand the goal first.
|
|
54
52
|
|
|
55
|
-
3.
|
|
56
|
-
|
|
57
|
-
4. Work through tasks.md sequentially:
|
|
53
|
+
3. Work through tasks.md sequentially:
|
|
58
54
|
- Show progress: "Working on task 3/7: <description>"
|
|
59
55
|
- Implement the code changes
|
|
60
56
|
- Mark each task complete: \`- [ ]\` → \`- [x]\` in tasks.md
|
|
57
|
+
- Run the task's verify: check
|
|
61
58
|
- Commit atomically (one commit per task or logical unit)
|
|
62
59
|
|
|
63
|
-
|
|
60
|
+
4. If reality contradicts the design, STOP and flag it — don't silently override.
|
|
64
61
|
|
|
65
62
|
## Important
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
63
|
+
- Never skip the plan. Read intent.md before writing code.
|
|
64
|
+
- Commit atomically — one commit per task, not one giant commit.
|
|
65
|
+
- Pause on design contradictions — update the plan before continuing.`;
|
|
69
66
|
case "capture":
|
|
70
|
-
return
|
|
67
|
+
return `Capture reasoning — resolve the Decision Bridge and preserve the full story.
|
|
71
68
|
|
|
72
|
-
|
|
69
|
+
View the complete story with \`/whyspec:show\`
|
|
73
70
|
|
|
74
71
|
## Workflow
|
|
75
72
|
|
|
76
|
-
1. Call the CLI to get the capture template
|
|
73
|
+
1. Call the CLI to get the capture template:
|
|
77
74
|
\`\`\`bash
|
|
78
75
|
whyspec capture --json "<change-name>"
|
|
79
76
|
\`\`\`
|
|
80
77
|
|
|
81
|
-
2.
|
|
82
|
-
|
|
83
|
-
3. Read intent.md and design.md from the change folder.
|
|
84
|
-
|
|
85
|
-
4. Create a ctx_<id>.md file in the change folder using the GitWhy SaaS XML format:
|
|
86
|
-
- Map each "Decision to Make" from design.md → "Decisions Made" with rationale
|
|
87
|
-
- Map each "Question to Resolve" → resolved answer
|
|
88
|
-
- Capture "Surprises" — decisions NOT in the plan
|
|
89
|
-
- Include story, rejected alternatives, trade-offs, verification, risks
|
|
78
|
+
2. Read intent.md and design.md for the Decision Bridge mapping.
|
|
90
79
|
|
|
91
|
-
|
|
80
|
+
3. Create ctx_<id>.md in GitWhy SaaS XML format:
|
|
81
|
+
- Map each "Decision to Make" → "Decisions Made" with full rationale
|
|
82
|
+
- Map each "Question to Resolve" → answer with reasoning
|
|
83
|
+
- Capture "Surprises" — decisions NOT in the original plan
|
|
92
84
|
|
|
93
85
|
## Important
|
|
94
|
-
-
|
|
95
|
-
-
|
|
86
|
+
- Capture reasoning, not summaries. "We chose X because Y outweighs Z" not just "we used X."
|
|
87
|
+
- Every planned decision must be resolved. Prompt the user for any gaps.
|
|
96
88
|
- Surprises (unplanned decisions) are the most valuable part of the capture.`;
|
|
97
89
|
case "show":
|
|
98
|
-
return
|
|
99
|
-
|
|
100
|
-
Use this skill when the developer wants to view the full story of a change.
|
|
90
|
+
return `Show the full story — intent, design, tasks, reasoning — with the Decision Bridge delta.
|
|
101
91
|
|
|
102
92
|
## Workflow
|
|
103
93
|
|
|
104
|
-
1. Call the CLI
|
|
94
|
+
1. Call the CLI:
|
|
105
95
|
\`\`\`bash
|
|
106
96
|
whyspec show --json "<change-name>"
|
|
107
97
|
\`\`\`
|
|
108
98
|
|
|
109
|
-
2.
|
|
99
|
+
2. Display: Intent (WHY) → Design (HOW) → Tasks (WHAT) → Reasoning (AFTER)
|
|
110
100
|
|
|
111
|
-
3.
|
|
112
|
-
- **Intent** — WHY (from intent.md)
|
|
113
|
-
- **Design** — HOW (from design.md)
|
|
114
|
-
- **Tasks** — WHAT (from tasks.md with completion status)
|
|
115
|
-
- **Context** — REASONING (from ctx_<id>.md)
|
|
116
|
-
- **Decision Bridge Delta** — Decisions to Make vs Decisions Made, highlighting changes and surprises
|
|
101
|
+
3. Highlight the Decision Bridge Delta: planned vs actual decisions with rationale.
|
|
117
102
|
|
|
118
103
|
## Important
|
|
119
|
-
- The Decision Bridge delta is the
|
|
120
|
-
- If context hasn't been captured
|
|
104
|
+
- The Decision Bridge delta is the core value — always show it.
|
|
105
|
+
- If context hasn't been captured, suggest running /whyspec:capture.`;
|
|
121
106
|
case "search":
|
|
122
|
-
return
|
|
123
|
-
|
|
124
|
-
Use this skill when the developer wants to find past decisions and reasoning.
|
|
107
|
+
return `Search reasoning — find past decisions and contexts across all changes.
|
|
125
108
|
|
|
126
109
|
## Workflow
|
|
127
110
|
|
|
128
|
-
1. Call the CLI
|
|
111
|
+
1. Call the CLI:
|
|
129
112
|
\`\`\`bash
|
|
130
113
|
whyspec search --json "<query>"
|
|
131
114
|
\`\`\`
|
|
132
115
|
|
|
133
|
-
2.
|
|
134
|
-
|
|
135
|
-
3. Display results ranked by relevance:
|
|
136
|
-
- Title matches score highest (100 points)
|
|
137
|
-
- Reasoning/decision matches score next (30 points)
|
|
138
|
-
- File path matches score lower (20 points)
|
|
139
|
-
|
|
140
|
-
4. For each result, show: title, change name, score, and a relevant snippet.
|
|
116
|
+
2. Display results ranked by relevance with reasoning snippets — not just titles.
|
|
141
117
|
|
|
142
118
|
## Important
|
|
143
|
-
-
|
|
144
|
-
- Search
|
|
145
|
-
- Use this before starting new work: "Has anyone reasoned about this area before?"`;
|
|
119
|
+
- Always show reasoning snippets, not just titles.
|
|
120
|
+
- Search includes plan files (intent.md, design.md), not just captured contexts.`;
|
|
146
121
|
case "debug":
|
|
147
|
-
return
|
|
148
|
-
|
|
149
|
-
Use this skill when the developer is investigating a bug.
|
|
122
|
+
return `Debug with scientific method. No fix without root cause.
|
|
150
123
|
|
|
151
124
|
## Workflow
|
|
152
125
|
|
|
@@ -155,54 +128,21 @@ Use this skill when the developer is investigating a bug.
|
|
|
155
128
|
whyspec debug --json "<bug-description>"
|
|
156
129
|
\`\`\`
|
|
157
130
|
|
|
158
|
-
2.
|
|
131
|
+
2. Search past contexts first — check if this domain has been reasoned about before.
|
|
159
132
|
|
|
160
133
|
3. Follow the scientific method:
|
|
161
|
-
- **Symptoms** — Expected vs actual
|
|
162
|
-
- **
|
|
163
|
-
- **
|
|
164
|
-
- **
|
|
165
|
-
- **
|
|
166
|
-
- **Fix** — Apply the fix and verify
|
|
167
|
-
- **Prevention** — How to prevent this class of bug in the future
|
|
168
|
-
|
|
169
|
-
4. Create debug.md with the full investigation trail.
|
|
170
|
-
|
|
171
|
-
5. Auto-prompt: "Ready to capture debug reasoning? Run /whyspec-capture"
|
|
134
|
+
- **Symptoms** — Expected vs actual, error messages, reproduction steps
|
|
135
|
+
- **Hypotheses** — 3+ falsifiable claims with concrete tests
|
|
136
|
+
- **Investigation** — Test one at a time, record evidence
|
|
137
|
+
- **Root cause** — Prove diagnosis BEFORE proposing fix (Iron Law)
|
|
138
|
+
- **Fix + Capture** — Minimal fix, then auto-capture reasoning
|
|
172
139
|
|
|
173
140
|
## Important
|
|
174
|
-
- No fix without root cause —
|
|
175
|
-
-
|
|
176
|
-
-
|
|
141
|
+
- No fix without root cause — the Iron Law is non-negotiable.
|
|
142
|
+
- Write debug.md incrementally — it persists across context resets.
|
|
143
|
+
- Always capture the investigation as a context file when resolved.`;
|
|
177
144
|
}
|
|
178
145
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Generate Claude Code skill files for all 6 WhySpec commands.
|
|
181
|
-
*
|
|
182
|
-
* Creates .claude/skills/whyspec-<command>/SKILL.md with:
|
|
183
|
-
* - YAML frontmatter (name, description)
|
|
184
|
-
* - Placeholder instructions showing the CLI-as-oracle pattern
|
|
185
|
-
*
|
|
186
|
-
* @param projectRoot - Optional project root prefix for paths (default: "")
|
|
187
|
-
* @returns Array of GeneratedFile objects
|
|
188
|
-
*/
|
|
189
|
-
export function generateClaudeCodeSkills(projectRoot = "") {
|
|
190
|
-
const prefix = projectRoot ? `${projectRoot}/` : "";
|
|
191
|
-
return WHYSPEC_COMMANDS.map((command) => {
|
|
192
|
-
const frontmatter = [
|
|
193
|
-
"---",
|
|
194
|
-
`name: whyspec-${command}`,
|
|
195
|
-
`description: ${COMMAND_DESCRIPTIONS[command]}`,
|
|
196
|
-
"---",
|
|
197
|
-
].join("\n");
|
|
198
|
-
const instructions = getSkillInstructions(command);
|
|
199
|
-
const content = `${frontmatter}\n\n${instructions}\n`;
|
|
200
|
-
return {
|
|
201
|
-
path: `${prefix}.claude/skills/whyspec-${command}/SKILL.md`,
|
|
202
|
-
content,
|
|
203
|
-
};
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
146
|
export function generateClaudeCodeCommands(projectRoot = "") {
|
|
207
147
|
const prefix = projectRoot ? `${projectRoot}/` : "";
|
|
208
148
|
return WHYSPEC_COMMANDS.map((command) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,GAEvB,MAAM,YAAY,CAAC;AAEpB
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,GAEvB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAuB;IAC1D,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFA4BqE,CAAC;QAE/E,KAAK,SAAS;YACZ,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;sEAyByD,CAAC;QAEnE,KAAK,SAAS;YACZ,OAAO;;;;;;;;;;;;;;;;;;;;;6EAqBgE,CAAC;QAE1E,KAAK,MAAM;YACT,OAAO;;;;;;;;;;;;;;;qEAewD,CAAC;QAElE,KAAK,QAAQ;YACX,OAAO;;;;;;;;;;;;;iFAaoE,CAAC;QAE9E,KAAK,OAAO;YACV,OAAO;;;;;;;;;;;;;;;;;;;;;oEAqBuD,CAAC;IACnE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,cAAsB,EAAE;IAExB,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpD,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACtC,MAAM,WAAW,GAAG;YAClB,KAAK;YACL,gBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;YAC/C,kBAAkB,sBAAsB,CAAC,OAAO,CAAC,EAAE;YACnD,KAAK;SACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,YAAY,GAAG,oBAAoB,CAAC,OAAO,CAAC;aAC/C,UAAU,CAAC,WAAW,EAAE,WAAW,CAAC;aACpC,UAAU,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;QAChD,MAAM,cAAc,GAAG,qCAAqC,OAAO,KAAK,CAAC;QAEzE,OAAO;YACL,IAAI,EAAE,GAAG,MAAM,4BAA4B,OAAO,KAAK;YACvD,OAAO,EAAE,GAAG,WAAW,OAAO,cAAc,OAAO,YAAY,IAAI;SACpE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/adapters/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAId,MAAM,YAAY,CAAC;AAgCpB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,GAAE,MAAW,GACvB,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/adapters/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAId,MAAM,YAAY,CAAC;AAgCpB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,GAAE,MAAW,GACvB,aAAa,EAAE,CAyBjB"}
|
package/dist/adapters/codex.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WHYSPEC_COMMANDS, COMMAND_DESCRIPTIONS, } from "./types.js";
|
|
2
|
-
import {
|
|
2
|
+
import { getSkillInstructions } from "./claude-code.js";
|
|
3
3
|
function getDisplayName(command) {
|
|
4
4
|
return `WhySpec ${command[0].toUpperCase()}${command.slice(1)}`;
|
|
5
5
|
}
|
|
@@ -34,20 +34,23 @@ function renderOpenAiMetadata(command) {
|
|
|
34
34
|
*/
|
|
35
35
|
export function generateCodexSkills(projectRoot = "") {
|
|
36
36
|
const prefix = projectRoot ? `${projectRoot}/` : "";
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const skillFiles = WHYSPEC_COMMANDS.map((command) => {
|
|
38
|
+
const frontmatter = [
|
|
39
|
+
"---",
|
|
40
|
+
`name: whyspec-${command}`,
|
|
41
|
+
`description: ${COMMAND_DESCRIPTIONS[command]}`,
|
|
42
|
+
"---",
|
|
43
|
+
].join("\n");
|
|
44
|
+
const instructions = getSkillInstructions(command);
|
|
42
45
|
return {
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
path: `${prefix}whyspec-${command}/SKILL.md`,
|
|
47
|
+
content: `${frontmatter}\n\n${instructions}\n`,
|
|
45
48
|
};
|
|
46
49
|
});
|
|
47
50
|
const metadataFiles = WHYSPEC_COMMANDS.map((command) => ({
|
|
48
51
|
path: `${prefix}whyspec-${command}/agents/openai.yaml`,
|
|
49
52
|
content: renderOpenAiMetadata(command),
|
|
50
53
|
}));
|
|
51
|
-
return [...
|
|
54
|
+
return [...skillFiles, ...metadataFiles];
|
|
52
55
|
}
|
|
53
56
|
//# sourceMappingURL=codex.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/adapters/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,gBAAgB,EAChB,oBAAoB,GAErB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/adapters/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,gBAAgB,EAChB,oBAAoB,GAErB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,SAAS,cAAc,CAAC,OAAuB;IAC7C,OAAO,WAAW,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAClE,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAuB;IAC/C,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,gDAAgD,CAAC;QAC1D,KAAK,SAAS;YACZ,OAAO,oDAAoD,CAAC;QAC9D,KAAK,SAAS;YACZ,OAAO,iEAAiE,CAAC;QAC3E,KAAK,MAAM;YACT,OAAO,yEAAyE,CAAC;QACnF,KAAK,QAAQ;YACX,OAAO,oEAAoE,CAAC;QAC9E,KAAK,OAAO;YACV,OAAO,6DAA6D,CAAC;IACzE,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAuB;IACnD,OAAO;mBACU,cAAc,CAAC,OAAO,CAAC;wBAClB,oBAAoB,CAAC,OAAO,CAAC;qBAChC,gBAAgB,CAAC,OAAO,CAAC;CAC7C,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,cAAsB,EAAE;IAExB,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAClD,MAAM,WAAW,GAAG;YAClB,KAAK;YACL,iBAAiB,OAAO,EAAE;YAC1B,gBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;YAC/C,KAAK;SACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,YAAY,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAEnD,OAAO;YACL,IAAI,EAAE,GAAG,MAAM,WAAW,OAAO,WAAW;YAC5C,OAAO,EAAE,GAAG,WAAW,OAAO,YAAY,IAAI;SAC/C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,EAAE,GAAG,MAAM,WAAW,OAAO,qBAAqB;QACtD,OAAO,EAAE,oBAAoB,CAAC,OAAO,CAAC;KACvC,CAAC,CAAC,CAAC;IAEJ,OAAO,CAAC,GAAG,UAAU,EAAE,GAAG,aAAa,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/adapters/types.d.ts
CHANGED
|
@@ -11,7 +11,9 @@ export interface GeneratedFile {
|
|
|
11
11
|
/** The 6 WhySpec commands that adapters generate config for. */
|
|
12
12
|
export declare const WHYSPEC_COMMANDS: readonly ["plan", "execute", "capture", "show", "search", "debug"];
|
|
13
13
|
export type WhySpecCommand = (typeof WHYSPEC_COMMANDS)[number];
|
|
14
|
-
/** One-line descriptions for each command, used across all adapters.
|
|
14
|
+
/** One-line descriptions for each command, used across all adapters.
|
|
15
|
+
* IMPORTANT: These must be trigger conditions ("Use when..."), not workflow summaries.
|
|
16
|
+
* Summary descriptions cause Claude to shortcut the skill body. */
|
|
15
17
|
export declare const COMMAND_DESCRIPTIONS: Record<WhySpecCommand, string>;
|
|
16
18
|
/** Gray placeholder text shown beside slash commands in UIs that support it. */
|
|
17
19
|
export declare const COMMAND_ARGUMENT_HINTS: Record<WhySpecCommand, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,oEAOnB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,oEAOnB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D;;mEAEmE;AACnE,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAO/D,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAOjE,CAAC"}
|
package/dist/adapters/types.js
CHANGED
|
@@ -7,22 +7,24 @@ export const WHYSPEC_COMMANDS = [
|
|
|
7
7
|
"search",
|
|
8
8
|
"debug",
|
|
9
9
|
];
|
|
10
|
-
/** One-line descriptions for each command, used across all adapters.
|
|
10
|
+
/** One-line descriptions for each command, used across all adapters.
|
|
11
|
+
* IMPORTANT: These must be trigger conditions ("Use when..."), not workflow summaries.
|
|
12
|
+
* Summary descriptions cause Claude to shortcut the skill body. */
|
|
11
13
|
export const COMMAND_DESCRIPTIONS = {
|
|
12
|
-
plan: "
|
|
13
|
-
execute: "
|
|
14
|
-
capture: "
|
|
15
|
-
show: "
|
|
16
|
-
search: "
|
|
17
|
-
debug: "
|
|
14
|
+
plan: "Use when planning a code change, capturing decisions before coding, or setting up the Decision Bridge",
|
|
15
|
+
execute: "Use when starting implementation, continuing work, or executing tasks from a WhySpec plan",
|
|
16
|
+
capture: "Use after coding to preserve reasoning — resolves the Decision Bridge with actual outcomes",
|
|
17
|
+
show: "Use when reviewing the full story of a change — intent, design, tasks, and Decision Bridge delta",
|
|
18
|
+
search: "Use when looking for why something was built a certain way or finding past decisions",
|
|
19
|
+
debug: "Use when encountering any bug, test failure, or unexpected behavior — before proposing fixes",
|
|
18
20
|
};
|
|
19
21
|
/** Gray placeholder text shown beside slash commands in UIs that support it. */
|
|
20
22
|
export const COMMAND_ARGUMENT_HINTS = {
|
|
21
|
-
plan: "change
|
|
22
|
-
execute: "change
|
|
23
|
-
capture: "change
|
|
24
|
-
show: "change
|
|
25
|
-
search: "query",
|
|
26
|
-
debug: "
|
|
23
|
+
plan: "<change-name-or-description>",
|
|
24
|
+
execute: "[change-name]",
|
|
25
|
+
capture: "[change-name]",
|
|
26
|
+
show: "[change-name]",
|
|
27
|
+
search: "<query> [--domain <domain>]",
|
|
28
|
+
debug: "<bug-description-or-change-name>",
|
|
27
29
|
};
|
|
28
30
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAWA,gEAAgE;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,MAAM;IACN,SAAS;IACT,SAAS;IACT,MAAM;IACN,QAAQ;IACR,OAAO;CACC,CAAC;AAIX
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAWA,gEAAgE;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,MAAM;IACN,SAAS;IACT,SAAS;IACT,MAAM;IACN,QAAQ;IACR,OAAO;CACC,CAAC;AAIX;;mEAEmE;AACnE,MAAM,CAAC,MAAM,oBAAoB,GAAmC;IAClE,IAAI,EAAE,uGAAuG;IAC7G,OAAO,EAAE,2FAA2F;IACpG,OAAO,EAAE,4FAA4F;IACrG,IAAI,EAAE,kGAAkG;IACxG,MAAM,EAAE,sFAAsF;IAC9F,KAAK,EAAE,8FAA8F;CACtG,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,sBAAsB,GAAmC;IACpE,IAAI,EAAE,8BAA8B;IACpC,OAAO,EAAE,eAAe;IACxB,OAAO,EAAE,eAAe;IACxB,IAAI,EAAE,eAAe;IACrB,MAAM,EAAE,6BAA6B;IACrC,KAAK,EAAE,kCAAkC;CAC1C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAID,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQlD;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CA8D5E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAwBvE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAID,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQlD;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CA8D5E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAwBvE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA+BjD;AAsED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAoB1D;AA0FD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAoBrE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAIpE;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CActD;AAID,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAkJ7C"}
|
package/dist/commands/init.js
CHANGED
|
@@ -93,40 +93,34 @@ export function writeConfigYaml(root, opts) {
|
|
|
93
93
|
}
|
|
94
94
|
export function addToGitignore(root) {
|
|
95
95
|
const entry = ".gitwhy/";
|
|
96
|
-
const gitDir = path.join(root, ".git");
|
|
97
96
|
const gitignorePath = path.join(root, ".gitignore");
|
|
97
|
+
const gitDir = path.join(root, ".git");
|
|
98
98
|
const gitExcludePath = path.join(gitDir, "info", "exclude");
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
99
|
+
// Always use .gitignore (committed, visible to all agents).
|
|
100
|
+
// .git/info/exclude is local-only and some agents delete files
|
|
101
|
+
// listed there on startup, causing data loss.
|
|
102
|
+
if (fs.existsSync(gitignorePath)) {
|
|
103
|
+
const content = fs.readFileSync(gitignorePath, "utf-8");
|
|
104
|
+
const lines = content.split("\n");
|
|
105
|
+
if (!lines.some((line) => line.trim() === entry)) {
|
|
106
106
|
const separator = content.endsWith("\n") ? "" : "\n";
|
|
107
|
-
fs.writeFileSync(
|
|
108
|
-
return;
|
|
107
|
+
fs.writeFileSync(gitignorePath, content + separator + entry + "\n", "utf-8");
|
|
109
108
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
fs.writeFileSync(gitignorePath, entry + "\n", "utf-8");
|
|
112
|
+
}
|
|
113
|
+
// Migrate: remove from .git/info/exclude if it was previously added there.
|
|
114
|
+
// This prevents double-ignoring and completes the migration to .gitignore.
|
|
115
|
+
if (fs.existsSync(gitExcludePath)) {
|
|
116
|
+
const excludeContent = fs.readFileSync(gitExcludePath, "utf-8");
|
|
117
|
+
const excludeLines = excludeContent.split("\n");
|
|
118
|
+
if (excludeLines.some((line) => line.trim() === entry)) {
|
|
119
|
+
const filtered = excludeLines
|
|
120
|
+
.filter((line) => line.trim() !== entry);
|
|
121
|
+
fs.writeFileSync(gitExcludePath, filtered.join("\n"), "utf-8");
|
|
116
122
|
}
|
|
117
|
-
const content = fs.readFileSync(filePath, "utf-8");
|
|
118
|
-
const filtered = content
|
|
119
|
-
.split("\n")
|
|
120
|
-
.filter((line) => line.trim() !== entry && line.length > 0);
|
|
121
|
-
const nextContent = filtered.length > 0 ? `${filtered.join("\n")}\n` : "";
|
|
122
|
-
fs.writeFileSync(filePath, nextContent, "utf-8");
|
|
123
|
-
};
|
|
124
|
-
if (fs.existsSync(gitDir)) {
|
|
125
|
-
ensureIgnoreEntry(gitExcludePath);
|
|
126
|
-
removeIgnoreEntry(gitignorePath);
|
|
127
|
-
return;
|
|
128
123
|
}
|
|
129
|
-
ensureIgnoreEntry(gitignorePath);
|
|
130
124
|
}
|
|
131
125
|
const WHYSPEC_COMMANDS = ["plan", "execute", "capture", "show", "search", "debug"];
|
|
132
126
|
/** Write GeneratedFile[] to disk, creating directories as needed. */
|
|
@@ -246,6 +240,21 @@ function installClaudeCommandsFromSkills(root, skillsSourceDir) {
|
|
|
246
240
|
}
|
|
247
241
|
return installed;
|
|
248
242
|
}
|
|
243
|
+
function removeLegacyClaudeSkills(root) {
|
|
244
|
+
const skillsRoot = path.join(root, ".claude", "skills");
|
|
245
|
+
let removed = false;
|
|
246
|
+
for (const cmd of WHYSPEC_COMMANDS) {
|
|
247
|
+
const legacyPath = path.join(skillsRoot, `whyspec-${cmd}`);
|
|
248
|
+
if (fs.existsSync(legacyPath)) {
|
|
249
|
+
fs.rmSync(legacyPath, { recursive: true, force: true });
|
|
250
|
+
removed = true;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (removed && fs.existsSync(skillsRoot) && fs.readdirSync(skillsRoot).length === 0) {
|
|
254
|
+
fs.rmdirSync(skillsRoot);
|
|
255
|
+
}
|
|
256
|
+
return removed;
|
|
257
|
+
}
|
|
249
258
|
function getSkillsSourceDir() {
|
|
250
259
|
const currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
251
260
|
return path.join(path.dirname(path.dirname(currentDir)), "skills");
|
|
@@ -268,6 +277,7 @@ export function installSkillFiles(root, tools) {
|
|
|
268
277
|
const skillsDir = getSkillsSourceDir();
|
|
269
278
|
// Claude Code skills
|
|
270
279
|
if (tools.includes("claude-code")) {
|
|
280
|
+
removeLegacyClaudeSkills(root);
|
|
271
281
|
const commandsInstalled = installClaudeCommandsFromSkills(path.join(root, ".claude", "commands"), skillsDir);
|
|
272
282
|
if (!commandsInstalled) {
|
|
273
283
|
writeGeneratedFiles(root, generateClaudeCodeCommands());
|
|
@@ -335,6 +345,10 @@ export async function runInit() {
|
|
|
335
345
|
// Check if skills need to be installed (e.g. prior crash before skill step)
|
|
336
346
|
if (tools.includes("claude-code")) {
|
|
337
347
|
const commandCheck = path.join(root, ".claude", "commands", "whyspec:plan.md");
|
|
348
|
+
const removedLegacySkills = removeLegacyClaudeSkills(root);
|
|
349
|
+
if (removedLegacySkills) {
|
|
350
|
+
repaired = true;
|
|
351
|
+
}
|
|
338
352
|
if (!fs.existsSync(commandCheck)) {
|
|
339
353
|
console.log(chalk.yellow("\n Repairing missing Claude commands...\n"));
|
|
340
354
|
installSkillFiles(root, tools);
|