spine-framework 0.3.124 → 0.3.126

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 (319) hide show
  1. package/.framework/cli/commands/agents.ts +35 -37
  2. package/.framework/cli/commands/auth.ts +35 -34
  3. package/.framework/cli/commands/create-app.ts +104 -40
  4. package/.framework/cli/commands/dev.ts +104 -69
  5. package/.framework/cli/commands/doctor.ts +179 -69
  6. package/.framework/cli/commands/generate.ts +83 -143
  7. package/.framework/cli/commands/init.ts +72 -34
  8. package/.framework/cli/commands/install-app.ts +260 -125
  9. package/.framework/cli/commands/items.ts +33 -44
  10. package/.framework/cli/commands/migrate.ts +122 -40
  11. package/.framework/cli/commands/migrations.ts +33 -40
  12. package/.framework/cli/commands/pipelines.ts +31 -39
  13. package/.framework/cli/commands/status.ts +47 -23
  14. package/.framework/cli/commands/system.ts +47 -37
  15. package/.framework/cli/commands/test.ts +112 -68
  16. package/.framework/cli/commands/validate-app.ts +215 -121
  17. package/.framework/cli/context.ts +112 -130
  18. package/.framework/cli/env-loader.ts +47 -18
  19. package/.framework/cli/index.ts +81 -42
  20. package/.framework/docs/runtime-types.md +1024 -0
  21. package/.framework/functions/_shared/agent-runner.ts +1296 -961
  22. package/.framework/functions/_shared/app-manifest.ts +82 -68
  23. package/.framework/functions/_shared/audit.ts +135 -83
  24. package/.framework/functions/_shared/{cil-state.ts → cil.ts} +158 -56
  25. package/.framework/functions/_shared/db.ts +80 -126
  26. package/.framework/functions/_shared/hash-api-key.ts +63 -0
  27. package/.framework/functions/_shared/index.ts +224 -335
  28. package/.framework/functions/_shared/kb.ts +319 -0
  29. package/.framework/functions/_shared/llm.ts +92 -0
  30. package/.framework/functions/_shared/logging.ts +288 -0
  31. package/.framework/functions/_shared/middleware.ts +329 -365
  32. package/.framework/functions/_shared/outcomes.ts +36 -0
  33. package/.framework/functions/_shared/permissions.ts +359 -643
  34. package/.framework/functions/_shared/pipeline-runner.ts +243 -316
  35. package/.framework/functions/_shared/principal.ts +376 -468
  36. package/.framework/functions/_shared/resolve-credentials.ts +102 -0
  37. package/.framework/functions/_shared/resolve-ids.ts +188 -16
  38. package/.framework/functions/_shared/retry-deliveries.ts +104 -0
  39. package/.framework/functions/_shared/schema-utils.ts +611 -373
  40. package/.framework/functions/_shared/testing.ts +207 -137
  41. package/.framework/functions/_shared/tracing.ts +276 -0
  42. package/.framework/functions/_shared/trigger-engine.ts +159 -211
  43. package/.framework/functions/_shared/webhook-registration.ts +95 -81
  44. package/.framework/functions/_shared/webhook-registry.ts +153 -75
  45. package/.framework/functions/account-nodes.ts +31 -53
  46. package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
  47. package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
  48. package/.framework/functions/adapters/openai-outbound.ts +40 -0
  49. package/.framework/functions/admin-data.ts +685 -537
  50. package/.framework/functions/admin-funnel.ts +31 -20
  51. package/.framework/functions/admin-install-funnel.ts +47 -28
  52. package/.framework/functions/admin-signals.ts +47 -29
  53. package/.framework/functions/ai-agents.ts +122 -147
  54. package/.framework/functions/ai-interactions.ts +180 -90
  55. package/.framework/functions/api-keys.ts +250 -192
  56. package/.framework/functions/apps.ts +203 -197
  57. package/.framework/functions/auth.ts +98 -91
  58. package/.framework/functions/cil-agent-ingest.ts +773 -0
  59. package/.framework/functions/cil-agent.ts +592 -0
  60. package/.framework/functions/cil-callmap.ts +1227 -0
  61. package/.framework/functions/cil-config.ts +583 -0
  62. package/.framework/functions/cil-context.ts +445 -0
  63. package/.framework/functions/cil-doc.ts +1752 -0
  64. package/.framework/functions/cil-embeddings.ts +1202 -0
  65. package/.framework/functions/cil-graph.ts +585 -0
  66. package/.framework/functions/cil-ingest.ts +2416 -0
  67. package/.framework/functions/cil-pipeline.ts +318 -0
  68. package/.framework/functions/cil-project.ts +499 -0
  69. package/.framework/functions/cil-validate.ts +469 -0
  70. package/.framework/functions/debug-auth.ts +73 -53
  71. package/.framework/functions/deliveries.ts +117 -0
  72. package/.framework/functions/embeddings.ts +528 -516
  73. package/.framework/functions/eval-harness.ts +158 -106
  74. package/.framework/functions/integration-outbound.ts +311 -0
  75. package/.framework/functions/integration-routes.ts +240 -466
  76. package/.framework/functions/integrations.ts +132 -140
  77. package/.framework/functions/invites.ts +401 -201
  78. package/.framework/functions/item-progress.ts +113 -53
  79. package/.framework/functions/kb.ts +28 -0
  80. package/.framework/functions/logs.ts +239 -222
  81. package/.framework/functions/observability.ts +308 -259
  82. package/.framework/functions/pipeline-executions.ts +179 -235
  83. package/.framework/functions/pipelines.ts +163 -205
  84. package/.framework/functions/prompt-configs.ts +109 -156
  85. package/.framework/functions/roles.ts +97 -147
  86. package/.framework/functions/system-cron.ts +132 -218
  87. package/.framework/functions/system.ts +112 -52
  88. package/.framework/functions/tests.ts +32 -28
  89. package/.framework/functions/timers.ts +162 -210
  90. package/.framework/functions/triggers.ts +282 -346
  91. package/.framework/functions/types.ts +283 -400
  92. package/.framework/migrations/001_core_schema.sql +630 -0
  93. package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
  94. package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
  95. package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
  96. package/.framework/migrations/005_core_observability.sql +598 -0
  97. package/.framework/migrations/006_security_hardening_rls.sql +97 -0
  98. package/.framework/migrations/007_kb_article_list.sql +237 -0
  99. package/.framework/migrations/008_items_target.sql +8 -0
  100. package/.framework/migrations/009_roles_slug_unique.sql +11 -0
  101. package/.framework/public/spine.config.json +91 -0
  102. package/.framework/scripts/app-install-cli.ts +112 -98
  103. package/.framework/src/App.tsx +67 -20
  104. package/.framework/src/apps/admin/index.tsx +97 -27
  105. package/.framework/src/components/AppWrapper.tsx +50 -11
  106. package/.framework/src/components/CustomAppLoader.tsx +131 -22
  107. package/.framework/src/components/admin/AdminListPage.tsx +75 -8
  108. package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
  109. package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
  110. package/.framework/src/components/admin/PageInstructions.tsx +49 -0
  111. package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
  112. package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
  113. package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
  114. package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
  115. package/.framework/src/components/app-sidebar.tsx +50 -3
  116. package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
  117. package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
  118. package/.framework/src/components/kb/KBArticleList.tsx +557 -0
  119. package/.framework/src/components/layout/AppShell.tsx +54 -16
  120. package/.framework/src/components/layout/Header.tsx +50 -38
  121. package/.framework/src/components/layout/Layout.tsx +48 -32
  122. package/.framework/src/components/layout/Sidebar.tsx +167 -16
  123. package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
  124. package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
  125. package/.framework/src/components/runtime/DataFilters.tsx +78 -1
  126. package/.framework/src/components/runtime/DataHeader.tsx +32 -29
  127. package/.framework/src/components/runtime/DataListPage.tsx +161 -2
  128. package/.framework/src/components/runtime/DataStats.tsx +48 -1
  129. package/.framework/src/components/runtime/DataTable.tsx +153 -1
  130. package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
  131. package/.framework/src/components/runtime/index.ts +16 -9
  132. package/.framework/src/components/search-form.tsx +33 -1
  133. package/.framework/src/components/shared/AgentView.tsx +48 -51
  134. package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
  135. package/.framework/src/components/shared/InviteManager.tsx +113 -52
  136. package/.framework/src/components/shared/MemberList.tsx +182 -0
  137. package/.framework/src/components/shared/SchemaFields.tsx +96 -78
  138. package/.framework/src/components/ui/DataTable.tsx +86 -56
  139. package/.framework/src/components/ui/Form.tsx +188 -109
  140. package/.framework/src/components/ui/ItemCard.tsx +86 -58
  141. package/.framework/src/components/ui/ItemListView.tsx +88 -61
  142. package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
  143. package/.framework/src/components/ui/Modal.tsx +81 -4
  144. package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
  145. package/.framework/src/components/ui/accordion.tsx +97 -5
  146. package/.framework/src/components/ui/alert-dialog.tsx +225 -13
  147. package/.framework/src/components/ui/alert.tsx +113 -6
  148. package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
  149. package/.framework/src/components/ui/avatar.tsx +129 -7
  150. package/.framework/src/components/ui/badge.tsx +65 -3
  151. package/.framework/src/components/ui/breadcrumb.tsx +145 -8
  152. package/.framework/src/components/ui/button-group.tsx +81 -4
  153. package/.framework/src/components/ui/button.tsx +49 -2
  154. package/.framework/src/components/ui/calendar.tsx +65 -3
  155. package/.framework/src/components/ui/card.tsx +145 -8
  156. package/.framework/src/components/ui/carousel.tsx +129 -7
  157. package/.framework/src/components/ui/chart.tsx +161 -10
  158. package/.framework/src/components/ui/checkbox.tsx +49 -2
  159. package/.framework/src/components/ui/collapsible.tsx +81 -5
  160. package/.framework/src/components/ui/combobox.tsx +305 -20
  161. package/.framework/src/components/ui/command.tsx +177 -11
  162. package/.framework/src/components/ui/context-menu.tsx +273 -17
  163. package/.framework/src/components/ui/dialog.tsx +209 -27
  164. package/.framework/src/components/ui/direction.tsx +64 -4
  165. package/.framework/src/components/ui/drawer.tsx +193 -12
  166. package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
  167. package/.framework/src/components/ui/empty.tsx +145 -9
  168. package/.framework/src/components/ui/field.tsx +209 -14
  169. package/.framework/src/components/ui/hover-card.tsx +81 -4
  170. package/.framework/src/components/ui/input-group.tsx +162 -10
  171. package/.framework/src/components/ui/input-otp.tsx +98 -5
  172. package/.framework/src/components/ui/input.tsx +49 -2
  173. package/.framework/src/components/ui/item.tsx +225 -13
  174. package/.framework/src/components/ui/kbd.tsx +65 -3
  175. package/.framework/src/components/ui/label.tsx +49 -2
  176. package/.framework/src/components/ui/menubar.tsx +289 -17
  177. package/.framework/src/components/ui/native-select.tsx +97 -5
  178. package/.framework/src/components/ui/navigation-menu.tsx +177 -10
  179. package/.framework/src/components/ui/pagination.tsx +161 -9
  180. package/.framework/src/components/ui/popover.tsx +145 -8
  181. package/.framework/src/components/ui/progress.tsx +49 -2
  182. package/.framework/src/components/ui/radio-group.tsx +65 -3
  183. package/.framework/src/components/ui/resizable.tsx +82 -4
  184. package/.framework/src/components/ui/scroll-area.tsx +65 -3
  185. package/.framework/src/components/ui/select.tsx +193 -11
  186. package/.framework/src/components/ui/separator.tsx +49 -2
  187. package/.framework/src/components/ui/sheet.tsx +193 -11
  188. package/.framework/src/components/ui/sidebar.tsx +481 -38
  189. package/.framework/src/components/ui/skeleton.tsx +49 -2
  190. package/.framework/src/components/ui/slider.tsx +49 -2
  191. package/.framework/src/components/ui/sonner.tsx +49 -2
  192. package/.framework/src/components/ui/spinner.tsx +49 -2
  193. package/.framework/src/components/ui/switch.tsx +49 -2
  194. package/.framework/src/components/ui/table-primitives.tsx +160 -33
  195. package/.framework/src/components/ui/table.tsx +161 -9
  196. package/.framework/src/components/ui/tabs.tsx +113 -6
  197. package/.framework/src/components/ui/textarea.tsx +49 -2
  198. package/.framework/src/components/ui/toggle-group.tsx +81 -4
  199. package/.framework/src/components/ui/toggle.tsx +65 -3
  200. package/.framework/src/components/ui/tooltip.tsx +97 -5
  201. package/.framework/src/contexts/AppContext.tsx +129 -45
  202. package/.framework/src/contexts/AuthContext.tsx +187 -144
  203. package/.framework/src/hooks/use-mobile.ts +48 -2
  204. package/.framework/src/hooks/useApi.ts +208 -159
  205. package/.framework/src/hooks/useAppPath.ts +32 -23
  206. package/.framework/src/hooks/useApps.ts +51 -20
  207. package/.framework/src/hooks/useEntityList.ts +32 -78
  208. package/.framework/src/hooks/useEntityRecord.ts +35 -96
  209. package/.framework/src/hooks/useForm.ts +32 -92
  210. package/.framework/src/hooks/useListSchema.ts +49 -78
  211. package/.framework/src/hooks/useSchemaRecord.ts +114 -105
  212. package/.framework/src/lib/api.ts +195 -116
  213. package/.framework/src/lib/supabase.ts +98 -64
  214. package/.framework/src/lib/utils.ts +287 -151
  215. package/.framework/src/main.tsx +49 -3
  216. package/.framework/src/pages/DashboardPage.tsx +52 -29
  217. package/.framework/src/pages/NotFoundPage.tsx +32 -10
  218. package/.framework/src/pages/SetupPage.tsx +32 -12
  219. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
  220. package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
  221. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
  222. package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
  223. package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
  224. package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
  225. package/.framework/src/pages/admin/AppsPage.tsx +49 -2
  226. package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
  227. package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
  228. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
  229. package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
  230. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
  231. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
  232. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
  233. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
  234. package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
  235. package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
  236. package/.framework/src/pages/admin/LogsPage.tsx +422 -75
  237. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
  238. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
  239. package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
  240. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
  241. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
  242. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
  243. package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
  244. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
  245. package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
  246. package/.framework/src/pages/admin/RolesPage.tsx +171 -18
  247. package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
  248. package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
  249. package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
  250. package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
  251. package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
  252. package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
  253. package/.framework/src/pages/admin/TimersPage.tsx +48 -20
  254. package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
  255. package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
  256. package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
  257. package/.framework/src/pages/admin/TypesPage.tsx +48 -20
  258. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
  259. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
  260. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
  261. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
  262. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
  263. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
  264. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
  265. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
  266. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
  267. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  268. package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
  269. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
  270. package/.framework/src/pages/auth/LoginPage.tsx +50 -23
  271. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
  272. package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
  273. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
  274. package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
  275. package/.framework/src/types/auth.ts +128 -71
  276. package/.framework/src/types/types.ts +373 -157
  277. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
  278. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
  279. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
  280. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
  281. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
  282. package/docs/README.md +9 -130
  283. package/netlify.toml +5 -2
  284. package/package.json +13 -25
  285. package/scripts/kb-ingest-docs.ts +203 -0
  286. package/spine.config.json +65 -4
  287. package/.framework/migrations/001_schema.sql +0 -425
  288. package/.framework/migrations/002_rls_and_functions.sql +0 -763
  289. package/.framework/migrations/004_enhancements.sql +0 -43
  290. package/.framework/migrations/005_auth_user_trigger.sql +0 -105
  291. package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
  292. package/.framework/migrations/016_invites.sql +0 -27
  293. package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
  294. package/.framework/migrations/018_apps_required_roles.sql +0 -17
  295. package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
  296. package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
  297. package/.framework/migrations/021_app_domains.sql +0 -112
  298. package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
  299. package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
  300. package/.framework/migrations/024_messages_account_id.sql +0 -9
  301. package/.framework/migrations/025_retype_threads_messages.sql +0 -240
  302. package/.framework/migrations/026_fix_rls_policies.sql +0 -47
  303. package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
  304. package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
  305. package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
  306. package/.framework/migrations/030_messages_updated_by.sql +0 -6
  307. package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
  308. package/docs/APPS.md +0 -232
  309. package/docs/ARCHITECTURE.md +0 -246
  310. package/docs/INSTALL.md +0 -155
  311. package/docs/design-schema-spec.md +0 -1837
  312. package/docs/dev-guides/01-create-an-app.md +0 -183
  313. package/docs/dev-guides/02-create-a-function.md +0 -178
  314. package/docs/dev-guides/03-create-a-component.md +0 -178
  315. package/docs/dev-guides/04-webhook-handlers.md +0 -129
  316. package/docs/dev-guides/05-testing.md +0 -168
  317. package/docs/dev-guides/README.md +0 -40
  318. package/docs/npm-packages-plan.md +0 -288
  319. package/docs/spine-core--api-reference.md +0 -822
