gsdd-cli 0.1.0 → 0.2.0
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 +8 -8
- package/agents/DISTILLATION.md +116 -3
- package/agents/README.md +9 -0
- package/agents/approach-explorer.md +361 -0
- package/agents/planner.md +20 -5
- package/bin/adapters/claude.mjs +41 -11
- package/bin/adapters/codex.mjs +20 -1
- package/bin/adapters/opencode.mjs +37 -11
- package/bin/lib/init.mjs +383 -379
- package/bin/lib/models.mjs +27 -10
- package/distilled/DESIGN.md +80 -7
- package/distilled/README.md +169 -169
- package/distilled/templates/agents.block.md +1 -1
- package/distilled/templates/approach.md +232 -0
- package/distilled/templates/delegates/approach-explorer.md +25 -0
- package/distilled/templates/delegates/plan-checker.md +7 -1
- package/distilled/workflows/plan.md +82 -12
- package/package.json +9 -1
package/bin/adapters/claude.mjs
CHANGED
|
@@ -7,6 +7,18 @@ const CLAUDE_MODEL_PROFILES = {
|
|
|
7
7
|
budget: 'haiku',
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
+
function renderClaudeApproachExplorer(delegateContent, modelAlias = 'opus') {
|
|
11
|
+
return `---
|
|
12
|
+
name: gsdd-approach-explorer
|
|
13
|
+
description: Explores implementation approaches for a phase and aligns with the user through structured questioning before planning begins.
|
|
14
|
+
model: ${modelAlias}
|
|
15
|
+
tools: Read, Grep, Glob, WebSearch, WebFetch, Write, AskUserQuestion
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
${delegateContent.trim()}
|
|
19
|
+
`;
|
|
20
|
+
}
|
|
21
|
+
|
|
10
22
|
function renderClaudePlanChecker(delegateContent, modelAlias = 'sonnet') {
|
|
11
23
|
return `---
|
|
12
24
|
name: gsdd-plan-checker
|
|
@@ -42,21 +54,28 @@ Native Claude adapter rule:
|
|
|
42
54
|
Execution flow:
|
|
43
55
|
1. Read \`.planning/SPEC.md\`, \`.planning/ROADMAP.md\`, \`.planning/config.json\`, relevant phase research, and any existing phase plan files.
|
|
44
56
|
2. Resolve the target phase from the command arguments. If no phase is provided, choose the first roadmap phase that is not complete.
|
|
45
|
-
3.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
57
|
+
3. **Approach exploration** (before planning):
|
|
58
|
+
a. Check \`.planning/config.json\` for \`workflow.discuss\`. If \`false\` or missing, skip to step 4 and report \`reduced_alignment\` in the summary.
|
|
59
|
+
b. Check if \`{phase_dir}/{padded_phase}-APPROACH.md\` exists. If it does, offer the user: "Use existing" / "Update it" / "View it". If "Use existing", load decisions and skip to step 4.
|
|
60
|
+
c. If no APPROACH.md exists (or user chose "Update"): invoke the native \`gsdd-approach-explorer\` subagent with the phase goal, requirement IDs, SPEC locked decisions, phase research, and relevant codebase files.
|
|
61
|
+
d. The explorer runs a GSD-style interactive conversation with the user (gray areas, research, deep-dive questions, assumptions) and writes APPROACH.md.
|
|
62
|
+
e. Load APPROACH.md decisions as locked constraints alongside SPEC.md decisions.
|
|
63
|
+
4. Produce the initial phase plan according to \`.agents/skills/gsdd-plan/SKILL.md\`. Pass APPROACH.md decisions (if any) as locked constraints to the planner.
|
|
64
|
+
5. If \`.planning/config.json\` has \`workflow.planCheck: false\`, stop after planner self-check and explicitly report reduced assurance.
|
|
65
|
+
6. If \`workflow.planCheck: true\`, invoke the native \`gsdd-plan-checker\` subagent with fresh context.
|
|
66
|
+
7. Pass only explicit inputs to the checker:
|
|
49
67
|
- target phase goal and requirement IDs
|
|
50
68
|
- relevant locked decisions / deferred items from \`.planning/SPEC.md\`
|
|
69
|
+
- approach decisions from \`.planning/phases/*-APPROACH.md\` (if exists)
|
|
51
70
|
- relevant phase research file(s)
|
|
52
71
|
- produced \`.planning/phases/*-PLAN.md\` file(s)
|
|
53
|
-
|
|
72
|
+
8. Require the checker to return a single JSON object with this shape:
|
|
54
73
|
{
|
|
55
74
|
"status": "passed",
|
|
56
75
|
"summary": "One sentence overall assessment",
|
|
57
76
|
"issues": [
|
|
58
77
|
{
|
|
59
|
-
"dimension": "requirement_coverage | task_completeness | dependency_correctness | key_link_completeness | scope_sanity | must_have_quality | context_compliance",
|
|
78
|
+
"dimension": "requirement_coverage | task_completeness | dependency_correctness | key_link_completeness | scope_sanity | must_have_quality | context_compliance | approach_alignment",
|
|
60
79
|
"severity": "blocker | warning",
|
|
61
80
|
"description": "What is wrong",
|
|
62
81
|
"plan": "01-PLAN",
|
|
@@ -66,12 +85,13 @@ Execution flow:
|
|
|
66
85
|
]
|
|
67
86
|
}
|
|
68
87
|
Status must be either "passed" or "issues_found".
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
88
|
+
9. If the checker returns \`passed\`, finish and summarize.
|
|
89
|
+
10. If the checker returns \`issues_found\`, revise the existing plan files only where needed, then run the checker again.
|
|
90
|
+
11. Maximum 3 checker cycles total. If blockers remain after cycle 3, stop and escalate to the user instead of pretending the plan is ready.
|
|
72
91
|
|
|
73
92
|
Return a concise orchestration summary:
|
|
74
93
|
- target phase
|
|
94
|
+
- whether approach exploration ran (and alignment level: full | reduced_alignment | skipped)
|
|
75
95
|
- whether native plan checking ran
|
|
76
96
|
- checker cycle count
|
|
77
97
|
- final result: passed | reduced_assurance | escalated
|
|
@@ -112,12 +132,18 @@ function createClaudeAdapter({ cwd, workflows, renderSkillContent, getDelegateCo
|
|
|
112
132
|
return existsSync(skillsDir) || existsSync(commandsDir) || existsSync(agentsDir);
|
|
113
133
|
},
|
|
114
134
|
generate() {
|
|
115
|
-
const
|
|
135
|
+
const checkerModelAlias = resolveRuntimeAgentModel({
|
|
116
136
|
cwd,
|
|
117
137
|
runtime: 'claude',
|
|
118
138
|
agentId: 'plan-checker',
|
|
119
139
|
profileMap: CLAUDE_MODEL_PROFILES,
|
|
120
140
|
});
|
|
141
|
+
const explorerModelAlias = resolveRuntimeAgentModel({
|
|
142
|
+
cwd,
|
|
143
|
+
runtime: 'claude',
|
|
144
|
+
agentId: 'approach-explorer',
|
|
145
|
+
profileMap: CLAUDE_MODEL_PROFILES,
|
|
146
|
+
});
|
|
121
147
|
for (const workflow of workflows) {
|
|
122
148
|
const dir = join(skillsDir, workflow.name);
|
|
123
149
|
mkdirSync(dir, { recursive: true });
|
|
@@ -133,7 +159,11 @@ function createClaudeAdapter({ cwd, workflows, renderSkillContent, getDelegateCo
|
|
|
133
159
|
mkdirSync(agentsDir, { recursive: true });
|
|
134
160
|
writeFileSync(
|
|
135
161
|
join(agentsDir, 'gsdd-plan-checker.md'),
|
|
136
|
-
renderClaudePlanChecker(getDelegateContent('plan-checker.md'),
|
|
162
|
+
renderClaudePlanChecker(getDelegateContent('plan-checker.md'), checkerModelAlias)
|
|
163
|
+
);
|
|
164
|
+
writeFileSync(
|
|
165
|
+
join(agentsDir, 'gsdd-approach-explorer.md'),
|
|
166
|
+
renderClaudeApproachExplorer(getDelegateContent('approach-explorer.md'), explorerModelAlias)
|
|
137
167
|
);
|
|
138
168
|
},
|
|
139
169
|
summary(action) {
|
package/bin/adapters/codex.mjs
CHANGED
|
@@ -5,6 +5,19 @@ function safeTomlString(value) {
|
|
|
5
5
|
return value.replace(/[\\"]/g, '\\$&').replace(/\n/g, '\\n');
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
function renderCodexApproachExplorer(delegateContent, modelId = null) {
|
|
9
|
+
const safe = delegateContent.trim().replaceAll('"""', '"" "');
|
|
10
|
+
const modelLine = modelId ? `model = "${safeTomlString(modelId)}"\n` : '';
|
|
11
|
+
return `name = "gsdd-approach-explorer"
|
|
12
|
+
description = "Explores implementation approaches for a phase and aligns with the user through structured questioning before planning begins."
|
|
13
|
+
model_reasoning_effort = "high"
|
|
14
|
+
${modelLine}
|
|
15
|
+
developer_instructions = """
|
|
16
|
+
${safe}
|
|
17
|
+
"""
|
|
18
|
+
`;
|
|
19
|
+
}
|
|
20
|
+
|
|
8
21
|
function renderCodexPlanChecker(delegateContent, modelId = null) {
|
|
9
22
|
const safe = delegateContent.trim().replaceAll('"""', '"" "');
|
|
10
23
|
const modelLine = modelId ? `model = "${safeTomlString(modelId)}"\n` : '';
|
|
@@ -40,6 +53,7 @@ function createCodexAdapter({
|
|
|
40
53
|
generate() {
|
|
41
54
|
const config = loadProjectModelConfig(cwd);
|
|
42
55
|
const checkerModelId = getRuntimeModelOverride(config, 'codex', 'plan-checker');
|
|
56
|
+
const explorerModelId = getRuntimeModelOverride(config, 'codex', 'approach-explorer');
|
|
43
57
|
|
|
44
58
|
mkdirSync(agentsDir, { recursive: true });
|
|
45
59
|
|
|
@@ -48,9 +62,14 @@ function createCodexAdapter({
|
|
|
48
62
|
join(agentsDir, 'gsdd-plan-checker.toml'),
|
|
49
63
|
renderCodexPlanChecker(getDelegateContent('plan-checker.md'), checkerModelId)
|
|
50
64
|
);
|
|
65
|
+
// Approach explorer agent (interactive, spawned by the portable skill's approach exploration step)
|
|
66
|
+
writeFileSync(
|
|
67
|
+
join(agentsDir, 'gsdd-approach-explorer.toml'),
|
|
68
|
+
renderCodexApproachExplorer(getDelegateContent('approach-explorer.md'), explorerModelId)
|
|
69
|
+
);
|
|
51
70
|
},
|
|
52
71
|
summary(action) {
|
|
53
|
-
return `${action} Codex CLI native
|
|
72
|
+
return `${action} Codex CLI native agents (.codex/agents/gsdd-plan-checker.toml, .codex/agents/gsdd-approach-explorer.toml)`;
|
|
54
73
|
},
|
|
55
74
|
};
|
|
56
75
|
}
|
|
@@ -111,6 +111,19 @@ function detectOpenCodeConfiguredModel(cwd) {
|
|
|
111
111
|
return configuredModel;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
function renderOpenCodeApproachExplorer(delegateContent, modelId = null) {
|
|
115
|
+
const modelLine = modelId ? `model: ${modelId}\n` : '';
|
|
116
|
+
return `---
|
|
117
|
+
description: Explores implementation approaches for a phase and aligns with the user through structured questioning before planning begins.
|
|
118
|
+
mode: agent
|
|
119
|
+
${modelLine}tools:
|
|
120
|
+
bash: false
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
${delegateContent.trim()}
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
|
|
114
127
|
function renderOpenCodePlanChecker(delegateContent, modelId = null) {
|
|
115
128
|
const modelLine = modelId ? `model: ${modelId}\n` : '';
|
|
116
129
|
return `---
|
|
@@ -149,21 +162,28 @@ Native OpenCode adapter rule:
|
|
|
149
162
|
Execution flow:
|
|
150
163
|
1. Read \`.planning/SPEC.md\`, \`.planning/ROADMAP.md\`, \`.planning/config.json\`, relevant phase research, and any existing phase plan files.
|
|
151
164
|
2. Resolve the target phase from the command arguments. If no phase is provided, choose the first roadmap phase that is not complete.
|
|
152
|
-
3.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
165
|
+
3. **Approach exploration** (before planning):
|
|
166
|
+
a. Check \`.planning/config.json\` for \`workflow.discuss\`. If \`false\` or missing, skip to step 4 and report \`reduced_alignment\` in the summary.
|
|
167
|
+
b. Check if \`{phase_dir}/{padded_phase}-APPROACH.md\` exists. If it does, offer the user: "Use existing" / "Update it" / "View it". If "Use existing", load decisions and skip to step 4.
|
|
168
|
+
c. If no APPROACH.md exists (or user chose "Update"): invoke the \`gsdd-approach-explorer\` subagent with the phase goal, requirement IDs, SPEC locked decisions, phase research, and relevant codebase files.
|
|
169
|
+
d. The explorer runs a GSD-style interactive conversation with the user (gray areas, research, deep-dive questions, assumptions) and writes APPROACH.md.
|
|
170
|
+
e. Load APPROACH.md decisions as locked constraints alongside SPEC.md decisions.
|
|
171
|
+
4. Produce the initial phase plan according to \`.agents/skills/gsdd-plan/SKILL.md\`. Pass APPROACH.md decisions (if any) as locked constraints to the planner.
|
|
172
|
+
5. If \`.planning/config.json\` has \`workflow.planCheck: false\`, stop after planner self-check and explicitly report reduced assurance.
|
|
173
|
+
6. If \`workflow.planCheck: true\`, invoke the hidden \`gsdd-plan-checker\` subagent with fresh context.
|
|
174
|
+
7. Pass only explicit inputs to the checker:
|
|
156
175
|
- target phase goal and requirement IDs
|
|
157
176
|
- relevant locked decisions / deferred items from \`.planning/SPEC.md\`
|
|
177
|
+
- approach decisions from \`.planning/phases/*-APPROACH.md\` (if exists)
|
|
158
178
|
- relevant phase research file(s)
|
|
159
179
|
- produced \`.planning/phases/*-PLAN.md\` file(s)
|
|
160
|
-
|
|
180
|
+
8. Require the checker to return a single JSON object with this shape:
|
|
161
181
|
{
|
|
162
182
|
"status": "passed",
|
|
163
183
|
"summary": "One sentence overall assessment",
|
|
164
184
|
"issues": [
|
|
165
185
|
{
|
|
166
|
-
"dimension": "requirement_coverage | task_completeness | dependency_correctness | key_link_completeness | scope_sanity | must_have_quality | context_compliance",
|
|
186
|
+
"dimension": "requirement_coverage | task_completeness | dependency_correctness | key_link_completeness | scope_sanity | must_have_quality | context_compliance | approach_alignment",
|
|
167
187
|
"severity": "blocker | warning",
|
|
168
188
|
"description": "What is wrong",
|
|
169
189
|
"plan": "01-PLAN",
|
|
@@ -173,12 +193,13 @@ Execution flow:
|
|
|
173
193
|
]
|
|
174
194
|
}
|
|
175
195
|
Status must be either "passed" or "issues_found".
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
196
|
+
9. If the checker returns \`passed\`, finish and summarize.
|
|
197
|
+
10. If the checker returns \`issues_found\`, revise the existing plan files only where needed, then run the checker again.
|
|
198
|
+
11. Maximum 3 checker cycles total. If blockers remain after cycle 3, stop and escalate to the user instead of pretending the plan is ready.
|
|
179
199
|
|
|
180
200
|
Return a concise orchestration summary:
|
|
181
201
|
- target phase
|
|
202
|
+
- whether approach exploration ran (and alignment level: full | reduced_alignment | skipped)
|
|
182
203
|
- whether native plan checking ran
|
|
183
204
|
- checker cycle count
|
|
184
205
|
- final result: passed | reduced_assurance | escalated
|
|
@@ -210,7 +231,8 @@ function createOpenCodeAdapter({
|
|
|
210
231
|
},
|
|
211
232
|
generate() {
|
|
212
233
|
const config = loadProjectModelConfig(cwd);
|
|
213
|
-
const
|
|
234
|
+
const checkerModelId = getRuntimeModelOverride(config, 'opencode', 'plan-checker');
|
|
235
|
+
const explorerModelId = getRuntimeModelOverride(config, 'opencode', 'approach-explorer');
|
|
214
236
|
mkdirSync(commandsDir, { recursive: true });
|
|
215
237
|
for (const workflow of workflows) {
|
|
216
238
|
const content = workflow.name === 'gsdd-plan'
|
|
@@ -225,7 +247,11 @@ function createOpenCodeAdapter({
|
|
|
225
247
|
mkdirSync(agentsDir, { recursive: true });
|
|
226
248
|
writeFileSync(
|
|
227
249
|
join(agentsDir, 'gsdd-plan-checker.md'),
|
|
228
|
-
renderOpenCodePlanChecker(getDelegateContent('plan-checker.md'),
|
|
250
|
+
renderOpenCodePlanChecker(getDelegateContent('plan-checker.md'), checkerModelId)
|
|
251
|
+
);
|
|
252
|
+
writeFileSync(
|
|
253
|
+
join(agentsDir, 'gsdd-approach-explorer.md'),
|
|
254
|
+
renderOpenCodeApproachExplorer(getDelegateContent('approach-explorer.md'), explorerModelId)
|
|
229
255
|
);
|
|
230
256
|
},
|
|
231
257
|
summary(action) {
|