@agile-vibe-coding/avc 0.1.0 → 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.
Files changed (290) hide show
  1. package/README.md +2 -0
  2. package/cli/agent-loader.js +21 -0
  3. package/cli/agents/agent-selector.md +129 -0
  4. package/cli/agents/architecture-recommender.md +418 -0
  5. package/cli/agents/database-deep-dive.md +470 -0
  6. package/cli/agents/database-recommender.md +634 -0
  7. package/cli/agents/doc-distributor.md +176 -0
  8. package/cli/agents/documentation-updater.md +203 -0
  9. package/cli/agents/epic-story-decomposer.md +280 -0
  10. package/cli/agents/feature-context-generator.md +91 -0
  11. package/cli/agents/gap-checker-epic.md +52 -0
  12. package/cli/agents/impact-checker-story.md +51 -0
  13. package/cli/agents/migration-guide-generator.md +305 -0
  14. package/cli/agents/mission-scope-generator.md +79 -0
  15. package/cli/agents/mission-scope-validator.md +112 -0
  16. package/cli/agents/project-context-extractor.md +107 -0
  17. package/cli/agents/project-documentation-creator.json +226 -0
  18. package/cli/agents/project-documentation-creator.md +595 -0
  19. package/cli/agents/question-prefiller.md +269 -0
  20. package/cli/agents/refiner-epic.md +39 -0
  21. package/cli/agents/refiner-story.md +42 -0
  22. package/cli/agents/solver-epic-api.json +15 -0
  23. package/cli/agents/solver-epic-api.md +39 -0
  24. package/cli/agents/solver-epic-backend.json +15 -0
  25. package/cli/agents/solver-epic-backend.md +39 -0
  26. package/cli/agents/solver-epic-cloud.json +15 -0
  27. package/cli/agents/solver-epic-cloud.md +39 -0
  28. package/cli/agents/solver-epic-data.json +15 -0
  29. package/cli/agents/solver-epic-data.md +39 -0
  30. package/cli/agents/solver-epic-database.json +15 -0
  31. package/cli/agents/solver-epic-database.md +39 -0
  32. package/cli/agents/solver-epic-developer.json +15 -0
  33. package/cli/agents/solver-epic-developer.md +39 -0
  34. package/cli/agents/solver-epic-devops.json +15 -0
  35. package/cli/agents/solver-epic-devops.md +39 -0
  36. package/cli/agents/solver-epic-frontend.json +15 -0
  37. package/cli/agents/solver-epic-frontend.md +39 -0
  38. package/cli/agents/solver-epic-mobile.json +15 -0
  39. package/cli/agents/solver-epic-mobile.md +39 -0
  40. package/cli/agents/solver-epic-qa.json +15 -0
  41. package/cli/agents/solver-epic-qa.md +39 -0
  42. package/cli/agents/solver-epic-security.json +15 -0
  43. package/cli/agents/solver-epic-security.md +39 -0
  44. package/cli/agents/solver-epic-solution-architect.json +15 -0
  45. package/cli/agents/solver-epic-solution-architect.md +39 -0
  46. package/cli/agents/solver-epic-test-architect.json +15 -0
  47. package/cli/agents/solver-epic-test-architect.md +39 -0
  48. package/cli/agents/solver-epic-ui.json +15 -0
  49. package/cli/agents/solver-epic-ui.md +39 -0
  50. package/cli/agents/solver-epic-ux.json +15 -0
  51. package/cli/agents/solver-epic-ux.md +39 -0
  52. package/cli/agents/solver-story-api.json +15 -0
  53. package/cli/agents/solver-story-api.md +39 -0
  54. package/cli/agents/solver-story-backend.json +15 -0
  55. package/cli/agents/solver-story-backend.md +39 -0
  56. package/cli/agents/solver-story-cloud.json +15 -0
  57. package/cli/agents/solver-story-cloud.md +39 -0
  58. package/cli/agents/solver-story-data.json +15 -0
  59. package/cli/agents/solver-story-data.md +39 -0
  60. package/cli/agents/solver-story-database.json +15 -0
  61. package/cli/agents/solver-story-database.md +39 -0
  62. package/cli/agents/solver-story-developer.json +15 -0
  63. package/cli/agents/solver-story-developer.md +39 -0
  64. package/cli/agents/solver-story-devops.json +15 -0
  65. package/cli/agents/solver-story-devops.md +39 -0
  66. package/cli/agents/solver-story-frontend.json +15 -0
  67. package/cli/agents/solver-story-frontend.md +39 -0
  68. package/cli/agents/solver-story-mobile.json +15 -0
  69. package/cli/agents/solver-story-mobile.md +39 -0
  70. package/cli/agents/solver-story-qa.json +15 -0
  71. package/cli/agents/solver-story-qa.md +39 -0
  72. package/cli/agents/solver-story-security.json +15 -0
  73. package/cli/agents/solver-story-security.md +39 -0
  74. package/cli/agents/solver-story-solution-architect.json +15 -0
  75. package/cli/agents/solver-story-solution-architect.md +39 -0
  76. package/cli/agents/solver-story-test-architect.json +15 -0
  77. package/cli/agents/solver-story-test-architect.md +39 -0
  78. package/cli/agents/solver-story-ui.json +15 -0
  79. package/cli/agents/solver-story-ui.md +39 -0
  80. package/cli/agents/solver-story-ux.json +15 -0
  81. package/cli/agents/solver-story-ux.md +39 -0
  82. package/cli/agents/story-doc-enricher.md +133 -0
  83. package/cli/agents/suggestion-business-analyst.md +88 -0
  84. package/cli/agents/suggestion-deployment-architect.md +263 -0
  85. package/cli/agents/suggestion-product-manager.md +129 -0
  86. package/cli/agents/suggestion-security-specialist.md +156 -0
  87. package/cli/agents/suggestion-technical-architect.md +269 -0
  88. package/cli/agents/suggestion-ux-researcher.md +93 -0
  89. package/cli/agents/task-subtask-decomposer.md +188 -0
  90. package/cli/agents/validator-documentation.json +152 -0
  91. package/cli/agents/validator-documentation.md +453 -0
  92. package/cli/agents/validator-epic-api.json +93 -0
  93. package/cli/agents/validator-epic-api.md +137 -0
  94. package/cli/agents/validator-epic-backend.json +93 -0
  95. package/cli/agents/validator-epic-backend.md +130 -0
  96. package/cli/agents/validator-epic-cloud.json +93 -0
  97. package/cli/agents/validator-epic-cloud.md +137 -0
  98. package/cli/agents/validator-epic-data.json +93 -0
  99. package/cli/agents/validator-epic-data.md +130 -0
  100. package/cli/agents/validator-epic-database.json +93 -0
  101. package/cli/agents/validator-epic-database.md +137 -0
  102. package/cli/agents/validator-epic-developer.json +74 -0
  103. package/cli/agents/validator-epic-developer.md +153 -0
  104. package/cli/agents/validator-epic-devops.json +74 -0
  105. package/cli/agents/validator-epic-devops.md +153 -0
  106. package/cli/agents/validator-epic-frontend.json +74 -0
  107. package/cli/agents/validator-epic-frontend.md +153 -0
  108. package/cli/agents/validator-epic-mobile.json +93 -0
  109. package/cli/agents/validator-epic-mobile.md +130 -0
  110. package/cli/agents/validator-epic-qa.json +93 -0
  111. package/cli/agents/validator-epic-qa.md +130 -0
  112. package/cli/agents/validator-epic-security.json +74 -0
  113. package/cli/agents/validator-epic-security.md +154 -0
  114. package/cli/agents/validator-epic-solution-architect.json +74 -0
  115. package/cli/agents/validator-epic-solution-architect.md +156 -0
  116. package/cli/agents/validator-epic-test-architect.json +93 -0
  117. package/cli/agents/validator-epic-test-architect.md +130 -0
  118. package/cli/agents/validator-epic-ui.json +93 -0
  119. package/cli/agents/validator-epic-ui.md +130 -0
  120. package/cli/agents/validator-epic-ux.json +93 -0
  121. package/cli/agents/validator-epic-ux.md +130 -0
  122. package/cli/agents/validator-selector.md +211 -0
  123. package/cli/agents/validator-story-api.json +104 -0
  124. package/cli/agents/validator-story-api.md +152 -0
  125. package/cli/agents/validator-story-backend.json +104 -0
  126. package/cli/agents/validator-story-backend.md +152 -0
  127. package/cli/agents/validator-story-cloud.json +104 -0
  128. package/cli/agents/validator-story-cloud.md +152 -0
  129. package/cli/agents/validator-story-data.json +104 -0
  130. package/cli/agents/validator-story-data.md +152 -0
  131. package/cli/agents/validator-story-database.json +104 -0
  132. package/cli/agents/validator-story-database.md +152 -0
  133. package/cli/agents/validator-story-developer.json +104 -0
  134. package/cli/agents/validator-story-developer.md +152 -0
  135. package/cli/agents/validator-story-devops.json +104 -0
  136. package/cli/agents/validator-story-devops.md +152 -0
  137. package/cli/agents/validator-story-frontend.json +104 -0
  138. package/cli/agents/validator-story-frontend.md +152 -0
  139. package/cli/agents/validator-story-mobile.json +104 -0
  140. package/cli/agents/validator-story-mobile.md +152 -0
  141. package/cli/agents/validator-story-qa.json +104 -0
  142. package/cli/agents/validator-story-qa.md +152 -0
  143. package/cli/agents/validator-story-security.json +104 -0
  144. package/cli/agents/validator-story-security.md +152 -0
  145. package/cli/agents/validator-story-solution-architect.json +104 -0
  146. package/cli/agents/validator-story-solution-architect.md +152 -0
  147. package/cli/agents/validator-story-test-architect.json +104 -0
  148. package/cli/agents/validator-story-test-architect.md +152 -0
  149. package/cli/agents/validator-story-ui.json +104 -0
  150. package/cli/agents/validator-story-ui.md +152 -0
  151. package/cli/agents/validator-story-ux.json +104 -0
  152. package/cli/agents/validator-story-ux.md +152 -0
  153. package/cli/ansi-colors.js +21 -0
  154. package/cli/build-docs.js +298 -0
  155. package/cli/ceremony-history.js +369 -0
  156. package/cli/command-logger.js +245 -0
  157. package/cli/components/static-output.js +63 -0
  158. package/cli/console-output-manager.js +94 -0
  159. package/cli/docs-sync.js +306 -0
  160. package/cli/epic-story-validator.js +1174 -0
  161. package/cli/evaluation-prompts.js +1008 -0
  162. package/cli/execution-context.js +195 -0
  163. package/cli/generate-summary-table.js +340 -0
  164. package/cli/index.js +3 -25
  165. package/cli/init-model-config.js +697 -0
  166. package/cli/init.js +1765 -100
  167. package/cli/kanban-server-manager.js +228 -0
  168. package/cli/llm-claude.js +109 -0
  169. package/cli/llm-gemini.js +115 -0
  170. package/cli/llm-mock.js +233 -0
  171. package/cli/llm-openai.js +233 -0
  172. package/cli/llm-provider.js +300 -0
  173. package/cli/llm-token-limits.js +102 -0
  174. package/cli/llm-verifier.js +454 -0
  175. package/cli/logger.js +32 -5
  176. package/cli/message-constants.js +58 -0
  177. package/cli/message-manager.js +334 -0
  178. package/cli/message-types.js +96 -0
  179. package/cli/messaging-api.js +297 -0
  180. package/cli/model-pricing.js +169 -0
  181. package/cli/model-query-engine.js +468 -0
  182. package/cli/model-recommendation-analyzer.js +495 -0
  183. package/cli/model-selector.js +269 -0
  184. package/cli/output-buffer.js +107 -0
  185. package/cli/process-manager.js +332 -0
  186. package/cli/repl-ink.js +5840 -504
  187. package/cli/repl-old.js +4 -4
  188. package/cli/seed-processor.js +792 -0
  189. package/cli/sprint-planning-processor.js +1813 -0
  190. package/cli/template-processor.js +2306 -108
  191. package/cli/templates/project.md +25 -8
  192. package/cli/templates/vitepress-config.mts.template +34 -0
  193. package/cli/token-tracker.js +520 -0
  194. package/cli/tools/generate-story-validators.js +317 -0
  195. package/cli/tools/generate-validators.js +669 -0
  196. package/cli/update-checker.js +19 -17
  197. package/cli/update-notifier.js +4 -4
  198. package/cli/validation-router.js +605 -0
  199. package/cli/verification-tracker.js +563 -0
  200. package/kanban/README.md +386 -0
  201. package/kanban/client/README.md +205 -0
  202. package/kanban/client/components.json +20 -0
  203. package/kanban/client/dist/assets/index-CiD8PS2e.js +306 -0
  204. package/kanban/client/dist/assets/index-nLh0m82Q.css +1 -0
  205. package/kanban/client/dist/index.html +16 -0
  206. package/kanban/client/dist/vite.svg +1 -0
  207. package/kanban/client/index.html +15 -0
  208. package/kanban/client/package-lock.json +9442 -0
  209. package/kanban/client/package.json +44 -0
  210. package/kanban/client/postcss.config.js +6 -0
  211. package/kanban/client/public/vite.svg +1 -0
  212. package/kanban/client/src/App.jsx +622 -0
  213. package/kanban/client/src/components/ProjectFileEditorPopup.jsx +117 -0
  214. package/kanban/client/src/components/ceremony/AskArchPopup.jsx +416 -0
  215. package/kanban/client/src/components/ceremony/AskModelPopup.jsx +616 -0
  216. package/kanban/client/src/components/ceremony/CeremonyWorkflowModal.jsx +946 -0
  217. package/kanban/client/src/components/ceremony/EpicStorySelectionModal.jsx +254 -0
  218. package/kanban/client/src/components/ceremony/SponsorCallModal.jsx +619 -0
  219. package/kanban/client/src/components/ceremony/SprintPlanningModal.jsx +704 -0
  220. package/kanban/client/src/components/ceremony/steps/ArchitectureStep.jsx +150 -0
  221. package/kanban/client/src/components/ceremony/steps/CompleteStep.jsx +154 -0
  222. package/kanban/client/src/components/ceremony/steps/DatabaseStep.jsx +202 -0
  223. package/kanban/client/src/components/ceremony/steps/DeploymentStep.jsx +123 -0
  224. package/kanban/client/src/components/ceremony/steps/MissionStep.jsx +106 -0
  225. package/kanban/client/src/components/ceremony/steps/ReviewAnswersStep.jsx +125 -0
  226. package/kanban/client/src/components/ceremony/steps/RunningStep.jsx +228 -0
  227. package/kanban/client/src/components/kanban/CardDetailModal.jsx +559 -0
  228. package/kanban/client/src/components/kanban/EpicSection.jsx +146 -0
  229. package/kanban/client/src/components/kanban/FilterToolbar.jsx +222 -0
  230. package/kanban/client/src/components/kanban/GroupingSelector.jsx +57 -0
  231. package/kanban/client/src/components/kanban/KanbanBoard.jsx +211 -0
  232. package/kanban/client/src/components/kanban/KanbanCard.jsx +138 -0
  233. package/kanban/client/src/components/kanban/KanbanColumn.jsx +90 -0
  234. package/kanban/client/src/components/kanban/RefineWorkItemPopup.jsx +789 -0
  235. package/kanban/client/src/components/layout/LoadingScreen.jsx +82 -0
  236. package/kanban/client/src/components/process/ProcessMonitorBar.jsx +80 -0
  237. package/kanban/client/src/components/settings/AgentEditorPopup.jsx +171 -0
  238. package/kanban/client/src/components/settings/AgentsTab.jsx +353 -0
  239. package/kanban/client/src/components/settings/ApiKeysTab.jsx +113 -0
  240. package/kanban/client/src/components/settings/CeremonyModelsTab.jsx +98 -0
  241. package/kanban/client/src/components/settings/CostThresholdsTab.jsx +94 -0
  242. package/kanban/client/src/components/settings/ModelPricingTab.jsx +204 -0
  243. package/kanban/client/src/components/settings/ServersTab.jsx +121 -0
  244. package/kanban/client/src/components/settings/SettingsModal.jsx +84 -0
  245. package/kanban/client/src/components/stats/CostModal.jsx +353 -0
  246. package/kanban/client/src/components/ui/badge.jsx +27 -0
  247. package/kanban/client/src/components/ui/dialog.jsx +121 -0
  248. package/kanban/client/src/components/ui/tabs.jsx +85 -0
  249. package/kanban/client/src/hooks/__tests__/useGrouping.test.js +232 -0
  250. package/kanban/client/src/hooks/useGrouping.js +118 -0
  251. package/kanban/client/src/hooks/useWebSocket.js +120 -0
  252. package/kanban/client/src/lib/__tests__/api.test.js +196 -0
  253. package/kanban/client/src/lib/__tests__/status-grouping.test.js +94 -0
  254. package/kanban/client/src/lib/api.js +401 -0
  255. package/kanban/client/src/lib/status-grouping.js +144 -0
  256. package/kanban/client/src/lib/utils.js +11 -0
  257. package/kanban/client/src/main.jsx +10 -0
  258. package/kanban/client/src/store/__tests__/kanbanStore.test.js +164 -0
  259. package/kanban/client/src/store/ceremonyStore.js +172 -0
  260. package/kanban/client/src/store/filterStore.js +201 -0
  261. package/kanban/client/src/store/kanbanStore.js +115 -0
  262. package/kanban/client/src/store/processStore.js +65 -0
  263. package/kanban/client/src/store/sprintPlanningStore.js +33 -0
  264. package/kanban/client/src/styles/globals.css +59 -0
  265. package/kanban/client/tailwind.config.js +77 -0
  266. package/kanban/client/vite.config.js +28 -0
  267. package/kanban/client/vitest.config.js +28 -0
  268. package/kanban/dev-start.sh +47 -0
  269. package/kanban/package.json +12 -0
  270. package/kanban/server/index.js +516 -0
  271. package/kanban/server/routes/ceremony.js +305 -0
  272. package/kanban/server/routes/costs.js +157 -0
  273. package/kanban/server/routes/processes.js +50 -0
  274. package/kanban/server/routes/settings.js +303 -0
  275. package/kanban/server/routes/websocket.js +276 -0
  276. package/kanban/server/routes/work-items.js +347 -0
  277. package/kanban/server/services/CeremonyService.js +1190 -0
  278. package/kanban/server/services/FileSystemScanner.js +95 -0
  279. package/kanban/server/services/FileWatcher.js +144 -0
  280. package/kanban/server/services/HierarchyBuilder.js +196 -0
  281. package/kanban/server/services/ProcessRegistry.js +122 -0
  282. package/kanban/server/services/WorkItemReader.js +123 -0
  283. package/kanban/server/services/WorkItemRefineService.js +510 -0
  284. package/kanban/server/start.js +49 -0
  285. package/kanban/server/utils/kanban-logger.js +132 -0
  286. package/kanban/server/utils/markdown.js +91 -0
  287. package/kanban/server/utils/status-grouping.js +107 -0
  288. package/kanban/server/workers/sponsor-call-worker.js +84 -0
  289. package/kanban/server/workers/sprint-planning-worker.js +130 -0
  290. package/package.json +34 -7
@@ -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 &amp; 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
+ }