@su-record/vibe 2.7.14 → 2.7.15
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/.env.example +37 -37
- package/CLAUDE.md +134 -126
- package/LICENSE +21 -21
- package/README.md +449 -449
- package/agents/architect-low.md +41 -41
- package/agents/architect-medium.md +59 -59
- package/agents/architect.md +80 -80
- package/agents/build-error-resolver.md +115 -115
- package/agents/compounder.md +261 -261
- package/agents/diagrammer.md +178 -178
- package/agents/docs/api-documenter.md +99 -99
- package/agents/docs/changelog-writer.md +93 -93
- package/agents/e2e-tester.md +294 -294
- package/agents/explorer-low.md +42 -42
- package/agents/explorer-medium.md +59 -59
- package/agents/explorer.md +48 -48
- package/agents/implementer-low.md +43 -43
- package/agents/implementer-medium.md +52 -52
- package/agents/implementer.md +54 -54
- package/agents/junior-mentor.md +141 -141
- package/agents/planning/requirements-analyst.md +84 -84
- package/agents/planning/ux-advisor.md +83 -83
- package/agents/qa/acceptance-tester.md +86 -86
- package/agents/qa/edge-case-finder.md +93 -93
- package/agents/refactor-cleaner.md +143 -143
- package/agents/research/best-practices-agent.md +199 -199
- package/agents/research/codebase-patterns-agent.md +157 -157
- package/agents/research/framework-docs-agent.md +188 -188
- package/agents/research/security-advisory-agent.md +213 -213
- package/agents/review/architecture-reviewer.md +107 -107
- package/agents/review/complexity-reviewer.md +116 -116
- package/agents/review/data-integrity-reviewer.md +88 -88
- package/agents/review/git-history-reviewer.md +103 -103
- package/agents/review/performance-reviewer.md +86 -86
- package/agents/review/python-reviewer.md +150 -150
- package/agents/review/rails-reviewer.md +139 -139
- package/agents/review/react-reviewer.md +144 -144
- package/agents/review/security-reviewer.md +80 -80
- package/agents/review/simplicity-reviewer.md +140 -140
- package/agents/review/test-coverage-reviewer.md +116 -116
- package/agents/review/typescript-reviewer.md +127 -127
- package/agents/searcher.md +54 -54
- package/agents/simplifier.md +120 -120
- package/agents/tester.md +49 -49
- package/agents/ui/ui-a11y-auditor.md +93 -93
- package/agents/ui/ui-antipattern-detector.md +94 -94
- package/agents/ui/ui-dataviz-advisor.md +69 -69
- package/agents/ui/ui-design-system-gen.md +57 -57
- package/agents/ui/ui-industry-analyzer.md +49 -49
- package/agents/ui/ui-layout-architect.md +65 -65
- package/agents/ui/ui-stack-implementer.md +68 -68
- package/agents/ui/ux-compliance-reviewer.md +81 -81
- package/agents/ui-previewer.md +258 -258
- package/commands/vibe.analyze.md +11 -13
- package/commands/vibe.review.md +43 -1
- package/commands/vibe.run.md +2124 -2078
- package/commands/vibe.spec.md +9 -4
- package/commands/vibe.spec.review.md +569 -565
- package/commands/vibe.utils.md +413 -413
- package/commands/vibe.verify.md +33 -8
- package/dist/cli/collaborator.js +52 -52
- package/dist/cli/commands/evolution.js +12 -12
- package/dist/cli/commands/info.js +54 -54
- package/dist/cli/commands/init.js +5 -5
- package/dist/cli/commands/remove.js +14 -14
- package/dist/cli/commands/sentinel.js +27 -27
- package/dist/cli/commands/skills.js +5 -5
- package/dist/cli/commands/slack.js +10 -10
- package/dist/cli/commands/telegram.js +12 -12
- package/dist/cli/detect.js +32 -32
- package/dist/cli/index.js +51 -51
- package/dist/cli/llm/claude-commands.js +16 -16
- package/dist/cli/llm/config.js +18 -18
- package/dist/cli/llm/gemini-commands.js +16 -16
- package/dist/cli/llm/gpt-commands.js +19 -19
- package/dist/cli/llm/help.js +21 -21
- package/dist/cli/postinstall/cursor-agents.js +32 -32
- package/dist/cli/postinstall/cursor-rules.js +83 -83
- package/dist/cli/postinstall/cursor-skills.js +743 -743
- package/dist/cli/setup/Provisioner.js +42 -42
- package/dist/infra/lib/DeepInit.js +24 -24
- package/dist/infra/lib/IterationTracker.js +11 -11
- package/dist/infra/lib/PythonParser.js +108 -108
- package/dist/infra/lib/ReviewRace.js +96 -96
- package/dist/infra/lib/SkillFrontmatter.js +28 -28
- package/dist/infra/lib/SkillQualityGate.js +9 -9
- package/dist/infra/lib/SkillRepository.js +159 -159
- package/dist/infra/lib/UltraQA.js +99 -99
- package/dist/infra/lib/autonomy/AuditStore.js +41 -41
- package/dist/infra/lib/autonomy/ConfirmationStore.js +30 -30
- package/dist/infra/lib/autonomy/EventOutbox.js +38 -38
- package/dist/infra/lib/autonomy/PolicyEngine.js +18 -18
- package/dist/infra/lib/autonomy/SecuritySentinel.js +1 -1
- package/dist/infra/lib/autonomy/SuggestionStore.js +33 -33
- package/dist/infra/lib/embedding/VectorStore.js +22 -22
- package/dist/infra/lib/evolution/AgentAnalyzer.js +10 -10
- package/dist/infra/lib/evolution/DescriptionOptimizer.js +21 -21
- package/dist/infra/lib/evolution/GenerationRegistry.js +36 -36
- package/dist/infra/lib/evolution/InsightStore.js +90 -90
- package/dist/infra/lib/evolution/RollbackManager.js +5 -5
- package/dist/infra/lib/evolution/SkillBenchmark.js +23 -23
- package/dist/infra/lib/evolution/SkillEvalRunner.js +50 -50
- package/dist/infra/lib/evolution/SkillGapDetector.js +10 -10
- package/dist/infra/lib/evolution/UsageTracker.js +28 -28
- package/dist/infra/lib/gemini/orchestration.js +5 -5
- package/dist/infra/lib/gpt/orchestration.js +4 -4
- package/dist/infra/lib/memory/KnowledgeGraph.js +4 -4
- package/dist/infra/lib/memory/MemorySearch.js +57 -57
- package/dist/infra/lib/memory/MemoryStorage.js +181 -181
- package/dist/infra/lib/memory/ObservationStore.js +28 -28
- package/dist/infra/lib/memory/ReflectionStore.js +30 -30
- package/dist/infra/lib/memory/SessionRAGRetriever.js +7 -7
- package/dist/infra/lib/memory/SessionRAGStore.js +225 -225
- package/dist/infra/lib/memory/SessionSummarizer.js +9 -9
- package/dist/infra/orchestrator/AgentManager.js +12 -12
- package/dist/infra/orchestrator/AgentRegistry.js +65 -65
- package/dist/infra/orchestrator/MultiLlmResearch.js +8 -8
- package/dist/infra/orchestrator/SwarmOrchestrator.test.js +16 -16
- package/dist/infra/orchestrator/parallelResearch.js +24 -24
- package/dist/tools/convention/analyzeComplexity.test.js +115 -115
- package/dist/tools/convention/validateCodeQuality.test.js +104 -104
- package/dist/tools/memory/createMemoryTimeline.js +10 -10
- package/dist/tools/memory/getMemoryGraph.js +12 -12
- package/dist/tools/memory/getSessionContext.js +9 -9
- package/dist/tools/memory/linkMemories.js +14 -14
- package/dist/tools/memory/listMemories.js +4 -4
- package/dist/tools/memory/recallMemory.js +4 -4
- package/dist/tools/memory/saveMemory.js +4 -4
- package/dist/tools/memory/searchMemoriesAdvanced.js +23 -23
- package/dist/tools/semantic/analyzeDependencyGraph.js +12 -12
- package/dist/tools/semantic/astGrep.test.js +6 -6
- package/dist/tools/spec/prdParser.test.js +171 -171
- package/dist/tools/spec/specGenerator.js +169 -169
- package/dist/tools/spec/traceabilityMatrix.js +64 -64
- package/dist/tools/spec/traceabilityMatrix.test.js +28 -28
- package/hooks/gemini-hooks.json +73 -73
- package/hooks/hooks.json +137 -137
- package/hooks/scripts/code-check.js +77 -70
- package/hooks/scripts/context-save.js +212 -212
- package/hooks/scripts/hud-status.js +291 -291
- package/hooks/scripts/keyword-detector.js +214 -214
- package/hooks/scripts/llm-orchestrate.js +475 -475
- package/hooks/scripts/post-edit.js +32 -32
- package/hooks/scripts/pre-tool-guard.js +125 -125
- package/hooks/scripts/prompt-dispatcher.js +185 -185
- package/hooks/scripts/sentinel-guard.js +104 -104
- package/hooks/scripts/session-start.js +106 -106
- package/hooks/scripts/stop-notify.js +209 -209
- package/hooks/scripts/utils.js +100 -100
- package/languages/csharp-unity.md +515 -515
- package/languages/gdscript-godot.md +470 -470
- package/languages/ruby-rails.md +489 -489
- package/languages/typescript-angular.md +433 -433
- package/languages/typescript-astro.md +416 -416
- package/languages/typescript-electron.md +406 -406
- package/languages/typescript-nestjs.md +524 -524
- package/languages/typescript-svelte.md +407 -407
- package/languages/typescript-tauri.md +365 -365
- package/package.json +121 -121
- package/skills/agents-md/SKILL.md +120 -120
- package/skills/arch-guard/SKILL.md +180 -180
- package/skills/brand-assets/SKILL.md +146 -146
- package/skills/capability-loop/SKILL.md +167 -167
- package/skills/characterization-test/SKILL.md +206 -206
- package/skills/commerce-patterns/SKILL.md +59 -59
- package/skills/commit-push-pr/SKILL.md +75 -75
- package/skills/context7-usage/SKILL.md +105 -105
- package/skills/core-capabilities/SKILL.md +48 -48
- package/skills/e2e-commerce/SKILL.md +57 -57
- package/skills/exec-plan/SKILL.md +147 -147
- package/skills/frontend-design/SKILL.md +73 -73
- package/skills/git-worktree/SKILL.md +72 -72
- package/skills/handoff/SKILL.md +109 -109
- package/skills/parallel-research/SKILL.md +87 -87
- package/skills/priority-todos/SKILL.md +63 -63
- package/skills/seo-checklist/SKILL.md +57 -57
- package/skills/techdebt/SKILL.md +122 -122
- package/skills/tool-fallback/SKILL.md +103 -103
- package/skills/typescript-advanced-types/SKILL.md +66 -66
- package/skills/ui-ux-pro-max/SKILL.md +206 -206
- package/skills/vercel-react-best-practices/SKILL.md +59 -59
- package/skills/video-production/SKILL.md +51 -51
- package/vibe/config.json +29 -29
- package/vibe/constitution.md +227 -227
- package/vibe/rules/principles/communication-guide.md +98 -98
- package/vibe/rules/principles/development-philosophy.md +52 -52
- package/vibe/rules/principles/quick-start.md +102 -102
- package/vibe/rules/quality/bdd-contract-testing.md +393 -393
- package/vibe/rules/quality/checklist.md +276 -276
- package/vibe/rules/quality/performance.md +236 -236
- package/vibe/rules/quality/testing-strategy.md +440 -440
- package/vibe/rules/standards/anti-patterns.md +541 -541
- package/vibe/rules/standards/code-structure.md +291 -291
- package/vibe/rules/standards/complexity-metrics.md +313 -313
- package/vibe/rules/standards/git-workflow.md +237 -237
- package/vibe/rules/standards/naming-conventions.md +198 -198
- package/vibe/rules/standards/security.md +305 -305
- package/vibe/rules/writing/document-style.md +74 -74
- package/vibe/setup.sh +31 -31
- package/vibe/templates/constitution-template.md +252 -252
- package/vibe/templates/contract-backend-template.md +526 -526
- package/vibe/templates/contract-frontend-template.md +599 -599
- package/vibe/templates/feature-template.md +96 -96
- package/vibe/templates/spec-template.md +221 -221
- package/vibe/ui-ux-data/charts.csv +26 -26
- package/vibe/ui-ux-data/colors.csv +97 -97
- package/vibe/ui-ux-data/icons.csv +101 -101
- package/vibe/ui-ux-data/landing.csv +31 -31
- package/vibe/ui-ux-data/products.csv +96 -96
- package/vibe/ui-ux-data/react-performance.csv +45 -45
- package/vibe/ui-ux-data/stacks/astro.csv +54 -54
- package/vibe/ui-ux-data/stacks/flutter.csv +53 -53
- package/vibe/ui-ux-data/stacks/html-tailwind.csv +56 -56
- package/vibe/ui-ux-data/stacks/jetpack-compose.csv +53 -53
- package/vibe/ui-ux-data/stacks/nextjs.csv +53 -53
- package/vibe/ui-ux-data/stacks/nuxt-ui.csv +51 -51
- package/vibe/ui-ux-data/stacks/nuxtjs.csv +59 -59
- package/vibe/ui-ux-data/stacks/react-native.csv +52 -52
- package/vibe/ui-ux-data/stacks/react.csv +54 -54
- package/vibe/ui-ux-data/stacks/shadcn.csv +61 -61
- package/vibe/ui-ux-data/stacks/svelte.csv +54 -54
- package/vibe/ui-ux-data/stacks/swiftui.csv +51 -51
- package/vibe/ui-ux-data/stacks/vue.csv +50 -50
- package/vibe/ui-ux-data/styles.csv +68 -68
- package/vibe/ui-ux-data/typography.csv +57 -57
- package/vibe/ui-ux-data/ui-reasoning.csv +101 -101
- package/vibe/ui-ux-data/ux-guidelines.csv +99 -99
- package/vibe/ui-ux-data/version.json +31 -31
- package/vibe/ui-ux-data/web-interface.csv +31 -31
|
@@ -71,45 +71,45 @@ function generateSplitSpec(prd, featureName, phases, options) {
|
|
|
71
71
|
function buildSpecContent(prd, featureName, phases, options) {
|
|
72
72
|
const { techStack = [], relatedCodePaths = [], designReference, additionalConstraints = [], additionalOutputs = [] } = options;
|
|
73
73
|
const now = new Date().toISOString();
|
|
74
|
-
let content = `---
|
|
75
|
-
status: pending
|
|
76
|
-
currentPhase: 0
|
|
77
|
-
totalPhases: ${phases.length}
|
|
78
|
-
createdAt: ${now}
|
|
79
|
-
lastUpdated: ${now}
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
# SPEC: ${featureName}
|
|
83
|
-
|
|
84
|
-
## Persona
|
|
85
|
-
<role>
|
|
86
|
-
Senior developer implementing ${featureName}.
|
|
87
|
-
- Follow existing code patterns and conventions
|
|
88
|
-
- Write testable, maintainable code
|
|
89
|
-
- Consider security and performance implications
|
|
90
|
-
</role>
|
|
91
|
-
|
|
92
|
-
## Context
|
|
93
|
-
<context>
|
|
94
|
-
### Background
|
|
95
|
-
${prd.description || `Implementation of ${prd.title}`}
|
|
96
|
-
|
|
97
|
-
### Tech Stack
|
|
98
|
-
${techStack.length > 0 ? techStack.map(t => `- ${t}`).join('\n') : '- (To be determined based on project)'}
|
|
99
|
-
|
|
100
|
-
### Related Code
|
|
101
|
-
${relatedCodePaths.length > 0 ? relatedCodePaths.map(p => `- \`${p}\``).join('\n') : '- (Analyze existing codebase for patterns)'}
|
|
102
|
-
|
|
103
|
-
### Design Reference
|
|
104
|
-
${designReference || '- (None specified)'}
|
|
105
|
-
|
|
106
|
-
### Requirements Source
|
|
107
|
-
- Parsed from PRD: ${prd.requirements.length} requirements
|
|
108
|
-
- Format: ${prd.metadata.format}
|
|
109
|
-
</context>
|
|
110
|
-
|
|
111
|
-
## Task
|
|
112
|
-
<task>
|
|
74
|
+
let content = `---
|
|
75
|
+
status: pending
|
|
76
|
+
currentPhase: 0
|
|
77
|
+
totalPhases: ${phases.length}
|
|
78
|
+
createdAt: ${now}
|
|
79
|
+
lastUpdated: ${now}
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
# SPEC: ${featureName}
|
|
83
|
+
|
|
84
|
+
## Persona
|
|
85
|
+
<role>
|
|
86
|
+
Senior developer implementing ${featureName}.
|
|
87
|
+
- Follow existing code patterns and conventions
|
|
88
|
+
- Write testable, maintainable code
|
|
89
|
+
- Consider security and performance implications
|
|
90
|
+
</role>
|
|
91
|
+
|
|
92
|
+
## Context
|
|
93
|
+
<context>
|
|
94
|
+
### Background
|
|
95
|
+
${prd.description || `Implementation of ${prd.title}`}
|
|
96
|
+
|
|
97
|
+
### Tech Stack
|
|
98
|
+
${techStack.length > 0 ? techStack.map(t => `- ${t}`).join('\n') : '- (To be determined based on project)'}
|
|
99
|
+
|
|
100
|
+
### Related Code
|
|
101
|
+
${relatedCodePaths.length > 0 ? relatedCodePaths.map(p => `- \`${p}\``).join('\n') : '- (Analyze existing codebase for patterns)'}
|
|
102
|
+
|
|
103
|
+
### Design Reference
|
|
104
|
+
${designReference || '- (None specified)'}
|
|
105
|
+
|
|
106
|
+
### Requirements Source
|
|
107
|
+
- Parsed from PRD: ${prd.requirements.length} requirements
|
|
108
|
+
- Format: ${prd.metadata.format}
|
|
109
|
+
</context>
|
|
110
|
+
|
|
111
|
+
## Task
|
|
112
|
+
<task>
|
|
113
113
|
`;
|
|
114
114
|
// Phase별 태스크 추가
|
|
115
115
|
for (let i = 0; i < phases.length; i++) {
|
|
@@ -121,47 +121,47 @@ ${designReference || '- (None specified)'}
|
|
|
121
121
|
}
|
|
122
122
|
content += '\n';
|
|
123
123
|
}
|
|
124
|
-
content += `</task>
|
|
125
|
-
|
|
126
|
-
## Constraints
|
|
127
|
-
<constraints>
|
|
128
|
-
### Must Follow
|
|
129
|
-
- Follow existing code patterns (ES Module, async/await)
|
|
130
|
-
- Maintain backward compatibility
|
|
131
|
-
- TypeScript strict mode compliance
|
|
132
|
-
- No \`any\` type → Use \`unknown\` + type guards
|
|
133
|
-
- Functions ≤30 lines recommended, ≤50 lines max
|
|
134
|
-
- Nesting ≤3 levels
|
|
135
|
-
|
|
136
|
-
### Error Handling
|
|
137
|
-
- Proper try-catch with meaningful error messages
|
|
138
|
-
- Loading state handling for async operations
|
|
139
|
-
- User-friendly error messages
|
|
140
|
-
|
|
141
|
-
### Security
|
|
142
|
-
- Input validation for all user inputs
|
|
143
|
-
- Authentication/authorization checks where needed
|
|
144
|
-
- No sensitive data in logs
|
|
145
|
-
${additionalConstraints.map(c => `\n- ${c}`).join('')}
|
|
146
|
-
</constraints>
|
|
147
|
-
|
|
148
|
-
## Output Format
|
|
149
|
-
<output_format>
|
|
150
|
-
### Files to Create
|
|
151
|
-
${generateFileList(phases, 'create')}
|
|
152
|
-
|
|
153
|
-
### Files to Modify
|
|
154
|
-
${generateFileList(phases, 'modify')}
|
|
155
|
-
|
|
156
|
-
### Verification Commands
|
|
157
|
-
- \`npm run build\` (build success)
|
|
158
|
-
- \`npm test\` (tests pass)
|
|
159
|
-
- \`tsc --noEmit\` (type check)
|
|
160
|
-
${additionalOutputs.map(o => `- ${o}`).join('\n')}
|
|
161
|
-
</output_format>
|
|
162
|
-
|
|
163
|
-
## Acceptance Criteria
|
|
164
|
-
<acceptance>
|
|
124
|
+
content += `</task>
|
|
125
|
+
|
|
126
|
+
## Constraints
|
|
127
|
+
<constraints>
|
|
128
|
+
### Must Follow
|
|
129
|
+
- Follow existing code patterns (ES Module, async/await)
|
|
130
|
+
- Maintain backward compatibility
|
|
131
|
+
- TypeScript strict mode compliance
|
|
132
|
+
- No \`any\` type → Use \`unknown\` + type guards
|
|
133
|
+
- Functions ≤30 lines recommended, ≤50 lines max
|
|
134
|
+
- Nesting ≤3 levels
|
|
135
|
+
|
|
136
|
+
### Error Handling
|
|
137
|
+
- Proper try-catch with meaningful error messages
|
|
138
|
+
- Loading state handling for async operations
|
|
139
|
+
- User-friendly error messages
|
|
140
|
+
|
|
141
|
+
### Security
|
|
142
|
+
- Input validation for all user inputs
|
|
143
|
+
- Authentication/authorization checks where needed
|
|
144
|
+
- No sensitive data in logs
|
|
145
|
+
${additionalConstraints.map(c => `\n- ${c}`).join('')}
|
|
146
|
+
</constraints>
|
|
147
|
+
|
|
148
|
+
## Output Format
|
|
149
|
+
<output_format>
|
|
150
|
+
### Files to Create
|
|
151
|
+
${generateFileList(phases, 'create')}
|
|
152
|
+
|
|
153
|
+
### Files to Modify
|
|
154
|
+
${generateFileList(phases, 'modify')}
|
|
155
|
+
|
|
156
|
+
### Verification Commands
|
|
157
|
+
- \`npm run build\` (build success)
|
|
158
|
+
- \`npm test\` (tests pass)
|
|
159
|
+
- \`tsc --noEmit\` (type check)
|
|
160
|
+
${additionalOutputs.map(o => `- ${o}`).join('\n')}
|
|
161
|
+
</output_format>
|
|
162
|
+
|
|
163
|
+
## Acceptance Criteria
|
|
164
|
+
<acceptance>
|
|
165
165
|
`;
|
|
166
166
|
// 요구사항별 AC 추가
|
|
167
167
|
for (const req of prd.requirements) {
|
|
@@ -176,11 +176,11 @@ ${additionalOutputs.map(o => `- ${o}`).join('\n')}
|
|
|
176
176
|
}
|
|
177
177
|
content += '\n';
|
|
178
178
|
}
|
|
179
|
-
content += `### Build & Test
|
|
180
|
-
- [ ] \`npm run build\` succeeds
|
|
181
|
-
- [ ] All tests pass
|
|
182
|
-
- [ ] No TypeScript errors
|
|
183
|
-
</acceptance>
|
|
179
|
+
content += `### Build & Test
|
|
180
|
+
- [ ] \`npm run build\` succeeds
|
|
181
|
+
- [ ] All tests pass
|
|
182
|
+
- [ ] No TypeScript errors
|
|
183
|
+
</acceptance>
|
|
184
184
|
`;
|
|
185
185
|
return content;
|
|
186
186
|
}
|
|
@@ -189,53 +189,53 @@ ${additionalOutputs.map(o => `- ${o}`).join('\n')}
|
|
|
189
189
|
*/
|
|
190
190
|
function buildMasterSpecContent(prd, featureName, phases, options) {
|
|
191
191
|
const now = new Date().toISOString();
|
|
192
|
-
let content = `---
|
|
193
|
-
status: pending
|
|
194
|
-
currentPhase: 0
|
|
195
|
-
totalPhases: ${phases.length}
|
|
196
|
-
createdAt: ${now}
|
|
197
|
-
lastUpdated: ${now}
|
|
198
|
-
isMaster: true
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
# SPEC: ${featureName} (Master)
|
|
202
|
-
|
|
203
|
-
## Overview
|
|
204
|
-
- **Feature**: ${prd.title}
|
|
205
|
-
- **Total Phases**: ${phases.length}
|
|
206
|
-
- **Total Requirements**: ${prd.requirements.length}
|
|
207
|
-
- **Format**: Split SPEC (large scope)
|
|
208
|
-
|
|
209
|
-
## Sub-SPECs
|
|
210
|
-
|
|
211
|
-
| Order | SPEC File | Description | Status |
|
|
212
|
-
|-------|-----------|-------------|--------|
|
|
192
|
+
let content = `---
|
|
193
|
+
status: pending
|
|
194
|
+
currentPhase: 0
|
|
195
|
+
totalPhases: ${phases.length}
|
|
196
|
+
createdAt: ${now}
|
|
197
|
+
lastUpdated: ${now}
|
|
198
|
+
isMaster: true
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
# SPEC: ${featureName} (Master)
|
|
202
|
+
|
|
203
|
+
## Overview
|
|
204
|
+
- **Feature**: ${prd.title}
|
|
205
|
+
- **Total Phases**: ${phases.length}
|
|
206
|
+
- **Total Requirements**: ${prd.requirements.length}
|
|
207
|
+
- **Format**: Split SPEC (large scope)
|
|
208
|
+
|
|
209
|
+
## Sub-SPECs
|
|
210
|
+
|
|
211
|
+
| Order | SPEC File | Description | Status |
|
|
212
|
+
|-------|-----------|-------------|--------|
|
|
213
213
|
`;
|
|
214
214
|
for (let i = 0; i < phases.length; i++) {
|
|
215
215
|
const phase = phases[i];
|
|
216
216
|
const fileName = `phase-${i + 1}-${normalizeFileName(phase.name)}.md`;
|
|
217
217
|
content += `| ${i + 1} | ${fileName} | ${phase.name} | ⬜ |\n`;
|
|
218
218
|
}
|
|
219
|
-
content += `
|
|
220
|
-
## Shared Context
|
|
221
|
-
|
|
222
|
-
### Tech Stack
|
|
223
|
-
${options.techStack?.map(t => `- ${t}`).join('\n') || '- (See project configuration)'}
|
|
224
|
-
|
|
225
|
-
### Constraints (Apply to All Phases)
|
|
226
|
-
- Follow existing code patterns
|
|
227
|
-
- TypeScript strict mode
|
|
228
|
-
- No \`any\` type
|
|
229
|
-
- Functions ≤50 lines max
|
|
230
|
-
${options.additionalConstraints?.map(c => `- ${c}`).join('\n') || ''}
|
|
231
|
-
|
|
232
|
-
## Execution Order
|
|
233
|
-
\`\`\`
|
|
234
|
-
${phases.map((p, i) => `Phase ${i + 1}: ${p.name}`).join(' → ')}
|
|
235
|
-
\`\`\`
|
|
236
|
-
|
|
237
|
-
## Dependencies
|
|
238
|
-
${generateDependencyList(phases)}
|
|
219
|
+
content += `
|
|
220
|
+
## Shared Context
|
|
221
|
+
|
|
222
|
+
### Tech Stack
|
|
223
|
+
${options.techStack?.map(t => `- ${t}`).join('\n') || '- (See project configuration)'}
|
|
224
|
+
|
|
225
|
+
### Constraints (Apply to All Phases)
|
|
226
|
+
- Follow existing code patterns
|
|
227
|
+
- TypeScript strict mode
|
|
228
|
+
- No \`any\` type
|
|
229
|
+
- Functions ≤50 lines max
|
|
230
|
+
${options.additionalConstraints?.map(c => `- ${c}`).join('\n') || ''}
|
|
231
|
+
|
|
232
|
+
## Execution Order
|
|
233
|
+
\`\`\`
|
|
234
|
+
${phases.map((p, i) => `Phase ${i + 1}: ${p.name}`).join(' → ')}
|
|
235
|
+
\`\`\`
|
|
236
|
+
|
|
237
|
+
## Dependencies
|
|
238
|
+
${generateDependencyList(phases)}
|
|
239
239
|
`;
|
|
240
240
|
return content;
|
|
241
241
|
}
|
|
@@ -244,54 +244,54 @@ ${generateDependencyList(phases)}
|
|
|
244
244
|
*/
|
|
245
245
|
function buildPhaseSpecContent(prd, featureName, phase, phaseNumber, totalPhases, options) {
|
|
246
246
|
const now = new Date().toISOString();
|
|
247
|
-
let content = `---
|
|
248
|
-
status: pending
|
|
249
|
-
phase: ${phaseNumber}
|
|
250
|
-
totalPhases: ${totalPhases}
|
|
251
|
-
masterSpec: _index.md
|
|
252
|
-
createdAt: ${now}
|
|
253
|
-
lastUpdated: ${now}
|
|
254
|
-
---
|
|
255
|
-
|
|
256
|
-
# SPEC: ${featureName} - Phase ${phaseNumber}: ${phase.name}
|
|
257
|
-
|
|
258
|
-
## Persona
|
|
259
|
-
<role>
|
|
260
|
-
Developer implementing Phase ${phaseNumber} of ${featureName}.
|
|
261
|
-
- Focus on ${phase.name}
|
|
262
|
-
- Follow project conventions
|
|
263
|
-
- Write testable code
|
|
264
|
-
</role>
|
|
265
|
-
|
|
266
|
-
## Context
|
|
267
|
-
<context>
|
|
268
|
-
### Phase Goal
|
|
269
|
-
${getPhaseGoal(phase)}
|
|
270
|
-
|
|
271
|
-
### Requirements (${phase.requirements.length})
|
|
272
|
-
${phase.requirements.map(r => `- ${r.id}: ${truncateText(r.description, 50)}`).join('\n')}
|
|
273
|
-
|
|
274
|
-
### Dependencies
|
|
275
|
-
${phaseNumber > 1 ? `- Requires Phase ${phaseNumber - 1} completion` : '- No dependencies (first phase)'}
|
|
276
|
-
</context>
|
|
277
|
-
|
|
278
|
-
## Task
|
|
279
|
-
<task>
|
|
247
|
+
let content = `---
|
|
248
|
+
status: pending
|
|
249
|
+
phase: ${phaseNumber}
|
|
250
|
+
totalPhases: ${totalPhases}
|
|
251
|
+
masterSpec: _index.md
|
|
252
|
+
createdAt: ${now}
|
|
253
|
+
lastUpdated: ${now}
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
# SPEC: ${featureName} - Phase ${phaseNumber}: ${phase.name}
|
|
257
|
+
|
|
258
|
+
## Persona
|
|
259
|
+
<role>
|
|
260
|
+
Developer implementing Phase ${phaseNumber} of ${featureName}.
|
|
261
|
+
- Focus on ${phase.name}
|
|
262
|
+
- Follow project conventions
|
|
263
|
+
- Write testable code
|
|
264
|
+
</role>
|
|
265
|
+
|
|
266
|
+
## Context
|
|
267
|
+
<context>
|
|
268
|
+
### Phase Goal
|
|
269
|
+
${getPhaseGoal(phase)}
|
|
270
|
+
|
|
271
|
+
### Requirements (${phase.requirements.length})
|
|
272
|
+
${phase.requirements.map(r => `- ${r.id}: ${truncateText(r.description, 50)}`).join('\n')}
|
|
273
|
+
|
|
274
|
+
### Dependencies
|
|
275
|
+
${phaseNumber > 1 ? `- Requires Phase ${phaseNumber - 1} completion` : '- No dependencies (first phase)'}
|
|
276
|
+
</context>
|
|
277
|
+
|
|
278
|
+
## Task
|
|
279
|
+
<task>
|
|
280
280
|
`;
|
|
281
281
|
for (const task of phase.tasks) {
|
|
282
282
|
content += `1. [ ] ${task}\n`;
|
|
283
283
|
}
|
|
284
|
-
content += `</task>
|
|
285
|
-
|
|
286
|
-
## Acceptance Criteria
|
|
287
|
-
<acceptance>
|
|
284
|
+
content += `</task>
|
|
285
|
+
|
|
286
|
+
## Acceptance Criteria
|
|
287
|
+
<acceptance>
|
|
288
288
|
`;
|
|
289
289
|
for (const req of phase.requirements) {
|
|
290
290
|
content += `- [ ] ${req.id}: ${truncateText(req.description, 60)}\n`;
|
|
291
291
|
}
|
|
292
|
-
content += `- [ ] Phase ${phaseNumber} build succeeds
|
|
293
|
-
- [ ] Phase ${phaseNumber} tests pass
|
|
294
|
-
</acceptance>
|
|
292
|
+
content += `- [ ] Phase ${phaseNumber} build succeeds
|
|
293
|
+
- [ ] Phase ${phaseNumber} tests pass
|
|
294
|
+
</acceptance>
|
|
295
295
|
`;
|
|
296
296
|
return content;
|
|
297
297
|
}
|
|
@@ -384,11 +384,11 @@ function getPhaseGoal(phase) {
|
|
|
384
384
|
function generateFileList(phases, type) {
|
|
385
385
|
// 실제로는 요구사항을 분석해서 추론해야 하지만, 기본 템플릿 제공
|
|
386
386
|
if (type === 'create') {
|
|
387
|
-
return `- (To be determined based on implementation)
|
|
388
|
-
- \`src/[feature]/index.ts\`
|
|
387
|
+
return `- (To be determined based on implementation)
|
|
388
|
+
- \`src/[feature]/index.ts\`
|
|
389
389
|
- \`src/[feature]/[feature].test.ts\``;
|
|
390
390
|
}
|
|
391
|
-
return `- (Analyze existing codebase)
|
|
391
|
+
return `- (Analyze existing codebase)
|
|
392
392
|
- Relevant existing files`;
|
|
393
393
|
}
|
|
394
394
|
/**
|
|
@@ -116,74 +116,74 @@ export function formatMatrixAsMarkdown(matrix) {
|
|
|
116
116
|
* 매트릭스를 HTML로 출력
|
|
117
117
|
*/
|
|
118
118
|
export function formatMatrixAsHtml(matrix) {
|
|
119
|
-
let html = `<!DOCTYPE html>
|
|
120
|
-
<html>
|
|
121
|
-
<head>
|
|
122
|
-
<title>RTM: ${matrix.featureName}</title>
|
|
123
|
-
<style>
|
|
124
|
-
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; margin: 2rem; }
|
|
125
|
-
table { border-collapse: collapse; width: 100%; }
|
|
126
|
-
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
127
|
-
th { background: #f5f5f5; }
|
|
128
|
-
.full { background: #d4edda; }
|
|
129
|
-
.partial { background: #fff3cd; }
|
|
130
|
-
.none { background: #f8d7da; }
|
|
131
|
-
.summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin: 1rem 0; }
|
|
132
|
-
.summary-card { padding: 1rem; border-radius: 8px; background: #f5f5f5; }
|
|
133
|
-
.coverage-bar { height: 20px; background: #e0e0e0; border-radius: 4px; overflow: hidden; }
|
|
134
|
-
.coverage-fill { height: 100%; background: #4caf50; }
|
|
135
|
-
</style>
|
|
136
|
-
</head>
|
|
137
|
-
<body>
|
|
138
|
-
<h1>RTM: ${matrix.featureName}</h1>
|
|
139
|
-
<p>Generated: ${matrix.generatedAt}</p>
|
|
140
|
-
|
|
141
|
-
<div class="summary">
|
|
142
|
-
<div class="summary-card">
|
|
143
|
-
<strong>Requirements</strong><br>${matrix.summary.totalRequirements}
|
|
144
|
-
</div>
|
|
145
|
-
<div class="summary-card">
|
|
146
|
-
<strong>Feature Coverage</strong><br>${matrix.summary.featureCovered}/${matrix.summary.totalRequirements}
|
|
147
|
-
</div>
|
|
148
|
-
<div class="summary-card">
|
|
149
|
-
<strong>Test Coverage</strong><br>${matrix.summary.testCovered}/${matrix.summary.totalRequirements}
|
|
150
|
-
</div>
|
|
151
|
-
<div class="summary-card">
|
|
152
|
-
<strong>Overall</strong><br>
|
|
153
|
-
<div class="coverage-bar">
|
|
154
|
-
<div class="coverage-fill" style="width: ${matrix.summary.coveragePercent}%"></div>
|
|
155
|
-
</div>
|
|
156
|
-
${matrix.summary.coveragePercent}%
|
|
157
|
-
</div>
|
|
158
|
-
</div>
|
|
159
|
-
|
|
160
|
-
<table>
|
|
161
|
-
<thead>
|
|
162
|
-
<tr>
|
|
163
|
-
<th>Requirement</th>
|
|
164
|
-
<th>Description</th>
|
|
165
|
-
<th>SPEC</th>
|
|
166
|
-
<th>Feature</th>
|
|
167
|
-
<th>Test</th>
|
|
168
|
-
<th>Coverage</th>
|
|
169
|
-
</tr>
|
|
170
|
-
</thead>
|
|
171
|
-
<tbody>
|
|
119
|
+
let html = `<!DOCTYPE html>
|
|
120
|
+
<html>
|
|
121
|
+
<head>
|
|
122
|
+
<title>RTM: ${matrix.featureName}</title>
|
|
123
|
+
<style>
|
|
124
|
+
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; margin: 2rem; }
|
|
125
|
+
table { border-collapse: collapse; width: 100%; }
|
|
126
|
+
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
127
|
+
th { background: #f5f5f5; }
|
|
128
|
+
.full { background: #d4edda; }
|
|
129
|
+
.partial { background: #fff3cd; }
|
|
130
|
+
.none { background: #f8d7da; }
|
|
131
|
+
.summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin: 1rem 0; }
|
|
132
|
+
.summary-card { padding: 1rem; border-radius: 8px; background: #f5f5f5; }
|
|
133
|
+
.coverage-bar { height: 20px; background: #e0e0e0; border-radius: 4px; overflow: hidden; }
|
|
134
|
+
.coverage-fill { height: 100%; background: #4caf50; }
|
|
135
|
+
</style>
|
|
136
|
+
</head>
|
|
137
|
+
<body>
|
|
138
|
+
<h1>RTM: ${matrix.featureName}</h1>
|
|
139
|
+
<p>Generated: ${matrix.generatedAt}</p>
|
|
140
|
+
|
|
141
|
+
<div class="summary">
|
|
142
|
+
<div class="summary-card">
|
|
143
|
+
<strong>Requirements</strong><br>${matrix.summary.totalRequirements}
|
|
144
|
+
</div>
|
|
145
|
+
<div class="summary-card">
|
|
146
|
+
<strong>Feature Coverage</strong><br>${matrix.summary.featureCovered}/${matrix.summary.totalRequirements}
|
|
147
|
+
</div>
|
|
148
|
+
<div class="summary-card">
|
|
149
|
+
<strong>Test Coverage</strong><br>${matrix.summary.testCovered}/${matrix.summary.totalRequirements}
|
|
150
|
+
</div>
|
|
151
|
+
<div class="summary-card">
|
|
152
|
+
<strong>Overall</strong><br>
|
|
153
|
+
<div class="coverage-bar">
|
|
154
|
+
<div class="coverage-fill" style="width: ${matrix.summary.coveragePercent}%"></div>
|
|
155
|
+
</div>
|
|
156
|
+
${matrix.summary.coveragePercent}%
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<table>
|
|
161
|
+
<thead>
|
|
162
|
+
<tr>
|
|
163
|
+
<th>Requirement</th>
|
|
164
|
+
<th>Description</th>
|
|
165
|
+
<th>SPEC</th>
|
|
166
|
+
<th>Feature</th>
|
|
167
|
+
<th>Test</th>
|
|
168
|
+
<th>Coverage</th>
|
|
169
|
+
</tr>
|
|
170
|
+
</thead>
|
|
171
|
+
<tbody>
|
|
172
172
|
`;
|
|
173
173
|
for (const item of matrix.items) {
|
|
174
|
-
html += ` <tr class="${item.coverage}">
|
|
175
|
-
<td>${item.requirementId}</td>
|
|
176
|
-
<td>${escapeHtml(truncate(item.requirementDesc, 50))}</td>
|
|
177
|
-
<td>${item.specSection ? '✅' : '❌'}</td>
|
|
178
|
-
<td>${item.featureScenario ? '✅' : '❌'}</td>
|
|
179
|
-
<td>${item.testName ? '✅' : '❌'}</td>
|
|
180
|
-
<td>${getCoverageIcon(item.coverage)}</td>
|
|
181
|
-
</tr>
|
|
174
|
+
html += ` <tr class="${item.coverage}">
|
|
175
|
+
<td>${item.requirementId}</td>
|
|
176
|
+
<td>${escapeHtml(truncate(item.requirementDesc, 50))}</td>
|
|
177
|
+
<td>${item.specSection ? '✅' : '❌'}</td>
|
|
178
|
+
<td>${item.featureScenario ? '✅' : '❌'}</td>
|
|
179
|
+
<td>${item.testName ? '✅' : '❌'}</td>
|
|
180
|
+
<td>${getCoverageIcon(item.coverage)}</td>
|
|
181
|
+
</tr>
|
|
182
182
|
`;
|
|
183
183
|
}
|
|
184
|
-
html += ` </tbody>
|
|
185
|
-
</table>
|
|
186
|
-
</body>
|
|
184
|
+
html += ` </tbody>
|
|
185
|
+
</table>
|
|
186
|
+
</body>
|
|
187
187
|
</html>`;
|
|
188
188
|
return html;
|
|
189
189
|
}
|
|
@@ -8,37 +8,37 @@ import { generateTraceabilityMatrix, formatMatrixAsMarkdown, formatMatrixAsHtml,
|
|
|
8
8
|
vi.mock('fs', () => ({
|
|
9
9
|
readFileSync: vi.fn((path) => {
|
|
10
10
|
if (path.includes('test-feature.md')) {
|
|
11
|
-
return `# SPEC: test-feature
|
|
12
|
-
|
|
13
|
-
## Task
|
|
14
|
-
|
|
15
|
-
### Phase 1: Setup
|
|
16
|
-
|
|
17
|
-
1. [ ] REQ-test-001: Setup authentication
|
|
18
|
-
2. [ ] REQ-test-002: Create login form
|
|
19
|
-
3. [ ] REQ-test-003: Implement validation
|
|
11
|
+
return `# SPEC: test-feature
|
|
12
|
+
|
|
13
|
+
## Task
|
|
14
|
+
|
|
15
|
+
### Phase 1: Setup
|
|
16
|
+
|
|
17
|
+
1. [ ] REQ-test-001: Setup authentication
|
|
18
|
+
2. [ ] REQ-test-002: Create login form
|
|
19
|
+
3. [ ] REQ-test-003: Implement validation
|
|
20
20
|
`;
|
|
21
21
|
}
|
|
22
22
|
if (path.includes('test-feature.feature')) {
|
|
23
|
-
return `# Feature: test-feature
|
|
24
|
-
|
|
25
|
-
## Scenarios
|
|
26
|
-
|
|
27
|
-
### Scenario 1: User can login
|
|
28
|
-
\`\`\`gherkin
|
|
29
|
-
Given user is on login page
|
|
30
|
-
When user enters valid credentials
|
|
31
|
-
Then user is logged in
|
|
32
|
-
\`\`\`
|
|
33
|
-
**Verification**: REQ-test-001
|
|
34
|
-
|
|
35
|
-
### Scenario 2: Validation errors
|
|
36
|
-
\`\`\`gherkin
|
|
37
|
-
Given user is on login page
|
|
38
|
-
When user enters invalid email
|
|
39
|
-
Then error message is shown
|
|
40
|
-
\`\`\`
|
|
41
|
-
**Verification**: REQ-test-003
|
|
23
|
+
return `# Feature: test-feature
|
|
24
|
+
|
|
25
|
+
## Scenarios
|
|
26
|
+
|
|
27
|
+
### Scenario 1: User can login
|
|
28
|
+
\`\`\`gherkin
|
|
29
|
+
Given user is on login page
|
|
30
|
+
When user enters valid credentials
|
|
31
|
+
Then user is logged in
|
|
32
|
+
\`\`\`
|
|
33
|
+
**Verification**: REQ-test-001
|
|
34
|
+
|
|
35
|
+
### Scenario 2: Validation errors
|
|
36
|
+
\`\`\`gherkin
|
|
37
|
+
Given user is on login page
|
|
38
|
+
When user enters invalid email
|
|
39
|
+
Then error message is shown
|
|
40
|
+
\`\`\`
|
|
41
|
+
**Verification**: REQ-test-003
|
|
42
42
|
`;
|
|
43
43
|
}
|
|
44
44
|
throw new Error(`File not found: ${path}`);
|