@su-record/vibe 2.7.14 → 2.7.16
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.d.ts.map +1 -1
- package/dist/cli/commands/info.js +51 -55
- package/dist/cli/commands/info.js.map +1 -1
- 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/constants.d.ts.map +1 -1
- package/dist/cli/postinstall/constants.js +7 -8
- package/dist/cli/postinstall/constants.js.map +1 -1
- 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 +63 -59
- package/skills/commit-push-pr/SKILL.md +75 -75
- package/skills/context7-usage/SKILL.md +105 -105
- package/skills/core-capabilities/SKILL.md +13 -48
- package/skills/e2e-commerce/SKILL.md +61 -57
- package/skills/exec-plan/SKILL.md +147 -147
- package/skills/frontend-design/SKILL.md +12 -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 +221 -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
|
@@ -12,20 +12,20 @@ describe('PRD Parser', () => {
|
|
|
12
12
|
});
|
|
13
13
|
describe('parsePRD()', () => {
|
|
14
14
|
it('should parse basic markdown PRD', () => {
|
|
15
|
-
const content = `# Login Feature
|
|
16
|
-
|
|
17
|
-
A user authentication feature.
|
|
18
|
-
|
|
19
|
-
## Requirements
|
|
20
|
-
|
|
21
|
-
- User must be able to login with email and password
|
|
22
|
-
- User must be able to reset password
|
|
23
|
-
- User must be able to logout
|
|
24
|
-
|
|
25
|
-
## Acceptance Criteria
|
|
26
|
-
|
|
27
|
-
- Login form validates email format
|
|
28
|
-
- Password must be at least 8 characters
|
|
15
|
+
const content = `# Login Feature
|
|
16
|
+
|
|
17
|
+
A user authentication feature.
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
- User must be able to login with email and password
|
|
22
|
+
- User must be able to reset password
|
|
23
|
+
- User must be able to logout
|
|
24
|
+
|
|
25
|
+
## Acceptance Criteria
|
|
26
|
+
|
|
27
|
+
- Login form validates email format
|
|
28
|
+
- Password must be at least 8 characters
|
|
29
29
|
`;
|
|
30
30
|
const result = parsePRD(content, 'login');
|
|
31
31
|
expect(result.title).toBe('Login Feature');
|
|
@@ -34,33 +34,33 @@ A user authentication feature.
|
|
|
34
34
|
expect(result.metadata.hasYamlFrontmatter).toBe(false);
|
|
35
35
|
});
|
|
36
36
|
it('should extract title from first heading', () => {
|
|
37
|
-
const content = `# My Feature Title
|
|
38
|
-
|
|
39
|
-
Some description here.
|
|
37
|
+
const content = `# My Feature Title
|
|
38
|
+
|
|
39
|
+
Some description here.
|
|
40
40
|
`;
|
|
41
41
|
const result = parsePRD(content, 'feature');
|
|
42
42
|
expect(result.title).toBe('My Feature Title');
|
|
43
43
|
});
|
|
44
44
|
it('should extract description', () => {
|
|
45
|
-
const content = `# Feature
|
|
46
|
-
|
|
47
|
-
This is the feature description.
|
|
48
|
-
It spans multiple lines.
|
|
49
|
-
|
|
50
|
-
## Requirements
|
|
51
|
-
|
|
52
|
-
- Requirement 1
|
|
45
|
+
const content = `# Feature
|
|
46
|
+
|
|
47
|
+
This is the feature description.
|
|
48
|
+
It spans multiple lines.
|
|
49
|
+
|
|
50
|
+
## Requirements
|
|
51
|
+
|
|
52
|
+
- Requirement 1
|
|
53
53
|
`;
|
|
54
54
|
const result = parsePRD(content, 'feature');
|
|
55
55
|
expect(result.description).toContain('feature description');
|
|
56
56
|
});
|
|
57
57
|
it('should assign requirement IDs', () => {
|
|
58
|
-
const content = `# Feature
|
|
59
|
-
|
|
60
|
-
## Requirements
|
|
61
|
-
|
|
62
|
-
- First requirement
|
|
63
|
-
- Second requirement
|
|
58
|
+
const content = `# Feature
|
|
59
|
+
|
|
60
|
+
## Requirements
|
|
61
|
+
|
|
62
|
+
- First requirement
|
|
63
|
+
- Second requirement
|
|
64
64
|
`;
|
|
65
65
|
const result = parsePRD(content, 'test');
|
|
66
66
|
expect(result.requirements[0].id).toMatch(/^REQ-test-\d{3}$/);
|
|
@@ -70,30 +70,30 @@ It spans multiple lines.
|
|
|
70
70
|
});
|
|
71
71
|
describe('YAML frontmatter parsing', () => {
|
|
72
72
|
it('should parse YAML frontmatter', () => {
|
|
73
|
-
const content = `---
|
|
74
|
-
title: YAML Feature
|
|
75
|
-
version: 1.0.0
|
|
76
|
-
requirements:
|
|
77
|
-
- First YAML requirement
|
|
78
|
-
- Second YAML requirement
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
# YAML Feature
|
|
82
|
-
|
|
83
|
-
Content here.
|
|
73
|
+
const content = `---
|
|
74
|
+
title: YAML Feature
|
|
75
|
+
version: 1.0.0
|
|
76
|
+
requirements:
|
|
77
|
+
- First YAML requirement
|
|
78
|
+
- Second YAML requirement
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
# YAML Feature
|
|
82
|
+
|
|
83
|
+
Content here.
|
|
84
84
|
`;
|
|
85
85
|
const result = parsePRD(content, 'yaml-feature');
|
|
86
86
|
expect(result.metadata.hasYamlFrontmatter).toBe(true);
|
|
87
87
|
expect(result.metadata.format).toBe('mixed');
|
|
88
88
|
});
|
|
89
89
|
it('should extract requirements from YAML', () => {
|
|
90
|
-
const content = `---
|
|
91
|
-
requirements:
|
|
92
|
-
- YAML requirement one
|
|
93
|
-
- YAML requirement two
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
# Feature
|
|
90
|
+
const content = `---
|
|
91
|
+
requirements:
|
|
92
|
+
- YAML requirement one
|
|
93
|
+
- YAML requirement two
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
# Feature
|
|
97
97
|
`;
|
|
98
98
|
const result = parsePRD(content, 'yaml');
|
|
99
99
|
const yamlReqs = result.requirements.filter(r => r.source === 'YAML frontmatter');
|
|
@@ -102,42 +102,42 @@ requirements:
|
|
|
102
102
|
});
|
|
103
103
|
describe('Priority inference', () => {
|
|
104
104
|
it('should infer high priority from "must"', () => {
|
|
105
|
-
const content = `# Feature
|
|
106
|
-
|
|
107
|
-
## Requirements
|
|
108
|
-
|
|
109
|
-
- User must be authenticated
|
|
105
|
+
const content = `# Feature
|
|
106
|
+
|
|
107
|
+
## Requirements
|
|
108
|
+
|
|
109
|
+
- User must be authenticated
|
|
110
110
|
`;
|
|
111
111
|
const result = parsePRD(content, 'priority');
|
|
112
112
|
const req = result.requirements.find(r => r.description.includes('must'));
|
|
113
113
|
expect(req?.priority).toBe('high');
|
|
114
114
|
});
|
|
115
115
|
it('should infer high priority from "critical"', () => {
|
|
116
|
-
const content = `# Feature
|
|
117
|
-
|
|
118
|
-
## Requirements
|
|
119
|
-
|
|
120
|
-
- Critical security feature required
|
|
116
|
+
const content = `# Feature
|
|
117
|
+
|
|
118
|
+
## Requirements
|
|
119
|
+
|
|
120
|
+
- Critical security feature required
|
|
121
121
|
`;
|
|
122
122
|
const result = parsePRD(content, 'priority');
|
|
123
123
|
expect(result.requirements[0].priority).toBe('high');
|
|
124
124
|
});
|
|
125
125
|
it('should infer low priority from "nice to have"', () => {
|
|
126
|
-
const content = `# Feature
|
|
127
|
-
|
|
128
|
-
## Requirements
|
|
129
|
-
|
|
130
|
-
- Nice to have dark mode support
|
|
126
|
+
const content = `# Feature
|
|
127
|
+
|
|
128
|
+
## Requirements
|
|
129
|
+
|
|
130
|
+
- Nice to have dark mode support
|
|
131
131
|
`;
|
|
132
132
|
const result = parsePRD(content, 'priority');
|
|
133
133
|
expect(result.requirements[0].priority).toBe('low');
|
|
134
134
|
});
|
|
135
135
|
it('should default to medium priority', () => {
|
|
136
|
-
const content = `# Feature
|
|
137
|
-
|
|
138
|
-
## Requirements
|
|
139
|
-
|
|
140
|
-
- Regular feature without priority keywords
|
|
136
|
+
const content = `# Feature
|
|
137
|
+
|
|
138
|
+
## Requirements
|
|
139
|
+
|
|
140
|
+
- Regular feature without priority keywords
|
|
141
141
|
`;
|
|
142
142
|
const result = parsePRD(content, 'priority');
|
|
143
143
|
expect(result.requirements[0].priority).toBe('medium');
|
|
@@ -145,42 +145,42 @@ requirements:
|
|
|
145
145
|
});
|
|
146
146
|
describe('Section extraction', () => {
|
|
147
147
|
it('should extract from Requirements section', () => {
|
|
148
|
-
const content = `# Feature
|
|
149
|
-
|
|
150
|
-
## Overview
|
|
151
|
-
|
|
152
|
-
Some overview text.
|
|
153
|
-
|
|
154
|
-
## Requirements
|
|
155
|
-
|
|
156
|
-
- Requirement from requirements section
|
|
157
|
-
|
|
158
|
-
## Other Section
|
|
159
|
-
|
|
160
|
-
Other content.
|
|
148
|
+
const content = `# Feature
|
|
149
|
+
|
|
150
|
+
## Overview
|
|
151
|
+
|
|
152
|
+
Some overview text.
|
|
153
|
+
|
|
154
|
+
## Requirements
|
|
155
|
+
|
|
156
|
+
- Requirement from requirements section
|
|
157
|
+
|
|
158
|
+
## Other Section
|
|
159
|
+
|
|
160
|
+
Other content.
|
|
161
161
|
`;
|
|
162
162
|
const result = parsePRD(content, 'section');
|
|
163
163
|
const fromReqs = result.requirements.filter(r => r.source?.includes('Requirements'));
|
|
164
164
|
expect(fromReqs.length).toBeGreaterThan(0);
|
|
165
165
|
});
|
|
166
166
|
it('should extract from User Stories section', () => {
|
|
167
|
-
const content = `# Feature
|
|
168
|
-
|
|
169
|
-
## User Stories
|
|
170
|
-
|
|
171
|
-
As a user, I want to login so that I can access my account.
|
|
167
|
+
const content = `# Feature
|
|
168
|
+
|
|
169
|
+
## User Stories
|
|
170
|
+
|
|
171
|
+
As a user, I want to login so that I can access my account.
|
|
172
172
|
`;
|
|
173
173
|
const result = parsePRD(content, 'story');
|
|
174
174
|
const fromStories = result.requirements.filter(r => r.source?.includes('User Stories'));
|
|
175
175
|
expect(fromStories.length).toBe(1);
|
|
176
176
|
});
|
|
177
177
|
it('should handle Korean section names', () => {
|
|
178
|
-
const content = `# 기능
|
|
179
|
-
|
|
180
|
-
## 요구사항
|
|
181
|
-
|
|
182
|
-
- 한글 요구사항 1
|
|
183
|
-
- 한글 요구사항 2
|
|
178
|
+
const content = `# 기능
|
|
179
|
+
|
|
180
|
+
## 요구사항
|
|
181
|
+
|
|
182
|
+
- 한글 요구사항 1
|
|
183
|
+
- 한글 요구사항 2
|
|
184
184
|
`;
|
|
185
185
|
const result = parsePRD(content, 'korean');
|
|
186
186
|
expect(result.requirements.length).toBe(2);
|
|
@@ -188,47 +188,47 @@ As a user, I want to login so that I can access my account.
|
|
|
188
188
|
});
|
|
189
189
|
describe('List parsing', () => {
|
|
190
190
|
it('should parse bullet lists with -', () => {
|
|
191
|
-
const content = `# Feature
|
|
192
|
-
|
|
193
|
-
## Requirements
|
|
194
|
-
|
|
195
|
-
- Item one
|
|
196
|
-
- Item two
|
|
197
|
-
- Item three
|
|
191
|
+
const content = `# Feature
|
|
192
|
+
|
|
193
|
+
## Requirements
|
|
194
|
+
|
|
195
|
+
- Item one
|
|
196
|
+
- Item two
|
|
197
|
+
- Item three
|
|
198
198
|
`;
|
|
199
199
|
const result = parsePRD(content, 'bullet');
|
|
200
200
|
expect(result.requirements.length).toBe(3);
|
|
201
201
|
});
|
|
202
202
|
it('should parse bullet lists with *', () => {
|
|
203
|
-
const content = `# Feature
|
|
204
|
-
|
|
205
|
-
## Requirements
|
|
206
|
-
|
|
207
|
-
* Star item one
|
|
208
|
-
* Star item two
|
|
203
|
+
const content = `# Feature
|
|
204
|
+
|
|
205
|
+
## Requirements
|
|
206
|
+
|
|
207
|
+
* Star item one
|
|
208
|
+
* Star item two
|
|
209
209
|
`;
|
|
210
210
|
const result = parsePRD(content, 'star');
|
|
211
211
|
expect(result.requirements.length).toBe(2);
|
|
212
212
|
});
|
|
213
213
|
it('should parse numbered lists', () => {
|
|
214
|
-
const content = `# Feature
|
|
215
|
-
|
|
216
|
-
## Requirements
|
|
217
|
-
|
|
218
|
-
1. First item
|
|
219
|
-
2. Second item
|
|
220
|
-
3. Third item
|
|
214
|
+
const content = `# Feature
|
|
215
|
+
|
|
216
|
+
## Requirements
|
|
217
|
+
|
|
218
|
+
1. First item
|
|
219
|
+
2. Second item
|
|
220
|
+
3. Third item
|
|
221
221
|
`;
|
|
222
222
|
const result = parsePRD(content, 'numbered');
|
|
223
223
|
expect(result.requirements.length).toBe(3);
|
|
224
224
|
});
|
|
225
225
|
it('should parse numbered lists with parentheses', () => {
|
|
226
|
-
const content = `# Feature
|
|
227
|
-
|
|
228
|
-
## Requirements
|
|
229
|
-
|
|
230
|
-
1) First item
|
|
231
|
-
2) Second item
|
|
226
|
+
const content = `# Feature
|
|
227
|
+
|
|
228
|
+
## Requirements
|
|
229
|
+
|
|
230
|
+
1) First item
|
|
231
|
+
2) Second item
|
|
232
232
|
`;
|
|
233
233
|
const result = parsePRD(content, 'paren');
|
|
234
234
|
expect(result.requirements.length).toBe(2);
|
|
@@ -236,16 +236,16 @@ As a user, I want to login so that I can access my account.
|
|
|
236
236
|
});
|
|
237
237
|
describe('Acceptance Criteria', () => {
|
|
238
238
|
it('should extract AC and associate with requirements', () => {
|
|
239
|
-
const content = `# Feature
|
|
240
|
-
|
|
241
|
-
## Requirements
|
|
242
|
-
|
|
243
|
-
- User login functionality
|
|
244
|
-
|
|
245
|
-
## Acceptance Criteria
|
|
246
|
-
|
|
247
|
-
- Login form displays correctly
|
|
248
|
-
- Validation errors show properly
|
|
239
|
+
const content = `# Feature
|
|
240
|
+
|
|
241
|
+
## Requirements
|
|
242
|
+
|
|
243
|
+
- User login functionality
|
|
244
|
+
|
|
245
|
+
## Acceptance Criteria
|
|
246
|
+
|
|
247
|
+
- Login form displays correctly
|
|
248
|
+
- Validation errors show properly
|
|
249
249
|
`;
|
|
250
250
|
const result = parsePRD(content, 'ac');
|
|
251
251
|
expect(result.requirements.length).toBeGreaterThan(0);
|
|
@@ -253,16 +253,16 @@ As a user, I want to login so that I can access my account.
|
|
|
253
253
|
});
|
|
254
254
|
describe('Deduplication', () => {
|
|
255
255
|
it('should deduplicate similar requirements', () => {
|
|
256
|
-
const content = `# Feature
|
|
257
|
-
|
|
258
|
-
## Requirements
|
|
259
|
-
|
|
260
|
-
- User must login with email
|
|
261
|
-
- User must login with email and password
|
|
262
|
-
|
|
263
|
-
## Acceptance Criteria
|
|
264
|
-
|
|
265
|
-
- User must login with email validation
|
|
256
|
+
const content = `# Feature
|
|
257
|
+
|
|
258
|
+
## Requirements
|
|
259
|
+
|
|
260
|
+
- User must login with email
|
|
261
|
+
- User must login with email and password
|
|
262
|
+
|
|
263
|
+
## Acceptance Criteria
|
|
264
|
+
|
|
265
|
+
- User must login with email validation
|
|
266
266
|
`;
|
|
267
267
|
const result = parsePRD(content, 'dedup');
|
|
268
268
|
// First 50 chars are used for deduplication
|
|
@@ -272,15 +272,15 @@ As a user, I want to login so that I can access my account.
|
|
|
272
272
|
});
|
|
273
273
|
describe('Fallback extraction', () => {
|
|
274
274
|
it('should use fallback when no standard sections found', () => {
|
|
275
|
-
const content = `# Feature
|
|
276
|
-
|
|
277
|
-
Some text here.
|
|
278
|
-
|
|
279
|
-
- This is a long enough item to be captured
|
|
280
|
-
- Another sufficiently long item
|
|
281
|
-
- Short
|
|
282
|
-
|
|
283
|
-
Random paragraph.
|
|
275
|
+
const content = `# Feature
|
|
276
|
+
|
|
277
|
+
Some text here.
|
|
278
|
+
|
|
279
|
+
- This is a long enough item to be captured
|
|
280
|
+
- Another sufficiently long item
|
|
281
|
+
- Short
|
|
282
|
+
|
|
283
|
+
Random paragraph.
|
|
284
284
|
`;
|
|
285
285
|
const result = parsePRD(content, 'fallback');
|
|
286
286
|
// Fallback only captures items > 20 chars
|
|
@@ -290,39 +290,39 @@ Random paragraph.
|
|
|
290
290
|
});
|
|
291
291
|
describe('Metadata', () => {
|
|
292
292
|
it('should count sections correctly', () => {
|
|
293
|
-
const content = `# Feature
|
|
294
|
-
|
|
295
|
-
## Section One
|
|
296
|
-
|
|
297
|
-
Content.
|
|
298
|
-
|
|
299
|
-
## Section Two
|
|
300
|
-
|
|
301
|
-
More content.
|
|
302
|
-
|
|
303
|
-
## Section Three
|
|
304
|
-
|
|
305
|
-
Even more.
|
|
293
|
+
const content = `# Feature
|
|
294
|
+
|
|
295
|
+
## Section One
|
|
296
|
+
|
|
297
|
+
Content.
|
|
298
|
+
|
|
299
|
+
## Section Two
|
|
300
|
+
|
|
301
|
+
More content.
|
|
302
|
+
|
|
303
|
+
## Section Three
|
|
304
|
+
|
|
305
|
+
Even more.
|
|
306
306
|
`;
|
|
307
307
|
const result = parsePRD(content, 'meta');
|
|
308
308
|
expect(result.metadata.sectionCount).toBe(3);
|
|
309
309
|
});
|
|
310
310
|
it('should track requirement count', () => {
|
|
311
|
-
const content = `# Feature
|
|
312
|
-
|
|
313
|
-
## Requirements
|
|
314
|
-
|
|
315
|
-
- Req 1
|
|
316
|
-
- Req 2
|
|
317
|
-
- Req 3
|
|
311
|
+
const content = `# Feature
|
|
312
|
+
|
|
313
|
+
## Requirements
|
|
314
|
+
|
|
315
|
+
- Req 1
|
|
316
|
+
- Req 2
|
|
317
|
+
- Req 3
|
|
318
318
|
`;
|
|
319
319
|
const result = parsePRD(content, 'count');
|
|
320
320
|
expect(result.metadata.requirementCount).toBe(3);
|
|
321
321
|
});
|
|
322
322
|
it('should preserve raw content', () => {
|
|
323
|
-
const content = `# Feature
|
|
324
|
-
|
|
325
|
-
Original content preserved.
|
|
323
|
+
const content = `# Feature
|
|
324
|
+
|
|
325
|
+
Original content preserved.
|
|
326
326
|
`;
|
|
327
327
|
const result = parsePRD(content, 'raw');
|
|
328
328
|
expect(result.raw).toBe(content);
|