@undeemed/get-shit-done-codex 1.23.2 → 1.24.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 +51 -5
- package/agents/gsd-debugger.md +8 -56
- package/agents/gsd-planner.md +2 -118
- package/agents/gsd-project-researcher.md +0 -3
- package/agents/gsd-research-synthesizer.md +0 -3
- package/bin/install.js +267 -5
- package/commands/gsd/add-phase.md +2 -6
- package/commands/gsd/add-todo.md +1 -6
- package/commands/gsd/check-todos.md +2 -6
- package/commands/gsd/debug.md +1 -6
- package/commands/gsd/discuss-phase.md +16 -9
- package/commands/gsd/execute-phase.md +2 -1
- package/commands/gsd/new-milestone.md +8 -1
- package/commands/gsd/pause-work.md +1 -4
- package/commands/gsd/plan-phase.md +1 -2
- package/commands/gsd/research-phase.md +15 -17
- package/commands/gsd/verify-work.md +2 -1
- package/get-shit-done/bin/gsd-tools.cjs +4951 -121
- package/get-shit-done/bin/lib/commands.cjs +4 -9
- package/get-shit-done/bin/lib/core.cjs +102 -23
- package/get-shit-done/bin/lib/init.cjs +11 -11
- package/get-shit-done/bin/lib/milestone.cjs +54 -3
- package/get-shit-done/bin/lib/phase.cjs +40 -10
- package/get-shit-done/bin/lib/state.cjs +86 -33
- package/get-shit-done/references/checkpoints.md +0 -1
- package/get-shit-done/references/model-profile-resolution.md +13 -6
- package/get-shit-done/references/model-profiles.md +60 -51
- package/get-shit-done/templates/context.md +14 -0
- package/get-shit-done/templates/phase-prompt.md +0 -2
- package/get-shit-done/workflows/audit-milestone.md +8 -63
- package/get-shit-done/workflows/diagnose-issues.md +1 -1
- package/get-shit-done/workflows/execute-phase.md +9 -54
- package/get-shit-done/workflows/execute-plan.md +13 -17
- package/get-shit-done/workflows/help.md +3 -3
- package/get-shit-done/workflows/map-codebase.md +44 -32
- package/get-shit-done/workflows/new-milestone.md +7 -16
- package/get-shit-done/workflows/new-project.md +80 -49
- package/get-shit-done/workflows/progress.md +26 -14
- package/get-shit-done/workflows/quick.md +15 -24
- package/get-shit-done/workflows/set-profile.md +12 -8
- package/get-shit-done/workflows/settings.md +14 -21
- package/get-shit-done/workflows/transition.md +0 -5
- package/get-shit-done/workflows/verify-work.md +12 -11
- package/hooks/dist/gsd-context-monitor.js +1 -1
- package/package.json +3 -2
- package/scripts/run-tests.cjs +43 -0
package/bin/install.js
CHANGED
|
@@ -19,6 +19,23 @@ const UPSTREAM_PACKAGE = 'get-shit-done-cc';
|
|
|
19
19
|
const UPSTREAM_REPO = 'https://github.com/glittercowboy/get-shit-done';
|
|
20
20
|
const FORK_REPO = 'https://github.com/undeemed/get-shit-done-codex';
|
|
21
21
|
|
|
22
|
+
// ─── Codex Config Constants ───────────────────────────────────────────────────
|
|
23
|
+
const GSD_CODEX_MARKER = '# GSD Agent Configuration \u2014 managed by get-shit-done installer';
|
|
24
|
+
|
|
25
|
+
const CODEX_AGENT_SANDBOX = {
|
|
26
|
+
'gsd-executor': 'workspace-write',
|
|
27
|
+
'gsd-planner': 'workspace-write',
|
|
28
|
+
'gsd-phase-researcher': 'workspace-write',
|
|
29
|
+
'gsd-project-researcher': 'workspace-write',
|
|
30
|
+
'gsd-research-synthesizer': 'workspace-write',
|
|
31
|
+
'gsd-verifier': 'workspace-write',
|
|
32
|
+
'gsd-codebase-mapper': 'workspace-write',
|
|
33
|
+
'gsd-roadmapper': 'workspace-write',
|
|
34
|
+
'gsd-debugger': 'workspace-write',
|
|
35
|
+
'gsd-plan-checker': 'read-only',
|
|
36
|
+
'gsd-integration-checker': 'read-only',
|
|
37
|
+
};
|
|
38
|
+
|
|
22
39
|
const banner = `
|
|
23
40
|
${green} ██████╗ ███████╗██████╗
|
|
24
41
|
██╔════╝ ██╔════╝██╔══██╗
|
|
@@ -169,12 +186,45 @@ function toSingleLine(value) {
|
|
|
169
186
|
}
|
|
170
187
|
|
|
171
188
|
function getCodexSkillAdapterHeader(skillName) {
|
|
189
|
+
const invocation = `$${skillName}`;
|
|
172
190
|
return `<codex_skill_adapter>
|
|
173
|
-
|
|
174
|
-
-
|
|
175
|
-
-
|
|
176
|
-
-
|
|
177
|
-
|
|
191
|
+
## A. Skill Invocation
|
|
192
|
+
- This skill is invoked by mentioning \`${invocation}\`.
|
|
193
|
+
- Treat all user text after \`${invocation}\` as \`{{GSD_ARGS}}\`.
|
|
194
|
+
- If no arguments are present, treat \`{{GSD_ARGS}}\` as empty.
|
|
195
|
+
|
|
196
|
+
## B. AskUserQuestion → request_user_input Mapping
|
|
197
|
+
GSD workflows use \`AskUserQuestion\` (GSD workflow syntax). Translate to Codex \`request_user_input\`:
|
|
198
|
+
|
|
199
|
+
Parameter mapping:
|
|
200
|
+
- \`header\` → \`header\`
|
|
201
|
+
- \`question\` → \`question\`
|
|
202
|
+
- Options formatted as \`"Label" — description\` → \`{label: "Label", description: "description"}\`
|
|
203
|
+
- Generate \`id\` from header: lowercase, replace spaces with underscores
|
|
204
|
+
|
|
205
|
+
Batched calls:
|
|
206
|
+
- \`AskUserQuestion([q1, q2])\` → single \`request_user_input\` with multiple entries in \`questions[]\`
|
|
207
|
+
|
|
208
|
+
Multi-select workaround:
|
|
209
|
+
- Codex has no \`multiSelect\`. Use sequential single-selects, or present a numbered freeform list asking the user to enter comma-separated numbers.
|
|
210
|
+
|
|
211
|
+
Execute mode fallback:
|
|
212
|
+
- When \`request_user_input\` is rejected (Execute mode), present a plain-text numbered list and pick a reasonable default.
|
|
213
|
+
|
|
214
|
+
## C. Task() → spawn_agent Mapping
|
|
215
|
+
GSD workflows use \`Task(...)\` (GSD workflow syntax). Translate to Codex collaboration tools:
|
|
216
|
+
|
|
217
|
+
Direct mapping:
|
|
218
|
+
- \`Task(subagent_type="X", prompt="Y")\` → \`spawn_agent(agent_type="X", message="Y")\`
|
|
219
|
+
- \`Task(model="...")\` → omit (Codex uses per-role config, not inline model selection)
|
|
220
|
+
- \`fork_context: false\` by default — GSD agents load their own context via \`<files_to_read>\` blocks
|
|
221
|
+
|
|
222
|
+
Parallel fan-out:
|
|
223
|
+
- Spawn multiple agents → collect agent IDs → \`wait(ids)\` for all to complete
|
|
224
|
+
|
|
225
|
+
Result parsing:
|
|
226
|
+
- Look for structured markers in agent output: \`CHECKPOINT\`, \`PLAN COMPLETE\`, \`SUMMARY\`, etc.
|
|
227
|
+
- \`close_agent(id)\` after collecting results from each agent
|
|
178
228
|
</codex_skill_adapter>`;
|
|
179
229
|
}
|
|
180
230
|
|
|
@@ -638,6 +688,216 @@ if (locationFlagCount > 1) {
|
|
|
638
688
|
process.exit(1);
|
|
639
689
|
}
|
|
640
690
|
|
|
691
|
+
// ─── Upstream Codex Config Functions ──────────────────────────────────────────
|
|
692
|
+
// These are ported from upstream's install.js for multi-agent config.toml
|
|
693
|
+
// generation, merge, strip, and per-agent .toml config files.
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Convert an agent markdown file to Codex agent format.
|
|
697
|
+
* Applies base markdown conversions, then adds a <codex_agent_role> header
|
|
698
|
+
* and cleans up frontmatter (removes tools/color fields).
|
|
699
|
+
*/
|
|
700
|
+
function convertAgentToCodexFormat(content) {
|
|
701
|
+
let converted = convertPromptRefsToSkillRefs(content);
|
|
702
|
+
converted = convertCommandRefsToSkillMentions(converted);
|
|
703
|
+
converted = converted.replace(/\$ARGUMENTS\b/g, '{{GSD_ARGS}}');
|
|
704
|
+
|
|
705
|
+
const { frontmatter, body } = extractFrontmatterAndBody(converted);
|
|
706
|
+
if (!frontmatter) return converted;
|
|
707
|
+
|
|
708
|
+
const name = extractFrontmatterField(frontmatter, 'name') || 'unknown';
|
|
709
|
+
const description = extractFrontmatterField(frontmatter, 'description') || '';
|
|
710
|
+
const tools = extractFrontmatterField(frontmatter, 'tools') || '';
|
|
711
|
+
|
|
712
|
+
const roleHeader = `<codex_agent_role>
|
|
713
|
+
role: ${name}
|
|
714
|
+
tools: ${tools}
|
|
715
|
+
purpose: ${toSingleLine(description)}
|
|
716
|
+
</codex_agent_role>`;
|
|
717
|
+
|
|
718
|
+
const cleanFrontmatter = `---\nname: ${yamlQuote(name)}\ndescription: ${yamlQuote(toSingleLine(description))}\n---`;
|
|
719
|
+
|
|
720
|
+
return `${cleanFrontmatter}\n\n${roleHeader}\n${body}`;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
function convertCommandToCodexSkill(content, skillName) {
|
|
724
|
+
let converted = convertPromptRefsToSkillRefs(content);
|
|
725
|
+
converted = convertCommandRefsToSkillMentions(converted);
|
|
726
|
+
converted = converted.replace(/\$ARGUMENTS\b/g, '{{GSD_ARGS}}');
|
|
727
|
+
const { frontmatter, body } = extractFrontmatterAndBody(converted);
|
|
728
|
+
let description = `Run GSD workflow ${skillName}.`;
|
|
729
|
+
if (frontmatter) {
|
|
730
|
+
const maybeDescription = extractFrontmatterField(frontmatter, 'description');
|
|
731
|
+
if (maybeDescription) {
|
|
732
|
+
description = maybeDescription;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
description = toSingleLine(description);
|
|
736
|
+
const shortDescription = description.length > 180 ? `${description.slice(0, 177)}...` : description;
|
|
737
|
+
const adapter = getCodexSkillAdapterHeader(skillName);
|
|
738
|
+
|
|
739
|
+
return `---\nname: ${yamlQuote(skillName)}\ndescription: ${yamlQuote(description)}\nmetadata:\n short-description: ${yamlQuote(shortDescription)}\n---\n\n${adapter}\n\n${body.trimStart()}`;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Generate a per-agent .toml config file for Codex.
|
|
744
|
+
* Sets sandbox_mode and developer_instructions from the agent markdown body.
|
|
745
|
+
*/
|
|
746
|
+
function generateCodexAgentToml(agentName, agentContent) {
|
|
747
|
+
const sandboxMode = CODEX_AGENT_SANDBOX[agentName] || 'read-only';
|
|
748
|
+
const { body } = extractFrontmatterAndBody(agentContent);
|
|
749
|
+
const instructions = body.trim();
|
|
750
|
+
|
|
751
|
+
const lines = [
|
|
752
|
+
`sandbox_mode = "${sandboxMode}"`,
|
|
753
|
+
`developer_instructions = """`,
|
|
754
|
+
instructions,
|
|
755
|
+
`"""`,
|
|
756
|
+
];
|
|
757
|
+
return lines.join('\n') + '\n';
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Generate the GSD config block for Codex config.toml.
|
|
762
|
+
* @param {Array<{name: string, description: string}>} agents
|
|
763
|
+
*/
|
|
764
|
+
function generateCodexConfigBlock(agents) {
|
|
765
|
+
const lines = [
|
|
766
|
+
GSD_CODEX_MARKER,
|
|
767
|
+
'[features]',
|
|
768
|
+
'multi_agent = true',
|
|
769
|
+
'default_mode_request_user_input = true',
|
|
770
|
+
'',
|
|
771
|
+
'[agents]',
|
|
772
|
+
'max_threads = 4',
|
|
773
|
+
'max_depth = 2',
|
|
774
|
+
'',
|
|
775
|
+
];
|
|
776
|
+
|
|
777
|
+
for (const { name, description } of agents) {
|
|
778
|
+
lines.push(`[agents.${name}]`);
|
|
779
|
+
lines.push(`description = ${JSON.stringify(description)}`);
|
|
780
|
+
lines.push(`config_file = "agents/${name}.toml"`);
|
|
781
|
+
lines.push('');
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
return lines.join('\n');
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Strip GSD sections from Codex config.toml content.
|
|
789
|
+
* Returns cleaned content, or null if file would be empty.
|
|
790
|
+
*/
|
|
791
|
+
function stripGsdFromCodexConfig(content) {
|
|
792
|
+
const markerIndex = content.indexOf(GSD_CODEX_MARKER);
|
|
793
|
+
|
|
794
|
+
if (markerIndex !== -1) {
|
|
795
|
+
let before = content.substring(0, markerIndex).trimEnd();
|
|
796
|
+
before = before.replace(/^multi_agent\s*=\s*true\s*\n?/m, '');
|
|
797
|
+
before = before.replace(/^default_mode_request_user_input\s*=\s*true\s*\n?/m, '');
|
|
798
|
+
before = before.replace(/^\[features\]\s*\n(?=\[|$)/m, '');
|
|
799
|
+
before = before.replace(/\n{3,}/g, '\n\n').trim();
|
|
800
|
+
if (!before) return null;
|
|
801
|
+
return before + '\n';
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
let cleaned = content;
|
|
805
|
+
cleaned = cleaned.replace(/^multi_agent\s*=\s*true\s*\n?/m, '');
|
|
806
|
+
cleaned = cleaned.replace(/^default_mode_request_user_input\s*=\s*true\s*\n?/m, '');
|
|
807
|
+
cleaned = cleaned.replace(/^\[agents\.gsd-[^\]]+\]\n(?:(?!\[)[^\n]*\n?)*/gm, '');
|
|
808
|
+
cleaned = cleaned.replace(/^\[features\]\s*\n(?=\[|$)/m, '');
|
|
809
|
+
cleaned = cleaned.replace(/^\[agents\]\s*\n(?=\[|$)/m, '');
|
|
810
|
+
cleaned = cleaned.replace(/\n{3,}/g, '\n\n').trim();
|
|
811
|
+
|
|
812
|
+
if (!cleaned) return null;
|
|
813
|
+
return cleaned + '\n';
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* Merge GSD config block into an existing or new config.toml.
|
|
818
|
+
*/
|
|
819
|
+
function mergeCodexConfig(configPath, gsdBlock) {
|
|
820
|
+
if (!fs.existsSync(configPath)) {
|
|
821
|
+
fs.writeFileSync(configPath, gsdBlock + '\n');
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
const existing = fs.readFileSync(configPath, 'utf8');
|
|
826
|
+
const markerIndex = existing.indexOf(GSD_CODEX_MARKER);
|
|
827
|
+
|
|
828
|
+
if (markerIndex !== -1) {
|
|
829
|
+
const before = existing.substring(0, markerIndex).trimEnd();
|
|
830
|
+
const newContent = before ? before + '\n\n' + gsdBlock + '\n' : gsdBlock + '\n';
|
|
831
|
+
fs.writeFileSync(configPath, newContent);
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
let content = existing;
|
|
836
|
+
const featuresRegex = /^\[features\]\s*$/m;
|
|
837
|
+
const hasFeatures = featuresRegex.test(content);
|
|
838
|
+
|
|
839
|
+
if (hasFeatures) {
|
|
840
|
+
if (!content.includes('multi_agent')) {
|
|
841
|
+
content = content.replace(featuresRegex, '[features]\nmulti_agent = true');
|
|
842
|
+
}
|
|
843
|
+
if (!content.includes('default_mode_request_user_input')) {
|
|
844
|
+
content = content.replace(/^\[features\].*$/m, '$&\ndefault_mode_request_user_input = true');
|
|
845
|
+
}
|
|
846
|
+
const agentsBlock = gsdBlock.substring(gsdBlock.indexOf('[agents]'));
|
|
847
|
+
content = content.trimEnd() + '\n\n' + GSD_CODEX_MARKER + '\n' + agentsBlock + '\n';
|
|
848
|
+
} else {
|
|
849
|
+
content = content.trimEnd() + '\n\n' + gsdBlock + '\n';
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
fs.writeFileSync(configPath, content);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* Generate config.toml and per-agent .toml files for Codex.
|
|
857
|
+
*/
|
|
858
|
+
function installCodexConfig(targetDir, agentsSrc) {
|
|
859
|
+
const configPath = path.join(targetDir, 'config.toml');
|
|
860
|
+
const agentsTomlDir = path.join(targetDir, 'agents');
|
|
861
|
+
fs.mkdirSync(agentsTomlDir, { recursive: true });
|
|
862
|
+
|
|
863
|
+
const agentEntries = fs.readdirSync(agentsSrc).filter(f => f.startsWith('gsd-') && f.endsWith('.md'));
|
|
864
|
+
const agents = [];
|
|
865
|
+
|
|
866
|
+
for (const file of agentEntries) {
|
|
867
|
+
const content = fs.readFileSync(path.join(agentsSrc, file), 'utf8');
|
|
868
|
+
const { frontmatter } = extractFrontmatterAndBody(content);
|
|
869
|
+
const name = extractFrontmatterField(frontmatter, 'name') || file.replace('.md', '');
|
|
870
|
+
const description = extractFrontmatterField(frontmatter, 'description') || '';
|
|
871
|
+
|
|
872
|
+
agents.push({ name, description: toSingleLine(description) });
|
|
873
|
+
|
|
874
|
+
const tomlContent = generateCodexAgentToml(name, content);
|
|
875
|
+
fs.writeFileSync(path.join(agentsTomlDir, `${name}.toml`), tomlContent);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
const gsdBlock = generateCodexConfigBlock(agents);
|
|
879
|
+
mergeCodexConfig(configPath, gsdBlock);
|
|
880
|
+
|
|
881
|
+
return agents.length;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// ─── Test-only exports ───────────────────────────────────────────────────────
|
|
885
|
+
// When loaded as a module for testing, skip main CLI logic and export functions
|
|
886
|
+
if (process.env.GSD_TEST_MODE) {
|
|
887
|
+
module.exports = {
|
|
888
|
+
getCodexSkillAdapterHeader,
|
|
889
|
+
convertAgentToCodexFormat,
|
|
890
|
+
generateCodexAgentToml,
|
|
891
|
+
generateCodexConfigBlock,
|
|
892
|
+
stripGsdFromCodexConfig,
|
|
893
|
+
mergeCodexConfig,
|
|
894
|
+
installCodexConfig,
|
|
895
|
+
convertCommandToCodexSkill,
|
|
896
|
+
GSD_CODEX_MARKER,
|
|
897
|
+
CODEX_AGENT_SANDBOX,
|
|
898
|
+
};
|
|
899
|
+
} else {
|
|
900
|
+
|
|
641
901
|
if (pathIdx !== -1 && !customPath) {
|
|
642
902
|
console.error(` ${yellow}--path requires a directory argument${reset}`);
|
|
643
903
|
process.exit(1);
|
|
@@ -684,3 +944,5 @@ if (hasVerify) {
|
|
|
684
944
|
});
|
|
685
945
|
}
|
|
686
946
|
}
|
|
947
|
+
|
|
948
|
+
} // end of else block for GSD_TEST_MODE
|
|
@@ -19,15 +19,11 @@ Routes to the add-phase workflow which handles:
|
|
|
19
19
|
</objective>
|
|
20
20
|
|
|
21
21
|
<execution_context>
|
|
22
|
+
@.planning/ROADMAP.md
|
|
23
|
+
@.planning/STATE.md
|
|
22
24
|
@~/.codex/get-shit-done/workflows/add-phase.md
|
|
23
25
|
</execution_context>
|
|
24
26
|
|
|
25
|
-
<context>
|
|
26
|
-
Arguments: $ARGUMENTS (phase description)
|
|
27
|
-
|
|
28
|
-
Roadmap and state are resolved in-workflow via `init phase-op` and targeted tool calls.
|
|
29
|
-
</context>
|
|
30
|
-
|
|
31
27
|
<process>
|
|
32
28
|
**Follow the add-phase workflow** from `@~/.codex/get-shit-done/workflows/add-phase.md`.
|
|
33
29
|
|
package/commands/gsd/add-todo.md
CHANGED
|
@@ -23,15 +23,10 @@ Routes to the add-todo workflow which handles:
|
|
|
23
23
|
</objective>
|
|
24
24
|
|
|
25
25
|
<execution_context>
|
|
26
|
+
@.planning/STATE.md
|
|
26
27
|
@~/.codex/get-shit-done/workflows/add-todo.md
|
|
27
28
|
</execution_context>
|
|
28
29
|
|
|
29
|
-
<context>
|
|
30
|
-
Arguments: $ARGUMENTS (optional todo description)
|
|
31
|
-
|
|
32
|
-
State is resolved in-workflow via `init todos` and targeted reads.
|
|
33
|
-
</context>
|
|
34
|
-
|
|
35
30
|
<process>
|
|
36
31
|
**Follow the add-todo workflow** from `@~/.codex/get-shit-done/workflows/add-todo.md`.
|
|
37
32
|
|
|
@@ -21,15 +21,11 @@ Routes to the check-todos workflow which handles:
|
|
|
21
21
|
</objective>
|
|
22
22
|
|
|
23
23
|
<execution_context>
|
|
24
|
+
@.planning/STATE.md
|
|
25
|
+
@.planning/ROADMAP.md
|
|
24
26
|
@~/.codex/get-shit-done/workflows/check-todos.md
|
|
25
27
|
</execution_context>
|
|
26
28
|
|
|
27
|
-
<context>
|
|
28
|
-
Arguments: $ARGUMENTS (optional area filter)
|
|
29
|
-
|
|
30
|
-
Todo state and roadmap correlation are loaded in-workflow using `init todos` and targeted reads.
|
|
31
|
-
</context>
|
|
32
|
-
|
|
33
29
|
<process>
|
|
34
30
|
**Follow the check-todos workflow** from `@~/.codex/get-shit-done/workflows/check-todos.md`.
|
|
35
31
|
|
package/commands/gsd/debug.md
CHANGED
|
@@ -110,9 +110,6 @@ Task(
|
|
|
110
110
|
**If `## CHECKPOINT REACHED`:**
|
|
111
111
|
- Present checkpoint details to user
|
|
112
112
|
- Get user response
|
|
113
|
-
- If checkpoint type is `human-verify`:
|
|
114
|
-
- If user confirms fixed: continue so agent can finalize/resolve/archive
|
|
115
|
-
- If user reports issues: continue so agent returns to investigation/fixing
|
|
116
113
|
- Spawn continuation agent (see step 5)
|
|
117
114
|
|
|
118
115
|
**If `## INVESTIGATION INCONCLUSIVE`:**
|
|
@@ -132,9 +129,7 @@ Continue debugging {slug}. Evidence is in the debug file.
|
|
|
132
129
|
</objective>
|
|
133
130
|
|
|
134
131
|
<prior_state>
|
|
135
|
-
|
|
136
|
-
- .planning/debug/{slug}.md (Debug session state)
|
|
137
|
-
</files_to_read>
|
|
132
|
+
Debug file: @.planning/debug/{slug}.md
|
|
138
133
|
</prior_state>
|
|
139
134
|
|
|
140
135
|
<checkpoint_response>
|
|
@@ -10,16 +10,20 @@ allowed-tools:
|
|
|
10
10
|
- Grep
|
|
11
11
|
- AskUserQuestion
|
|
12
12
|
- Task
|
|
13
|
+
- mcp__context7__resolve-library-id
|
|
14
|
+
- mcp__context7__query-docs
|
|
13
15
|
---
|
|
14
16
|
|
|
15
17
|
<objective>
|
|
16
18
|
Extract implementation decisions that downstream agents need — researcher and planner will use CONTEXT.md to know what to investigate and what choices are locked.
|
|
17
19
|
|
|
18
20
|
**How it works:**
|
|
19
|
-
1.
|
|
20
|
-
2.
|
|
21
|
-
3.
|
|
22
|
-
4.
|
|
21
|
+
1. Load prior context (PROJECT.md, REQUIREMENTS.md, STATE.md, prior CONTEXT.md files)
|
|
22
|
+
2. Scout codebase for reusable assets and patterns
|
|
23
|
+
3. Analyze phase — skip gray areas already decided in prior phases
|
|
24
|
+
4. Present remaining gray areas — user selects which to discuss
|
|
25
|
+
5. Deep-dive each selected area until satisfied
|
|
26
|
+
6. Create CONTEXT.md with decisions that guide research and planning
|
|
23
27
|
|
|
24
28
|
**Output:** `{phase_num}-CONTEXT.md` — decisions clear enough that downstream agents can act without asking the user again
|
|
25
29
|
</objective>
|
|
@@ -38,11 +42,13 @@ Context files are resolved in-workflow using `init phase-op` and roadmap/state t
|
|
|
38
42
|
<process>
|
|
39
43
|
1. Validate phase number (error if missing or not in roadmap)
|
|
40
44
|
2. Check if CONTEXT.md exists (offer update/view/skip if yes)
|
|
41
|
-
3. **
|
|
42
|
-
4. **
|
|
43
|
-
5. **
|
|
44
|
-
6. **
|
|
45
|
-
7.
|
|
45
|
+
3. **Load prior context** — Read PROJECT.md, REQUIREMENTS.md, STATE.md, and all prior CONTEXT.md files
|
|
46
|
+
4. **Scout codebase** — Find reusable assets, patterns, and integration points
|
|
47
|
+
5. **Analyze phase** — Check prior decisions, skip already-decided areas, generate remaining gray areas
|
|
48
|
+
6. **Present gray areas** — Multi-select: which to discuss? Annotate with prior decisions + code context
|
|
49
|
+
7. **Deep-dive each area** — 4 questions per area, code-informed options, Context7 for library choices
|
|
50
|
+
8. **Write CONTEXT.md** — Sections match areas discussed + code_context section
|
|
51
|
+
9. Offer next steps (research or plan)
|
|
46
52
|
|
|
47
53
|
**CRITICAL: Scope guardrail**
|
|
48
54
|
- Phase boundary from ROADMAP.md is FIXED
|
|
@@ -74,6 +80,7 @@ Generate 3-4 **phase-specific** gray areas, not generic categories.
|
|
|
74
80
|
</process>
|
|
75
81
|
|
|
76
82
|
<success_criteria>
|
|
83
|
+
- Prior context loaded and applied (no re-asking decided questions)
|
|
77
84
|
- Gray areas identified through intelligent analysis
|
|
78
85
|
- User chose which areas to discuss
|
|
79
86
|
- Each selected area explored until satisfied
|
|
@@ -32,7 +32,8 @@ Phase: $ARGUMENTS
|
|
|
32
32
|
**Flags:**
|
|
33
33
|
- `--gaps-only` — Execute only gap closure plans (plans with `gap_closure: true` in frontmatter). Use after verify-work creates fix plans.
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
@.planning/ROADMAP.md
|
|
36
|
+
@.planning/STATE.md
|
|
36
37
|
</context>
|
|
37
38
|
|
|
38
39
|
<process>
|
|
@@ -35,7 +35,14 @@ Brownfield equivalent of new-project. Project exists, PROJECT.md has history. Ga
|
|
|
35
35
|
<context>
|
|
36
36
|
Milestone name: $ARGUMENTS (optional - will prompt if not provided)
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
**Load project context:**
|
|
39
|
+
@.planning/PROJECT.md
|
|
40
|
+
@.planning/STATE.md
|
|
41
|
+
@.planning/MILESTONES.md
|
|
42
|
+
@.planning/config.json
|
|
43
|
+
|
|
44
|
+
**Load milestone context (if exists, from /gsd:discuss-milestone):**
|
|
45
|
+
@.planning/MILESTONE-CONTEXT.md
|
|
39
46
|
</context>
|
|
40
47
|
|
|
41
48
|
<process>
|
|
@@ -19,13 +19,10 @@ Routes to the pause-work workflow which handles:
|
|
|
19
19
|
</objective>
|
|
20
20
|
|
|
21
21
|
<execution_context>
|
|
22
|
+
@.planning/STATE.md
|
|
22
23
|
@~/.codex/get-shit-done/workflows/pause-work.md
|
|
23
24
|
</execution_context>
|
|
24
25
|
|
|
25
|
-
<context>
|
|
26
|
-
State and phase progress are gathered in-workflow with targeted reads.
|
|
27
|
-
</context>
|
|
28
|
-
|
|
29
26
|
<process>
|
|
30
27
|
**Follow the pause-work workflow** from `@~/.codex/get-shit-done/workflows/pause-work.md`.
|
|
31
28
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd:plan-phase
|
|
3
3
|
description: Create detailed phase plan (PLAN.md) with verification loop
|
|
4
|
-
argument-hint: "[phase] [--auto] [--research] [--skip-research] [--gaps] [--skip-verify]
|
|
4
|
+
argument-hint: "[phase] [--auto] [--research] [--skip-research] [--gaps] [--skip-verify]"
|
|
5
5
|
agent: gsd-planner
|
|
6
6
|
allowed-tools:
|
|
7
7
|
- Read
|
|
@@ -34,7 +34,6 @@ Phase number: $ARGUMENTS (optional — auto-detects next unplanned phase if omit
|
|
|
34
34
|
- `--skip-research` — Skip research, go straight to planning
|
|
35
35
|
- `--gaps` — Gap closure mode (reads VERIFICATION.md, skips research)
|
|
36
36
|
- `--skip-verify` — Skip verification loop
|
|
37
|
-
- `--prd <file>` — Use a PRD/acceptance criteria file instead of discuss-phase. Parses requirements into CONTEXT.md automatically. Skips discuss-phase entirely.
|
|
38
37
|
|
|
39
38
|
Normalize phase input in step 2 before any directory lookups.
|
|
40
39
|
</context>
|
|
@@ -37,7 +37,7 @@ Normalize phase input in step 1 before any directory lookups.
|
|
|
37
37
|
INIT=$(node ~/.codex/get-shit-done/bin/gsd-tools.cjs init phase-op "$ARGUMENTS")
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
Extract from init JSON: `phase_dir`, `phase_number`, `phase_name`, `phase_found`, `commit_docs`, `has_research
|
|
40
|
+
Extract from init JSON: `phase_dir`, `phase_number`, `phase_name`, `phase_found`, `commit_docs`, `has_research`.
|
|
41
41
|
|
|
42
42
|
Resolve researcher model:
|
|
43
43
|
```bash
|
|
@@ -64,12 +64,15 @@ ls .planning/phases/${PHASE}-*/RESEARCH.md 2>/dev/null
|
|
|
64
64
|
|
|
65
65
|
## 3. Gather Phase Context
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
|
|
67
|
+
```bash
|
|
68
|
+
# Phase section already loaded in PHASE_INFO
|
|
69
|
+
echo "$PHASE_INFO" | jq -r '.section'
|
|
70
|
+
cat .planning/REQUIREMENTS.md 2>/dev/null
|
|
71
|
+
cat .planning/phases/${PHASE}-*/*-CONTEXT.md 2>/dev/null
|
|
72
|
+
grep -A30 "### Decisions Made" .planning/STATE.md 2>/dev/null
|
|
73
|
+
```
|
|
71
74
|
|
|
72
|
-
Present summary with phase description
|
|
75
|
+
Present summary with phase description, requirements, prior decisions.
|
|
73
76
|
|
|
74
77
|
## 4. Spawn gsd-phase-researcher Agent
|
|
75
78
|
|
|
@@ -98,15 +101,12 @@ Research implementation approach for Phase {phase_number}: {phase_name}
|
|
|
98
101
|
Mode: ecosystem
|
|
99
102
|
</objective>
|
|
100
103
|
|
|
101
|
-
<
|
|
102
|
-
- {requirements_path} (Requirements)
|
|
103
|
-
- {context_path} (Phase context from discuss-phase, if exists)
|
|
104
|
-
- {state_path} (Prior project decisions and blockers)
|
|
105
|
-
</files_to_read>
|
|
106
|
-
|
|
107
|
-
<additional_context>
|
|
104
|
+
<context>
|
|
108
105
|
**Phase description:** {phase_description}
|
|
109
|
-
|
|
106
|
+
**Requirements:** {requirements_list}
|
|
107
|
+
**Prior decisions:** {decisions_if_any}
|
|
108
|
+
**Phase context:** {context_md_content}
|
|
109
|
+
</context>
|
|
110
110
|
|
|
111
111
|
<downstream_consumer>
|
|
112
112
|
Your RESEARCH.md will be loaded by `$gsd-plan-phase` which uses specific sections:
|
|
@@ -158,9 +158,7 @@ Continue research for Phase {phase_number}: {phase_name}
|
|
|
158
158
|
</objective>
|
|
159
159
|
|
|
160
160
|
<prior_state>
|
|
161
|
-
|
|
162
|
-
- .planning/phases/${PHASE}-{slug}/${PHASE}-RESEARCH.md (Existing research)
|
|
163
|
-
</files_to_read>
|
|
161
|
+
Research file: @.planning/phases/${PHASE}-{slug}/${PHASE}-RESEARCH.md
|
|
164
162
|
</prior_state>
|
|
165
163
|
|
|
166
164
|
<checkpoint_response>
|
|
@@ -29,7 +29,8 @@ Phase: $ARGUMENTS (optional)
|
|
|
29
29
|
- If provided: Test specific phase (e.g., "4")
|
|
30
30
|
- If not provided: Check for active sessions or prompt for phase
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
@.planning/STATE.md
|
|
33
|
+
@.planning/ROADMAP.md
|
|
33
34
|
</context>
|
|
34
35
|
|
|
35
36
|
<process>
|