@builderos/create-agent-os 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/README.md +39 -0
  2. package/bin/cli.js +133 -0
  3. package/package.json +40 -0
  4. package/src/template/App.tsx +68 -0
  5. package/src/template/agent-os/commands/create-tasks/1-get-spec-requirements.md +19 -0
  6. package/src/template/agent-os/commands/create-tasks/2-create-tasks-list.md +234 -0
  7. package/src/template/agent-os/commands/create-tasks/create-tasks.md +254 -0
  8. package/src/template/agent-os/commands/design-screen/design-screen.md +32 -0
  9. package/src/template/agent-os/commands/design-shell/design-shell.md +34 -0
  10. package/src/template/agent-os/commands/design-tokens/design-tokens.md +36 -0
  11. package/src/template/agent-os/commands/export-product/export-product.md +44 -0
  12. package/src/template/agent-os/commands/implement-tasks/1-determine-tasks.md +13 -0
  13. package/src/template/agent-os/commands/implement-tasks/2-implement-tasks.md +63 -0
  14. package/src/template/agent-os/commands/implement-tasks/3-verify-implementation.md +113 -0
  15. package/src/template/agent-os/commands/implement-tasks/implement-tasks.md +207 -0
  16. package/src/template/agent-os/commands/initialize-design/initialize-design.md +54 -0
  17. package/src/template/agent-os/commands/orchestrate-tasks/orchestrate-tasks.md +180 -0
  18. package/src/template/agent-os/commands/plan-product/1-product-concept.md +53 -0
  19. package/src/template/agent-os/commands/plan-product/2-create-mission.md +78 -0
  20. package/src/template/agent-os/commands/plan-product/3-create-roadmap.md +73 -0
  21. package/src/template/agent-os/commands/plan-product/4-create-tech-stack.md +46 -0
  22. package/src/template/agent-os/commands/plan-product/plan-product.md +241 -0
  23. package/src/template/agent-os/commands/sample-data/sample-data.md +51 -0
  24. package/src/template/agent-os/commands/scaffold-implementation/scaffold-implementation.md +36 -0
  25. package/src/template/agent-os/commands/screenshot-design/screenshot-design.md +21 -0
  26. package/src/template/agent-os/commands/shape-spec/1-initialize-spec.md +95 -0
  27. package/src/template/agent-os/commands/shape-spec/2-shape-spec.md +300 -0
  28. package/src/template/agent-os/commands/shape-spec/shape-spec.md +40 -0
  29. package/src/template/agent-os/commands/write-spec/write-spec.md +134 -0
  30. package/src/template/agent-os/config.yml +13 -0
  31. package/src/template/agent-os/product/mission.md +29 -0
  32. package/src/template/agent-os/product/roadmap.md +9 -0
  33. package/src/template/agent-os/product/tech-stack.md +14 -0
  34. package/src/template/agent-os/specs/README.md +1 -0
  35. package/src/template/agent-os/standards/backend/api.md +10 -0
  36. package/src/template/agent-os/standards/backend/migrations.md +9 -0
  37. package/src/template/agent-os/standards/backend/models.md +10 -0
  38. package/src/template/agent-os/standards/backend/queries.md +9 -0
  39. package/src/template/agent-os/standards/frontend/accessibility.md +10 -0
  40. package/src/template/agent-os/standards/frontend/components.md +11 -0
  41. package/src/template/agent-os/standards/frontend/css.md +7 -0
  42. package/src/template/agent-os/standards/frontend/responsive.md +11 -0
  43. package/src/template/agent-os/standards/global/coding-style.md +10 -0
  44. package/src/template/agent-os/standards/global/commenting.md +5 -0
  45. package/src/template/agent-os/standards/global/conventions.md +11 -0
  46. package/src/template/agent-os/standards/global/error-handling.md +9 -0
  47. package/src/template/agent-os/standards/global/tech-stack.md +31 -0
  48. package/src/template/agent-os/standards/global/validation.md +11 -0
  49. package/src/template/agent-os/standards/testing/test-writing.md +9 -0
  50. package/src/template/agent-os-ui/README.md +73 -0
  51. package/src/template/agent-os-ui/package-lock.json +5028 -0
  52. package/src/template/agent-os-ui/package.json +52 -0
  53. package/src/template/agent-os-ui/postcss.config.js +6 -0
  54. package/src/template/agent-os-ui/src/components/AgentShell.tsx +31 -0
  55. package/src/template/agent-os-ui/src/components/AgentSidebar.tsx +65 -0
  56. package/src/template/agent-os-ui/src/components/GuidanceCard.tsx +75 -0
  57. package/src/template/agent-os-ui/src/components/MarkdownViewer.tsx +25 -0
  58. package/src/template/agent-os-ui/src/components/PromptButton.tsx +28 -0
  59. package/src/template/agent-os-ui/src/components/StatusItem.tsx +45 -0
  60. package/src/template/agent-os-ui/src/components/ThemeToggle.tsx +72 -0
  61. package/src/template/agent-os-ui/src/index.ts +11 -0
  62. package/src/template/agent-os-ui/src/style.css +3 -0
  63. package/src/template/agent-os-ui/tailwind.config.js +50 -0
  64. package/src/template/agent-os-ui/tsconfig.json +33 -0
  65. package/src/template/agent-os-ui/vite.config.ts +32 -0
  66. package/src/template/control-center/backend/backend.log +2 -0
  67. package/src/template/control-center/backend/index.js +228 -0
  68. package/src/template/control-center/backend/package-lock.json +951 -0
  69. package/src/template/control-center/backend/package.json +19 -0
  70. package/src/template/control-center/frontend/README.md +73 -0
  71. package/src/template/control-center/frontend/eslint.config.js +23 -0
  72. package/src/template/control-center/frontend/index.html +21 -0
  73. package/src/template/control-center/frontend/package-lock.json +5752 -0
  74. package/src/template/control-center/frontend/package.json +42 -0
  75. package/src/template/control-center/frontend/public/runtime-config.json +11 -0
  76. package/src/template/control-center/frontend/public/vite.svg +1 -0
  77. package/src/template/control-center/frontend/src/App.css +42 -0
  78. package/src/template/control-center/frontend/src/App.tsx +738 -0
  79. package/src/template/control-center/frontend/src/assets/react.svg +1 -0
  80. package/src/template/control-center/frontend/src/components/ThemeToggle.tsx +64 -0
  81. package/src/template/control-center/frontend/src/components/ui/ToastContext.tsx +81 -0
  82. package/src/template/control-center/frontend/src/index.css +194 -0
  83. package/src/template/control-center/frontend/src/main.tsx +14 -0
  84. package/src/template/control-center/frontend/src/vite-env.d.ts +1 -0
  85. package/src/template/control-center/frontend/tsconfig.app.json +28 -0
  86. package/src/template/control-center/frontend/tsconfig.json +7 -0
  87. package/src/template/control-center/frontend/tsconfig.node.json +26 -0
  88. package/src/template/control-center/frontend/vite.config.ts +22 -0
  89. package/src/template/design/.claude/commands/design-os/data-model.md +122 -0
  90. package/src/template/design/.claude/commands/design-os/design-screen.md +309 -0
  91. package/src/template/design/.claude/commands/design-os/design-shell.md +238 -0
  92. package/src/template/design/.claude/commands/design-os/design-tokens.md +166 -0
  93. package/src/template/design/.claude/commands/design-os/export-product.md +1105 -0
  94. package/src/template/design/.claude/commands/design-os/product-roadmap.md +121 -0
  95. package/src/template/design/.claude/commands/design-os/product-vision.md +99 -0
  96. package/src/template/design/.claude/commands/design-os/sample-data.md +263 -0
  97. package/src/template/design/.claude/commands/design-os/screenshot-design.md +112 -0
  98. package/src/template/design/.claude/commands/design-os/shape-section.md +138 -0
  99. package/src/template/design/.claude/skills/frontend-design/SKILL.md +42 -0
  100. package/src/template/design/.github/CODE_OF_CONDUCT.md +5 -0
  101. package/src/template/design/.github/CONTRIBUTING.md +51 -0
  102. package/src/template/design/.github/ISSUE_TEMPLATE/config.yml +22 -0
  103. package/src/template/design/.github/PULL_REQUEST_TEMPLATE.md +20 -0
  104. package/src/template/design/.github/SECURITY.yml +5 -0
  105. package/src/template/design/.github/SUPPORT.md +19 -0
  106. package/src/template/design/.github/workflows/pr-decline.yml +135 -0
  107. package/src/template/design/.github/workflows/stale.yml +25 -0
  108. package/src/template/design/CHANGELOG.md +13 -0
  109. package/src/template/design/LICENSE +21 -0
  110. package/src/template/design/README.md +54 -0
  111. package/src/template/design/agents.md +218 -0
  112. package/src/template/design/claude.md +1 -0
  113. package/src/template/design/components.json +22 -0
  114. package/src/template/design/docs/codebase-implementation.md +153 -0
  115. package/src/template/design/docs/design-section.md +135 -0
  116. package/src/template/design/docs/export.md +149 -0
  117. package/src/template/design/docs/getting-started.md +59 -0
  118. package/src/template/design/docs/index.md +56 -0
  119. package/src/template/design/docs/product-planning.md +113 -0
  120. package/src/template/design/docs/requirements.md +22 -0
  121. package/src/template/design/docs/usage.md +62 -0
  122. package/src/template/design/eslint.config.js +23 -0
  123. package/src/template/design/index.html +21 -0
  124. package/src/template/design/package-lock.json +5473 -0
  125. package/src/template/design/package.json +47 -0
  126. package/src/template/design/product-plan.zip +0 -0
  127. package/src/template/design/public/vite.svg +1 -0
  128. package/src/template/design/src/assets/react.svg +1 -0
  129. package/src/template/design/src/components/AppLayout.tsx +95 -0
  130. package/src/template/design/src/components/DataCard.tsx +139 -0
  131. package/src/template/design/src/components/DataModelPage.tsx +120 -0
  132. package/src/template/design/src/components/DesignPage.tsx +284 -0
  133. package/src/template/design/src/components/EmptyState.tsx +155 -0
  134. package/src/template/design/src/components/ExportPage.tsx +344 -0
  135. package/src/template/design/src/components/NextPhaseButton.tsx +33 -0
  136. package/src/template/design/src/components/PhaseNav.tsx +152 -0
  137. package/src/template/design/src/components/PhaseWarningBanner.tsx +81 -0
  138. package/src/template/design/src/components/ProductOverviewCard.tsx +102 -0
  139. package/src/template/design/src/components/ProductPage.tsx +97 -0
  140. package/src/template/design/src/components/ScreenDesignPage.tsx +370 -0
  141. package/src/template/design/src/components/ScreenDesignsCard.tsx +49 -0
  142. package/src/template/design/src/components/SectionPage.tsx +256 -0
  143. package/src/template/design/src/components/SectionsCard.tsx +47 -0
  144. package/src/template/design/src/components/SectionsPage.tsx +181 -0
  145. package/src/template/design/src/components/ShellCard.tsx +85 -0
  146. package/src/template/design/src/components/ShellDesignPage.tsx +242 -0
  147. package/src/template/design/src/components/SpecCard.tsx +121 -0
  148. package/src/template/design/src/components/StepIndicator.tsx +75 -0
  149. package/src/template/design/src/components/ThemeToggle.tsx +86 -0
  150. package/src/template/design/src/components/ui/ToastContext.tsx +81 -0
  151. package/src/template/design/src/components/ui/avatar.tsx +53 -0
  152. package/src/template/design/src/components/ui/badge.tsx +46 -0
  153. package/src/template/design/src/components/ui/button.tsx +60 -0
  154. package/src/template/design/src/components/ui/card.tsx +92 -0
  155. package/src/template/design/src/components/ui/collapsible.tsx +48 -0
  156. package/src/template/design/src/components/ui/dialog.tsx +143 -0
  157. package/src/template/design/src/components/ui/dropdown-menu.tsx +255 -0
  158. package/src/template/design/src/components/ui/input.tsx +21 -0
  159. package/src/template/design/src/components/ui/label.tsx +22 -0
  160. package/src/template/design/src/components/ui/progress.tsx +24 -0
  161. package/src/template/design/src/components/ui/scroll-area.tsx +18 -0
  162. package/src/template/design/src/components/ui/select.tsx +67 -0
  163. package/src/template/design/src/components/ui/separator.tsx +28 -0
  164. package/src/template/design/src/components/ui/sheet.tsx +137 -0
  165. package/src/template/design/src/components/ui/skeleton.tsx +13 -0
  166. package/src/template/design/src/components/ui/switch.tsx +46 -0
  167. package/src/template/design/src/components/ui/table.tsx +116 -0
  168. package/src/template/design/src/components/ui/tabs.tsx +64 -0
  169. package/src/template/design/src/index.css +284 -0
  170. package/src/template/design/src/lib/data-model-loader.ts +91 -0
  171. package/src/template/design/src/lib/design-system-loader.ts +101 -0
  172. package/src/template/design/src/lib/product-loader.ts +221 -0
  173. package/src/template/design/src/lib/router.tsx +52 -0
  174. package/src/template/design/src/lib/section-loader.ts +272 -0
  175. package/src/template/design/src/lib/shell-loader.ts +175 -0
  176. package/src/template/design/src/lib/utils.ts +6 -0
  177. package/src/template/design/src/main.tsx +15 -0
  178. package/src/template/design/src/sections/.gitkeep +0 -0
  179. package/src/template/design/src/sections/ai-orchestration-engine-oai/OrchestrationEngine.tsx +348 -0
  180. package/src/template/design/src/sections/core-platform-shell/AppShell.tsx +403 -0
  181. package/src/template/design/src/sections/gemini-live-integration/GeminiIntegration.tsx +332 -0
  182. package/src/template/design/src/sections/interactive-2d-canvas/WhiteboardCanvas.tsx +334 -0
  183. package/src/template/design/src/sections/participation-equity-tracker/EquityTracker.tsx +383 -0
  184. package/src/template/design/src/sections/persistent-memory-system/PersistentMemory.tsx +308 -0
  185. package/src/template/design/src/sections/real-time-communication-layer/VideoSession.tsx +342 -0
  186. package/src/template/design/src/sections/visual-intelligence-agents/VisualAgents.tsx +311 -0
  187. package/src/template/design/src/types/product.ts +97 -0
  188. package/src/template/design/src/types/section.ts +33 -0
  189. package/src/template/design/tsconfig.app.json +34 -0
  190. package/src/template/design/tsconfig.json +13 -0
  191. package/src/template/design/tsconfig.node.json +26 -0
  192. package/src/template/design/vite.config.ts +18 -0
  193. package/src/template/package.json +27 -0
  194. package/src/template/vite.config.ts +16 -0
