sumulige-claude 1.5.1 → 1.5.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/.claude/hooks/hook-registry.json +0 -15
- package/.claude/rules/coding-style.md +18 -7
- package/.claude/rules/hooks.md +15 -4
- package/.claude/rules/performance.md +15 -5
- package/.claude/rules/security.md +140 -4
- package/.claude/rules/testing.md +138 -9
- package/.claude/rules/web-design-standard.md +16 -5
- package/.claude/skills/algorithmic-art/metadata.yaml +28 -0
- package/.claude/skills/api-tester/SKILL.md +61 -0
- package/.claude/skills/api-tester/examples/basic.md +3 -0
- package/.claude/skills/api-tester/metadata.yaml +30 -0
- package/.claude/skills/api-tester/templates/default.md +3 -0
- package/.claude/skills/brand-guidelines/metadata.yaml +26 -0
- package/.claude/skills/canvas-design/metadata.yaml +27 -0
- package/.claude/skills/code-reviewer-123/SKILL.md +61 -0
- package/.claude/skills/code-reviewer-123/examples/basic.md +3 -0
- package/.claude/skills/code-reviewer-123/metadata.yaml +30 -0
- package/.claude/skills/code-reviewer-123/templates/default.md +3 -0
- package/.claude/skills/doc-coauthoring/metadata.yaml +27 -0
- package/.claude/skills/docx/metadata.yaml +30 -0
- package/.claude/skills/frontend-design/metadata.yaml +28 -0
- package/.claude/skills/internal-comms/metadata.yaml +28 -0
- package/.claude/skills/mcp-builder/metadata.yaml +26 -0
- package/.claude/skills/my-skill/SKILL.md +61 -0
- package/.claude/skills/my-skill/examples/basic.md +3 -0
- package/.claude/skills/my-skill/metadata.yaml +30 -0
- package/.claude/skills/my-skill/templates/default.md +3 -0
- package/.claude/skills/pdf/metadata.yaml +29 -0
- package/.claude/skills/pptx/metadata.yaml +29 -0
- package/.claude/skills/react-best-practices/metadata.yaml +26 -0
- package/.claude/skills/react-node-practices/SKILL.md +409 -0
- package/.claude/skills/react-node-practices/metadata.yaml +56 -0
- package/.claude/skills/skill-creator/metadata.yaml +25 -0
- package/.claude/skills/slack-gif-creator/metadata.yaml +28 -0
- package/.claude/skills/test-skill-name/SKILL.md +61 -0
- package/.claude/skills/test-skill-name/examples/basic.md +3 -0
- package/.claude/skills/test-skill-name/metadata.yaml +30 -0
- package/.claude/skills/test-skill-name/templates/default.md +3 -0
- package/.claude/skills/test-workflow/metadata.yaml +32 -0
- package/.claude/skills/theme-factory/metadata.yaml +26 -0
- package/.claude/skills/threejs-fundamentals/metadata.yaml +27 -0
- package/.claude/skills/web-artifacts-builder/metadata.yaml +30 -0
- package/.claude/skills/web-design-guidelines/metadata.yaml +26 -0
- package/.claude/skills/webapp-testing/metadata.yaml +26 -0
- package/.claude/skills/xlsx/metadata.yaml +29 -0
- package/LICENSE +21 -0
- package/cli.js +1 -1
- package/package.json +25 -3
- package/.claude/.kickoff-hint.txt +0 -52
- package/.claude/.sumulige-claude-version +0 -1
- package/.claude/.version +0 -1
- package/.claude/AGENTS.md +0 -42
- package/.claude/ANCHORS.md +0 -40
- package/.claude/CLAUDE.md +0 -138
- package/.claude/MEMORY.md +0 -69
- package/.claude/PROJECT_LOG.md +0 -101
- package/.claude/THINKING_CHAIN_GUIDE.md +0 -287
- package/.claude/USAGE.md +0 -175
- package/.claude/boris-optimizations.md +0 -167
- package/.claude/handoffs/INDEX.md +0 -21
- package/.claude/handoffs/LATEST.md +0 -76
- package/.claude/handoffs/handoff_2026-01-22T13-07-04-757Z.md +0 -76
- package/.claude/quality-gate.json +0 -82
- package/.claude/rag/skill-index.json +0 -135
- package/.claude/settings.json +0 -99
- package/.claude/settings.local.json +0 -175
- package/.claude/templates/PROJECT_KICKOFF.md +0 -89
- package/.claude/templates/PROJECT_PROPOSAL.md +0 -227
- package/.claude/templates/TASK_PLAN.md +0 -121
- package/.claude/templates/hooks/README.md +0 -302
- package/.claude/templates/hooks/hook.sh.template +0 -94
- package/.claude/templates/hooks/user-prompt-submit.cjs.template +0 -116
- package/.claude/templates/hooks/user-response-submit.cjs.template +0 -94
- package/.claude/templates/hooks/validate.js +0 -173
- package/.claude/templates/tasks/develop.md +0 -69
- package/.claude/templates/tasks/research.md +0 -64
- package/.claude/templates/tasks/test.md +0 -96
- package/.claude/thinking-routes/.last-sync +0 -1
- package/.claude/thinking-routes/QUICKREF.md +0 -98
- package/.claude/workflow/document-scanner.js +0 -426
- package/.claude/workflow/knowledge-engine.js +0 -941
- package/.claude/workflow/notebooklm/browser.js +0 -1028
- package/.claude/workflow/phases/phase1-research.js +0 -578
- package/.claude/workflow/phases/phase1-research.ts +0 -465
- package/.claude/workflow/phases/phase2-approve.js +0 -722
- package/.claude/workflow/phases/phase3-plan.js +0 -1200
- package/.claude/workflow/phases/phase4-develop.js +0 -894
- package/.claude/workflow/search-cache.js +0 -230
- package/.claude/workflow/templates/approval.md +0 -315
- package/.claude/workflow/templates/development.md +0 -377
- package/.claude/workflow/templates/planning.md +0 -328
- package/.claude/workflow/templates/research.md +0 -250
- package/.claude/workflow/types.js +0 -37
- package/.claude/workflow/web-search.js +0 -278
- package/.claude-plugin/marketplace.json +0 -71
- package/.github/workflows/sync-skills.yml +0 -74
- package/.versionrc +0 -25
- package/AGENTS.md +0 -580
- package/CHANGELOG.md +0 -481
- package/CLAUDE-template.md +0 -114
- package/DEV_TOOLS_GUIDE.md +0 -190
- package/PROJECT_STRUCTURE.md +0 -266
- package/Q&A.md +0 -325
- package/config/defaults.json +0 -34
- package/config/official-skills.json +0 -183
- package/config/quality-gate.json +0 -67
- package/config/skill-categories.json +0 -40
- package/config/version-manifest.json +0 -85
- package/demos/power-3d-scatter.html +0 -683
- package/development/cache/web-search/search_1193d605f8eb364651fc2f2041b58a31.json +0 -36
- package/development/cache/web-search/search_3798bf06960edc125f744a1abb5b72c5.json +0 -36
- package/development/cache/web-search/search_37c7d4843a53f0d83f1122a6f908a2a3.json +0 -36
- package/development/cache/web-search/search_44166fa0153709ee168485a22aa0ab40.json +0 -36
- package/development/cache/web-search/search_4deaebb1f77e86a8ca066dc5a49c59fd.json +0 -36
- package/development/cache/web-search/search_94da91789466070a7f545612e73c7372.json +0 -36
- package/development/cache/web-search/search_dd5de8491b8b803a3cb01339cd210fb0.json +0 -36
- package/development/knowledge-base/.index.clean.json +0 -1
- package/development/knowledge-base/.index.json +0 -486
- package/development/knowledge-base/test-best-practices.md +0 -29
- package/development/projects/proj_mkh1pazz_ixmt1/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4jvnb_z7rwf/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4jxkd_ewz5a/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4k84n_ni73k/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4wfyd_u9w88/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4wsbo_iahvf/development/projects/proj_mkh4xbpg_4na5w/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4wsbo_iahvf/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4xulg_1ka8x/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4xwhj_gch8j/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4y2qk_9lm8z/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4y2qk_9lm8z/phase2/requirements.md +0 -226
- package/development/projects/proj_mkh4y2qk_9lm8z/phase3/PRD.md +0 -345
- package/development/projects/proj_mkh4y2qk_9lm8z/phase3/TASK_PLAN.md +0 -284
- package/development/projects/proj_mkh4y2qk_9lm8z/phase3/prototype/README.md +0 -14
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/DEVELOPMENT_LOG.md +0 -35
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/TASKS.md +0 -34
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/.env.example +0 -5
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/README.md +0 -60
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/package.json +0 -25
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/src/index.js +0 -70
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/src/routes/index.js +0 -48
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/tests/health.test.js +0 -20
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/tests/jest.config.js +0 -21
- package/development/projects/proj_mkh7veqg_3lypc/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh7veqg_3lypc/phase2/requirements.md +0 -226
- package/development/projects/proj_mkh7veqg_3lypc/phase3/PRD.md +0 -345
- package/development/projects/proj_mkh7veqg_3lypc/phase3/TASK_PLAN.md +0 -284
- package/development/projects/proj_mkh7veqg_3lypc/phase3/prototype/README.md +0 -14
- package/development/projects/proj_mkh8k8fo_rmqn5/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh8xyhy_1vshq/phase1/feasibility-report.md +0 -178
- package/development/projects/proj_mkh8zddd_dhamf/phase1/feasibility-report.md +0 -377
- package/development/projects/proj_mkh8zddd_dhamf/phase2/requirements.md +0 -442
- package/development/projects/proj_mkh8zddd_dhamf/phase3/api-design.md +0 -800
- package/development/projects/proj_mkh8zddd_dhamf/phase3/architecture.md +0 -625
- package/development/projects/proj_mkh8zddd_dhamf/phase3/data-model.md +0 -830
- package/development/projects/proj_mkh8zddd_dhamf/phase3/risks.md +0 -957
- package/development/projects/proj_mkh8zddd_dhamf/phase3/wbs.md +0 -381
- package/development/todos/.state.json +0 -19
- package/development/todos/INDEX.md +0 -63
- package/development/todos/active/_README.md +0 -49
- package/development/todos/archived/_README.md +0 -11
- package/development/todos/backlog/_README.md +0 -11
- package/development/todos/backlog/mcp-integration.md +0 -35
- package/development/todos/completed/_README.md +0 -11
- package/development/todos/completed/boris-optimizations.md +0 -39
- package/development/todos/completed/develop/local-knowledge-index.md +0 -85
- package/development/todos/completed/develop/todo-system.md +0 -47
- package/development/todos/completed/develop/web-search-integration.md +0 -83
- package/development/todos/completed/test/phase1-e2e-test.md +0 -103
- package/docs/DEVELOPMENT.md +0 -461
- package/docs/MARKETPLACE.md +0 -352
- package/docs/RELEASE.md +0 -93
- package/jest.config.js +0 -63
- package/lib/commands.js +0 -3588
- package/lib/config-manager.js +0 -441
- package/lib/config-schema.js +0 -408
- package/lib/config-validator.js +0 -330
- package/lib/config.js +0 -122
- package/lib/errors.js +0 -305
- package/lib/incremental-sync.js +0 -274
- package/lib/marketplace.js +0 -487
- package/lib/migrations.js +0 -154
- package/lib/permission-audit.js +0 -255
- package/lib/quality-gate.js +0 -431
- package/lib/quality-rules.js +0 -373
- package/lib/utils.js +0 -150
- package/lib/version-check.js +0 -169
- package/lib/version-manifest.js +0 -171
- package/project-paradigm.md +0 -313
- package/prompts/how-to-find.md +0 -163
- package/prompts/linus-architect.md +0 -71
- package/prompts/software-architect.md +0 -173
- package/prompts/web-designer.md +0 -249
- package/scripts/fix-hooks.mjs +0 -97
- package/scripts/sync-external.mjs +0 -298
- package/scripts/sync-to-home.sh +0 -108
- package/scripts/update-registry.mjs +0 -325
- package/sources.yaml +0 -83
- package/tests/README.md +0 -263
- package/tests/commands.test.js +0 -1086
- package/tests/config-manager.test.js +0 -677
- package/tests/config-schema.test.js +0 -425
- package/tests/config-validator.test.js +0 -436
- package/tests/config.test.js +0 -100
- package/tests/errors.test.js +0 -477
- package/tests/manual/phase1-e2e.sh +0 -389
- package/tests/manual/phase2-test-cases.md +0 -311
- package/tests/manual/phase3-test-cases.md +0 -309
- package/tests/manual/phase4-test-cases.md +0 -414
- package/tests/manual/test-cases.md +0 -417
- package/tests/marketplace.test.js +0 -420
- package/tests/migrations.test.js +0 -187
- package/tests/quality-gate.test.js +0 -679
- package/tests/quality-rules.test.js +0 -619
- package/tests/sync-external.test.js +0 -214
- package/tests/update-registry.test.js +0 -251
- package/tests/utils.test.js +0 -171
- package/tests/version-check.test.js +0 -75
- package/tests/web-search.test.js +0 -392
- package/thinkinglens-silent.md +0 -138
|
@@ -1,894 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase 4: Development - Execute Implementation Tasks
|
|
3
|
-
*
|
|
4
|
-
* Input: Phase 3 TASK_PLAN.md
|
|
5
|
-
* Output: Source code, tests, documentation
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
|
|
11
|
-
// ============================================================================
|
|
12
|
-
// Configuration
|
|
13
|
-
// ============================================================================
|
|
14
|
-
|
|
15
|
-
const PROJECTS_DIR = path.join(process.cwd(), 'development/projects');
|
|
16
|
-
|
|
17
|
-
// ============================================================================
|
|
18
|
-
// Development Validator
|
|
19
|
-
// ============================================================================
|
|
20
|
-
|
|
21
|
-
class DevelopmentValidator {
|
|
22
|
-
/**
|
|
23
|
-
* Validate development completion from project state
|
|
24
|
-
*/
|
|
25
|
-
static validateProject(projectDir) {
|
|
26
|
-
const checks = [];
|
|
27
|
-
const blockers = [];
|
|
28
|
-
const warnings = [];
|
|
29
|
-
|
|
30
|
-
const sourceDir = path.join(projectDir, 'phase4', 'source');
|
|
31
|
-
|
|
32
|
-
// Check 1: Source directory exists
|
|
33
|
-
const hasSourceDir = fs.existsSync(sourceDir);
|
|
34
|
-
checks.push({
|
|
35
|
-
name: 'Source Directory',
|
|
36
|
-
passed: hasSourceDir,
|
|
37
|
-
message: hasSourceDir
|
|
38
|
-
? 'Source code directory exists'
|
|
39
|
-
: 'Source code directory not found'
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
if (!hasSourceDir) {
|
|
43
|
-
blockers.push('Create source code directory with implementation');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Check 2: Has main application file
|
|
47
|
-
const mainFiles = [
|
|
48
|
-
'index.js', 'index.ts', 'main.js', 'main.ts', 'app.js', 'app.ts',
|
|
49
|
-
'server.js', 'server.ts', 'api.js', 'api.ts'
|
|
50
|
-
];
|
|
51
|
-
const hasMainFile = hasSourceDir && mainFiles.some(file =>
|
|
52
|
-
fs.existsSync(path.join(sourceDir, file)) ||
|
|
53
|
-
fs.existsSync(path.join(sourceDir, 'src', file))
|
|
54
|
-
);
|
|
55
|
-
checks.push({
|
|
56
|
-
name: 'Main Application File',
|
|
57
|
-
passed: hasMainFile,
|
|
58
|
-
message: hasMainFile
|
|
59
|
-
? 'Main application file exists'
|
|
60
|
-
: 'Missing main application file'
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
if (!hasMainFile) {
|
|
64
|
-
blockers.push('Create main application entry point');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Check 3: Has package.json
|
|
68
|
-
const packageJsonPath = path.join(projectDir, 'phase4', 'source', 'package.json');
|
|
69
|
-
const hasPackageJson = fs.existsSync(packageJsonPath);
|
|
70
|
-
checks.push({
|
|
71
|
-
name: 'Package Configuration',
|
|
72
|
-
passed: hasPackageJson,
|
|
73
|
-
message: hasPackageJson
|
|
74
|
-
? 'package.json exists'
|
|
75
|
-
: 'Missing package.json'
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
if (!hasPackageJson) {
|
|
79
|
-
warnings.push('Add package.json with dependencies and scripts');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Check 4: Has README
|
|
83
|
-
const readmePath = path.join(projectDir, 'phase4', 'source', 'README.md');
|
|
84
|
-
const hasReadme = fs.existsSync(readmePath);
|
|
85
|
-
checks.push({
|
|
86
|
-
name: 'Documentation',
|
|
87
|
-
passed: hasReadme,
|
|
88
|
-
message: hasReadme
|
|
89
|
-
? 'README.md exists'
|
|
90
|
-
: 'Missing README.md'
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
if (!hasReadme) {
|
|
94
|
-
warnings.push('Add README.md with setup and usage instructions');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Check 5: Has test directory
|
|
98
|
-
const testDir = path.join(projectDir, 'phase4', 'source', 'tests');
|
|
99
|
-
const hasTests = fs.existsSync(testDir);
|
|
100
|
-
checks.push({
|
|
101
|
-
name: 'Test Directory',
|
|
102
|
-
passed: hasTests,
|
|
103
|
-
message: hasTests
|
|
104
|
-
? 'Test directory exists'
|
|
105
|
-
: 'Missing test directory'
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
if (!hasTests) {
|
|
109
|
-
warnings.push('Add test directory with test cases');
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Check 6: Has .gitignore
|
|
113
|
-
const gitignorePath = path.join(projectDir, 'phase4', 'source', '.gitignore');
|
|
114
|
-
const hasGitignore = fs.existsSync(gitignorePath);
|
|
115
|
-
checks.push({
|
|
116
|
-
name: 'Git Configuration',
|
|
117
|
-
passed: hasGitignore,
|
|
118
|
-
message: hasGitignore
|
|
119
|
-
? '.gitignore exists'
|
|
120
|
-
: 'Missing .gitignore'
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
if (!hasGitignore) {
|
|
124
|
-
warnings.push('Add .gitignore for version control');
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Calculate score
|
|
128
|
-
const passedChecks = checks.filter(c => c.passed).length;
|
|
129
|
-
const score = Math.round((passedChecks / checks.length) * 100);
|
|
130
|
-
|
|
131
|
-
// Determine if passed (need at least 80% and no blockers)
|
|
132
|
-
const passed = score >= 80 && blockers.length === 0;
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
passed,
|
|
136
|
-
score,
|
|
137
|
-
checks,
|
|
138
|
-
blockers,
|
|
139
|
-
warnings
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Validate a project directory
|
|
145
|
-
*/
|
|
146
|
-
static validateProjectDir(projectId) {
|
|
147
|
-
const projectDir = path.join(PROJECTS_DIR, projectId);
|
|
148
|
-
|
|
149
|
-
if (!fs.existsSync(projectDir)) {
|
|
150
|
-
return {
|
|
151
|
-
passed: false,
|
|
152
|
-
score: 0,
|
|
153
|
-
checks: [],
|
|
154
|
-
blockers: [`Project not found: ${projectId}`],
|
|
155
|
-
warnings: []
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return this.validateProject(projectDir);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Generate a validation report for display
|
|
164
|
-
*/
|
|
165
|
-
static generateReport(result) {
|
|
166
|
-
const lines = [];
|
|
167
|
-
|
|
168
|
-
lines.push('═══════════════════════════════════════════════════════');
|
|
169
|
-
lines.push(' Development Phase Validation');
|
|
170
|
-
lines.push('═══════════════════════════════════════════════════════');
|
|
171
|
-
lines.push('');
|
|
172
|
-
|
|
173
|
-
// Status
|
|
174
|
-
const status = result.passed ? '✅ PASSED' : '❌ FAILED';
|
|
175
|
-
const statusColor = result.passed ? '🟢' : '🔴';
|
|
176
|
-
lines.push(`Status: ${statusColor} ${status} (Score: ${result.score}/100)`);
|
|
177
|
-
lines.push('');
|
|
178
|
-
|
|
179
|
-
// Checks
|
|
180
|
-
lines.push('Quality Checks:');
|
|
181
|
-
lines.push('───────────────────────────────────────────────────────');
|
|
182
|
-
|
|
183
|
-
result.checks.forEach(check => {
|
|
184
|
-
const icon = check.passed ? '✅' : '❌';
|
|
185
|
-
lines.push(` ${icon} ${check.name}: ${check.message || 'Failed'}`);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
lines.push('');
|
|
189
|
-
|
|
190
|
-
// Blockers
|
|
191
|
-
if (result.blockers.length > 0) {
|
|
192
|
-
lines.push('🚫 BLOCKERS (must fix before proceeding):');
|
|
193
|
-
lines.push('───────────────────────────────────────────────────────');
|
|
194
|
-
result.blockers.forEach((blocker, i) => {
|
|
195
|
-
lines.push(` ${i + 1}. ${blocker}`);
|
|
196
|
-
});
|
|
197
|
-
lines.push('');
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Warnings
|
|
201
|
-
if (result.warnings.length > 0) {
|
|
202
|
-
lines.push('⚠️ WARNINGS (recommended improvements):');
|
|
203
|
-
lines.push('───────────────────────────────────────────────────────');
|
|
204
|
-
result.warnings.forEach((warning, i) => {
|
|
205
|
-
lines.push(` ${i + 1}. ${warning}`);
|
|
206
|
-
});
|
|
207
|
-
lines.push('');
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Recommendation
|
|
211
|
-
if (result.passed) {
|
|
212
|
-
lines.push('🎉 Development phase complete! Ready for Phase 5 (Deployment).');
|
|
213
|
-
} else {
|
|
214
|
-
lines.push('📝 Development phase needs work. Address blockers and re-validate.');
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
lines.push('');
|
|
218
|
-
lines.push('═══════════════════════════════════════════════════════');
|
|
219
|
-
|
|
220
|
-
return lines.join('\n');
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// ============================================================================
|
|
225
|
-
// Phase 4 Development Executor
|
|
226
|
-
// ============================================================================
|
|
227
|
-
|
|
228
|
-
class Phase4DevelopmentExecutor {
|
|
229
|
-
constructor(projectId) {
|
|
230
|
-
this.projectId = projectId;
|
|
231
|
-
this.projectDir = path.join(PROJECTS_DIR, projectId);
|
|
232
|
-
this.phaseDir = path.join(this.projectDir, 'phase4');
|
|
233
|
-
this.sourceDir = path.join(this.phaseDir, 'source');
|
|
234
|
-
this.taskPlanPath = path.join(this.projectDir, 'phase3', 'TASK_PLAN.md');
|
|
235
|
-
this.prdPath = path.join(this.projectDir, 'phase3', 'PRD.md');
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Ensure project directories exist
|
|
240
|
-
*/
|
|
241
|
-
ensureDirectories() {
|
|
242
|
-
if (!fs.existsSync(this.phaseDir)) {
|
|
243
|
-
fs.mkdirSync(this.phaseDir, { recursive: true });
|
|
244
|
-
}
|
|
245
|
-
if (!fs.existsSync(this.sourceDir)) {
|
|
246
|
-
fs.mkdirSync(this.sourceDir, { recursive: true });
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Read Phase 3 task plan
|
|
252
|
-
*/
|
|
253
|
-
readTaskPlan() {
|
|
254
|
-
if (!fs.existsSync(this.taskPlanPath)) {
|
|
255
|
-
return null;
|
|
256
|
-
}
|
|
257
|
-
return fs.readFileSync(this.taskPlanPath, 'utf-8');
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Read Phase 3 PRD
|
|
262
|
-
*/
|
|
263
|
-
readPRD() {
|
|
264
|
-
if (!fs.existsSync(this.prdPath)) {
|
|
265
|
-
return null;
|
|
266
|
-
}
|
|
267
|
-
return fs.readFileSync(this.prdPath, 'utf-8');
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Extract project info from PRD
|
|
272
|
-
*/
|
|
273
|
-
extractProjectInfo() {
|
|
274
|
-
const prdContent = this.readPRD();
|
|
275
|
-
if (!prdContent) {
|
|
276
|
-
return { name: this.projectId, description: '' };
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// Extract project name/vision
|
|
280
|
-
const visionMatch = prdContent.match(/### Vision\s+([\s\S]*?)(?=###|\n\n|\*\*|$)/);
|
|
281
|
-
const goalsMatch = prdContent.match(/### Goals\s+([\s\S]*?)(?=###|\n\n|$)/);
|
|
282
|
-
|
|
283
|
-
return {
|
|
284
|
-
name: this.projectId,
|
|
285
|
-
vision: visionMatch ? visionMatch[1].trim() : '',
|
|
286
|
-
goals: goalsMatch ? goalsMatch[1].trim() : ''
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Extract tech stack from PRD
|
|
292
|
-
*/
|
|
293
|
-
extractTechStack() {
|
|
294
|
-
const prdContent = this.readPRD();
|
|
295
|
-
if (!prdContent) {
|
|
296
|
-
return { frontend: 'To be decided', backend: 'To be decided' };
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Look for tech stack section
|
|
300
|
-
const techStackMatch = prdContent.match(/## Components\s+([\s\S]*?)(?=##|$)/);
|
|
301
|
-
if (techStackMatch) {
|
|
302
|
-
// Extract frontend/backend technologies
|
|
303
|
-
const frontendMatch = techStackMatch[1].match(/Frontend.*?\|.*?\| ([^\n]+)/i);
|
|
304
|
-
const backendMatch = techStackMatch[1].match(/Backend.*?\|.*?\| ([^\n]+)/i);
|
|
305
|
-
|
|
306
|
-
return {
|
|
307
|
-
frontend: frontendMatch ? frontendMatch[1].trim() : 'To be decided',
|
|
308
|
-
backend: backendMatch ? backendMatch[1].trim() : 'To be decided'
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return { frontend: 'To be decided', backend: 'To be decided' };
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Generate project scaffold
|
|
317
|
-
*/
|
|
318
|
-
async generateScaffold(progressCallback) {
|
|
319
|
-
await progressCallback?.('Creating project structure...', 1, 7);
|
|
320
|
-
|
|
321
|
-
const projectInfo = this.extractProjectInfo();
|
|
322
|
-
const techStack = this.extractTechStack();
|
|
323
|
-
|
|
324
|
-
// Create subdirectories
|
|
325
|
-
const subdirs = ['src', 'tests', 'docs', 'scripts'];
|
|
326
|
-
for (const subdir of subdirs) {
|
|
327
|
-
fs.mkdirSync(path.join(this.sourceDir, subdir), { recursive: true });
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// Generate package.json
|
|
331
|
-
await progressCallback?.('Generating package.json...', 2, 7);
|
|
332
|
-
|
|
333
|
-
const packageJson = {
|
|
334
|
-
name: this.projectId.replace('proj_', ''),
|
|
335
|
-
version: '0.1.0',
|
|
336
|
-
description: projectInfo.vision || 'Project from AI workflow',
|
|
337
|
-
main: 'src/index.js',
|
|
338
|
-
scripts: {
|
|
339
|
-
start: 'node src/index.js',
|
|
340
|
-
test: 'jest',
|
|
341
|
-
lint: 'eslint src/**/*.js',
|
|
342
|
-
format: 'prettier --write "src/**/*.js"'
|
|
343
|
-
},
|
|
344
|
-
dependencies: {
|
|
345
|
-
express: '^4.18.0',
|
|
346
|
-
dotenv: '^16.0.0'
|
|
347
|
-
},
|
|
348
|
-
devDependencies: {
|
|
349
|
-
jest: '^29.0.0',
|
|
350
|
-
eslint: '^8.0.0',
|
|
351
|
-
prettier: '^3.0.0',
|
|
352
|
-
nodemon: '^3.0.0'
|
|
353
|
-
},
|
|
354
|
-
engines: {
|
|
355
|
-
node: '>=16.0.0'
|
|
356
|
-
}
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
await fs.promises.writeFile(
|
|
360
|
-
path.join(this.sourceDir, 'package.json'),
|
|
361
|
-
JSON.stringify(packageJson, null, 2),
|
|
362
|
-
'utf-8'
|
|
363
|
-
);
|
|
364
|
-
|
|
365
|
-
// Generate .gitignore
|
|
366
|
-
await fs.promises.writeFile(
|
|
367
|
-
path.join(this.sourceDir, '.gitignore'),
|
|
368
|
-
`# Dependencies
|
|
369
|
-
node_modules/
|
|
370
|
-
|
|
371
|
-
# Environment
|
|
372
|
-
.env
|
|
373
|
-
.env.local
|
|
374
|
-
.env.*.local
|
|
375
|
-
|
|
376
|
-
# Logs
|
|
377
|
-
logs
|
|
378
|
-
*.log
|
|
379
|
-
npm-debug.log*
|
|
380
|
-
|
|
381
|
-
# Coverage
|
|
382
|
-
coverage/
|
|
383
|
-
*.lcov
|
|
384
|
-
|
|
385
|
-
# Build
|
|
386
|
-
dist/
|
|
387
|
-
build/
|
|
388
|
-
|
|
389
|
-
# IDE
|
|
390
|
-
.idea/
|
|
391
|
-
.vscode/
|
|
392
|
-
*.swp
|
|
393
|
-
*.swo
|
|
394
|
-
*.DS_Store
|
|
395
|
-
|
|
396
|
-
# OS
|
|
397
|
-
Thumbs.db
|
|
398
|
-
`,
|
|
399
|
-
'utf-8'
|
|
400
|
-
);
|
|
401
|
-
|
|
402
|
-
// Generate .env.example
|
|
403
|
-
await fs.promises.writeFile(
|
|
404
|
-
path.join(this.sourceDir, '.env.example'),
|
|
405
|
-
`# Environment Variables
|
|
406
|
-
PORT=3000
|
|
407
|
-
NODE_ENV=development
|
|
408
|
-
|
|
409
|
-
# Add your environment variables here
|
|
410
|
-
`,
|
|
411
|
-
'utf-8'
|
|
412
|
-
);
|
|
413
|
-
|
|
414
|
-
// Generate README.md
|
|
415
|
-
await progressCallback?.('Generating README.md...', 3, 7);
|
|
416
|
-
|
|
417
|
-
const readmeContent = `# ${projectInfo.name}
|
|
418
|
-
|
|
419
|
-
${projectInfo.vision ? projectInfo.vision + '\n\n' : ''}## Installation
|
|
420
|
-
|
|
421
|
-
\`\`\`bash
|
|
422
|
-
# Install dependencies
|
|
423
|
-
npm install
|
|
424
|
-
|
|
425
|
-
# Copy environment file
|
|
426
|
-
cp .env.example .env
|
|
427
|
-
|
|
428
|
-
# Start development server
|
|
429
|
-
npm start
|
|
430
|
-
\`\`\`
|
|
431
|
-
|
|
432
|
-
## Development
|
|
433
|
-
|
|
434
|
-
\`\`\`bash
|
|
435
|
-
# Run in development mode
|
|
436
|
-
npm run dev
|
|
437
|
-
|
|
438
|
-
# Run tests
|
|
439
|
-
npm test
|
|
440
|
-
|
|
441
|
-
# Lint code
|
|
442
|
-
npm run lint
|
|
443
|
-
|
|
444
|
-
# Format code
|
|
445
|
-
npm run format
|
|
446
|
-
\`\`\`
|
|
447
|
-
|
|
448
|
-
## Project Structure
|
|
449
|
-
|
|
450
|
-
\`\`\`
|
|
451
|
-
src/
|
|
452
|
-
index.js # Application entry point
|
|
453
|
-
routes/ # API routes
|
|
454
|
-
controllers/ # Business logic
|
|
455
|
-
models/ # Data models
|
|
456
|
-
middleware/ # Custom middleware
|
|
457
|
-
services/ # External services
|
|
458
|
-
tests/
|
|
459
|
-
unit/ # Unit tests
|
|
460
|
-
integration/ # Integration tests
|
|
461
|
-
docs/ # Documentation
|
|
462
|
-
\`\`\`
|
|
463
|
-
|
|
464
|
-
## API Documentation
|
|
465
|
-
|
|
466
|
-
[API documentation will be added here]
|
|
467
|
-
|
|
468
|
-
## Contributing
|
|
469
|
-
|
|
470
|
-
[Contributing guidelines]
|
|
471
|
-
|
|
472
|
-
## License
|
|
473
|
-
|
|
474
|
-
[License information]
|
|
475
|
-
`;
|
|
476
|
-
|
|
477
|
-
await fs.promises.writeFile(
|
|
478
|
-
path.join(this.sourceDir, 'README.md'),
|
|
479
|
-
readmeContent,
|
|
480
|
-
'utf-8'
|
|
481
|
-
);
|
|
482
|
-
|
|
483
|
-
// Generate main application scaffold
|
|
484
|
-
await progressCallback?.('Creating application scaffold...', 4, 7);
|
|
485
|
-
|
|
486
|
-
// Generate main index.js
|
|
487
|
-
const indexJs = `/**
|
|
488
|
-
* Main Application Entry Point
|
|
489
|
-
* Generated by Phase 4 Development Workflow
|
|
490
|
-
*/
|
|
491
|
-
|
|
492
|
-
const express = require('express');
|
|
493
|
-
const dotenv = require('dotenv');
|
|
494
|
-
|
|
495
|
-
// Load environment variables
|
|
496
|
-
dotenv.config();
|
|
497
|
-
|
|
498
|
-
const app = express();
|
|
499
|
-
const PORT = process.env.PORT || 3000;
|
|
500
|
-
|
|
501
|
-
// Middleware
|
|
502
|
-
app.use(express.json());
|
|
503
|
-
app.use(express.urlencoded({ extended: true }));
|
|
504
|
-
|
|
505
|
-
// CORS middleware
|
|
506
|
-
app.use((req, res, next) => {
|
|
507
|
-
res.header('Access-Control-Allow-Origin', '*');
|
|
508
|
-
res.header('Access-Control-Allow-Headers', '*');
|
|
509
|
-
res.header('Access-Control-Allow-Methods', '*');
|
|
510
|
-
next();
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
// Request logging middleware
|
|
514
|
-
app.use((req, res, next) => {
|
|
515
|
-
console.log(\`\${new Date().toISOString()} \${req.method} \${req.path}\`);
|
|
516
|
-
next();
|
|
517
|
-
});
|
|
518
|
-
|
|
519
|
-
// Health check endpoint
|
|
520
|
-
app.get('/health', (req, res) => {
|
|
521
|
-
res.json({
|
|
522
|
-
status: 'ok',
|
|
523
|
-
timestamp: new Date().toISOString(),
|
|
524
|
-
uptime: process.uptime()
|
|
525
|
-
});
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
// API routes
|
|
529
|
-
app.use('/api/v1', require('./routes'));
|
|
530
|
-
|
|
531
|
-
// 404 handler
|
|
532
|
-
app.use((req, res) => {
|
|
533
|
-
res.status(404).json({
|
|
534
|
-
error: 'Not Found',
|
|
535
|
-
path: req.path
|
|
536
|
-
});
|
|
537
|
-
});
|
|
538
|
-
|
|
539
|
-
// Error handler
|
|
540
|
-
app.use((err, req, res, next) => {
|
|
541
|
-
console.error(err.stack);
|
|
542
|
-
res.status(err.status || 500).json({
|
|
543
|
-
error: err.message || 'Internal Server Error',
|
|
544
|
-
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
|
|
545
|
-
});
|
|
546
|
-
});
|
|
547
|
-
|
|
548
|
-
// Start server
|
|
549
|
-
if (require.main === module) {
|
|
550
|
-
app.listen(PORT, () => {
|
|
551
|
-
console.log(\`🚀 Server running on port \${PORT}\`);
|
|
552
|
-
console.log(\`📖 Health check: http://localhost:\${PORT}/health\`);
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
module.exports = app;
|
|
557
|
-
`;
|
|
558
|
-
|
|
559
|
-
await fs.promises.writeFile(
|
|
560
|
-
path.join(this.sourceDir, 'src', 'index.js'),
|
|
561
|
-
indexJs,
|
|
562
|
-
'utf-8'
|
|
563
|
-
);
|
|
564
|
-
|
|
565
|
-
// Generate routes scaffold
|
|
566
|
-
await fs.promises.mkdir(path.join(this.sourceDir, 'src', 'routes'), { recursive: true });
|
|
567
|
-
|
|
568
|
-
const routesIndexJs = `/**
|
|
569
|
-
* API Routes v1
|
|
570
|
-
*/
|
|
571
|
-
|
|
572
|
-
const express = require('express');
|
|
573
|
-
const router = express.Router();
|
|
574
|
-
|
|
575
|
-
// Example: Resource routes
|
|
576
|
-
router.get('/resources', (req, res) => {
|
|
577
|
-
res.json({
|
|
578
|
-
data: [],
|
|
579
|
-
meta: {
|
|
580
|
-
page: 1,
|
|
581
|
-
limit: 20,
|
|
582
|
-
total: 0
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
});
|
|
586
|
-
|
|
587
|
-
router.post('/resources', (req, res) => {
|
|
588
|
-
res.status(201).json({
|
|
589
|
-
message: 'Resource created',
|
|
590
|
-
data: req.body
|
|
591
|
-
});
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
router.get('/resources/:id', (req, res) => {
|
|
595
|
-
const { id } = req.params;
|
|
596
|
-
res.json({
|
|
597
|
-
id,
|
|
598
|
-
// Resource details
|
|
599
|
-
});
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
router.put('/resources/:id', (req, res) => {
|
|
603
|
-
const { id } = req.params;
|
|
604
|
-
res.json({
|
|
605
|
-
id,
|
|
606
|
-
...req.body,
|
|
607
|
-
message: 'Resource updated'
|
|
608
|
-
});
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
router.delete('/resources/:id', (req, res) => {
|
|
612
|
-
res.status(204).send();
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
module.exports = router;
|
|
616
|
-
`;
|
|
617
|
-
|
|
618
|
-
await fs.promises.writeFile(
|
|
619
|
-
path.join(this.sourceDir, 'src', 'routes', 'index.js'),
|
|
620
|
-
routesIndexJs,
|
|
621
|
-
'utf-8'
|
|
622
|
-
);
|
|
623
|
-
|
|
624
|
-
// Generate test scaffold
|
|
625
|
-
await progressCallback?.('Creating test scaffold...', 5, 7);
|
|
626
|
-
|
|
627
|
-
const testSetupJs = `/**
|
|
628
|
-
* Test Configuration
|
|
629
|
-
*/
|
|
630
|
-
|
|
631
|
-
module.exports = {
|
|
632
|
-
testEnvironment: 'node',
|
|
633
|
-
testMatch: ['**/*.test.js'],
|
|
634
|
-
coverageDirectory: 'coverage',
|
|
635
|
-
collectCoverageFrom: [
|
|
636
|
-
'src/**/*.js',
|
|
637
|
-
'!src/**/*.test.js'
|
|
638
|
-
],
|
|
639
|
-
coverageThreshold: {
|
|
640
|
-
global: {
|
|
641
|
-
branches: 80,
|
|
642
|
-
functions: 80,
|
|
643
|
-
lines: 80,
|
|
644
|
-
statements: 80
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
};
|
|
648
|
-
`;
|
|
649
|
-
|
|
650
|
-
await fs.promises.writeFile(
|
|
651
|
-
path.join(this.sourceDir, 'tests', 'jest.config.js'),
|
|
652
|
-
testSetupJs,
|
|
653
|
-
'utf-8'
|
|
654
|
-
);
|
|
655
|
-
|
|
656
|
-
// Generate example test
|
|
657
|
-
const exampleTestJs = `/**
|
|
658
|
-
* Health Check API Test
|
|
659
|
-
*/
|
|
660
|
-
|
|
661
|
-
const request = require('supertest');
|
|
662
|
-
const app = require('../src/index');
|
|
663
|
-
|
|
664
|
-
describe('Health Check API', () => {
|
|
665
|
-
describe('GET /health', () => {
|
|
666
|
-
it('should return 200 and health status', async () => {
|
|
667
|
-
const response = await request(app)
|
|
668
|
-
.get('/health')
|
|
669
|
-
.expect('Content-Type', /json/)
|
|
670
|
-
.expect(200)
|
|
671
|
-
.expect((res) => {
|
|
672
|
-
expect(res.body).toHaveProperty('status', 'ok');
|
|
673
|
-
});
|
|
674
|
-
});
|
|
675
|
-
});
|
|
676
|
-
});
|
|
677
|
-
`;
|
|
678
|
-
|
|
679
|
-
await fs.promises.writeFile(
|
|
680
|
-
path.join(this.sourceDir, 'tests', 'health.test.js'),
|
|
681
|
-
exampleTestJs,
|
|
682
|
-
'utf-8'
|
|
683
|
-
);
|
|
684
|
-
|
|
685
|
-
// Generate task tracking file
|
|
686
|
-
await progressCallback?.('Creating task tracking...', 6, 7);
|
|
687
|
-
|
|
688
|
-
const tasksPath = path.join(this.phaseDir, 'TASKS.md');
|
|
689
|
-
const tasksContent = `# Development Tasks Tracker
|
|
690
|
-
|
|
691
|
-
**Project**: ${this.projectId}
|
|
692
|
-
**Started**: ${new Date().toLocaleDateString()}
|
|
693
|
-
|
|
694
|
-
---
|
|
695
|
-
|
|
696
|
-
## Task Progress
|
|
697
|
-
|
|
698
|
-
| Task | Status | Assignee | Notes |
|
|
699
|
-
|------|--------|----------|-------|
|
|
700
|
-
| TASK-001 | 🔲 Pending | - | Project setup |
|
|
701
|
-
| TASK-002 | 🔲 Pending | - | Database schema |
|
|
702
|
-
| TASK-003 | 🔲 Pending | - | API infrastructure |
|
|
703
|
-
| TASK-004 | 🔲 Pending | - | Feature A |
|
|
704
|
-
| TASK-005 | 🔲 Pending | - | Feature B |
|
|
705
|
-
|
|
706
|
-
---
|
|
707
|
-
|
|
708
|
-
## Status Legend
|
|
709
|
-
|
|
710
|
-
- 🔲 Pending
|
|
711
|
-
- 🔳 In Progress
|
|
712
|
-
- ✅ Complete
|
|
713
|
-
- ⏸ Blocked
|
|
714
|
-
- ❌ Cancelled
|
|
715
|
-
|
|
716
|
-
---
|
|
717
|
-
|
|
718
|
-
## Notes
|
|
719
|
-
|
|
720
|
-
Use this file to track task progress during development.
|
|
721
|
-
|
|
722
|
-
Update status as work progresses.
|
|
723
|
-
`;
|
|
724
|
-
|
|
725
|
-
await fs.promises.writeFile(tasksPath, tasksContent, 'utf-8');
|
|
726
|
-
|
|
727
|
-
// Generate development log
|
|
728
|
-
const devLogPath = path.join(this.phaseDir, 'DEVELOPMENT_LOG.md');
|
|
729
|
-
const devLogContent = `# Development Log
|
|
730
|
-
|
|
731
|
-
**Project**: ${this.projectId}
|
|
732
|
-
**Phase**: 4 - Development
|
|
733
|
-
|
|
734
|
-
---
|
|
735
|
-
|
|
736
|
-
## Session History
|
|
737
|
-
|
|
738
|
-
### Session 1 - ${new Date().toLocaleDateString()}
|
|
739
|
-
|
|
740
|
-
#### Setup
|
|
741
|
-
- [x] Project scaffold created
|
|
742
|
-
- [x] Directory structure initialized
|
|
743
|
-
- [x] package.json generated
|
|
744
|
-
- [x] README.md created
|
|
745
|
-
|
|
746
|
-
#### Next Steps
|
|
747
|
-
1. Review generated scaffold
|
|
748
|
-
2. Implement TASK-001: [Description]
|
|
749
|
-
3. Implement TASK-002: [Description]
|
|
750
|
-
|
|
751
|
-
---
|
|
752
|
-
|
|
753
|
-
## Change Log
|
|
754
|
-
|
|
755
|
-
| Date | Change | Author |
|
|
756
|
-
|------|--------|--------|
|
|
757
|
-
| ${new Date().toLocaleDateString()} | Initial scaffold generated | Claude |
|
|
758
|
-
|
|
759
|
-
---
|
|
760
|
-
|
|
761
|
-
## Notes
|
|
762
|
-
|
|
763
|
-
Add development notes, decisions, and learnings here.
|
|
764
|
-
`;
|
|
765
|
-
|
|
766
|
-
await fs.promises.writeFile(devLogPath, devLogContent, 'utf-8');
|
|
767
|
-
|
|
768
|
-
await progressCallback?.('Scaffold generation complete!', 7, 7);
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
/**
|
|
772
|
-
* Execute Phase 4 development workflow
|
|
773
|
-
*/
|
|
774
|
-
async execute(progressCallback) {
|
|
775
|
-
await progressCallback?.('Initializing Phase 4 development...', 0, 8);
|
|
776
|
-
|
|
777
|
-
// Ensure directories exist
|
|
778
|
-
this.ensureDirectories();
|
|
779
|
-
|
|
780
|
-
// Step 1: Read task plan
|
|
781
|
-
await progressCallback?.('Reading task plan...', 1, 8);
|
|
782
|
-
const taskPlan = this.readTaskPlan();
|
|
783
|
-
|
|
784
|
-
if (!taskPlan) {
|
|
785
|
-
throw new Error(`Task plan not found: ${this.taskPlanPath}`);
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
// Step 2: Generate project scaffold
|
|
789
|
-
await this.generateScaffold(progressCallback);
|
|
790
|
-
|
|
791
|
-
await progressCallback?.('Phase 4 development initialized. Ready for coding!', 8, 8);
|
|
792
|
-
|
|
793
|
-
return {
|
|
794
|
-
projectId: this.projectId,
|
|
795
|
-
sourceDir: this.sourceDir,
|
|
796
|
-
tasksPath: path.join(this.phaseDir, 'TASKS.md'),
|
|
797
|
-
devLogPath: path.join(this.phaseDir, 'DEVELOPMENT_LOG.md'),
|
|
798
|
-
nextSteps: [
|
|
799
|
-
'Review the generated scaffold',
|
|
800
|
-
'Implement tasks according to TASK_PLAN.md',
|
|
801
|
-
'Write tests for each feature',
|
|
802
|
-
'Update task progress in TASKS.md',
|
|
803
|
-
'Validate when complete: smc workflow validate'
|
|
804
|
-
]
|
|
805
|
-
};
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
/**
|
|
809
|
-
* Check if source directory exists
|
|
810
|
-
*/
|
|
811
|
-
sourceExists() {
|
|
812
|
-
return fs.existsSync(this.sourceDir);
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
/**
|
|
816
|
-
* Get phase info
|
|
817
|
-
*/
|
|
818
|
-
getPhaseInfo() {
|
|
819
|
-
return {
|
|
820
|
-
phase: 4,
|
|
821
|
-
name: 'Development',
|
|
822
|
-
description: 'Execute implementation tasks',
|
|
823
|
-
input: 'Phase 3 Task Plan',
|
|
824
|
-
output: 'Source code, tests, documentation',
|
|
825
|
-
status: this.sourceExists() ? 'In Progress' : 'Not Started',
|
|
826
|
-
files: {
|
|
827
|
-
source: this.sourceDir,
|
|
828
|
-
tasks: path.join(this.phaseDir, 'TASKS.md'),
|
|
829
|
-
devLog: path.join(this.phaseDir, 'DEVELOPMENT_LOG.md'),
|
|
830
|
-
taskPlan: this.taskPlanPath,
|
|
831
|
-
prd: this.prdPath
|
|
832
|
-
}
|
|
833
|
-
};
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
// ============================================================================
|
|
838
|
-
// Project Management Helpers
|
|
839
|
-
// ============================================================================
|
|
840
|
-
|
|
841
|
-
function getAllProjectsWithPhases() {
|
|
842
|
-
if (!fs.existsSync(PROJECTS_DIR)) {
|
|
843
|
-
return [];
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
const projects = [];
|
|
847
|
-
const entries = fs.readdirSync(PROJECTS_DIR, { withFileTypes: true });
|
|
848
|
-
|
|
849
|
-
for (const entry of entries) {
|
|
850
|
-
if (entry.isDirectory() && entry.name.startsWith('proj_')) {
|
|
851
|
-
const projectPath = path.join(PROJECTS_DIR, entry.name);
|
|
852
|
-
const phase1Report = path.join(projectPath, 'phase1', 'feasibility-report.md');
|
|
853
|
-
const phase2Requirements = path.join(projectPath, 'phase2', 'requirements.md');
|
|
854
|
-
const phase3PRD = path.join(projectPath, 'phase3', 'PRD.md');
|
|
855
|
-
const phase4Source = path.join(projectPath, 'phase4', 'source');
|
|
856
|
-
|
|
857
|
-
let currentPhase = 1;
|
|
858
|
-
let status = 'draft';
|
|
859
|
-
|
|
860
|
-
if (fs.existsSync(phase4Source)) {
|
|
861
|
-
currentPhase = 4;
|
|
862
|
-
status = 'development';
|
|
863
|
-
} else if (fs.existsSync(phase3PRD)) {
|
|
864
|
-
currentPhase = 3;
|
|
865
|
-
status = 'planned';
|
|
866
|
-
} else if (fs.existsSync(phase2Requirements)) {
|
|
867
|
-
currentPhase = 2;
|
|
868
|
-
status = 'in_progress';
|
|
869
|
-
} else if (fs.existsSync(phase1Report)) {
|
|
870
|
-
currentPhase = 1;
|
|
871
|
-
status = 'review';
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
projects.push({
|
|
875
|
-
id: entry.name,
|
|
876
|
-
path: projectPath,
|
|
877
|
-
currentPhase,
|
|
878
|
-
status,
|
|
879
|
-
hasPhase1: fs.existsSync(phase1Report),
|
|
880
|
-
hasPhase2: fs.existsSync(phase2Requirements),
|
|
881
|
-
hasPhase3: fs.existsSync(phase3PRD),
|
|
882
|
-
hasPhase4: fs.existsSync(phase4Source)
|
|
883
|
-
});
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
return projects.sort((a, b) => b.id.localeCompare(a.id));
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
module.exports = {
|
|
891
|
-
Phase4DevelopmentExecutor,
|
|
892
|
-
DevelopmentValidator,
|
|
893
|
-
getAllProjectsWithPhases
|
|
894
|
-
};
|