@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,52 @@
1
+ import { createBrowserRouter } from 'react-router-dom'
2
+ import { ProductPage } from '@/components/ProductPage'
3
+ import { DataModelPage } from '@/components/DataModelPage'
4
+ import { DesignPage } from '@/components/DesignPage'
5
+ import { SectionsPage } from '@/components/SectionsPage'
6
+ import { SectionPage } from '@/components/SectionPage'
7
+ import { ScreenDesignPage, ScreenDesignFullscreen } from '@/components/ScreenDesignPage'
8
+ import { ShellDesignPage, ShellDesignFullscreen } from '@/components/ShellDesignPage'
9
+ import { ExportPage } from '@/components/ExportPage'
10
+
11
+ export const router = createBrowserRouter([
12
+ {
13
+ path: '/',
14
+ element: <ProductPage />,
15
+ },
16
+ {
17
+ path: '/data-model',
18
+ element: <DataModelPage />,
19
+ },
20
+ {
21
+ path: '/design',
22
+ element: <DesignPage />,
23
+ },
24
+ {
25
+ path: '/sections',
26
+ element: <SectionsPage />,
27
+ },
28
+ {
29
+ path: '/sections/:sectionId',
30
+ element: <SectionPage />,
31
+ },
32
+ {
33
+ path: '/sections/:sectionId/screen-designs/:screenDesignName',
34
+ element: <ScreenDesignPage />,
35
+ },
36
+ {
37
+ path: '/sections/:sectionId/screen-designs/:screenDesignName/fullscreen',
38
+ element: <ScreenDesignFullscreen />,
39
+ },
40
+ {
41
+ path: '/shell/design',
42
+ element: <ShellDesignPage />,
43
+ },
44
+ {
45
+ path: '/shell/design/fullscreen',
46
+ element: <ShellDesignFullscreen />,
47
+ },
48
+ {
49
+ path: '/export',
50
+ element: <ExportPage />,
51
+ },
52
+ ])
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Section data loading utilities for spec.md, data.json, and screen designs
3
+ *
4
+ * File structure:
5
+ * - product/sections/[section-id]/spec.md - Section specification
6
+ * - product/sections/[section-id]/data.json - Sample data
7
+ * - src/sections/[section-id]/[PageName].tsx - Screen design pages
8
+ */
9
+
10
+ import type { SectionData, ParsedSpec, ScreenDesignInfo, ScreenshotInfo } from '@/types/section'
11
+ import type { ComponentType } from 'react'
12
+
13
+ // Load spec.md files from product/sections at build time
14
+ const specFiles = import.meta.glob('/product/sections/*/spec.md', {
15
+ query: '?raw',
16
+ import: 'default',
17
+ eager: true,
18
+ }) as Record<string, string>
19
+
20
+ // Load data.json files from product/sections at build time
21
+ const dataFiles = import.meta.glob('/product/sections/*/data.json', {
22
+ eager: true,
23
+ }) as Record<string, { default: Record<string, unknown> }>
24
+
25
+ // Load screen design components from src/sections lazily
26
+ const screenDesignModules = import.meta.glob('/src/sections/*/*.tsx') as Record<
27
+ string,
28
+ () => Promise<{ default: ComponentType }>
29
+ >
30
+
31
+ // Load screenshot files from product/sections at build time
32
+ const screenshotFiles = import.meta.glob('/product/sections/*/*.png', {
33
+ query: '?url',
34
+ import: 'default',
35
+ eager: true,
36
+ }) as Record<string, string>
37
+
38
+ /**
39
+ * Extract section ID from a product/sections file path
40
+ * e.g., "/product/sections/invoices/spec.md" -> "invoices"
41
+ */
42
+ function extractSectionIdFromProduct(path: string): string | null {
43
+ const match = path.match(/\/product\/sections\/([^/]+)\//)
44
+ return match?.[1] || null
45
+ }
46
+
47
+ /**
48
+ * Extract section ID from a src/sections file path
49
+ * e.g., "/src/sections/invoices/InvoiceList.tsx" -> "invoices"
50
+ */
51
+ function extractSectionIdFromSrc(path: string): string | null {
52
+ const match = path.match(/\/src\/sections\/([^/]+)\//)
53
+ return match?.[1] || null
54
+ }
55
+
56
+ /**
57
+ * Extract screen design name from a file path
58
+ * e.g., "/src/sections/invoices/InvoiceList.tsx" -> "InvoiceList"
59
+ */
60
+ function extractScreenDesignName(path: string): string | null {
61
+ const match = path.match(/\/src\/sections\/[^/]+\/([^/]+)\.tsx$/)
62
+ return match?.[1] || null
63
+ }
64
+
65
+ /**
66
+ * Extract screenshot name from a file path
67
+ * e.g., "/product/sections/invoices/invoice-list.png" -> "invoice-list"
68
+ */
69
+ function extractScreenshotName(path: string): string | null {
70
+ const match = path.match(/\/product\/sections\/[^/]+\/([^/]+)\.png$/)
71
+ return match?.[1] || null
72
+ }
73
+
74
+ /**
75
+ * Parse spec.md content into ParsedSpec structure
76
+ *
77
+ * Expected format:
78
+ * # Section Specification
79
+ *
80
+ * ## Overview
81
+ * [Brief description of the section]
82
+ *
83
+ * ## User Flows
84
+ * - Flow 1
85
+ * - Flow 2
86
+ *
87
+ * ## UI Requirements
88
+ * - Requirement 1
89
+ * - Requirement 2
90
+ *
91
+ * ## Configuration (optional)
92
+ * - shell: false (to disable app shell wrapping for this section's screen designs)
93
+ */
94
+ export function parseSpec(md: string): ParsedSpec | null {
95
+ if (!md || !md.trim()) return null
96
+
97
+ try {
98
+ // Extract title from first # heading
99
+ const titleMatch = md.match(/^#\s+(.+)$/m)
100
+ const title = titleMatch?.[1]?.trim() || 'Section Specification'
101
+
102
+ // Extract overview - content between ## Overview and next ##
103
+ const overviewMatch = md.match(/## Overview\s*\n+([\s\S]*?)(?=\n## |\n#[^#]|$)/)
104
+ const overview = overviewMatch?.[1]?.trim() || ''
105
+
106
+ // Extract user flows - bullet list after ## User Flows
107
+ const userFlowsSection = md.match(/## User Flows\s*\n+([\s\S]*?)(?=\n## |\n#[^#]|$)/)
108
+ const userFlows: string[] = []
109
+
110
+ if (userFlowsSection?.[1]) {
111
+ const lines = userFlowsSection[1].split('\n')
112
+ for (const line of lines) {
113
+ const trimmed = line.trim()
114
+ if (trimmed.startsWith('- ')) {
115
+ userFlows.push(trimmed.slice(2).trim())
116
+ }
117
+ }
118
+ }
119
+
120
+ // Extract UI requirements - bullet list after ## UI Requirements
121
+ const uiReqSection = md.match(/## UI Requirements\s*\n+([\s\S]*?)(?=\n## |\n#[^#]|$)/)
122
+ const uiRequirements: string[] = []
123
+
124
+ if (uiReqSection?.[1]) {
125
+ const lines = uiReqSection[1].split('\n')
126
+ for (const line of lines) {
127
+ const trimmed = line.trim()
128
+ if (trimmed.startsWith('- ')) {
129
+ uiRequirements.push(trimmed.slice(2).trim())
130
+ }
131
+ }
132
+ }
133
+
134
+ // Extract configuration - check for shell: false
135
+ // Look for "shell: false" or "- shell: false" anywhere in the document
136
+ const shellDisabled = /(?:^|\n)\s*-?\s*shell\s*:\s*false/i.test(md)
137
+ const useShell = !shellDisabled
138
+
139
+ return { title, overview, userFlows, uiRequirements, useShell }
140
+ } catch {
141
+ return null
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Get screen designs for a specific section
147
+ */
148
+ export function getSectionScreenDesigns(sectionId: string): ScreenDesignInfo[] {
149
+ const screenDesigns: ScreenDesignInfo[] = []
150
+ const prefix = `/src/sections/${sectionId}/`
151
+
152
+ for (const path of Object.keys(screenDesignModules)) {
153
+ if (path.startsWith(prefix)) {
154
+ const name = extractScreenDesignName(path)
155
+ if (name) {
156
+ screenDesigns.push({
157
+ name,
158
+ path,
159
+ componentName: name,
160
+ })
161
+ }
162
+ }
163
+ }
164
+
165
+ return screenDesigns
166
+ }
167
+
168
+ /**
169
+ * Get screenshots for a specific section
170
+ */
171
+ export function getSectionScreenshots(sectionId: string): ScreenshotInfo[] {
172
+ const screenshots: ScreenshotInfo[] = []
173
+ const prefix = `/product/sections/${sectionId}/`
174
+
175
+ for (const [path, url] of Object.entries(screenshotFiles)) {
176
+ if (path.startsWith(prefix)) {
177
+ const name = extractScreenshotName(path)
178
+ if (name) {
179
+ screenshots.push({
180
+ name,
181
+ path,
182
+ url,
183
+ })
184
+ }
185
+ }
186
+ }
187
+
188
+ return screenshots
189
+ }
190
+
191
+ /**
192
+ * Load screen design component dynamically
193
+ */
194
+ export function loadScreenDesignComponent(
195
+ sectionId: string,
196
+ screenDesignName: string
197
+ ): (() => Promise<{ default: ComponentType }>) | null {
198
+ const path = `/src/sections/${sectionId}/${screenDesignName}.tsx`
199
+ return screenDesignModules[path] || null
200
+ }
201
+
202
+ /**
203
+ * Load all data for a specific section
204
+ */
205
+ export function loadSectionData(sectionId: string): SectionData {
206
+ const specPath = `/product/sections/${sectionId}/spec.md`
207
+ const dataPath = `/product/sections/${sectionId}/data.json`
208
+
209
+ const specContent = specFiles[specPath] || null
210
+ const dataModule = dataFiles[dataPath]
211
+ const data = dataModule?.default || null
212
+
213
+ return {
214
+ sectionId,
215
+ spec: specContent,
216
+ specParsed: specContent ? parseSpec(specContent) : null,
217
+ data,
218
+ screenDesigns: getSectionScreenDesigns(sectionId),
219
+ screenshots: getSectionScreenshots(sectionId),
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Check if a section has a spec.md file
225
+ */
226
+ export function hasSectionSpec(sectionId: string): boolean {
227
+ return `/product/sections/${sectionId}/spec.md` in specFiles
228
+ }
229
+
230
+ /**
231
+ * Check if a section's screen designs should use the app shell
232
+ * Returns true by default, false if spec contains "shell: false"
233
+ */
234
+ export function sectionUsesShell(sectionId: string): boolean {
235
+ const specPath = `/product/sections/${sectionId}/spec.md`
236
+ const specContent = specFiles[specPath]
237
+ if (!specContent) return true // Default to using shell if no spec
238
+
239
+ const parsed = parseSpec(specContent)
240
+ return parsed?.useShell ?? true
241
+ }
242
+
243
+ /**
244
+ * Check if a section has a data.json file
245
+ */
246
+ export function hasSectionData(sectionId: string): boolean {
247
+ return `/product/sections/${sectionId}/data.json` in dataFiles
248
+ }
249
+
250
+ /**
251
+ * Get all section IDs that have any artifacts
252
+ */
253
+ export function getAllSectionIds(): string[] {
254
+ const ids = new Set<string>()
255
+
256
+ for (const path of Object.keys(specFiles)) {
257
+ const id = extractSectionIdFromProduct(path)
258
+ if (id) ids.add(id)
259
+ }
260
+
261
+ for (const path of Object.keys(dataFiles)) {
262
+ const id = extractSectionIdFromProduct(path)
263
+ if (id) ids.add(id)
264
+ }
265
+
266
+ for (const path of Object.keys(screenDesignModules)) {
267
+ const id = extractSectionIdFromSrc(path)
268
+ if (id) ids.add(id)
269
+ }
270
+
271
+ return Array.from(ids)
272
+ }
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Shell loading and parsing utilities
3
+ */
4
+
5
+ import type { ShellSpec, ShellInfo } from '@/types/product'
6
+ import type { ComponentType, ReactNode } from 'react'
7
+
8
+ // Load shell spec markdown file at build time
9
+ const shellSpecFiles = import.meta.glob('/product/shell/*.md', {
10
+ query: '?raw',
11
+ import: 'default',
12
+ eager: true,
13
+ }) as Record<string, string>
14
+
15
+ // Load shell components lazily
16
+ const shellComponentModules = import.meta.glob('/src/shell/components/*.tsx') as Record<
17
+ string,
18
+ () => Promise<{ default: ComponentType }>
19
+ >
20
+
21
+ // Load shell preview component lazily
22
+ const shellPreviewModules = import.meta.glob('/src/shell/*.tsx') as Record<
23
+ string,
24
+ () => Promise<{ default: ComponentType }>
25
+ >
26
+
27
+ /**
28
+ * Parse shell spec.md content into ShellSpec structure
29
+ *
30
+ * Expected format:
31
+ * # Application Shell Specification
32
+ *
33
+ * ## Overview
34
+ * Description of the shell design
35
+ *
36
+ * ## Navigation Structure
37
+ * - Nav Item 1 → Section
38
+ * - Nav Item 2 → Section
39
+ *
40
+ * ## Layout Pattern
41
+ * Description of layout (sidebar, top nav, etc.)
42
+ */
43
+ export function parseShellSpec(md: string): ShellSpec | null {
44
+ if (!md || !md.trim()) return null
45
+
46
+ try {
47
+ // Extract overview
48
+ const overviewMatch = md.match(/## Overview\s*\n+([\s\S]*?)(?=\n## |\n#[^#]|$)/)
49
+ const overview = overviewMatch?.[1]?.trim() || ''
50
+
51
+ // Extract navigation items
52
+ const navSection = md.match(/## Navigation Structure\s*\n+([\s\S]*?)(?=\n## |\n#[^#]|$)/)
53
+ const navigationItems: string[] = []
54
+
55
+ if (navSection?.[1]) {
56
+ const lines = navSection[1].split('\n')
57
+ for (const line of lines) {
58
+ const trimmed = line.trim()
59
+ if (trimmed.startsWith('- ')) {
60
+ navigationItems.push(trimmed.slice(2).trim())
61
+ }
62
+ }
63
+ }
64
+
65
+ // Extract layout pattern
66
+ const layoutMatch = md.match(/## Layout Pattern\s*\n+([\s\S]*?)(?=\n## |\n#[^#]|$)/)
67
+ const layoutPattern = layoutMatch?.[1]?.trim() || ''
68
+
69
+ // Return null if we couldn't parse anything meaningful
70
+ if (!overview && navigationItems.length === 0 && !layoutPattern) {
71
+ return null
72
+ }
73
+
74
+ return {
75
+ raw: md,
76
+ overview,
77
+ navigationItems,
78
+ layoutPattern,
79
+ }
80
+ } catch {
81
+ return null
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Check if shell components exist
87
+ */
88
+ export function hasShellComponents(): boolean {
89
+ // Check if AppShell.tsx exists
90
+ const exists = '/src/shell/components/AppShell.tsx' in shellComponentModules
91
+ // Debug: log available shell components
92
+ console.log('[Shell] hasShellComponents check:', {
93
+ exists,
94
+ availableComponents: Object.keys(shellComponentModules),
95
+ lookingFor: '/src/shell/components/AppShell.tsx'
96
+ })
97
+ return exists
98
+ }
99
+
100
+ /**
101
+ * Load shell component dynamically
102
+ */
103
+ export function loadShellComponent(
104
+ componentName: string
105
+ ): (() => Promise<{ default: ComponentType }>) | null {
106
+ const path = `/src/shell/components/${componentName}.tsx`
107
+ return shellComponentModules[path] || null
108
+ }
109
+
110
+ /**
111
+ * Load AppShell component that can wrap content
112
+ * First tries to load ShellWrapper (designed for wrapping arbitrary content)
113
+ * Falls back to AppShell if ShellWrapper doesn't exist
114
+ */
115
+ export function loadAppShell(): (() => Promise<{ default: ComponentType<{ children?: ReactNode }> }>) | null {
116
+ // First try ShellWrapper - a component specifically designed to wrap content
117
+ const wrapperPath = '/src/shell/components/ShellWrapper.tsx'
118
+ if (wrapperPath in shellComponentModules) {
119
+ return shellComponentModules[wrapperPath] as (() => Promise<{ default: ComponentType<{ children?: ReactNode }> }>)
120
+ }
121
+ // Fall back to AppShell
122
+ const path = '/src/shell/components/AppShell.tsx'
123
+ return shellComponentModules[path] as (() => Promise<{ default: ComponentType<{ children?: ReactNode }> }>) || null
124
+ }
125
+
126
+ /**
127
+ * Load shell preview wrapper dynamically
128
+ */
129
+ export function loadShellPreview(): (() => Promise<{ default: ComponentType }>) | null {
130
+ return shellPreviewModules['/src/shell/ShellPreview.tsx'] || null
131
+ }
132
+
133
+ /**
134
+ * Load the complete shell info
135
+ */
136
+ export function loadShellInfo(): ShellInfo | null {
137
+ const specContent = shellSpecFiles['/product/shell/spec.md']
138
+ const spec = specContent ? parseShellSpec(specContent) : null
139
+ const hasComponents = hasShellComponents()
140
+
141
+ // Return null if neither spec nor components exist
142
+ if (!spec && !hasComponents) {
143
+ return null
144
+ }
145
+
146
+ return { spec, hasComponents }
147
+ }
148
+
149
+ /**
150
+ * Check if shell has been defined (spec or components)
151
+ */
152
+ export function hasShell(): boolean {
153
+ return hasShellSpec() || hasShellComponents()
154
+ }
155
+
156
+ /**
157
+ * Check if shell spec has been defined
158
+ */
159
+ export function hasShellSpec(): boolean {
160
+ return '/product/shell/spec.md' in shellSpecFiles
161
+ }
162
+
163
+ /**
164
+ * Get list of shell component names
165
+ */
166
+ export function getShellComponentNames(): string[] {
167
+ const names: string[] = []
168
+ for (const path of Object.keys(shellComponentModules)) {
169
+ const match = path.match(/\/src\/shell\/components\/([^/]+)\.tsx$/)
170
+ if (match) {
171
+ names.push(match[1])
172
+ }
173
+ }
174
+ return names
175
+ }
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -0,0 +1,15 @@
1
+ import { StrictMode } from 'react'
2
+ import { createRoot } from 'react-dom/client'
3
+ import { RouterProvider } from 'react-router-dom'
4
+ import './index.css'
5
+ import { router } from '@/lib/router'
6
+
7
+ import { ToastProvider } from '@/components/ui/ToastContext'
8
+
9
+ createRoot(document.getElementById('root')!).render(
10
+ <StrictMode>
11
+ <ToastProvider>
12
+ <RouterProvider router={router} />
13
+ </ToastProvider>
14
+ </StrictMode>,
15
+ )
File without changes