@@ -0,0 +1,344 @@
1
+ import { useMemo } from 'react'
2
+ import { Check, AlertTriangle, FileText, FolderTree, ChevronDown, Download, Package, Copy } from 'lucide-react'
3
+ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
4
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'
5
+ import { AppLayout } from '@/components/AppLayout'
6
+ import { loadProductData, hasExportZip, getExportZipUrl } from '@/lib/product-loader'
7
+ import { getAllSectionIds, getSectionScreenDesigns } from '@/lib/section-loader'
8
+ import { useToast } from '@/components/ui/ToastContext'
9
+
10
+ export function ExportPage() {
11
+ const productData = useMemo(() => loadProductData(), [])
12
+
13
+ // Get section stats
14
+ const sectionStats = useMemo(() => {
15
+ const allSectionIds = getAllSectionIds()
16
+ const sectionCount = productData.roadmap?.sections.length || 0
17
+ const sectionsWithScreenDesigns = allSectionIds.filter(id => {
18
+ const screenDesigns = getSectionScreenDesigns(id)
19
+ return screenDesigns.length > 0
20
+ }).length
21
+ return { sectionCount, sectionsWithScreenDesigns, allSectionIds }
22
+ }, [productData.roadmap])
23
+
24
+ const hasOverview = !!productData.overview
25
+ const hasRoadmap = !!productData.roadmap
26
+ const hasDataModel = !!productData.dataModel
27
+ const hasDesignSystem = !!productData.designSystem
28
+ const hasShell = !!productData.shell
29
+ const hasSections = sectionStats.sectionsWithScreenDesigns > 0
30
+
31
+ const requiredComplete = hasOverview && hasRoadmap && hasSections
32
+
33
+ // Check for export zip
34
+ const exportZipAvailable = hasExportZip()
35
+ const exportZipUrl = getExportZipUrl()
36
+
37
+ return (
38
+ <AppLayout>
39
+ <div className="space-y-6">
40
+ {/* Page intro */}
41
+ <div className="mb-8">
42
+ <h1 className="text-2xl font-semibold text-stone-900 dark:text-stone-100 mb-2">
43
+ {exportZipAvailable ? 'Ready for implementation!' : 'Export'}
44
+ </h1>
45
+ <p className="text-stone-600 dark:text-stone-400">
46
+ {exportZipAvailable
47
+ ? 'Download your product design package and implement it in your codebase using the provided handoff prompts and assets.'
48
+ : 'Generate a complete handoff package for your development team.'}
49
+ </p>
50
+ </div>
51
+
52
+ {/* Status - only show if zip not available */}
53
+ {!exportZipAvailable && (
54
+ <Card className="border-stone-200 dark:border-stone-700 shadow-sm">
55
+ <CardHeader>
56
+ <CardTitle className="text-lg font-semibold text-stone-900 dark:text-stone-100 flex items-center gap-2">
57
+ {requiredComplete ? (
58
+ <>
59
+ <div className="w-6 h-6 rounded-full bg-lime-100 dark:bg-lime-900/30 flex items-center justify-center">
60
+ <Check className="w-4 h-4 text-lime-600 dark:text-lime-400" strokeWidth={2.5} />
61
+ </div>
62
+ Ready to Export
63
+ </>
64
+ ) : (
65
+ <>
66
+ <div className="w-6 h-6 rounded-full bg-amber-100 dark:bg-amber-900/30 flex items-center justify-center">
67
+ <AlertTriangle className="w-4 h-4 text-amber-600 dark:text-amber-400" strokeWidth={2.5} />
68
+ </div>
69
+ Not Ready
70
+ </>
71
+ )}
72
+ </CardTitle>
73
+ </CardHeader>
74
+ <CardContent>
75
+ <div className="space-y-1">
76
+ <ChecklistItem label="Product Overview" isComplete={hasOverview} />
77
+ <ChecklistItem label="Product Roadmap" isComplete={hasRoadmap} />
78
+ <ChecklistItem label="Data Model" isComplete={hasDataModel} />
79
+ <ChecklistItem label="Design System" isComplete={hasDesignSystem} />
80
+ <ChecklistItem label="Application Shell" isComplete={hasShell} />
81
+ <ChecklistItem
82
+ label={`Sections with screen designs (${sectionStats.sectionsWithScreenDesigns}/${sectionStats.sectionCount})`}
83
+ isComplete={hasSections}
84
+ />
85
+ </div>
86
+ </CardContent>
87
+ </Card>
88
+ )}
89
+
90
+ {/* Export command */}
91
+ {requiredComplete && (
92
+ <Card className="border-stone-200 dark:border-stone-700 shadow-sm">
93
+ <CardHeader>
94
+ <CardTitle className="text-lg font-semibold text-stone-900 dark:text-stone-100 flex items-center gap-2">
95
+ {exportZipAvailable ? (
96
+ <>
97
+ <div className="w-6 h-6 rounded-full bg-lime-100 dark:bg-lime-900/30 flex items-center justify-center">
98
+ <Check className="w-4 h-4 text-lime-600 dark:text-lime-400" strokeWidth={2.5} />
99
+ </div>
100
+ Export Package is Ready
101
+ </>
102
+ ) : (
103
+ 'Generate Export Package'
104
+ )}
105
+ </CardTitle>
106
+ </CardHeader>
107
+ <CardContent className="space-y-6">
108
+ {exportZipAvailable && exportZipUrl ? (
109
+ <div className="space-y-4">
110
+ <div className="flex items-center gap-3 p-4 bg-lime-50 dark:bg-lime-900/20 rounded-lg border border-lime-200 dark:border-lime-800">
111
+ <div className="w-10 h-10 rounded-full bg-lime-100 dark:bg-lime-900/40 flex items-center justify-center shrink-0">
112
+ <Package className="w-5 h-5 text-lime-600 dark:text-lime-400" strokeWidth={1.5} />
113
+ </div>
114
+ <div className="flex-1 min-w-0">
115
+ <p className="font-medium text-stone-900 dark:text-stone-100">
116
+ Synced to Agent OS & Ready for Download
117
+ </p>
118
+ <p className="text-sm text-stone-500 dark:text-stone-400">
119
+ Files handover complete. You can also download the zip backup.
120
+ </p>
121
+ </div>
122
+ <a
123
+ href={exportZipUrl}
124
+ download="product-plan.zip"
125
+ className="inline-flex items-center gap-2 px-4 py-2 bg-white hover:bg-stone-50 border border-stone-200 text-stone-700 font-medium text-sm rounded-md transition-colors shrink-0"
126
+ >
127
+ <Download className="w-4 h-4" strokeWidth={2} />
128
+ Backup
129
+ </a>
130
+ </div>
131
+ <p className="text-sm text-stone-500 dark:text-stone-400">
132
+ To regenerate and re-sync, run <code className="font-mono text-stone-700 dark:text-stone-300">/export-product</code> again.
133
+ </p>
134
+ </div>
135
+ ) : (
136
+ <div className="space-y-4">
137
+ <p className="text-stone-600 dark:text-stone-400">
138
+ Run the following command to generate the export package and <strong>automatically sync</strong> it to the Agent OS (app/agent-os):
139
+ </p>
140
+ <PromptButton
141
+ command="/export-product"
142
+ prompt="Antigravity, generate the export package and sync it. Read 'agent-os/commands/export-product/export-product.md'."
143
+ />
144
+ </div>
145
+ )}
146
+
147
+ {/* What's included */}
148
+ <div className="pt-4 border-t border-stone-200 dark:border-stone-700">
149
+ <h4 className="text-sm font-medium text-stone-500 dark:text-stone-400 uppercase tracking-wide mb-4 flex items-center gap-2">
150
+ <FolderTree className="w-4 h-4" strokeWidth={1.5} />
151
+ What's Included
152
+ </h4>
153
+ <div className="grid sm:grid-cols-2 gap-4">
154
+ <ExportItem
155
+ title="Ready-to-Use Prompts"
156
+ description="Pre-written prompts to copy/paste into your coding agent."
157
+ items={['one-shot-prompt.md', 'section-prompt.md']}
158
+ />
159
+ <ExportItem
160
+ title="Instructions"
161
+ description="Detailed implementation guides for your coding agent."
162
+ items={['product-overview.md', 'one-shot-instructions.md', 'incremental/ (milestones)']}
163
+ />
164
+ <ExportItem
165
+ title="Design System"
166
+ description="Colors, typography, and styling configuration for consistent branding."
167
+ items={['CSS tokens', 'Tailwind config', 'Font setup']}
168
+ />
169
+ <ExportItem
170
+ title="Data Model"
171
+ description="Entity definitions and sample data for your application."
172
+ items={['TypeScript types', 'Sample data', 'Entity docs']}
173
+ />
174
+ <ExportItem
175
+ title="Components"
176
+ description="React components and visual references for each section."
177
+ items={['Shell components', 'Section components', 'Screenshots']}
178
+ />
179
+ <ExportItem
180
+ title="Test Instructions"
181
+ description="Framework-agnostic test specs for TDD implementation."
182
+ items={['tests.md per section', 'User flow tests', 'Empty state tests']}
183
+ />
184
+ </div>
185
+ </div>
186
+ </CardContent>
187
+ </Card>
188
+ )}
189
+
190
+ {/* How to use */}
191
+ <Card className="border-stone-200 dark:border-stone-700 shadow-sm">
192
+ <CardHeader>
193
+ <CardTitle className="text-lg font-semibold text-stone-900 dark:text-stone-100 flex items-center gap-2">
194
+ <FileText className="w-5 h-5 text-stone-500 dark:text-stone-400" strokeWidth={1.5} />
195
+ How to Use the Export
196
+ </CardTitle>
197
+ </CardHeader>
198
+ <CardContent className="space-y-4">
199
+ {/* Option A - Incremental (Recommended) */}
200
+ <Collapsible>
201
+ <CollapsibleTrigger className="flex items-start justify-between w-full text-left group">
202
+ <div className="flex-1">
203
+ <h4 className="font-medium text-stone-900 dark:text-stone-100">
204
+ Option A: Incremental (Recommended)
205
+ </h4>
206
+ <p className="text-sm text-stone-500 dark:text-stone-400 mt-1">
207
+ Build milestone by milestone for better control and easier debugging.
208
+ </p>
209
+ </div>
210
+ <ChevronDown className="w-4 h-4 text-stone-400 dark:text-stone-500 mt-1 shrink-0 transition-transform group-data-[state=open]:rotate-180" strokeWidth={1.5} />
211
+ </CollapsibleTrigger>
212
+ <CollapsibleContent>
213
+ <ol className="text-sm text-stone-600 dark:text-stone-400 space-y-2 list-decimal list-inside mt-4 pl-1">
214
+ <li>Copy the <code className="font-mono text-stone-800 dark:text-stone-200">product-plan/</code> folder into your codebase</li>
215
+ <li>Start with Foundation (<code className="font-mono text-stone-800 dark:text-stone-200">instructions/incremental/01-foundation.md</code>)</li>
216
+ <li>Then Shell (<code className="font-mono text-stone-800 dark:text-stone-200">instructions/incremental/02-shell.md</code>)</li>
217
+ <li>
218
+ For each section:
219
+ <ul className="mt-1.5 ml-5 space-y-1">
220
+ <li className="flex items-center gap-2">
221
+ <span className="w-1 h-1 rounded-full bg-stone-400 dark:bg-stone-500" />
222
+ Open <code className="font-mono text-stone-800 dark:text-stone-200">prompts/section-prompt.md</code>
223
+ </li>
224
+ <li className="flex items-center gap-2">
225
+ <span className="w-1 h-1 rounded-full bg-stone-400 dark:bg-stone-500" />
226
+ Fill in the section variables at the top (SECTION_NAME, SECTION_ID, NN)
227
+ </li>
228
+ <li className="flex items-center gap-2">
229
+ <span className="w-1 h-1 rounded-full bg-stone-400 dark:bg-stone-500" />
230
+ Copy/paste the prompt into your AI coding agent
231
+ </li>
232
+ </ul>
233
+ </li>
234
+ <li>Review and test after each milestone before moving to the next</li>
235
+ </ol>
236
+ </CollapsibleContent>
237
+ </Collapsible>
238
+
239
+ <div className="border-t border-stone-200 dark:border-stone-700" />
240
+
241
+ {/* Option B - One-Shot */}
242
+ <Collapsible>
243
+ <CollapsibleTrigger className="flex items-start justify-between w-full text-left group">
244
+ <div className="flex-1">
245
+ <h4 className="font-medium text-stone-900 dark:text-stone-100">
246
+ Option B: One-Shot
247
+ </h4>
248
+ <p className="text-sm text-stone-500 dark:text-stone-400 mt-1">
249
+ Build the entire app in one session using a pre-written prompt.
250
+ </p>
251
+ </div>
252
+ <ChevronDown className="w-4 h-4 text-stone-400 dark:text-stone-500 mt-1 shrink-0 transition-transform group-data-[state=open]:rotate-180" strokeWidth={1.5} />
253
+ </CollapsibleTrigger>
254
+ <CollapsibleContent>
255
+ <ol className="text-sm text-stone-600 dark:text-stone-400 space-y-2 list-decimal list-inside mt-4 pl-1">
256
+ <li>Copy the <code className="font-mono text-stone-800 dark:text-stone-200">product-plan/</code> folder into your codebase</li>
257
+ <li>Open <code className="font-mono text-stone-800 dark:text-stone-200">prompts/one-shot-prompt.md</code></li>
258
+ <li>Add any additional notes to the prompt (tech stack preferences, etc.)</li>
259
+ <li>Copy/paste the prompt into your AI coding agent</li>
260
+ <li>Answer the agent's clarifying questions about auth, user modeling, etc.</li>
261
+ <li>Let the agent plan and implement everything</li>
262
+ </ol>
263
+ </CollapsibleContent>
264
+ </Collapsible>
265
+ </CardContent>
266
+ </Card>
267
+ </div>
268
+ </AppLayout>
269
+ )
270
+ }
271
+
272
+ interface ChecklistItemProps {
273
+ label: string
274
+ isComplete: boolean
275
+ }
276
+
277
+ function ChecklistItem({ label, isComplete }: ChecklistItemProps) {
278
+ return (
279
+ <div className="flex items-center gap-2 py-1">
280
+ {isComplete ? (
281
+ <div className="w-4 h-4 rounded bg-stone-200 dark:bg-stone-700 flex items-center justify-center">
282
+ <Check className="w-2.5 h-2.5 text-stone-600 dark:text-stone-400" strokeWidth={3} />
283
+ </div>
284
+ ) : (
285
+ <div className="w-4 h-4 rounded border-2 border-amber-400 dark:border-amber-500" />
286
+ )}
287
+ <span className="text-sm text-stone-700 dark:text-stone-300">
288
+ {label}
289
+ </span>
290
+ </div>
291
+ )
292
+ }
293
+
294
+ interface ExportItemProps {
295
+ title: string
296
+ description: string
297
+ items: string[]
298
+ }
299
+
300
+ function ExportItem({ title, description, items }: ExportItemProps) {
301
+ return (
302
+ <div className="bg-stone-50 dark:bg-stone-800/50 rounded-lg p-4">
303
+ <h4 className="font-medium text-stone-900 dark:text-stone-100 mb-1">{title}</h4>
304
+ <p className="text-xs text-stone-500 dark:text-stone-400 mb-3">{description}</p>
305
+ <ul className="text-sm text-stone-600 dark:text-stone-400 space-y-1">
306
+ {items.map((item, index) => (
307
+ <li key={index} className="flex items-center gap-2">
308
+ <span className="w-1 h-1 rounded-full bg-stone-400 dark:bg-stone-500" />
309
+ {item}
310
+ </li>
311
+ ))}
312
+ </ul>
313
+ </div>
314
+ )
315
+ }
316
+
317
+ function PromptButton({ command, prompt }: { command: string, prompt: string }) {
318
+ const { toast } = useToast()
319
+
320
+ const copyPrompt = () => {
321
+ navigator.clipboard.writeText(prompt)
322
+ toast({
323
+ title: "Prompt Copied!",
324
+ description: "Paste it into the Agent terminal to run the action.",
325
+ type: "success"
326
+ })
327
+ }
328
+
329
+ return (
330
+ <div className="bg-stone-100 dark:bg-stone-800 rounded-md px-4 py-2.5 w-full">
331
+ <button
332
+ onClick={copyPrompt}
333
+ className="w-full flex items-center justify-center gap-2 text-stone-700 dark:text-stone-300 hover:text-stone-900 dark:hover:text-stone-100 transition-colors mb-1"
334
+ title="Copy Agent Prompt"
335
+ >
336
+ <span className="text-xs font-medium uppercase tracking-wider text-stone-500">Run Action</span>
337
+ <Copy size={14} />
338
+ </button>
339
+ <code className="block text-center text-sm font-mono text-stone-700 dark:text-stone-300">
340
+ {command}
341
+ </code>
342
+ </div>
343
+ )
344
+ }
@@ -0,0 +1,33 @@
1
+ import { useNavigate } from 'react-router-dom'
2
+ import { FileText, Boxes, Layout, LayoutList, Package, ArrowRight } from 'lucide-react'
3
+ import type { Phase } from './PhaseNav'
4
+
5
+ interface NextPhaseButtonProps {
6
+ nextPhase: Exclude<Phase, 'product'> // Can't navigate "next" to product since it's first
7
+ }
8
+
9
+ const phaseConfig: Record<Exclude<Phase, 'product'>, { label: string; icon: typeof FileText; path: string }> = {
10
+ 'data-model': { label: 'Data Model', icon: Boxes, path: '/data-model' },
11
+ 'design': { label: 'Design', icon: Layout, path: '/design' },
12
+ 'sections': { label: 'Sections', icon: LayoutList, path: '/sections' },
13
+ 'export': { label: 'Export', icon: Package, path: '/export' },
14
+ }
15
+
16
+ export function NextPhaseButton({ nextPhase }: NextPhaseButtonProps) {
17
+ const navigate = useNavigate()
18
+ const config = phaseConfig[nextPhase]
19
+ const Icon = config.icon
20
+
21
+ return (
22
+ <button
23
+ onClick={() => navigate(config.path)}
24
+ className="w-full flex items-center justify-between gap-4 px-6 py-4 bg-stone-900 dark:bg-stone-100 text-stone-100 dark:text-stone-900 rounded-lg hover:bg-stone-800 dark:hover:bg-stone-200 transition-colors group"
25
+ >
26
+ <div className="flex items-center gap-3">
27
+ <Icon className="w-5 h-5" strokeWidth={1.5} />
28
+ <span className="font-medium">Continue to {config.label}</span>
29
+ </div>
30
+ <ArrowRight className="w-5 h-5 transition-transform group-hover:translate-x-1" strokeWidth={1.5} />
31
+ </button>
32
+ )
33
+ }
@@ -0,0 +1,152 @@
1
+ import { useLocation, useNavigate } from 'react-router-dom'
2
+ import { useMemo } from 'react'
3
+ import { FileText, Boxes, Layout, LayoutList, Package } from 'lucide-react'
4
+ import { loadProductData, hasExportZip } from '@/lib/product-loader'
5
+ import { getAllSectionIds, getSectionScreenDesigns, hasSectionSpec } from '@/lib/section-loader'
6
+
7
+ export type Phase = 'product' | 'data-model' | 'design' | 'sections' | 'export'
8
+
9
+ interface PhaseConfig {
10
+ id: Phase
11
+ label: string
12
+ icon: typeof FileText
13
+ path: string
14
+ }
15
+
16
+ const phases: PhaseConfig[] = [
17
+ { id: 'product', label: 'Product', icon: FileText, path: '/' },
18
+ { id: 'data-model', label: 'Data Model', icon: Boxes, path: '/data-model' },
19
+ { id: 'design', label: 'Design', icon: Layout, path: '/design' },
20
+ { id: 'sections', label: 'Sections', icon: LayoutList, path: '/sections' },
21
+ { id: 'export', label: 'Export', icon: Package, path: '/export' },
22
+ ]
23
+
24
+ export type PhaseStatus = 'completed' | 'current' | 'upcoming'
25
+
26
+ interface PhaseInfo {
27
+ phase: PhaseConfig
28
+ status: PhaseStatus
29
+ isComplete: boolean
30
+ }
31
+
32
+ function usePhaseStatuses(): PhaseInfo[] {
33
+ const location = useLocation()
34
+ const productData = useMemo(() => loadProductData(), [])
35
+
36
+ // Calculate completion status for each phase
37
+ const hasOverview = !!productData.overview
38
+ const hasRoadmap = !!productData.roadmap
39
+ const hasDataModel = !!productData.dataModel
40
+ const hasDesignSystem = !!productData.designSystem
41
+ const hasShell = !!productData.shell
42
+
43
+ const sectionIds = useMemo(() => getAllSectionIds(), [])
44
+ const sectionsWithScreenDesigns = useMemo(() => {
45
+ return sectionIds.filter(id => getSectionScreenDesigns(id).length > 0 && hasSectionSpec(id)).length
46
+ }, [sectionIds])
47
+ const hasSections = sectionsWithScreenDesigns > 0
48
+
49
+ // Determine current phase from URL
50
+ const currentPath = location.pathname
51
+ let currentPhaseId: Phase = 'product'
52
+
53
+ if (currentPath === '/' || currentPath === '/product') {
54
+ currentPhaseId = 'product'
55
+ } else if (currentPath === '/data-model') {
56
+ currentPhaseId = 'data-model'
57
+ } else if (currentPath === '/design' || currentPath === '/design-system' || currentPath.startsWith('/shell')) {
58
+ currentPhaseId = 'design'
59
+ } else if (currentPath === '/sections' || currentPath.startsWith('/sections/')) {
60
+ currentPhaseId = 'sections'
61
+ } else if (currentPath === '/export') {
62
+ currentPhaseId = 'export'
63
+ }
64
+
65
+ // Check if export zip exists
66
+ const exportZipExists = hasExportZip()
67
+
68
+ // Determine completion status
69
+ const phaseComplete: Record<Phase, boolean> = {
70
+ 'product': hasOverview && hasRoadmap,
71
+ 'data-model': hasDataModel,
72
+ 'design': hasDesignSystem || hasShell,
73
+ 'sections': hasSections,
74
+ 'export': exportZipExists,
75
+ }
76
+
77
+ return phases.map(phase => {
78
+ const isComplete = phaseComplete[phase.id]
79
+ let status: PhaseStatus
80
+ if (phase.id === currentPhaseId) {
81
+ status = 'current'
82
+ } else if (isComplete) {
83
+ status = 'completed'
84
+ } else {
85
+ status = 'upcoming'
86
+ }
87
+ return { phase, status, isComplete }
88
+ })
89
+ }
90
+
91
+ export function PhaseNav() {
92
+ const navigate = useNavigate()
93
+ const phaseInfos = usePhaseStatuses()
94
+
95
+ return (
96
+ <nav className="flex items-center justify-center">
97
+ {phaseInfos.map(({ phase, status, isComplete }, index) => {
98
+ const Icon = phase.icon
99
+ const isFirst = index === 0
100
+
101
+ return (
102
+ <div key={phase.id} className="flex items-center">
103
+ {/* Connector line */}
104
+ {!isFirst && (
105
+ <div
106
+ className={`w-4 sm:w-8 lg:w-12 h-px transition-colors duration-200 ${status === 'upcoming'
107
+ ? 'bg-stone-200 dark:bg-stone-700'
108
+ : 'bg-stone-400 dark:bg-stone-500'
109
+ }`}
110
+ />
111
+ )}
112
+
113
+ {/* Phase button */}
114
+ <button
115
+ onClick={() => navigate(phase.path)}
116
+ className={`
117
+ group relative flex items-center gap-1.5 sm:gap-2 px-2 sm:px-3 py-1.5 sm:py-2 rounded-lg transition-all duration-200 whitespace-nowrap
118
+ ${status === 'current'
119
+ ? 'bg-stone-900 dark:bg-stone-100 text-stone-100 dark:text-stone-900 shadow-sm'
120
+ : status === 'completed'
121
+ ? 'bg-stone-100 dark:bg-stone-800 text-stone-700 dark:text-stone-300 hover:bg-stone-200 dark:hover:bg-stone-700'
122
+ : 'text-stone-400 dark:text-stone-500 hover:text-stone-600 dark:hover:text-stone-400 hover:bg-stone-50 dark:hover:bg-stone-800/50'
123
+ }
124
+ `}
125
+ >
126
+ <Icon
127
+ className={`w-4 h-4 shrink-0 transition-transform duration-200 group-hover:scale-110 ${status === 'current' ? '' : status === 'completed' ? '' : 'opacity-60'
128
+ }`}
129
+ strokeWidth={1.5}
130
+ />
131
+ <span className={`text-sm font-medium hidden sm:inline ${status === 'upcoming' ? 'opacity-60' : ''
132
+ }`}>
133
+ {phase.label}
134
+ </span>
135
+
136
+ {/* Completion indicator - check circle at top-left (shows even when current) */}
137
+ {isComplete && (
138
+ <span className="absolute -top-1 -left-1 w-4 h-4 rounded-full bg-lime-500 flex items-center justify-center shadow-sm">
139
+ <svg className="w-2.5 h-2.5 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
140
+ <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
141
+ </svg>
142
+ </span>
143
+ )}
144
+ </button>
145
+ </div>
146
+ )
147
+ })}
148
+ </nav>
149
+ )
150
+ }
151
+
152
+ export { phases }
@@ -0,0 +1,81 @@
1
+ import { useState, useEffect, useMemo } from 'react'
2
+ import { Link } from 'react-router-dom'
3
+ import { AlertTriangle, X } from 'lucide-react'
4
+ import { loadProductData } from '@/lib/product-loader'
5
+
6
+ /**
7
+ * Get a storage key based on the product name to track dismissed warnings per product
8
+ */
9
+ function getStorageKey(productName: string): string {
10
+ const sanitized = productName.toLowerCase().replace(/[^a-z0-9]+/g, '-')
11
+ return `design-os-phase-warning-dismissed-${sanitized}`
12
+ }
13
+
14
+ export function PhaseWarningBanner() {
15
+ const productData = useMemo(() => loadProductData(), [])
16
+ const [isDismissed, setIsDismissed] = useState(true) // Start dismissed to avoid flash
17
+
18
+ const hasDataModel = !!productData.dataModel
19
+ const hasDesignSystem = !!(productData.designSystem?.colors || productData.designSystem?.typography)
20
+ const hasShell = !!productData.shell?.spec
21
+ const hasDesign = hasDesignSystem || hasShell
22
+
23
+ const productName = productData.overview?.name || 'default-product'
24
+ const storageKey = getStorageKey(productName)
25
+
26
+ // Check localStorage on mount
27
+ useEffect(() => {
28
+ const dismissed = localStorage.getItem(storageKey) === 'true'
29
+ setIsDismissed(dismissed)
30
+ }, [storageKey])
31
+
32
+ const handleDismiss = () => {
33
+ localStorage.setItem(storageKey, 'true')
34
+ setIsDismissed(true)
35
+ }
36
+
37
+ // Don't show if both phases are complete or if dismissed
38
+ if ((hasDataModel && hasDesign) || isDismissed) {
39
+ return null
40
+ }
41
+
42
+ // Build the warning message
43
+ const missingPhases: { name: string; path: string }[] = []
44
+ if (!hasDataModel) {
45
+ missingPhases.push({ name: 'Data Model', path: '/data-model' })
46
+ }
47
+ if (!hasDesign) {
48
+ missingPhases.push({ name: 'Design', path: '/design' })
49
+ }
50
+
51
+ return (
52
+ <div className="bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg px-4 py-3 mb-6">
53
+ <div className="flex items-start gap-3">
54
+ <AlertTriangle className="w-4 h-4 text-amber-600 dark:text-amber-400 mt-0.5 shrink-0" strokeWidth={2} />
55
+ <div className="flex-1 min-w-0">
56
+ <p className="text-sm text-amber-800 dark:text-amber-200">
57
+ Consider completing{' '}
58
+ {missingPhases.map((phase, index) => (
59
+ <span key={phase.path}>
60
+ {index > 0 && ' and '}
61
+ <Link
62
+ to={phase.path}
63
+ className="font-medium underline hover:no-underline"
64
+ >
65
+ {phase.name}
66
+ </Link>
67
+ </span>
68
+ ))}{' '}
69
+ before designing sections.
70
+ </p>
71
+ </div>
72
+ <button
73
+ onClick={handleDismiss}
74
+ className="text-amber-600 dark:text-amber-400 hover:text-amber-800 dark:hover:text-amber-200 transition-colors shrink-0"
75
+ >
76
+ <X className="w-4 h-4" strokeWidth={2} />
77
+ </button>
78
+ </div>
79
+ </div>
80
+ )
81
+ }