@@ -1,5 +1,28 @@
1
- #!/usr/bin/env node
2
1
 
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+ // CIL[BEGIN chunk_id="validate-app_moduleheader_1784068794" type="module_header" identity="imports" parent="none"]
12
+ // CIL[DOC-MACRO purpose="Import dependencies and define validation types"]
13
+ // CIL[DOC-RESPONSIBILITY responsibility="Load required modules and define interfaces"]
14
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
15
+ // CIL[DOC-CONTRACT inputs="none" outputs="loaded_modules" errors="none" side_effects="none"]
16
+ // CIL[DOC-MICRO logic_summary="Imports file system, path utilities, Commander, and defines validation types" notable_decisions="[]"]
17
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
18
+ // CIL[DOC-STABILITY stability="stable"]
19
+ // CIL[DOC-AUDIENCE audience="developer"]
20
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, \."]
21
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
22
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
23
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
24
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
25
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
3
26
  import { Command } from 'commander'
4
27
  import { readFileSync, existsSync, readdirSync, statSync } from 'fs'
5
28
  import { join, dirname } from 'path'
@@ -53,7 +76,21 @@ class ValidationError extends Error {
53
76
  this.name = 'ValidationError'
54
77
  }
55
78
  }
56
-
79
+ // CIL[END chunk_id="validate-app_moduleheader_1784068794"]
80
+ // CIL[BEGIN chunk_id="validate-app_validatemanifest_1784068794" type="function" identity="validateManifest" parent="none"]
81
+ // CIL[DOC-MACRO purpose="Validate manifest.json structure and required fields"]
82
+ // CIL[DOC-RESPONSIBILITY responsibility="Parse and validate manifest file"]
83
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/db.ts\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
84
+ // CIL[DOC-CONTRACT inputs="none" outputs="manifest" errors="validation_errors" side_effects="none"]
85
+ // CIL[DOC-MICRO logic_summary="Validates JSON format, required fields, and app_type values" notable_decisions="[]"]
86
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
87
+ // CIL[DOC-STABILITY stability="stable"]
88
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/db.ts, .framework/functions/_shared/schema-utils.ts, \."]
89
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
90
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
91
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
92
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
93
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
57
94
  function validateManifest(appPath: string): Manifest {
58
95
  const manifestPath = join(appPath, 'manifest.json')
59
96
 
@@ -68,7 +105,6 @@ function validateManifest(appPath: string): Manifest {
68
105
  throw new ValidationError('❌ manifest.json is not valid JSON')
69
106
  }
70
107
 
71
- // Required fields
72
108
  const requiredFields = ['name', 'slug', 'version', 'app_type']
73
109
  for (const field of requiredFields) {
74
110
  if (!manifest[field]) {
@@ -76,7 +112,6 @@ function validateManifest(appPath: string): Manifest {
76
112
  }
77
113
  }
78
114
 
79
- // Validate app_type
80
115
  const validAppTypes = ['full', 'ui', 'backend', 'data']
81
116
  if (!validAppTypes.includes(manifest.app_type)) {
82
117
  throw new ValidationError(`❌ manifest.json app_type must be one of: ${validAppTypes.join(', ')}`)
@@ -84,7 +119,21 @@ function validateManifest(appPath: string): Manifest {
84
119
 
85
120
  return manifest
86
121
  }
87
-
122
+ // CIL[END chunk_id="validate-app_validatemanifest_1784068794"]
123
+ // CIL[BEGIN chunk_id="validate-app_validatepackagejson_1784068794" type="function" identity="validatePackageJson" parent="none"]
124
+ // CIL[DOC-MACRO purpose="Validate package.json structure and version consistency"]
125
+ // CIL[DOC-RESPONSIBILITY responsibility="Parse and validate package file"]
126
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
127
+ // CIL[DOC-CONTRACT inputs="none" outputs="package_json" errors="validation_errors" side_effects="none"]
128
+ // CIL[DOC-MICRO logic_summary="Validates JSON format and version match with manifest" notable_decisions="[]"]
129
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
130
+ // CIL[DOC-STABILITY stability="stable"]
131
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, .framework/src/pages/admin/RolesPage.tsx, \."]
132
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
133
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
134
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
135
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
136
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
88
137
  function validatePackageJson(appPath: string, manifest: Manifest): PackageJson {
89
138
  const packagePath = join(appPath, 'package.json')
90
139
 
@@ -99,39 +148,63 @@ function validatePackageJson(appPath: string, manifest: Manifest): PackageJson {
99
148
  throw new ValidationError('❌ package.json is not valid JSON')
100
149
  }
101
150
 
102
- // Check version sync
103
151
  if (packageJson.version !== manifest.version) {
104
152
  throw new ValidationError(`❌ Version mismatch: package.json has ${packageJson.version} but manifest.json has ${manifest.version}`)
105
153
  }
106
154
 
107
155
  return packageJson
108
156
  }
109
-
157
+ // CIL[END chunk_id="validate-app_validatepackagejson_1784068794"]
158
+ // CIL[BEGIN chunk_id="validate-app_validaterequiredfiles_1784068794" type="function" identity="validateRequiredFiles" parent="none"]
159
+ // CIL[DOC-MACRO purpose="Validate required files and directories for app type"]
160
+ // CIL[DOC-RESPONSIBILITY responsibility="Check existence of required app structure"]
161
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"\\\"]"]
162
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="none"]
163
+ // CIL[DOC-MICRO logic_summary="Validates presence of index.tsx, pages/, and functions/ based on app_type" notable_decisions="[]"]
164
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
165
+ // CIL[DOC-STABILITY stability="stable"]
166
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/migrations/015_simplify_apps_table.sql, \."]
167
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
168
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
169
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
170
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
171
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
110
172
  function validateRequiredFiles(appPath: string, manifest: Manifest): void {
111
173
  const { app_type } = manifest
112
174
 
113
- // index.tsx is required for full and ui apps
114
175
  if (['full', 'ui'].includes(app_type)) {
115
176
  if (!existsSync(join(appPath, 'index.tsx'))) {
116
177
  throw new ValidationError('❌ index.tsx is required for full and ui apps')
117
178
  }
118
179
  }
119
180
 
120
- // pages/ is required for full and ui apps
121
181
  if (['full', 'ui'].includes(app_type)) {
122
182
  if (!existsSync(join(appPath, 'pages'))) {
123
183
  throw new ValidationError('❌ pages/ directory is required for full and ui apps')
124
184
  }
125
185
  }
126
186
 
127
- // functions/ is required for full and backend apps
128
187
  if (['full', 'backend'].includes(app_type)) {
129
188
  if (!existsSync(join(appPath, 'functions'))) {
130
189
  throw new ValidationError('❌ functions/ directory is required for full and backend apps')
131
190
  }
132
191
  }
133
192
  }
134
-
193
+ // CIL[END chunk_id="validate-app_validaterequiredfiles_1784068794"]
194
+ // CIL[BEGIN chunk_id="validate-app_validatealloweddirectories_1784068794" type="function" identity="validateAllowedDirectories" parent="none"]
195
+ // CIL[DOC-MACRO purpose="Validate only allowed directories exist in app"]
196
+ // CIL[DOC-RESPONSIBILITY responsibility="Check for unauthorized directory names"]
197
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
198
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="none"]
199
+ // CIL[DOC-MICRO logic_summary="Ensures only standard directories plus optional .devin/ exist" notable_decisions="[]"]
200
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
201
+ // CIL[DOC-STABILITY stability="stable"]
202
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: .framework/migrations/015_simplify_apps_table.sql, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
203
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
204
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
205
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
206
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
207
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
135
208
  function validateAllowedDirectories(appPath: string): void {
136
209
  const allowedDirs = [
137
210
  'pages', 'components', 'hooks', 'utils', 'functions',
@@ -142,14 +215,27 @@ function validateAllowedDirectories(appPath: string): void {
142
215
  .filter(dirent => dirent.isDirectory())
143
216
  .map(dirent => dirent.name)
144
217
 
145
- // Filter out .devin/ since it's optional and handled separately
146
218
  const unknownDirs = entries.filter(dir => !allowedDirs.includes(dir) && dir !== '.devin')
147
219
 
148
220
  if (unknownDirs.length > 0) {
149
221
  throw new ValidationError(`❌ Unknown directories found: ${unknownDirs.join(', ')}. Allowed directories: ${allowedDirs.join(', ')} (plus optional .devin/)`)
150
222
  }
151
223
  }
152
-
224
+ // CIL[END chunk_id="validate-app_validatealloweddirectories_1784068794"]
225
+ // CIL[BEGIN chunk_id="validate-app_validatedevindirectory_1784068794" type="function" identity="validateDevinDirectory" parent="none"]
226
+ // CIL[DOC-MACRO purpose="Validate .devin directory structure if present"]
227
+ // CIL[DOC-RESPONSIBILITY responsibility="Check AGENTS.md and skills structure"]
228
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
229
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="console_output"]
230
+ // CIL[DOC-MICRO logic_summary="Validates AGENTS.md presence and skills directory structure" notable_decisions="[]"]
231
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
232
+ // CIL[DOC-STABILITY stability="stable"]
233
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
234
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
235
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
236
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
237
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
238
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
153
239
  function validateDevinDirectory(appPath: string): void {
154
240
  const devinPath = join(appPath, '.devin')
155
241
 
@@ -161,7 +247,6 @@ function validateDevinDirectory(appPath: string): void {
161
247
  throw new ValidationError('❌ .devin/ directory exists but AGENTS.md is missing. If .devin/ exists, it must contain AGENTS.md with agentic guidance.')
162
248
  }
163
249
 
164
- // Validate skills if they exist
165
250
  const skillsPath = join(devinPath, 'skills')
166
251
  if (existsSync(skillsPath)) {
167
252
  const skillDirs = readdirSync(skillsPath, { withFileTypes: true })
@@ -180,7 +265,21 @@ function validateDevinDirectory(appPath: string): void {
180
265
  console.log(`✅ .devin/ directory not present (optional)`)
181
266
  }
182
267
  }
183
-
268
+ // CIL[END chunk_id="validate-app_validatedevindirectory_1784068794"]
269
+ // CIL[BEGIN chunk_id="validate-app_validateroutes_1784068794" type="function" identity="validateRoutes" parent="none"]
270
+ // CIL[DOC-MACRO purpose="Validate route and navigation item paths"]
271
+ // CIL[DOC-RESPONSIBILITY responsibility="Check route prefix and path formatting"]
272
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
273
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="console_output"]
274
+ // CIL[DOC-MICRO logic_summary="Validates routes and nav_items are root-relative and properly formatted" notable_decisions="[]"]
275
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="complex_dependencies"]
276
+ // CIL[DOC-STABILITY stability="stable"]
277
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
278
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
279
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
280
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
281
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
282
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
184
283
  function validateRoutes(appPath: string, manifest: Manifest): void {
185
284
  if (!manifest.route_prefix) {
186
285
  console.warn('⚠️ manifest.json is missing route_prefix — install-app will default to /{slug}')
@@ -204,7 +303,6 @@ function validateRoutes(appPath: string, manifest: Manifest): void {
204
303
  }
205
304
  }
206
305
 
207
- // nav_items paths must also be root-relative
208
306
  if (Array.isArray((manifest as any).nav_items)) {
209
307
  const checkNavItem = (item: any) => {
210
308
  if (item.path && prefix && item.path.startsWith(prefix)) {
@@ -219,9 +317,22 @@ function validateRoutes(appPath: string, manifest: Manifest): void {
219
317
  for (const item of (manifest as any).nav_items) checkNavItem(item)
220
318
  }
221
319
  }
222
-
320
+ // CIL[END chunk_id="validate-app_validateroutes_1784068794"]
321
+ // CIL[BEGIN chunk_id="validate-app_validatemanifestcomponents_1784068794" type="function" identity="validateManifestComponents" parent="none"]
322
+ // CIL[DOC-MACRO purpose="Validate manifest component references exist"]
323
+ // CIL[DOC-RESPONSIBILITY responsibility="Check entry_point and sidebar_component files"]
324
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
325
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="none"]
326
+ // CIL[DOC-MICRO logic_summary="Validates referenced files exist and registration config is consistent" notable_decisions="[]"]
327
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
328
+ // CIL[DOC-STABILITY stability="stable"]
329
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
330
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
331
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
332
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
333
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
334
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
223
335
  function validateManifestComponents(appPath: string, manifest: Manifest): void {
224
- // entry_point — if declared, the file must exist
225
336
  if (manifest.entry_point) {
226
337
  const ep = manifest.entry_point.replace(/^\.\//, '')
227
338
  if (!existsSync(join(appPath, ep))) {
@@ -229,7 +340,6 @@ function validateManifestComponents(appPath: string, manifest: Manifest): void {
229
340
  }
230
341
  }
231
342
 
232
- // sidebar_component — if declared, the file must exist
233
343
  if (manifest.sidebar_component) {
234
344
  const sc = manifest.sidebar_component.replace(/^\.\//, '')
235
345
  if (!existsSync(join(appPath, sc))) {
@@ -237,14 +347,27 @@ function validateManifestComponents(appPath: string, manifest: Manifest): void {
237
347
  }
238
348
  }
239
349
 
240
- // registration — account_strategy "existing" requires target_account
241
350
  if (manifest.registration?.account_strategy === 'existing' && !manifest.registration?.target_account) {
242
351
  throw new ValidationError(`❌ manifest.json registration.account_strategy is "existing" but target_account is not set`)
243
352
  }
244
353
  }
245
-
354
+ // CIL[END chunk_id="validate-app_validatemanifestcomponents_1784068794"]
355
+ // CIL[BEGIN chunk_id="validate-app_validateseedblock_1784068794" type="function" identity="validateSeedBlock" parent="none"]
356
+ // CIL[DOC-MACRO purpose="Validate seed data configuration"]
357
+ // CIL[DOC-RESPONSIBILITY responsibility="Check seed files and configuration"]
358
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
359
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="none"]
360
+ // CIL[DOC-MICRO logic_summary="Validates seed array structure and SQL file existence" notable_decisions="[]"]
361
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
362
+ // CIL[DOC-STABILITY stability="stable"]
363
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
364
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
365
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
366
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
367
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
368
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
246
369
  function validateSeedBlock(appPath: string, manifest: Manifest): void {
247
- if (!manifest.seed) return // optional — legacy apps without seed block are fine
370
+ if (!manifest.seed) return
248
371
 
249
372
  if (!Array.isArray(manifest.seed)) {
250
373
  throw new ValidationError('❌ manifest.json seed must be an array')
@@ -252,109 +375,80 @@ function validateSeedBlock(appPath: string, manifest: Manifest): void {
252
375
 
253
376
  for (const entry of manifest.seed) {
254
377
  if (!entry.file || !entry.table || !entry.conflict) {
255
- throw new ValidationError(
256
- `❌ manifest.json seed entry missing required field(s) (file, table, conflict): ${JSON.stringify(entry)}`
257
- )
258
- }
259
- const filePath = join(appPath, entry.file)
260
- if (!existsSync(filePath)) {
261
- throw new ValidationError(`❌ manifest.json seed entry file "${entry.file}" does not exist`)
262
- }
263
- // Verify the file is valid JSON and an array
264
- try {
265
- const contents = JSON.parse(readFileSync(filePath, 'utf8'))
266
- if (!Array.isArray(contents)) {
267
- throw new ValidationError(`❌ Seed file "${entry.file}" must export a JSON array`)
268
- }
269
- } catch (err: any) {
270
- if (err instanceof ValidationError) throw err
271
- throw new ValidationError(`❌ Seed file "${entry.file}" is not valid JSON: ${err.message}`)
378
+ throw new ValidationError('❌ manifest.json seed entries must have file, table, and conflict fields')
272
379
  }
273
- }
274
- }
275
380
 
276
- function validatePackagePublishability(packageJson: PackageJson): void {
277
- if (packageJson.private === true) {
278
- throw new ValidationError('❌ package.json has "private": true — app cannot be published to npm')
279
- }
280
- if (packageJson.private === undefined) {
281
- console.warn('⚠️ package.json is missing "private": false — add it to confirm the package is publishable')
282
- }
283
- }
284
-
285
- function validatePackageFiles(appPath: string, packageJson: PackageJson): void {
286
- const { files = [] } = packageJson
287
-
288
- // Check that important directories are included in files array
289
- const importantFiles = ['index.tsx', 'manifest.json']
290
- const importantDirs = ['pages', 'components', 'hooks', 'utils', 'functions', 'seed', 'public']
291
-
292
- for (const file of importantFiles) {
293
- if (existsSync(join(appPath, file)) && !files.includes(file)) {
294
- console.warn(`⚠️ ${file} exists but is not in package.json files array`)
295
- }
296
- }
297
-
298
- for (const dir of importantDirs) {
299
- if (existsSync(join(appPath, dir)) && !files.includes(`${dir}/`)) {
300
- console.warn(`⚠️ ${dir}/ exists but is not in package.json files array`)
381
+ const seedFile = join(appPath, 'seed', entry.file)
382
+ if (!existsSync(seedFile)) {
383
+ throw new ValidationError(`❌ Seed file not found: seed/${entry.file}`)
301
384
  }
302
- }
303
- }
304
-
305
- function validateApp(appPath: string): void {
306
- try {
307
- console.log(`🔍 Validating app at: ${appPath}`)
308
-
309
- const manifest = validateManifest(appPath)
310
- console.log(`✅ manifest.json valid for ${manifest.name} v${manifest.version}`)
311
-
312
- const packageJson = validatePackageJson(appPath, manifest)
313
- console.log(`✅ package.json valid and versions match`)
314
-
315
- validateRequiredFiles(appPath, manifest)
316
- console.log(`✅ Required files present for app_type: ${manifest.app_type}`)
317
-
318
- validateRoutes(appPath, manifest)
319
- console.log(`✅ manifest.json routes and nav_items are root-relative`)
320
-
321
- validateManifestComponents(appPath, manifest)
322
- console.log(`✅ manifest.json entry_point, sidebar_component, and registration valid`)
323
-
324
- validateSeedBlock(appPath, manifest)
325
- console.log(`✅ manifest.json seed block valid`)
326
385
 
327
- validateAllowedDirectories(appPath)
328
- console.log(`✅ No unknown directories found`)
329
-
330
- validateDevinDirectory(appPath)
331
- console.log(`✅ .devin/ directory valid (if present)`)
332
-
333
- validatePackagePublishability(packageJson)
334
- console.log(`✅ package.json publishability valid`)
335
-
336
- validatePackageFiles(appPath, packageJson)
337
- console.log(`✅ package.json files array checked`)
338
-
339
- console.log(`\n🎉 App validation passed!`)
340
-
341
- } catch (err) {
342
- if (err instanceof ValidationError) {
343
- console.error(err.message)
344
- process.exit(1)
345
- } else {
346
- console.error(`❌ Unexpected error: ${err.message}`)
347
- process.exit(1)
386
+ if (!seedFile.endsWith('.sql')) {
387
+ throw new ValidationError(`❌ Seed file must be .sql: seed/${entry.file}`)
348
388
  }
349
389
  }
350
390
  }
351
-
352
- const program = new Command()
353
-
354
- program
355
- .name('validate-app')
356
- .description('Validate a Spine app structure and configuration')
357
- .argument('[path]', 'Path to the app directory', '.')
358
- .action(validateApp)
359
-
360
- program.parse()
391
+ // CIL[END chunk_id="validate-app_validateseedblock_1784068794"]
392
+ // CIL[BEGIN chunk_id="validate-app_validateappstructure_1784068794" type="function" identity="validateAppStructure" parent="none"]
393
+ // CIL[DOC-MACRO purpose="Run complete app structure validation"]
394
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute all validation checks"]
395
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
396
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="validation_errors" side_effects="console_output"]
397
+ // CIL[DOC-MICRO logic_summary="Runs all validation functions in sequence and reports success" notable_decisions="[]"]
398
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
399
+ // CIL[DOC-STABILITY stability="stable"]
400
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
401
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
402
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
403
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
404
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
405
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
406
+ function validateAppStructure(appPath: string): void {
407
+ const manifest = validateManifest(appPath)
408
+ validatePackageJson(appPath, manifest)
409
+ validateRequiredFiles(appPath, manifest)
410
+ validateAllowedDirectories(appPath)
411
+ validateDevinDirectory(appPath)
412
+ validateRoutes(appPath, manifest)
413
+ validateManifestComponents(appPath, manifest)
414
+ validateSeedBlock(appPath, manifest)
415
+ console.log(`✅ App structure is valid`)
416
+ }
417
+ // CIL[END chunk_id="validate-app_validateappstructure_1784068794"]
418
+ // CIL[BEGIN chunk_id="validate-app_registervalidateappcommands_1784068794" type="function" identity="registerValidateAppCommands" parent="none"]
419
+ // CIL[DOC-MACRO purpose="Register validate-app command with CLI program"]
420
+ // CIL[DOC-RESPONSIBILITY responsibility="Configure app validation command interface"]
421
+ // CIL[DOC-CONTEXT module="cli" layer="commands" related_files="[]"]
422
+ // CIL[DOC-CONTRACT inputs="none" outputs="validate_app_command" errors="command_errors" side_effects="process_exit"]
423
+ // CIL[DOC-MICRO logic_summary="Registers validate-app command with path option and error handling" notable_decisions="[]"]
424
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
425
+ // CIL[DOC-STABILITY stability="stable"]
426
+ // CIL[DOC-VECTOR type="context" content="Layer: commands. Direct callers: 0. Direct calls: 0. Related files: none."]
427
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
428
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
429
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
430
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
431
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
432
+ export function registerValidateAppCommands(program: Command) {
433
+ program
434
+ .command('validate-app [path]')
435
+ .description('Validate app structure and manifest')
436
+ .option('--fix', 'Attempt to fix common issues (not implemented)')
437
+ .action(async (path = '.') => {
438
+ try {
439
+ const appPath = join(process.cwd(), path)
440
+ console.log(`Validating app at: ${appPath}`)
441
+ validateAppStructure(appPath)
442
+ console.log(`✅ App validation passed`)
443
+ } catch (err: any) {
444
+ if (err instanceof ValidationError) {
445
+ console.error(err.message)
446
+ process.exit(1)
447
+ } else {
448
+ console.error('❌ Unexpected error:', err.message)
449
+ process.exit(1)
450
+ }
451
+ }
452
+ })
453
+ }
454
+ // CIL[END chunk_id="validate-app_registervalidateappcommands_1784068794"]