@agile-vibe-coding/avc 0.1.1 → 0.2.3
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/cli/agent-loader.js +21 -0
- package/cli/agents/agent-selector.md +129 -0
- package/cli/agents/architecture-recommender.md +418 -0
- package/cli/agents/database-deep-dive.md +470 -0
- package/cli/agents/database-recommender.md +634 -0
- package/cli/agents/doc-distributor.md +176 -0
- package/cli/agents/documentation-updater.md +203 -0
- package/cli/agents/epic-story-decomposer.md +280 -0
- package/cli/agents/feature-context-generator.md +91 -0
- package/cli/agents/gap-checker-epic.md +52 -0
- package/cli/agents/impact-checker-story.md +51 -0
- package/cli/agents/migration-guide-generator.md +305 -0
- package/cli/agents/mission-scope-generator.md +79 -0
- package/cli/agents/mission-scope-validator.md +112 -0
- package/cli/agents/project-context-extractor.md +107 -0
- package/cli/agents/project-documentation-creator.json +226 -0
- package/cli/agents/project-documentation-creator.md +595 -0
- package/cli/agents/question-prefiller.md +269 -0
- package/cli/agents/refiner-epic.md +39 -0
- package/cli/agents/refiner-story.md +42 -0
- package/cli/agents/solver-epic-api.json +15 -0
- package/cli/agents/solver-epic-api.md +39 -0
- package/cli/agents/solver-epic-backend.json +15 -0
- package/cli/agents/solver-epic-backend.md +39 -0
- package/cli/agents/solver-epic-cloud.json +15 -0
- package/cli/agents/solver-epic-cloud.md +39 -0
- package/cli/agents/solver-epic-data.json +15 -0
- package/cli/agents/solver-epic-data.md +39 -0
- package/cli/agents/solver-epic-database.json +15 -0
- package/cli/agents/solver-epic-database.md +39 -0
- package/cli/agents/solver-epic-developer.json +15 -0
- package/cli/agents/solver-epic-developer.md +39 -0
- package/cli/agents/solver-epic-devops.json +15 -0
- package/cli/agents/solver-epic-devops.md +39 -0
- package/cli/agents/solver-epic-frontend.json +15 -0
- package/cli/agents/solver-epic-frontend.md +39 -0
- package/cli/agents/solver-epic-mobile.json +15 -0
- package/cli/agents/solver-epic-mobile.md +39 -0
- package/cli/agents/solver-epic-qa.json +15 -0
- package/cli/agents/solver-epic-qa.md +39 -0
- package/cli/agents/solver-epic-security.json +15 -0
- package/cli/agents/solver-epic-security.md +39 -0
- package/cli/agents/solver-epic-solution-architect.json +15 -0
- package/cli/agents/solver-epic-solution-architect.md +39 -0
- package/cli/agents/solver-epic-test-architect.json +15 -0
- package/cli/agents/solver-epic-test-architect.md +39 -0
- package/cli/agents/solver-epic-ui.json +15 -0
- package/cli/agents/solver-epic-ui.md +39 -0
- package/cli/agents/solver-epic-ux.json +15 -0
- package/cli/agents/solver-epic-ux.md +39 -0
- package/cli/agents/solver-story-api.json +15 -0
- package/cli/agents/solver-story-api.md +39 -0
- package/cli/agents/solver-story-backend.json +15 -0
- package/cli/agents/solver-story-backend.md +39 -0
- package/cli/agents/solver-story-cloud.json +15 -0
- package/cli/agents/solver-story-cloud.md +39 -0
- package/cli/agents/solver-story-data.json +15 -0
- package/cli/agents/solver-story-data.md +39 -0
- package/cli/agents/solver-story-database.json +15 -0
- package/cli/agents/solver-story-database.md +39 -0
- package/cli/agents/solver-story-developer.json +15 -0
- package/cli/agents/solver-story-developer.md +39 -0
- package/cli/agents/solver-story-devops.json +15 -0
- package/cli/agents/solver-story-devops.md +39 -0
- package/cli/agents/solver-story-frontend.json +15 -0
- package/cli/agents/solver-story-frontend.md +39 -0
- package/cli/agents/solver-story-mobile.json +15 -0
- package/cli/agents/solver-story-mobile.md +39 -0
- package/cli/agents/solver-story-qa.json +15 -0
- package/cli/agents/solver-story-qa.md +39 -0
- package/cli/agents/solver-story-security.json +15 -0
- package/cli/agents/solver-story-security.md +39 -0
- package/cli/agents/solver-story-solution-architect.json +15 -0
- package/cli/agents/solver-story-solution-architect.md +39 -0
- package/cli/agents/solver-story-test-architect.json +15 -0
- package/cli/agents/solver-story-test-architect.md +39 -0
- package/cli/agents/solver-story-ui.json +15 -0
- package/cli/agents/solver-story-ui.md +39 -0
- package/cli/agents/solver-story-ux.json +15 -0
- package/cli/agents/solver-story-ux.md +39 -0
- package/cli/agents/story-doc-enricher.md +133 -0
- package/cli/agents/suggestion-business-analyst.md +88 -0
- package/cli/agents/suggestion-deployment-architect.md +263 -0
- package/cli/agents/suggestion-product-manager.md +129 -0
- package/cli/agents/suggestion-security-specialist.md +156 -0
- package/cli/agents/suggestion-technical-architect.md +269 -0
- package/cli/agents/suggestion-ux-researcher.md +93 -0
- package/cli/agents/task-subtask-decomposer.md +188 -0
- package/cli/agents/validator-documentation.json +152 -0
- package/cli/agents/validator-documentation.md +453 -0
- package/cli/agents/validator-epic-api.json +93 -0
- package/cli/agents/validator-epic-api.md +137 -0
- package/cli/agents/validator-epic-backend.json +93 -0
- package/cli/agents/validator-epic-backend.md +130 -0
- package/cli/agents/validator-epic-cloud.json +93 -0
- package/cli/agents/validator-epic-cloud.md +137 -0
- package/cli/agents/validator-epic-data.json +93 -0
- package/cli/agents/validator-epic-data.md +130 -0
- package/cli/agents/validator-epic-database.json +93 -0
- package/cli/agents/validator-epic-database.md +137 -0
- package/cli/agents/validator-epic-developer.json +74 -0
- package/cli/agents/validator-epic-developer.md +153 -0
- package/cli/agents/validator-epic-devops.json +74 -0
- package/cli/agents/validator-epic-devops.md +153 -0
- package/cli/agents/validator-epic-frontend.json +74 -0
- package/cli/agents/validator-epic-frontend.md +153 -0
- package/cli/agents/validator-epic-mobile.json +93 -0
- package/cli/agents/validator-epic-mobile.md +130 -0
- package/cli/agents/validator-epic-qa.json +93 -0
- package/cli/agents/validator-epic-qa.md +130 -0
- package/cli/agents/validator-epic-security.json +74 -0
- package/cli/agents/validator-epic-security.md +154 -0
- package/cli/agents/validator-epic-solution-architect.json +74 -0
- package/cli/agents/validator-epic-solution-architect.md +156 -0
- package/cli/agents/validator-epic-test-architect.json +93 -0
- package/cli/agents/validator-epic-test-architect.md +130 -0
- package/cli/agents/validator-epic-ui.json +93 -0
- package/cli/agents/validator-epic-ui.md +130 -0
- package/cli/agents/validator-epic-ux.json +93 -0
- package/cli/agents/validator-epic-ux.md +130 -0
- package/cli/agents/validator-selector.md +211 -0
- package/cli/agents/validator-story-api.json +104 -0
- package/cli/agents/validator-story-api.md +152 -0
- package/cli/agents/validator-story-backend.json +104 -0
- package/cli/agents/validator-story-backend.md +152 -0
- package/cli/agents/validator-story-cloud.json +104 -0
- package/cli/agents/validator-story-cloud.md +152 -0
- package/cli/agents/validator-story-data.json +104 -0
- package/cli/agents/validator-story-data.md +152 -0
- package/cli/agents/validator-story-database.json +104 -0
- package/cli/agents/validator-story-database.md +152 -0
- package/cli/agents/validator-story-developer.json +104 -0
- package/cli/agents/validator-story-developer.md +152 -0
- package/cli/agents/validator-story-devops.json +104 -0
- package/cli/agents/validator-story-devops.md +152 -0
- package/cli/agents/validator-story-frontend.json +104 -0
- package/cli/agents/validator-story-frontend.md +152 -0
- package/cli/agents/validator-story-mobile.json +104 -0
- package/cli/agents/validator-story-mobile.md +152 -0
- package/cli/agents/validator-story-qa.json +104 -0
- package/cli/agents/validator-story-qa.md +152 -0
- package/cli/agents/validator-story-security.json +104 -0
- package/cli/agents/validator-story-security.md +152 -0
- package/cli/agents/validator-story-solution-architect.json +104 -0
- package/cli/agents/validator-story-solution-architect.md +152 -0
- package/cli/agents/validator-story-test-architect.json +104 -0
- package/cli/agents/validator-story-test-architect.md +152 -0
- package/cli/agents/validator-story-ui.json +104 -0
- package/cli/agents/validator-story-ui.md +152 -0
- package/cli/agents/validator-story-ux.json +104 -0
- package/cli/agents/validator-story-ux.md +152 -0
- package/cli/ansi-colors.js +21 -0
- package/cli/build-docs.js +29 -8
- package/cli/ceremony-history.js +369 -0
- package/cli/command-logger.js +49 -12
- package/cli/components/static-output.js +63 -0
- package/cli/console-output-manager.js +94 -0
- package/cli/docs-sync.js +306 -0
- package/cli/epic-story-validator.js +1174 -0
- package/cli/evaluation-prompts.js +1008 -0
- package/cli/execution-context.js +195 -0
- package/cli/generate-summary-table.js +340 -0
- package/cli/index.js +0 -0
- package/cli/init-model-config.js +697 -0
- package/cli/init.js +1311 -274
- package/cli/kanban-server-manager.js +228 -0
- package/cli/llm-claude.js +83 -1
- package/cli/llm-gemini.js +85 -0
- package/cli/llm-mock.js +233 -0
- package/cli/llm-openai.js +233 -0
- package/cli/llm-provider.js +240 -3
- package/cli/llm-token-limits.js +102 -0
- package/cli/llm-verifier.js +454 -0
- package/cli/message-constants.js +58 -0
- package/cli/message-manager.js +334 -0
- package/cli/message-types.js +96 -0
- package/cli/messaging-api.js +297 -0
- package/cli/model-pricing.js +169 -0
- package/cli/model-query-engine.js +468 -0
- package/cli/model-recommendation-analyzer.js +495 -0
- package/cli/model-selector.js +269 -0
- package/cli/output-buffer.js +107 -0
- package/cli/process-manager.js +73 -2
- package/cli/repl-ink.js +4988 -1217
- package/cli/repl-old.js +4 -4
- package/cli/seed-processor.js +792 -0
- package/cli/sprint-planning-processor.js +1813 -0
- package/cli/template-processor.js +2102 -105
- package/cli/templates/project.md +25 -8
- package/cli/templates/vitepress-config.mts.template +5 -4
- package/cli/token-tracker.js +520 -0
- package/cli/tools/generate-story-validators.js +317 -0
- package/cli/tools/generate-validators.js +669 -0
- package/cli/update-checker.js +19 -17
- package/cli/update-notifier.js +4 -4
- package/cli/validation-router.js +605 -0
- package/cli/verification-tracker.js +563 -0
- package/kanban/README.md +386 -0
- package/kanban/client/README.md +205 -0
- package/kanban/client/components.json +20 -0
- package/kanban/client/dist/assets/index-CiD8PS2e.js +306 -0
- package/kanban/client/dist/assets/index-nLh0m82Q.css +1 -0
- package/kanban/client/dist/index.html +16 -0
- package/kanban/client/dist/vite.svg +1 -0
- package/kanban/client/index.html +15 -0
- package/kanban/client/package-lock.json +9442 -0
- package/kanban/client/package.json +44 -0
- package/kanban/client/postcss.config.js +6 -0
- package/kanban/client/public/vite.svg +1 -0
- package/kanban/client/src/App.jsx +622 -0
- package/kanban/client/src/components/ProjectFileEditorPopup.jsx +117 -0
- package/kanban/client/src/components/ceremony/AskArchPopup.jsx +416 -0
- package/kanban/client/src/components/ceremony/AskModelPopup.jsx +616 -0
- package/kanban/client/src/components/ceremony/CeremonyWorkflowModal.jsx +946 -0
- package/kanban/client/src/components/ceremony/EpicStorySelectionModal.jsx +254 -0
- package/kanban/client/src/components/ceremony/SponsorCallModal.jsx +619 -0
- package/kanban/client/src/components/ceremony/SprintPlanningModal.jsx +704 -0
- package/kanban/client/src/components/ceremony/steps/ArchitectureStep.jsx +150 -0
- package/kanban/client/src/components/ceremony/steps/CompleteStep.jsx +154 -0
- package/kanban/client/src/components/ceremony/steps/DatabaseStep.jsx +202 -0
- package/kanban/client/src/components/ceremony/steps/DeploymentStep.jsx +123 -0
- package/kanban/client/src/components/ceremony/steps/MissionStep.jsx +106 -0
- package/kanban/client/src/components/ceremony/steps/ReviewAnswersStep.jsx +125 -0
- package/kanban/client/src/components/ceremony/steps/RunningStep.jsx +228 -0
- package/kanban/client/src/components/kanban/CardDetailModal.jsx +559 -0
- package/kanban/client/src/components/kanban/EpicSection.jsx +146 -0
- package/kanban/client/src/components/kanban/FilterToolbar.jsx +222 -0
- package/kanban/client/src/components/kanban/GroupingSelector.jsx +57 -0
- package/kanban/client/src/components/kanban/KanbanBoard.jsx +211 -0
- package/kanban/client/src/components/kanban/KanbanCard.jsx +138 -0
- package/kanban/client/src/components/kanban/KanbanColumn.jsx +90 -0
- package/kanban/client/src/components/kanban/RefineWorkItemPopup.jsx +789 -0
- package/kanban/client/src/components/layout/LoadingScreen.jsx +82 -0
- package/kanban/client/src/components/process/ProcessMonitorBar.jsx +80 -0
- package/kanban/client/src/components/settings/AgentEditorPopup.jsx +171 -0
- package/kanban/client/src/components/settings/AgentsTab.jsx +353 -0
- package/kanban/client/src/components/settings/ApiKeysTab.jsx +113 -0
- package/kanban/client/src/components/settings/CeremonyModelsTab.jsx +98 -0
- package/kanban/client/src/components/settings/CostThresholdsTab.jsx +94 -0
- package/kanban/client/src/components/settings/ModelPricingTab.jsx +204 -0
- package/kanban/client/src/components/settings/ServersTab.jsx +121 -0
- package/kanban/client/src/components/settings/SettingsModal.jsx +84 -0
- package/kanban/client/src/components/stats/CostModal.jsx +353 -0
- package/kanban/client/src/components/ui/badge.jsx +27 -0
- package/kanban/client/src/components/ui/dialog.jsx +121 -0
- package/kanban/client/src/components/ui/tabs.jsx +85 -0
- package/kanban/client/src/hooks/__tests__/useGrouping.test.js +232 -0
- package/kanban/client/src/hooks/useGrouping.js +118 -0
- package/kanban/client/src/hooks/useWebSocket.js +120 -0
- package/kanban/client/src/lib/__tests__/api.test.js +196 -0
- package/kanban/client/src/lib/__tests__/status-grouping.test.js +94 -0
- package/kanban/client/src/lib/api.js +401 -0
- package/kanban/client/src/lib/status-grouping.js +144 -0
- package/kanban/client/src/lib/utils.js +11 -0
- package/kanban/client/src/main.jsx +10 -0
- package/kanban/client/src/store/__tests__/kanbanStore.test.js +164 -0
- package/kanban/client/src/store/ceremonyStore.js +172 -0
- package/kanban/client/src/store/filterStore.js +201 -0
- package/kanban/client/src/store/kanbanStore.js +115 -0
- package/kanban/client/src/store/processStore.js +65 -0
- package/kanban/client/src/store/sprintPlanningStore.js +33 -0
- package/kanban/client/src/styles/globals.css +59 -0
- package/kanban/client/tailwind.config.js +77 -0
- package/kanban/client/vite.config.js +28 -0
- package/kanban/client/vitest.config.js +28 -0
- package/kanban/dev-start.sh +47 -0
- package/kanban/package.json +12 -0
- package/kanban/server/index.js +516 -0
- package/kanban/server/routes/ceremony.js +305 -0
- package/kanban/server/routes/costs.js +157 -0
- package/kanban/server/routes/processes.js +50 -0
- package/kanban/server/routes/settings.js +303 -0
- package/kanban/server/routes/websocket.js +276 -0
- package/kanban/server/routes/work-items.js +347 -0
- package/kanban/server/services/CeremonyService.js +1190 -0
- package/kanban/server/services/FileSystemScanner.js +95 -0
- package/kanban/server/services/FileWatcher.js +144 -0
- package/kanban/server/services/HierarchyBuilder.js +196 -0
- package/kanban/server/services/ProcessRegistry.js +122 -0
- package/kanban/server/services/WorkItemReader.js +123 -0
- package/kanban/server/services/WorkItemRefineService.js +510 -0
- package/kanban/server/start.js +49 -0
- package/kanban/server/utils/kanban-logger.js +132 -0
- package/kanban/server/utils/markdown.js +91 -0
- package/kanban/server/utils/status-grouping.js +107 -0
- package/kanban/server/workers/sponsor-call-worker.js +84 -0
- package/kanban/server/workers/sprint-planning-worker.js +130 -0
- package/package.json +18 -5
- package/cli/agents/documentation.md +0 -302
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { useCeremonyStore } from '../../../store/ceremonyStore';
|
|
3
|
+
import { AskModelPopup } from '../AskModelPopup';
|
|
4
|
+
|
|
5
|
+
export function MissionStep({ onNext, onBack, analyzing, onOpenSettings }) {
|
|
6
|
+
const { mission, setMission, initialScope, setInitialScope } = useCeremonyStore();
|
|
7
|
+
const [showPopup, setShowPopup] = useState(false);
|
|
8
|
+
|
|
9
|
+
const canContinue = mission.trim().length > 0 && initialScope.trim().length > 0;
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<div className="space-y-6">
|
|
13
|
+
<div>
|
|
14
|
+
<h2 className="text-xl font-semibold text-slate-900">Mission & Scope</h2>
|
|
15
|
+
<p className="text-sm text-slate-500 mt-1">
|
|
16
|
+
Describe what your project does and what it will deliver in the first version.
|
|
17
|
+
</p>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div className="space-y-4">
|
|
21
|
+
<div>
|
|
22
|
+
<div className="flex items-center justify-between mb-1">
|
|
23
|
+
<label className="block text-sm font-medium text-slate-700">
|
|
24
|
+
Mission Statement <span className="text-red-500">*</span>
|
|
25
|
+
</label>
|
|
26
|
+
<button
|
|
27
|
+
type="button"
|
|
28
|
+
onClick={() => setShowPopup(true)}
|
|
29
|
+
className="text-xs text-blue-600 hover:text-blue-700 flex items-center gap-1 transition-colors"
|
|
30
|
+
>
|
|
31
|
+
✨ Ask a Model
|
|
32
|
+
</button>
|
|
33
|
+
</div>
|
|
34
|
+
<p className="text-xs text-slate-400 mb-2">
|
|
35
|
+
A concise statement describing the core purpose and value proposition.
|
|
36
|
+
Example: "Enable small businesses to manage inventory through an intuitive mobile-first platform."
|
|
37
|
+
</p>
|
|
38
|
+
<textarea
|
|
39
|
+
value={mission}
|
|
40
|
+
onChange={(e) => setMission(e.target.value)}
|
|
41
|
+
rows={3}
|
|
42
|
+
placeholder="Enter your mission statement..."
|
|
43
|
+
className="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"
|
|
44
|
+
/>
|
|
45
|
+
{!mission.trim() && (
|
|
46
|
+
<p className="text-xs text-red-500 mt-1">Mission statement is required.</p>
|
|
47
|
+
)}
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div>
|
|
51
|
+
<label className="block text-sm font-medium text-slate-700 mb-1">
|
|
52
|
+
Initial Scope <span className="text-red-500">*</span>
|
|
53
|
+
</label>
|
|
54
|
+
<p className="text-xs text-slate-400 mb-2">
|
|
55
|
+
Describe key features, main workflows, and core functionality for the first version.
|
|
56
|
+
Example: "Users can create tasks, assign them to team members, track progress, and set deadlines."
|
|
57
|
+
</p>
|
|
58
|
+
<textarea
|
|
59
|
+
value={initialScope}
|
|
60
|
+
onChange={(e) => setInitialScope(e.target.value)}
|
|
61
|
+
rows={4}
|
|
62
|
+
placeholder="Describe the initial scope and features..."
|
|
63
|
+
className="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<div className="flex items-center justify-between pt-2">
|
|
69
|
+
<button
|
|
70
|
+
type="button"
|
|
71
|
+
onClick={onBack}
|
|
72
|
+
disabled={analyzing}
|
|
73
|
+
className="text-sm text-slate-400 hover:text-slate-600 disabled:opacity-40 transition-colors"
|
|
74
|
+
>
|
|
75
|
+
← Back
|
|
76
|
+
</button>
|
|
77
|
+
<button
|
|
78
|
+
onClick={onNext}
|
|
79
|
+
disabled={!canContinue || analyzing}
|
|
80
|
+
className="px-5 py-2 bg-slate-900 text-white text-sm font-medium rounded-lg disabled:opacity-40 hover:bg-slate-700 transition-colors flex items-center gap-2"
|
|
81
|
+
>
|
|
82
|
+
{analyzing ? (
|
|
83
|
+
<>
|
|
84
|
+
<span className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" />
|
|
85
|
+
Analysing…
|
|
86
|
+
</>
|
|
87
|
+
) : (
|
|
88
|
+
'Continue'
|
|
89
|
+
)}
|
|
90
|
+
</button>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
{showPopup && (
|
|
94
|
+
<AskModelPopup
|
|
95
|
+
onUse={(generatedMission, generatedScope) => {
|
|
96
|
+
setMission(generatedMission);
|
|
97
|
+
setInitialScope(generatedScope);
|
|
98
|
+
setShowPopup(false);
|
|
99
|
+
}}
|
|
100
|
+
onClose={() => setShowPopup(false)}
|
|
101
|
+
onOpenSettings={onOpenSettings}
|
|
102
|
+
/>
|
|
103
|
+
)}
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { useCeremonyStore } from '../../../store/ceremonyStore';
|
|
2
|
+
|
|
3
|
+
const FIELDS = [
|
|
4
|
+
{
|
|
5
|
+
key: 'TARGET_USERS',
|
|
6
|
+
label: 'Target Users',
|
|
7
|
+
description: 'Who will use this application? List different user types and their roles.',
|
|
8
|
+
rows: 3,
|
|
9
|
+
required: true,
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
key: 'DEPLOYMENT_TARGET',
|
|
13
|
+
label: 'Deployment Target',
|
|
14
|
+
description: 'Where and how will this application be deployed?',
|
|
15
|
+
rows: 3,
|
|
16
|
+
required: true,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
key: 'TECHNICAL_CONSIDERATIONS',
|
|
20
|
+
label: 'Technical Considerations',
|
|
21
|
+
description: 'Technology stack, architectural patterns, scalability, and performance requirements.',
|
|
22
|
+
rows: 4,
|
|
23
|
+
required: true,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
key: 'TECHNICAL_EXCLUSIONS',
|
|
27
|
+
label: 'Technical Exclusions',
|
|
28
|
+
description:
|
|
29
|
+
'Technologies, frameworks, or services to explicitly exclude from recommendations. Leave blank if none.',
|
|
30
|
+
rows: 2,
|
|
31
|
+
required: false,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: 'SECURITY_AND_COMPLIANCE_REQUIREMENTS',
|
|
35
|
+
label: 'Security & Compliance Requirements',
|
|
36
|
+
description:
|
|
37
|
+
'Security, privacy, or regulatory requirements your application must meet. Examples: GDPR compliance, PCI DSS, two-factor authentication.',
|
|
38
|
+
rows: 3,
|
|
39
|
+
required: true,
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
export function ReviewAnswersStep({ onNext, onBack }) {
|
|
44
|
+
const { requirements, updateRequirement, mission, setMission, initialScope, setInitialScope } = useCeremonyStore();
|
|
45
|
+
|
|
46
|
+
const canContinue =
|
|
47
|
+
mission.trim().length > 0 &&
|
|
48
|
+
initialScope.trim().length > 0 &&
|
|
49
|
+
FIELDS.filter((f) => f.required).every((f) => requirements[f.key]?.trim());
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<div className="space-y-6">
|
|
53
|
+
<div>
|
|
54
|
+
<h2 className="text-xl font-semibold text-slate-900">Review & Edit Requirements</h2>
|
|
55
|
+
<p className="text-sm text-slate-500 mt-1">
|
|
56
|
+
AI has pre-filled these requirements based on your selections. Review and edit as needed.
|
|
57
|
+
</p>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div className="space-y-4">
|
|
61
|
+
{/* Mission & Scope */}
|
|
62
|
+
<div>
|
|
63
|
+
<label className="block text-sm font-medium text-slate-700 mb-0.5">
|
|
64
|
+
Mission Statement <span className="text-red-500">*</span>
|
|
65
|
+
</label>
|
|
66
|
+
<textarea
|
|
67
|
+
value={mission}
|
|
68
|
+
onChange={(e) => setMission(e.target.value)}
|
|
69
|
+
rows={3}
|
|
70
|
+
className="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"
|
|
71
|
+
placeholder="Required..."
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
<div>
|
|
75
|
+
<label className="block text-sm font-medium text-slate-700 mb-0.5">
|
|
76
|
+
Initial Scope <span className="text-red-500">*</span>
|
|
77
|
+
</label>
|
|
78
|
+
<textarea
|
|
79
|
+
value={initialScope}
|
|
80
|
+
onChange={(e) => setInitialScope(e.target.value)}
|
|
81
|
+
rows={4}
|
|
82
|
+
className="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"
|
|
83
|
+
placeholder="Required..."
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<hr className="border-slate-200" />
|
|
88
|
+
|
|
89
|
+
{FIELDS.map((field) => (
|
|
90
|
+
<div key={field.key}>
|
|
91
|
+
<label className="block text-sm font-medium text-slate-700 mb-0.5">
|
|
92
|
+
{field.label}
|
|
93
|
+
{field.required && <span className="text-red-500 ml-1">*</span>}
|
|
94
|
+
</label>
|
|
95
|
+
<p className="text-xs text-slate-400 mb-1">{field.description}</p>
|
|
96
|
+
<textarea
|
|
97
|
+
value={requirements[field.key] || ''}
|
|
98
|
+
onChange={(e) => updateRequirement(field.key, e.target.value)}
|
|
99
|
+
rows={field.rows}
|
|
100
|
+
className="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"
|
|
101
|
+
placeholder={field.required ? `Required...` : 'Optional...'}
|
|
102
|
+
/>
|
|
103
|
+
</div>
|
|
104
|
+
))}
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div className="flex items-center justify-between pt-2">
|
|
108
|
+
<button
|
|
109
|
+
type="button"
|
|
110
|
+
onClick={onBack}
|
|
111
|
+
className="text-sm text-slate-400 hover:text-slate-600 transition-colors"
|
|
112
|
+
>
|
|
113
|
+
← Back
|
|
114
|
+
</button>
|
|
115
|
+
<button
|
|
116
|
+
onClick={onNext}
|
|
117
|
+
disabled={!canContinue}
|
|
118
|
+
className="px-5 py-2 bg-green-600 text-white text-sm font-medium rounded-lg disabled:opacity-40 hover:bg-green-700 transition-colors"
|
|
119
|
+
>
|
|
120
|
+
Generate Project Brief
|
|
121
|
+
</button>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { ArrowDownToLine } from 'lucide-react';
|
|
3
|
+
import { useCeremonyStore } from '../../../store/ceremonyStore';
|
|
4
|
+
import { resetCeremony } from '../../../lib/api';
|
|
5
|
+
|
|
6
|
+
function parseStageNumber(message) {
|
|
7
|
+
const m = message?.match(/Stage\s+(\d+(?:\.\d+)?)\/(\d+)/i);
|
|
8
|
+
if (m) return { current: parseFloat(m[1]), total: parseInt(m[2]) };
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function buildStageGroups(progressLog) {
|
|
13
|
+
const groups = [];
|
|
14
|
+
for (const entry of progressLog) {
|
|
15
|
+
if (entry.type === 'progress') {
|
|
16
|
+
groups.push({ message: entry.message, substeps: [], orphanDetails: [] });
|
|
17
|
+
} else if (entry.type === 'substep' && groups.length > 0) {
|
|
18
|
+
groups[groups.length - 1].substeps.push({ text: entry.substep, details: [] });
|
|
19
|
+
} else if (entry.type === 'detail' && groups.length > 0) {
|
|
20
|
+
const group = groups[groups.length - 1];
|
|
21
|
+
const substeps = group.substeps;
|
|
22
|
+
if (substeps.length > 0) {
|
|
23
|
+
substeps[substeps.length - 1].details.push(entry.detail);
|
|
24
|
+
} else {
|
|
25
|
+
group.orphanDetails.push(entry.detail);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return groups;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function RunningStep({ transitioning, onPause, onResume, onCancel, onBackground }) {
|
|
33
|
+
const { progressLog, ceremonyStatus, ceremonyError, isPaused, setWizardStep, setCeremonyStatus, setCeremonyError } = useCeremonyStore();
|
|
34
|
+
const logBottomRef = useRef(null);
|
|
35
|
+
|
|
36
|
+
const handleForceReset = async () => {
|
|
37
|
+
try { await resetCeremony(); } catch (_) {}
|
|
38
|
+
setCeremonyStatus('idle');
|
|
39
|
+
setCeremonyError(null);
|
|
40
|
+
setWizardStep(1);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
logBottomRef.current?.scrollIntoView({ behavior: 'smooth' });
|
|
45
|
+
}, [progressLog]);
|
|
46
|
+
|
|
47
|
+
// Auto-advance to CompleteStep when ceremony finishes
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (ceremonyStatus === 'complete') {
|
|
50
|
+
setWizardStep(7);
|
|
51
|
+
}
|
|
52
|
+
}, [ceremonyStatus, setWizardStep]);
|
|
53
|
+
|
|
54
|
+
const stageGroups = buildStageGroups(progressLog);
|
|
55
|
+
|
|
56
|
+
let currentStage = null;
|
|
57
|
+
let totalStages = 5;
|
|
58
|
+
for (const g of [...stageGroups].reverse()) {
|
|
59
|
+
const parsed = parseStageNumber(g.message);
|
|
60
|
+
if (parsed) {
|
|
61
|
+
currentStage = parsed.current;
|
|
62
|
+
totalStages = parsed.total;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const progressPct = currentStage ? Math.round((currentStage / totalStages) * 100) : 5;
|
|
68
|
+
const latestProgress = stageGroups[stageGroups.length - 1]?.message || 'Starting ceremony...';
|
|
69
|
+
|
|
70
|
+
if (ceremonyStatus === 'error') {
|
|
71
|
+
const isAlreadyRunning = ceremonyError?.includes('already running');
|
|
72
|
+
return (
|
|
73
|
+
<div className="space-y-4">
|
|
74
|
+
<h2 className="text-xl font-semibold text-slate-900">Generation Failed</h2>
|
|
75
|
+
<div className="bg-red-50 border border-red-200 rounded-lg p-4">
|
|
76
|
+
<p className="text-sm font-medium text-red-700 mb-1">Error</p>
|
|
77
|
+
<p className="text-sm text-red-600">{ceremonyError || 'An unknown error occurred.'}</p>
|
|
78
|
+
</div>
|
|
79
|
+
{isAlreadyRunning ? (
|
|
80
|
+
<div className="space-y-3">
|
|
81
|
+
<p className="text-sm text-slate-500">
|
|
82
|
+
A ceremony is already running on the server. You can force-stop it and reset the state — this will discard any in-progress work.
|
|
83
|
+
</p>
|
|
84
|
+
<button
|
|
85
|
+
onClick={handleForceReset}
|
|
86
|
+
className="px-4 py-2 text-sm rounded-lg bg-red-600 text-white hover:bg-red-700 transition-colors"
|
|
87
|
+
>
|
|
88
|
+
Force Stop & Reset
|
|
89
|
+
</button>
|
|
90
|
+
</div>
|
|
91
|
+
) : (
|
|
92
|
+
<p className="text-sm text-slate-500">
|
|
93
|
+
Check that your API key is configured correctly in your project's <code>.env</code> file.
|
|
94
|
+
</p>
|
|
95
|
+
)}
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<div className="space-y-6">
|
|
102
|
+
<div>
|
|
103
|
+
<h2 className="text-xl font-semibold text-slate-900">Generating Documentation</h2>
|
|
104
|
+
<p className="text-sm text-slate-500 mt-1">
|
|
105
|
+
The AI is generating your project documentation. Duration varies depending on the number of validation iterations — typically a few minutes, but may take longer.
|
|
106
|
+
</p>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
{/* Stage progress bar */}
|
|
110
|
+
<div>
|
|
111
|
+
<div className="flex items-center justify-between mb-1">
|
|
112
|
+
<span className="text-xs font-medium text-slate-600">{latestProgress}</span>
|
|
113
|
+
<span className="text-xs text-slate-400">{progressPct}%</span>
|
|
114
|
+
</div>
|
|
115
|
+
<div className="w-full bg-slate-200 rounded-full h-2">
|
|
116
|
+
<div
|
|
117
|
+
className="bg-blue-500 h-2 rounded-full transition-all duration-500"
|
|
118
|
+
style={{ width: `${progressPct}%` }}
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
{/* Stage log — hierarchical */}
|
|
124
|
+
<div className="bg-slate-900 rounded-lg p-4 h-56 overflow-y-auto font-mono text-xs">
|
|
125
|
+
{stageGroups.length === 0 ? (
|
|
126
|
+
<p className="text-slate-400 animate-pulse">Initializing...</p>
|
|
127
|
+
) : (
|
|
128
|
+
<div className="space-y-2">
|
|
129
|
+
{stageGroups.map((group, gi) => {
|
|
130
|
+
const isActive = gi === stageGroups.length - 1 && ceremonyStatus === 'running';
|
|
131
|
+
return (
|
|
132
|
+
<div key={gi}>
|
|
133
|
+
<div className="flex items-center gap-1.5">
|
|
134
|
+
{isActive ? (
|
|
135
|
+
<span className="inline-block w-3 h-3 border border-blue-400 border-t-blue-200 rounded-full animate-spin flex-shrink-0" />
|
|
136
|
+
) : (
|
|
137
|
+
<span className="text-green-500 flex-shrink-0">✓</span>
|
|
138
|
+
)}
|
|
139
|
+
<span className={isActive ? 'text-blue-300 font-medium' : 'text-slate-400'}>
|
|
140
|
+
{group.message}
|
|
141
|
+
</span>
|
|
142
|
+
</div>
|
|
143
|
+
{group.orphanDetails?.length > 0 && (
|
|
144
|
+
<div className="ml-5 mt-0.5 space-y-0.5 border-l border-slate-700 pl-2">
|
|
145
|
+
{group.orphanDetails.map((d, di) => (
|
|
146
|
+
<p key={di} className="text-slate-500">{d}</p>
|
|
147
|
+
))}
|
|
148
|
+
</div>
|
|
149
|
+
)}
|
|
150
|
+
{group.substeps.length > 0 && (
|
|
151
|
+
<div className="ml-5 mt-0.5 space-y-0.5 border-l border-slate-700 pl-2">
|
|
152
|
+
{group.substeps.map((sub, si) => (
|
|
153
|
+
<div key={si}>
|
|
154
|
+
<p className="text-slate-400">{sub.text}</p>
|
|
155
|
+
{sub.details.length > 0 && (
|
|
156
|
+
<div className="ml-3 mt-0.5 space-y-0.5 border-l border-slate-700 pl-2">
|
|
157
|
+
{sub.details.map((d, di) => (
|
|
158
|
+
<p key={di} className="text-slate-500">{d}</p>
|
|
159
|
+
))}
|
|
160
|
+
</div>
|
|
161
|
+
)}
|
|
162
|
+
</div>
|
|
163
|
+
))}
|
|
164
|
+
</div>
|
|
165
|
+
)}
|
|
166
|
+
</div>
|
|
167
|
+
);
|
|
168
|
+
})}
|
|
169
|
+
{transitioning === 'cancelling' && (
|
|
170
|
+
<div className="flex items-center gap-1.5 mt-1">
|
|
171
|
+
<span className="inline-block w-3 h-3 border border-red-400 border-t-red-200 rounded-full animate-spin flex-shrink-0" />
|
|
172
|
+
<span className="text-red-400 font-medium">Cancelling…</span>
|
|
173
|
+
</div>
|
|
174
|
+
)}
|
|
175
|
+
<div ref={logBottomRef} />
|
|
176
|
+
</div>
|
|
177
|
+
)}
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<div className="flex items-center justify-between gap-2 pt-2">
|
|
181
|
+
{/* Left: run in background */}
|
|
182
|
+
{onBackground && !transitioning && (
|
|
183
|
+
<button
|
|
184
|
+
type="button"
|
|
185
|
+
onClick={onBackground}
|
|
186
|
+
className="flex items-center gap-1.5 text-xs font-medium text-slate-500 hover:text-slate-700 bg-slate-50 hover:bg-slate-100 border border-slate-200 rounded-md px-2.5 py-1.5 transition-colors"
|
|
187
|
+
title="Hide this window — ceremony keeps running in the background"
|
|
188
|
+
>
|
|
189
|
+
<ArrowDownToLine className="w-3.5 h-3.5" />
|
|
190
|
+
Run in Background
|
|
191
|
+
</button>
|
|
192
|
+
)}
|
|
193
|
+
{transitioning && <span />}
|
|
194
|
+
|
|
195
|
+
{/* Right: pause / resume / cancel */}
|
|
196
|
+
<div className="flex items-center gap-2">
|
|
197
|
+
{transitioning === 'pausing' ? (
|
|
198
|
+
<span className="flex items-center gap-1.5 text-xs text-slate-400"><span className="inline-block w-3 h-3 border border-slate-400 border-t-slate-200 rounded-full animate-spin" />Pausing…</span>
|
|
199
|
+
) : transitioning === 'cancelling' ? (
|
|
200
|
+
<span className="flex items-center gap-1.5 text-xs text-red-400"><span className="inline-block w-3 h-3 border border-red-400 border-t-red-200 rounded-full animate-spin" />Cancelling…</span>
|
|
201
|
+
) : !isPaused ? (
|
|
202
|
+
<button
|
|
203
|
+
onClick={onPause}
|
|
204
|
+
className="px-4 py-2 text-sm rounded-lg border border-slate-200 text-slate-600 hover:bg-slate-50 transition-colors"
|
|
205
|
+
>
|
|
206
|
+
⏸ Pause
|
|
207
|
+
</button>
|
|
208
|
+
) : (
|
|
209
|
+
<button
|
|
210
|
+
onClick={onResume}
|
|
211
|
+
className="px-4 py-2 text-sm rounded-lg border border-amber-300 bg-amber-50 text-amber-700 hover:bg-amber-100 transition-colors"
|
|
212
|
+
>
|
|
213
|
+
▶ Resume
|
|
214
|
+
</button>
|
|
215
|
+
)}
|
|
216
|
+
{!transitioning && (
|
|
217
|
+
<button
|
|
218
|
+
onClick={onCancel}
|
|
219
|
+
className="px-4 py-2 text-sm rounded-lg border border-red-200 text-red-600 hover:bg-red-50 transition-colors"
|
|
220
|
+
>
|
|
221
|
+
✕ Cancel
|
|
222
|
+
</button>
|
|
223
|
+
)}
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
);
|
|
228
|
+
}
|