@ktpartners/dgs-platform 2.6.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/LICENSE +38 -0
- package/README.md +851 -0
- package/agents/dgs-codebase-cross-analyzer.md +183 -0
- package/agents/dgs-codebase-mapper.md +782 -0
- package/agents/dgs-codebase-synthesizer.md +156 -0
- package/agents/dgs-debugger.md +1256 -0
- package/agents/dgs-executor.md +550 -0
- package/agents/dgs-integration-checker.md +481 -0
- package/agents/dgs-nyquist-auditor.md +178 -0
- package/agents/dgs-phase-researcher.md +563 -0
- package/agents/dgs-phase-verifier.md +450 -0
- package/agents/dgs-plan-checker.md +708 -0
- package/agents/dgs-planner.md +1324 -0
- package/agents/dgs-project-researcher.md +631 -0
- package/agents/dgs-research-synthesizer.md +249 -0
- package/agents/dgs-roadmapper.md +652 -0
- package/agents/dgs-verifier.md +607 -0
- package/bin/install.js +2073 -0
- package/commands/dgs/add-doc.md +45 -0
- package/commands/dgs/add-idea.md +38 -0
- package/commands/dgs/add-phase.md +43 -0
- package/commands/dgs/add-repo.md +54 -0
- package/commands/dgs/add-tests.md +41 -0
- package/commands/dgs/add-todo.md +47 -0
- package/commands/dgs/approve-spec.md +38 -0
- package/commands/dgs/audit-milestone.md +36 -0
- package/commands/dgs/audit-phase.md +37 -0
- package/commands/dgs/cancel-job.md +23 -0
- package/commands/dgs/capture-principle.md +143 -0
- package/commands/dgs/check-todos.md +45 -0
- package/commands/dgs/cleanup.md +18 -0
- package/commands/dgs/complete-milestone.md +136 -0
- package/commands/dgs/complete-project.md +70 -0
- package/commands/dgs/consolidate-ideas.md +50 -0
- package/commands/dgs/create-milestone-job.md +37 -0
- package/commands/dgs/debug.md +164 -0
- package/commands/dgs/develop-idea.md +53 -0
- package/commands/dgs/discuss-idea.md +41 -0
- package/commands/dgs/discuss-phase.md +83 -0
- package/commands/dgs/execute-phase.md +41 -0
- package/commands/dgs/fast.md +38 -0
- package/commands/dgs/find-related-ideas.md +43 -0
- package/commands/dgs/health.md +28 -0
- package/commands/dgs/help.md +22 -0
- package/commands/dgs/import-spec.md +36 -0
- package/commands/dgs/init-product.md +28 -0
- package/commands/dgs/insert-phase.md +32 -0
- package/commands/dgs/join-discord.md +18 -0
- package/commands/dgs/list-docs.md +40 -0
- package/commands/dgs/list-ideas.md +42 -0
- package/commands/dgs/list-jobs.md +22 -0
- package/commands/dgs/list-phase-assumptions.md +46 -0
- package/commands/dgs/list-projects.md +57 -0
- package/commands/dgs/list-specs.md +40 -0
- package/commands/dgs/map-codebase.md +92 -0
- package/commands/dgs/new-milestone.md +44 -0
- package/commands/dgs/new-project.md +42 -0
- package/commands/dgs/node-repair.md +26 -0
- package/commands/dgs/overlap-check.md +20 -0
- package/commands/dgs/pause-work.md +38 -0
- package/commands/dgs/plan-milestone-gaps.md +34 -0
- package/commands/dgs/plan-phase.md +44 -0
- package/commands/dgs/progress.md +24 -0
- package/commands/dgs/quick.md +41 -0
- package/commands/dgs/reactivate-project.md +70 -0
- package/commands/dgs/reapply-patches.md +110 -0
- package/commands/dgs/refine-spec.md +38 -0
- package/commands/dgs/reject-idea.md +43 -0
- package/commands/dgs/remove-doc.md +44 -0
- package/commands/dgs/remove-phase.md +31 -0
- package/commands/dgs/remove-repo.md +69 -0
- package/commands/dgs/research-idea.md +43 -0
- package/commands/dgs/research-phase.md +189 -0
- package/commands/dgs/restore-idea.md +45 -0
- package/commands/dgs/resume-work.md +40 -0
- package/commands/dgs/rollback-job.md +24 -0
- package/commands/dgs/run-job.md +35 -0
- package/commands/dgs/search.md +40 -0
- package/commands/dgs/set-profile.md +34 -0
- package/commands/dgs/settings.md +38 -0
- package/commands/dgs/switch-project.md +58 -0
- package/commands/dgs/undo-consolidation.md +42 -0
- package/commands/dgs/update-idea.md +44 -0
- package/commands/dgs/update.md +37 -0
- package/commands/dgs/validate-phase.md +35 -0
- package/commands/dgs/verify-work.md +39 -0
- package/commands/dgs/write-spec.md +49 -0
- package/deliver-great-systems/.planning/phases/09-backend-wiring-and-error-handling/09-01-SUMMARY.md +84 -0
- package/deliver-great-systems/.planning/phases/09-backend-wiring-and-error-handling/09-02-SUMMARY.md +86 -0
- package/deliver-great-systems/.planning/phases/10-v1-to-v2-migration-flow/10-01-SUMMARY.md +85 -0
- package/deliver-great-systems/bin/dgs-tools.cjs +1444 -0
- package/deliver-great-systems/bin/lib/auto-test.cjs +1365 -0
- package/deliver-great-systems/bin/lib/commands.cjs +570 -0
- package/deliver-great-systems/bin/lib/config.cjs +417 -0
- package/deliver-great-systems/bin/lib/conflict-agent.cjs +1063 -0
- package/deliver-great-systems/bin/lib/conflict-agent.test.cjs +554 -0
- package/deliver-great-systems/bin/lib/context.cjs +929 -0
- package/deliver-great-systems/bin/lib/context.test.cjs +693 -0
- package/deliver-great-systems/bin/lib/core.cjs +744 -0
- package/deliver-great-systems/bin/lib/core.test.cjs +822 -0
- package/deliver-great-systems/bin/lib/docs.cjs +919 -0
- package/deliver-great-systems/bin/lib/docs.test.cjs +211 -0
- package/deliver-great-systems/bin/lib/execution.cjs +705 -0
- package/deliver-great-systems/bin/lib/execution.test.cjs +1472 -0
- package/deliver-great-systems/bin/lib/frontmatter.cjs +324 -0
- package/deliver-great-systems/bin/lib/ideas.cjs +1406 -0
- package/deliver-great-systems/bin/lib/ideas.test.cjs +1417 -0
- package/deliver-great-systems/bin/lib/identity.cjs +125 -0
- package/deliver-great-systems/bin/lib/init.cjs +1114 -0
- package/deliver-great-systems/bin/lib/init.test.cjs +1271 -0
- package/deliver-great-systems/bin/lib/jobs.cjs +2015 -0
- package/deliver-great-systems/bin/lib/jobs.test.cjs +2619 -0
- package/deliver-great-systems/bin/lib/merge-conflicts.cjs +654 -0
- package/deliver-great-systems/bin/lib/merge-conflicts.test.cjs +370 -0
- package/deliver-great-systems/bin/lib/migration.cjs +352 -0
- package/deliver-great-systems/bin/lib/migration.test.cjs +582 -0
- package/deliver-great-systems/bin/lib/milestone.cjs +243 -0
- package/deliver-great-systems/bin/lib/overlap.cjs +437 -0
- package/deliver-great-systems/bin/lib/overlap.test.cjs +747 -0
- package/deliver-great-systems/bin/lib/path-audit.test.cjs +384 -0
- package/deliver-great-systems/bin/lib/paths.cjs +144 -0
- package/deliver-great-systems/bin/lib/paths.test.cjs +486 -0
- package/deliver-great-systems/bin/lib/phase.cjs +910 -0
- package/deliver-great-systems/bin/lib/projects.cjs +691 -0
- package/deliver-great-systems/bin/lib/projects.test.cjs +871 -0
- package/deliver-great-systems/bin/lib/repos.cjs +1432 -0
- package/deliver-great-systems/bin/lib/repos.test.cjs +1882 -0
- package/deliver-great-systems/bin/lib/roadmap.cjs +305 -0
- package/deliver-great-systems/bin/lib/search.cjs +570 -0
- package/deliver-great-systems/bin/lib/specs.cjs +1303 -0
- package/deliver-great-systems/bin/lib/state.cjs +893 -0
- package/deliver-great-systems/bin/lib/template.cjs +228 -0
- package/deliver-great-systems/bin/lib/test-helpers.cjs +291 -0
- package/deliver-great-systems/bin/lib/verify.cjs +796 -0
- package/deliver-great-systems/references/checkpoints.md +776 -0
- package/deliver-great-systems/references/conflict-resolution.md +66 -0
- package/deliver-great-systems/references/context-tiers.md +166 -0
- package/deliver-great-systems/references/continuation-format.md +249 -0
- package/deliver-great-systems/references/decimal-phase-calculation.md +67 -0
- package/deliver-great-systems/references/git-integration.md +250 -0
- package/deliver-great-systems/references/git-planning-commit.md +40 -0
- package/deliver-great-systems/references/model-profile-resolution.md +36 -0
- package/deliver-great-systems/references/model-profiles.md +95 -0
- package/deliver-great-systems/references/phase-argument-parsing.md +61 -0
- package/deliver-great-systems/references/planning-config.md +224 -0
- package/deliver-great-systems/references/questioning.md +162 -0
- package/deliver-great-systems/references/spec-review-loop.md +177 -0
- package/deliver-great-systems/references/tdd.md +265 -0
- package/deliver-great-systems/references/ui-brand.md +160 -0
- package/deliver-great-systems/references/verification-patterns.md +612 -0
- package/deliver-great-systems/templates/DEBUG.md +166 -0
- package/deliver-great-systems/templates/UAT.md +251 -0
- package/deliver-great-systems/templates/VALIDATION.md +95 -0
- package/deliver-great-systems/templates/claude-md.md +74 -0
- package/deliver-great-systems/templates/codebase/architecture.md +257 -0
- package/deliver-great-systems/templates/codebase/concerns.md +312 -0
- package/deliver-great-systems/templates/codebase/conventions.md +309 -0
- package/deliver-great-systems/templates/codebase/integrations.md +282 -0
- package/deliver-great-systems/templates/codebase/stack.md +188 -0
- package/deliver-great-systems/templates/codebase/structure.md +287 -0
- package/deliver-great-systems/templates/codebase/testing.md +482 -0
- package/deliver-great-systems/templates/config.json +38 -0
- package/deliver-great-systems/templates/context.md +354 -0
- package/deliver-great-systems/templates/continue-here.md +80 -0
- package/deliver-great-systems/templates/debug-subagent-prompt.md +93 -0
- package/deliver-great-systems/templates/discovery.md +148 -0
- package/deliver-great-systems/templates/milestone-archive.md +125 -0
- package/deliver-great-systems/templates/milestone.md +117 -0
- package/deliver-great-systems/templates/phase-prompt.md +615 -0
- package/deliver-great-systems/templates/planner-subagent-prompt.md +119 -0
- package/deliver-great-systems/templates/project.md +186 -0
- package/deliver-great-systems/templates/requirements.md +233 -0
- package/deliver-great-systems/templates/research-project/ARCHITECTURE.md +206 -0
- package/deliver-great-systems/templates/research-project/FEATURES.md +149 -0
- package/deliver-great-systems/templates/research-project/PITFALLS.md +202 -0
- package/deliver-great-systems/templates/research-project/STACK.md +122 -0
- package/deliver-great-systems/templates/research-project/SUMMARY.md +172 -0
- package/deliver-great-systems/templates/research.md +554 -0
- package/deliver-great-systems/templates/retrospective.md +54 -0
- package/deliver-great-systems/templates/roadmap.md +204 -0
- package/deliver-great-systems/templates/state.md +178 -0
- package/deliver-great-systems/templates/summary-complex.md +59 -0
- package/deliver-great-systems/templates/summary-minimal.md +41 -0
- package/deliver-great-systems/templates/summary-standard.md +48 -0
- package/deliver-great-systems/templates/summary.md +253 -0
- package/deliver-great-systems/templates/user-setup.md +313 -0
- package/deliver-great-systems/templates/verification-report.md +324 -0
- package/deliver-great-systems/workflows/add-doc.md +151 -0
- package/deliver-great-systems/workflows/add-idea.md +96 -0
- package/deliver-great-systems/workflows/add-phase.md +120 -0
- package/deliver-great-systems/workflows/add-tests.md +359 -0
- package/deliver-great-systems/workflows/add-todo.md +162 -0
- package/deliver-great-systems/workflows/approve-spec.md +194 -0
- package/deliver-great-systems/workflows/audit-milestone.md +364 -0
- package/deliver-great-systems/workflows/audit-phase.md +462 -0
- package/deliver-great-systems/workflows/cancel-job.md +108 -0
- package/deliver-great-systems/workflows/check-todos.md +181 -0
- package/deliver-great-systems/workflows/cleanup.md +247 -0
- package/deliver-great-systems/workflows/codereview.md +526 -0
- package/deliver-great-systems/workflows/complete-milestone.md +1298 -0
- package/deliver-great-systems/workflows/consolidate-ideas.md +365 -0
- package/deliver-great-systems/workflows/create-milestone-job.md +177 -0
- package/deliver-great-systems/workflows/develop-idea.md +544 -0
- package/deliver-great-systems/workflows/diagnose-issues.md +231 -0
- package/deliver-great-systems/workflows/discovery-phase.md +301 -0
- package/deliver-great-systems/workflows/discuss-idea.md +263 -0
- package/deliver-great-systems/workflows/discuss-phase.md +733 -0
- package/deliver-great-systems/workflows/execute-phase.md +571 -0
- package/deliver-great-systems/workflows/execute-plan.md +592 -0
- package/deliver-great-systems/workflows/find-related-ideas.md +271 -0
- package/deliver-great-systems/workflows/health.md +173 -0
- package/deliver-great-systems/workflows/help.md +997 -0
- package/deliver-great-systems/workflows/import-spec.md +381 -0
- package/deliver-great-systems/workflows/init-product.md +767 -0
- package/deliver-great-systems/workflows/insert-phase.md +138 -0
- package/deliver-great-systems/workflows/list-docs.md +119 -0
- package/deliver-great-systems/workflows/list-ideas.md +154 -0
- package/deliver-great-systems/workflows/list-jobs.md +89 -0
- package/deliver-great-systems/workflows/list-phase-assumptions.md +192 -0
- package/deliver-great-systems/workflows/list-specs.md +101 -0
- package/deliver-great-systems/workflows/map-codebase.md +621 -0
- package/deliver-great-systems/workflows/new-milestone.md +591 -0
- package/deliver-great-systems/workflows/new-project.md +1113 -0
- package/deliver-great-systems/workflows/node-repair.md +94 -0
- package/deliver-great-systems/workflows/overlap-check.md +86 -0
- package/deliver-great-systems/workflows/pause-work.md +134 -0
- package/deliver-great-systems/workflows/plan-milestone-gaps.md +306 -0
- package/deliver-great-systems/workflows/plan-phase.md +698 -0
- package/deliver-great-systems/workflows/progress.md +386 -0
- package/deliver-great-systems/workflows/quick.md +845 -0
- package/deliver-great-systems/workflows/refine-spec.md +275 -0
- package/deliver-great-systems/workflows/reject-idea.md +109 -0
- package/deliver-great-systems/workflows/remove-doc.md +117 -0
- package/deliver-great-systems/workflows/remove-phase.md +163 -0
- package/deliver-great-systems/workflows/research-idea.md +325 -0
- package/deliver-great-systems/workflows/research-phase.md +81 -0
- package/deliver-great-systems/workflows/restore-idea.md +101 -0
- package/deliver-great-systems/workflows/resume-project.md +311 -0
- package/deliver-great-systems/workflows/rollback-job.md +130 -0
- package/deliver-great-systems/workflows/run-job.md +498 -0
- package/deliver-great-systems/workflows/search.md +130 -0
- package/deliver-great-systems/workflows/set-profile.md +83 -0
- package/deliver-great-systems/workflows/settings.md +470 -0
- package/deliver-great-systems/workflows/transition.md +563 -0
- package/deliver-great-systems/workflows/undo-consolidation.md +155 -0
- package/deliver-great-systems/workflows/update-idea.md +157 -0
- package/deliver-great-systems/workflows/update.md +242 -0
- package/deliver-great-systems/workflows/validate-phase.md +177 -0
- package/deliver-great-systems/workflows/verify-phase.md +253 -0
- package/deliver-great-systems/workflows/verify-work.md +671 -0
- package/deliver-great-systems/workflows/write-spec.md +450 -0
- package/hooks/dist/dgs-check-update.js +62 -0
- package/hooks/dist/dgs-context-monitor.js +141 -0
- package/hooks/dist/dgs-statusline.js +115 -0
- package/package.json +60 -0
- package/scripts/build-hooks.js +43 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template — Template selection and fill operations
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const { normalizePhaseName, findPhaseInternal, generateSlugInternal, toPosixPath, output, error } = require('./core.cjs');
|
|
8
|
+
const { reconstructFrontmatter } = require('./frontmatter.cjs');
|
|
9
|
+
|
|
10
|
+
function cmdTemplateSelect(cwd, planPath, raw) {
|
|
11
|
+
if (!planPath) {
|
|
12
|
+
error('plan-path required');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const fullPath = path.join(cwd, planPath);
|
|
17
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
18
|
+
|
|
19
|
+
// Simple heuristics
|
|
20
|
+
const taskMatch = content.match(/###\s*Task\s*\d+/g) || [];
|
|
21
|
+
const taskCount = taskMatch.length;
|
|
22
|
+
|
|
23
|
+
const decisionMatch = content.match(/decision/gi) || [];
|
|
24
|
+
const hasDecisions = decisionMatch.length > 0;
|
|
25
|
+
|
|
26
|
+
// Count file mentions
|
|
27
|
+
const fileMentions = new Set();
|
|
28
|
+
const filePattern = /`([^`]+\.[a-zA-Z]+)`/g;
|
|
29
|
+
let m;
|
|
30
|
+
while ((m = filePattern.exec(content)) !== null) {
|
|
31
|
+
if (m[1].includes('/') && !m[1].startsWith('http')) {
|
|
32
|
+
fileMentions.add(m[1]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const fileCount = fileMentions.size;
|
|
36
|
+
|
|
37
|
+
let template = 'templates/summary-standard.md';
|
|
38
|
+
let type = 'standard';
|
|
39
|
+
|
|
40
|
+
if (taskCount <= 2 && fileCount <= 3 && !hasDecisions) {
|
|
41
|
+
template = 'templates/summary-minimal.md';
|
|
42
|
+
type = 'minimal';
|
|
43
|
+
} else if (hasDecisions || fileCount > 6 || taskCount > 5) {
|
|
44
|
+
template = 'templates/summary-complex.md';
|
|
45
|
+
type = 'complex';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const result = { template, type, taskCount, fileCount, hasDecisions };
|
|
49
|
+
output(result, raw, template);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
// Fallback to standard
|
|
52
|
+
output({ template: 'templates/summary-standard.md', type: 'standard', error: e.message }, raw, 'templates/summary-standard.md');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function cmdTemplateFill(cwd, templateType, options, raw) {
|
|
57
|
+
if (!templateType) { error('template type required: summary, plan, or verification'); }
|
|
58
|
+
if (!options.phase) { error('--phase required'); }
|
|
59
|
+
|
|
60
|
+
const phaseInfo = findPhaseInternal(cwd, options.phase);
|
|
61
|
+
if (!phaseInfo || !phaseInfo.found) { output({ error: 'Phase not found', phase: options.phase }, raw); return; }
|
|
62
|
+
|
|
63
|
+
const padded = normalizePhaseName(options.phase);
|
|
64
|
+
const today = new Date().toISOString().split('T')[0];
|
|
65
|
+
const phaseName = options.name || phaseInfo.phase_name || 'Unnamed';
|
|
66
|
+
const phaseSlug = phaseInfo.phase_slug || generateSlugInternal(phaseName);
|
|
67
|
+
const phaseId = `${padded}-${phaseSlug}`;
|
|
68
|
+
const planNum = (options.plan || '01').padStart(2, '0');
|
|
69
|
+
const fields = options.fields || {};
|
|
70
|
+
|
|
71
|
+
// Build DGS metadata comment for plan and summary templates
|
|
72
|
+
const author = options.author || 'Unknown';
|
|
73
|
+
const metadataComment = `<!-- DGS metadata\nAuthor: ${author}\nCreated: ${today}\n-->\n`;
|
|
74
|
+
|
|
75
|
+
let frontmatter, body, fileName;
|
|
76
|
+
|
|
77
|
+
switch (templateType) {
|
|
78
|
+
case 'summary': {
|
|
79
|
+
frontmatter = {
|
|
80
|
+
phase: phaseId,
|
|
81
|
+
plan: planNum,
|
|
82
|
+
subsystem: '[primary category]',
|
|
83
|
+
tags: [],
|
|
84
|
+
provides: [],
|
|
85
|
+
affects: [],
|
|
86
|
+
'tech-stack': { added: [], patterns: [] },
|
|
87
|
+
'key-files': { created: [], modified: [] },
|
|
88
|
+
'key-decisions': [],
|
|
89
|
+
'patterns-established': [],
|
|
90
|
+
duration: '[X]min',
|
|
91
|
+
completed: today,
|
|
92
|
+
...fields,
|
|
93
|
+
};
|
|
94
|
+
body = [
|
|
95
|
+
`# Phase ${options.phase}: ${phaseName} Summary`,
|
|
96
|
+
'',
|
|
97
|
+
'**[Substantive one-liner describing outcome]**',
|
|
98
|
+
'',
|
|
99
|
+
'## Performance',
|
|
100
|
+
'- **Duration:** [time]',
|
|
101
|
+
'- **Tasks:** [count completed]',
|
|
102
|
+
'- **Files modified:** [count]',
|
|
103
|
+
'',
|
|
104
|
+
'## Accomplishments',
|
|
105
|
+
'- [Key outcome 1]',
|
|
106
|
+
'- [Key outcome 2]',
|
|
107
|
+
'',
|
|
108
|
+
'## Task Commits',
|
|
109
|
+
'1. **Task 1: [task name]** - `hash`',
|
|
110
|
+
'',
|
|
111
|
+
'## Files Created/Modified',
|
|
112
|
+
'- `path/to/file.ts` - What it does',
|
|
113
|
+
'',
|
|
114
|
+
'## Decisions & Deviations',
|
|
115
|
+
'[Key decisions or "None - followed plan as specified"]',
|
|
116
|
+
'',
|
|
117
|
+
'## Next Phase Readiness',
|
|
118
|
+
'[What\'s ready for next phase]',
|
|
119
|
+
].join('\n');
|
|
120
|
+
fileName = `${padded}-${planNum}-SUMMARY.md`;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
case 'plan': {
|
|
124
|
+
const planType = options.type || 'execute';
|
|
125
|
+
const wave = parseInt(options.wave) || 1;
|
|
126
|
+
frontmatter = {
|
|
127
|
+
phase: phaseId,
|
|
128
|
+
plan: planNum,
|
|
129
|
+
type: planType,
|
|
130
|
+
wave,
|
|
131
|
+
depends_on: [],
|
|
132
|
+
files_modified: [],
|
|
133
|
+
autonomous: true,
|
|
134
|
+
user_setup: [],
|
|
135
|
+
must_haves: { truths: [], artifacts: [], key_links: [] },
|
|
136
|
+
...fields,
|
|
137
|
+
};
|
|
138
|
+
body = [
|
|
139
|
+
`# Phase ${options.phase} Plan ${planNum}: [Title]`,
|
|
140
|
+
'',
|
|
141
|
+
'## Objective',
|
|
142
|
+
'- **What:** [What this plan builds]',
|
|
143
|
+
'- **Why:** [Why it matters for the phase goal]',
|
|
144
|
+
'- **Output:** [Concrete deliverable]',
|
|
145
|
+
'',
|
|
146
|
+
'## Context',
|
|
147
|
+
'@.planning/PROJECT.md',
|
|
148
|
+
'@.planning/ROADMAP.md',
|
|
149
|
+
'@.planning/STATE.md',
|
|
150
|
+
'',
|
|
151
|
+
'## Tasks',
|
|
152
|
+
'',
|
|
153
|
+
'<task type="code">',
|
|
154
|
+
' <name>[Task name]</name>',
|
|
155
|
+
' <files>[file paths]</files>',
|
|
156
|
+
' <action>[What to do]</action>',
|
|
157
|
+
' <verify>[How to verify]</verify>',
|
|
158
|
+
' <done>[Definition of done]</done>',
|
|
159
|
+
'</task>',
|
|
160
|
+
'',
|
|
161
|
+
'## Verification',
|
|
162
|
+
'[How to verify this plan achieved its objective]',
|
|
163
|
+
'',
|
|
164
|
+
'## Success Criteria',
|
|
165
|
+
'- [ ] [Criterion 1]',
|
|
166
|
+
'- [ ] [Criterion 2]',
|
|
167
|
+
].join('\n');
|
|
168
|
+
fileName = `${padded}-${planNum}-PLAN.md`;
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
case 'verification': {
|
|
172
|
+
frontmatter = {
|
|
173
|
+
phase: phaseId,
|
|
174
|
+
verified: new Date().toISOString(),
|
|
175
|
+
status: 'pending',
|
|
176
|
+
score: '0/0 must-haves verified',
|
|
177
|
+
...fields,
|
|
178
|
+
};
|
|
179
|
+
body = [
|
|
180
|
+
`# Phase ${options.phase}: ${phaseName} — Verification`,
|
|
181
|
+
'',
|
|
182
|
+
'## Observable Truths',
|
|
183
|
+
'| # | Truth | Status | Evidence |',
|
|
184
|
+
'|---|-------|--------|----------|',
|
|
185
|
+
'| 1 | [Truth] | pending | |',
|
|
186
|
+
'',
|
|
187
|
+
'## Required Artifacts',
|
|
188
|
+
'| Artifact | Expected | Status | Details |',
|
|
189
|
+
'|----------|----------|--------|---------|',
|
|
190
|
+
'| [path] | [what] | pending | |',
|
|
191
|
+
'',
|
|
192
|
+
'## Key Link Verification',
|
|
193
|
+
'| From | To | Via | Status | Details |',
|
|
194
|
+
'|------|----|----|--------|---------|',
|
|
195
|
+
'| [source] | [target] | [connection] | pending | |',
|
|
196
|
+
'',
|
|
197
|
+
'## Requirements Coverage',
|
|
198
|
+
'| Requirement | Status | Blocking Issue |',
|
|
199
|
+
'|-------------|--------|----------------|',
|
|
200
|
+
'| [req] | pending | |',
|
|
201
|
+
'',
|
|
202
|
+
'## Result',
|
|
203
|
+
'[Pending verification]',
|
|
204
|
+
].join('\n');
|
|
205
|
+
fileName = `${padded}-VERIFICATION.md`;
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
default:
|
|
209
|
+
error(`Unknown template type: ${templateType}. Available: summary, plan, verification`);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const needsMetadata = (templateType === 'plan' || templateType === 'summary');
|
|
214
|
+
const prefix = needsMetadata ? metadataComment : '';
|
|
215
|
+
const fullContent = `${prefix}---\n${reconstructFrontmatter(frontmatter)}\n---\n\n${body}\n`;
|
|
216
|
+
const outPath = path.join(cwd, phaseInfo.directory, fileName);
|
|
217
|
+
|
|
218
|
+
if (fs.existsSync(outPath)) {
|
|
219
|
+
output({ error: 'File already exists', path: toPosixPath(path.relative(cwd, outPath)) }, raw);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
fs.writeFileSync(outPath, fullContent, 'utf-8');
|
|
224
|
+
const relPath = toPosixPath(path.relative(cwd, outPath));
|
|
225
|
+
output({ created: true, path: relPath, template: templateType }, raw, relPath);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
module.exports = { cmdTemplateSelect, cmdTemplateFill };
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared test helper module for DGS test suite.
|
|
3
|
+
*
|
|
4
|
+
* Provides dual-mode fixture creation (v1 and v2 directory structures),
|
|
5
|
+
* temp directory management, file writing, and git repo initialization.
|
|
6
|
+
*
|
|
7
|
+
* All functions are synchronous, matching existing test patterns.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
const { execSync } = require('child_process');
|
|
14
|
+
const { initPaths, resetPaths, PROJECTS_DIR } = require('./paths.cjs');
|
|
15
|
+
|
|
16
|
+
// ─── Utility Helpers ─────────────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates a temp directory with optional prefix.
|
|
20
|
+
* @param {string} [prefix='dgs-test-'] - Prefix for the temp directory name.
|
|
21
|
+
* @returns {string} Absolute path to the created temp directory.
|
|
22
|
+
*/
|
|
23
|
+
function createTempDir(prefix) {
|
|
24
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), prefix || 'dgs-test-'));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Recursively removes a directory.
|
|
29
|
+
* @param {string} dir - Absolute path to the directory to remove.
|
|
30
|
+
*/
|
|
31
|
+
function cleanupDir(dir) {
|
|
32
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Creates parent directories and writes a file.
|
|
37
|
+
* @param {string} base - Base directory (absolute path).
|
|
38
|
+
* @param {string} relPath - Relative path from base.
|
|
39
|
+
* @param {string} content - File content to write.
|
|
40
|
+
*/
|
|
41
|
+
function writeFile(base, relPath, content) {
|
|
42
|
+
const fullPath = path.join(base, relPath);
|
|
43
|
+
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
44
|
+
fs.writeFileSync(fullPath, content);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Initializes a git repo with an initial commit.
|
|
49
|
+
* @param {string} dir - Directory to initialize as a git repo.
|
|
50
|
+
*/
|
|
51
|
+
function initGitRepo(dir) {
|
|
52
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
53
|
+
execSync('git init', { cwd: dir, stdio: 'pipe' });
|
|
54
|
+
execSync('git config user.email "test@test.com"', { cwd: dir, stdio: 'pipe' });
|
|
55
|
+
execSync('git config user.name "Test"', { cwd: dir, stdio: 'pipe' });
|
|
56
|
+
fs.writeFileSync(path.join(dir, '.gitkeep'), '');
|
|
57
|
+
execSync('git add .', { cwd: dir, stdio: 'pipe' });
|
|
58
|
+
execSync('git commit -m "initial"', { cwd: dir, stdio: 'pipe' });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ─── Fixture Helpers ─────────────────────────────────────────────────────────
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Creates a temporary directory with an arbitrary file/folder structure.
|
|
65
|
+
*
|
|
66
|
+
* @param {Object} structure - Keys are relative paths, values are file content
|
|
67
|
+
* (string) or null (directory). Paths ending with '/' are also treated as directories.
|
|
68
|
+
* @returns {{ cwd: string, cleanup: () => void }}
|
|
69
|
+
*
|
|
70
|
+
* Example:
|
|
71
|
+
* createFixture({
|
|
72
|
+
* '.planning/config.json': '{}',
|
|
73
|
+
* '.planning/STATE.md': '# State',
|
|
74
|
+
* '.planning/phases/': null, // directory
|
|
75
|
+
* })
|
|
76
|
+
*/
|
|
77
|
+
function createFixture(structure) {
|
|
78
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'dgs-test-'));
|
|
79
|
+
|
|
80
|
+
for (const [relPath, content] of Object.entries(structure)) {
|
|
81
|
+
const fullPath = path.join(cwd, relPath);
|
|
82
|
+
if (content === null || relPath.endsWith('/')) {
|
|
83
|
+
fs.mkdirSync(fullPath, { recursive: true });
|
|
84
|
+
} else {
|
|
85
|
+
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
86
|
+
fs.writeFileSync(fullPath, content, 'utf-8');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Prime the paths cache for this fixture
|
|
91
|
+
initPaths(cwd);
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
cwd,
|
|
95
|
+
cleanup: function cleanup() {
|
|
96
|
+
resetPaths();
|
|
97
|
+
fs.rmSync(cwd, { recursive: true, force: true });
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Creates a temporary project fixture with either v1 or v2 directory structure.
|
|
104
|
+
*
|
|
105
|
+
* @param {Object} [options={}]
|
|
106
|
+
* @param {number} [options.version=1] - 1 for v1 flat structure, 2 for v2 multi-project.
|
|
107
|
+
* @param {string} [options.project] - Project slug (required when version=2).
|
|
108
|
+
* @param {string} [options.projectName] - Display name (defaults to title-casing the slug).
|
|
109
|
+
* @param {boolean} [options.withGit=false] - Initialize as git repo and commit the structure.
|
|
110
|
+
* @param {Object} [options.withConfig] - Additional config.json fields to merge.
|
|
111
|
+
* @param {boolean} [options.withPhases=true] - Create phases/ directory with sample plan.
|
|
112
|
+
* @param {boolean} [options.withTodos=false] - Create todos/pending/ and todos/completed/.
|
|
113
|
+
* @param {boolean} [options.withResearch=false] - Create research/ directory.
|
|
114
|
+
* @returns {{ cwd: string, cleanup: () => void, planningDir: string, projectRoot: string }}
|
|
115
|
+
*/
|
|
116
|
+
function createTempProject(options) {
|
|
117
|
+
const opts = options || {};
|
|
118
|
+
const version = opts.version || 1;
|
|
119
|
+
const layout = opts.layout || 'dotplanning';
|
|
120
|
+
const project = opts.project || null;
|
|
121
|
+
const projectName = opts.projectName || titleCase(project || 'Test Project');
|
|
122
|
+
const withGit = opts.withGit || false;
|
|
123
|
+
const withConfig = opts.withConfig || {};
|
|
124
|
+
const withPhases = opts.withPhases !== undefined ? opts.withPhases : true;
|
|
125
|
+
const withTodos = opts.withTodos || false;
|
|
126
|
+
const withResearch = opts.withResearch || false;
|
|
127
|
+
|
|
128
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'dgs-test-'));
|
|
129
|
+
|
|
130
|
+
// If withGit, initialize repo first
|
|
131
|
+
if (withGit) {
|
|
132
|
+
initGitRepo(cwd);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var planningDir;
|
|
136
|
+
var projectRoot;
|
|
137
|
+
|
|
138
|
+
if (layout === 'root') {
|
|
139
|
+
// Root layout: planning files live at repo root, dgs.config.json at root
|
|
140
|
+
planningDir = cwd;
|
|
141
|
+
projectRoot = '.';
|
|
142
|
+
|
|
143
|
+
// Write dgs.config.json at repo root with planningRoot: '.'
|
|
144
|
+
var rootConfigData = Object.assign({ planningRoot: '.' }, withConfig);
|
|
145
|
+
writeFile(cwd, 'dgs.config.json', JSON.stringify(rootConfigData));
|
|
146
|
+
|
|
147
|
+
// Project files at root
|
|
148
|
+
writeFile(cwd, 'PROJECT.md', '# Project: ' + projectName + '\n');
|
|
149
|
+
writeFile(cwd, 'REQUIREMENTS.md', '# Requirements\n');
|
|
150
|
+
writeFile(cwd, 'ROADMAP.md', '# Roadmap\n\n## Phases\n\n- [ ] **Phase 1: Test Phase** - A test\n');
|
|
151
|
+
writeFile(cwd, 'STATE.md', '# Project State\n\nPhase: 1\nStatus: Ready\nProgress: [░░░░░░░░░░] 0%\n');
|
|
152
|
+
|
|
153
|
+
// v2 markers at root (for completeness if root-layout + v2 ever used)
|
|
154
|
+
writeFile(cwd, 'PROJECTS.md', '# Projects\n');
|
|
155
|
+
writeFile(cwd, 'REPOS.md', '# Repos\n');
|
|
156
|
+
|
|
157
|
+
if (withPhases) {
|
|
158
|
+
writeFile(cwd, 'phases/01-test-phase/01-01-PLAN.md',
|
|
159
|
+
'---\nphase: 01-test-phase\nplan: 01\n---\n# Plan\n');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (withTodos) {
|
|
163
|
+
fs.mkdirSync(path.join(cwd, 'todos', 'pending'), { recursive: true });
|
|
164
|
+
fs.mkdirSync(path.join(cwd, 'todos', 'completed'), { recursive: true });
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (withResearch) {
|
|
168
|
+
fs.mkdirSync(path.join(cwd, 'research'), { recursive: true });
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
} else if (version === 2) {
|
|
172
|
+
if (!project) {
|
|
173
|
+
throw new Error('createTempProject: version 2 requires a project slug');
|
|
174
|
+
}
|
|
175
|
+
planningDir = path.join(cwd, '.planning');
|
|
176
|
+
projectRoot = path.join('.planning', PROJECTS_DIR, project);
|
|
177
|
+
var absProjectRoot = path.join(cwd, '.planning', PROJECTS_DIR, project);
|
|
178
|
+
|
|
179
|
+
// Product-level config
|
|
180
|
+
var configData = Object.assign({ current_project: project }, withConfig);
|
|
181
|
+
writeFile(cwd, '.planning/config.json', JSON.stringify(configData));
|
|
182
|
+
|
|
183
|
+
// v2 markers
|
|
184
|
+
var projectsMd = '# Projects\n\n## Active\n\n';
|
|
185
|
+
projectsMd += '| Project | Status | Repos Touched | Current Phase |\n';
|
|
186
|
+
projectsMd += '|---------|--------|---------------|---------------|\n';
|
|
187
|
+
projectsMd += '| ' + project + ' | Active | | Phase 1 |\n';
|
|
188
|
+
projectsMd += '\n## Completed\n\n';
|
|
189
|
+
projectsMd += '| Project | Completed | Duration |\n';
|
|
190
|
+
projectsMd += '|---------|-----------|----------|\n';
|
|
191
|
+
writeFile(cwd, '.planning/PROJECTS.md', projectsMd);
|
|
192
|
+
|
|
193
|
+
var reposMd = '# Repos\n\n';
|
|
194
|
+
reposMd += 'Registered repositories for this product. Managed by DGS — manual edits may be overwritten.\n\n';
|
|
195
|
+
reposMd += '| Name | Path | GitHub URL | Description |\n';
|
|
196
|
+
reposMd += '|------|------|------------|-------------|\n';
|
|
197
|
+
writeFile(cwd, '.planning/REPOS.md', reposMd);
|
|
198
|
+
|
|
199
|
+
// Project-level files under .planning/projects/<slug>/
|
|
200
|
+
writeFile(cwd, path.join('.planning', PROJECTS_DIR, project, 'PROJECT.md'), '# Project: ' + projectName + '\n');
|
|
201
|
+
writeFile(cwd, path.join('.planning', PROJECTS_DIR, project, 'REQUIREMENTS.md'), '# Requirements\n');
|
|
202
|
+
writeFile(cwd, path.join('.planning', PROJECTS_DIR, project, 'ROADMAP.md'), '# Roadmap\n\n## Phases\n\n- [ ] **Phase 1: Test Phase** - A test\n');
|
|
203
|
+
writeFile(cwd, path.join('.planning', PROJECTS_DIR, project, 'STATE.md'), '# Project State\n\nPhase: 1\nStatus: Ready\nProgress: [░░░░░░░░░░] 0%\n');
|
|
204
|
+
|
|
205
|
+
if (withPhases) {
|
|
206
|
+
writeFile(cwd, path.join('.planning', PROJECTS_DIR, project, 'phases', '01-test-phase', '01-01-PLAN.md'),
|
|
207
|
+
'---\nphase: 01-test-phase\nplan: 01\n---\n# Plan\n');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (withTodos) {
|
|
211
|
+
fs.mkdirSync(path.join(cwd, '.planning', PROJECTS_DIR, project, 'todos', 'pending'), { recursive: true });
|
|
212
|
+
fs.mkdirSync(path.join(cwd, '.planning', PROJECTS_DIR, project, 'todos', 'completed'), { recursive: true });
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (withResearch) {
|
|
216
|
+
fs.mkdirSync(path.join(cwd, '.planning', PROJECTS_DIR, project, 'research'), { recursive: true });
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
} else {
|
|
220
|
+
// v1 mode (dotplanning layout)
|
|
221
|
+
planningDir = path.join(cwd, '.planning');
|
|
222
|
+
projectRoot = '.planning';
|
|
223
|
+
|
|
224
|
+
// config.json
|
|
225
|
+
var v1ConfigData = Object.assign({}, withConfig);
|
|
226
|
+
writeFile(cwd, '.planning/config.json', JSON.stringify(v1ConfigData));
|
|
227
|
+
|
|
228
|
+
// Project files
|
|
229
|
+
writeFile(cwd, '.planning/PROJECT.md', '# Project: ' + projectName + '\n');
|
|
230
|
+
writeFile(cwd, '.planning/REQUIREMENTS.md', '# Requirements\n');
|
|
231
|
+
writeFile(cwd, '.planning/ROADMAP.md', '# Roadmap\n\n## Phases\n\n- [ ] **Phase 1: Test Phase** - A test\n');
|
|
232
|
+
writeFile(cwd, '.planning/STATE.md', '# Project State\n\nPhase: 1\nStatus: Ready\nProgress: [░░░░░░░░░░] 0%\n');
|
|
233
|
+
|
|
234
|
+
if (withPhases) {
|
|
235
|
+
writeFile(cwd, '.planning/phases/01-test-phase/01-01-PLAN.md',
|
|
236
|
+
'---\nphase: 01-test-phase\nplan: 01\n---\n# Plan\n');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (withTodos) {
|
|
240
|
+
fs.mkdirSync(path.join(cwd, '.planning', 'todos', 'pending'), { recursive: true });
|
|
241
|
+
fs.mkdirSync(path.join(cwd, '.planning', 'todos', 'completed'), { recursive: true });
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (withResearch) {
|
|
245
|
+
fs.mkdirSync(path.join(cwd, '.planning', 'research'), { recursive: true });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// If withGit, commit the fixture structure
|
|
250
|
+
if (withGit) {
|
|
251
|
+
execSync('git add .', { cwd: cwd, stdio: 'pipe' });
|
|
252
|
+
execSync('git commit -m "test fixture"', { cwd: cwd, stdio: 'pipe' });
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Prime the paths cache for this fixture
|
|
256
|
+
initPaths(cwd);
|
|
257
|
+
|
|
258
|
+
return {
|
|
259
|
+
cwd: cwd,
|
|
260
|
+
cleanup: function cleanup() {
|
|
261
|
+
resetPaths();
|
|
262
|
+
fs.rmSync(cwd, { recursive: true, force: true });
|
|
263
|
+
},
|
|
264
|
+
planningDir: planningDir,
|
|
265
|
+
projectRoot: projectRoot,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// ─── Internal Helpers ────────────────────────────────────────────────────────
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Converts a slug or plain string to title case.
|
|
273
|
+
* @param {string} str
|
|
274
|
+
* @returns {string}
|
|
275
|
+
*/
|
|
276
|
+
function titleCase(str) {
|
|
277
|
+
return str
|
|
278
|
+
.replace(/-/g, ' ')
|
|
279
|
+
.replace(/\b\w/g, function (c) { return c.toUpperCase(); });
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// ─── Exports ─────────────────────────────────────────────────────────────────
|
|
283
|
+
|
|
284
|
+
module.exports = {
|
|
285
|
+
createTempDir,
|
|
286
|
+
cleanupDir,
|
|
287
|
+
writeFile,
|
|
288
|
+
initGitRepo,
|
|
289
|
+
createFixture,
|
|
290
|
+
createTempProject,
|
|
291
|
+
};
|