spine-framework 0.3.145 → 0.4.0

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 (451) hide show
  1. package/.env.example +76 -0
  2. package/.framework/.spine-manifest.json +19 -0
  3. package/.framework/cli/commands/agents.ts +61 -33
  4. package/.framework/cli/commands/auth.ts +60 -28
  5. package/.framework/cli/commands/create-app.ts +212 -80
  6. package/.framework/cli/commands/dev.ts +184 -68
  7. package/.framework/cli/commands/doctor.ts +324 -152
  8. package/.framework/cli/commands/generate.ts +119 -68
  9. package/.framework/cli/commands/init.ts +141 -242
  10. package/.framework/cli/commands/install-app.ts +1336 -314
  11. package/.framework/cli/commands/items.ts +31 -29
  12. package/.framework/cli/commands/migrate.ts +299 -156
  13. package/.framework/cli/commands/migrations.ts +62 -30
  14. package/.framework/cli/commands/pipelines.ts +31 -29
  15. package/.framework/cli/commands/status.ts +105 -45
  16. package/.framework/cli/commands/system.ts +47 -42
  17. package/.framework/cli/commands/test.ts +161 -102
  18. package/.framework/cli/commands/upgrade.ts +260 -0
  19. package/.framework/cli/commands/validate-app.ts +517 -161
  20. package/.framework/cli/context.ts +117 -85
  21. package/.framework/cli/env-loader.ts +74 -43
  22. package/.framework/cli/index.ts +70 -46
  23. package/.framework/cli/lib/project-files.ts +404 -0
  24. package/.framework/docs/guides/testing-guide.md +1 -1
  25. package/.framework/docs/runtime-types.md +72 -72
  26. package/.framework/functions/_shared/access.ts +84 -0
  27. package/.framework/functions/_shared/agent-runner.ts +5051 -1026
  28. package/.framework/functions/_shared/app-manifest.ts +214 -94
  29. package/.framework/functions/_shared/ast.ts +214 -0
  30. package/.framework/functions/_shared/audit.ts +91 -55
  31. package/.framework/functions/_shared/cil.ts +368 -127
  32. package/.framework/functions/_shared/db.ts +337 -68
  33. package/.framework/functions/_shared/funnel.ts +228 -0
  34. package/.framework/functions/_shared/geo.ts +105 -0
  35. package/.framework/functions/_shared/hash-api-key.ts +94 -17
  36. package/.framework/functions/_shared/index.ts +22 -224
  37. package/.framework/functions/_shared/kb.ts +832 -58
  38. package/.framework/functions/_shared/llm.ts +118 -18
  39. package/.framework/functions/_shared/logging.ts +317 -19
  40. package/.framework/functions/_shared/middleware.ts +701 -131
  41. package/.framework/functions/_shared/notify.ts +70 -0
  42. package/.framework/functions/_shared/outcomes.ts +34 -19
  43. package/.framework/functions/_shared/permissions.ts +501 -315
  44. package/.framework/functions/_shared/pipeline-runner.ts +704 -155
  45. package/.framework/functions/_shared/principal.ts +436 -263
  46. package/.framework/functions/_shared/rate-limit.ts +233 -0
  47. package/.framework/functions/_shared/resolve-credentials.ts +86 -19
  48. package/.framework/functions/_shared/resolve-ids.ts +203 -139
  49. package/.framework/functions/_shared/retry-deliveries.ts +51 -16
  50. package/.framework/functions/_shared/schema-utils.ts +602 -521
  51. package/.framework/functions/_shared/security.ts +345 -0
  52. package/.framework/functions/_shared/testing.ts +197 -172
  53. package/.framework/functions/_shared/tracing.ts +351 -21
  54. package/.framework/functions/_shared/trigger-engine.ts +425 -136
  55. package/.framework/functions/_shared/webhook-registration.ts +71 -70
  56. package/.framework/functions/_shared/webhook-registry.ts +126 -83
  57. package/.framework/functions/account-nodes.ts +30 -30
  58. package/.framework/functions/adapters/generic-webhook-inbound.ts +49 -16
  59. package/.framework/functions/adapters/generic-webhook-outbound.ts +17 -17
  60. package/.framework/functions/adapters/openai-outbound.ts +15 -16
  61. package/.framework/functions/admin-data.ts +596 -173
  62. package/.framework/functions/admin-funnel.ts +64 -60
  63. package/.framework/functions/admin-install-funnel.ts +84 -66
  64. package/.framework/functions/admin-signals.ts +69 -51
  65. package/.framework/functions/ai-agents.ts +431 -106
  66. package/.framework/functions/ai-interactions.ts +186 -112
  67. package/.framework/functions/api-keys.ts +107 -107
  68. package/.framework/functions/apps.ts +154 -136
  69. package/.framework/functions/auth.ts +83 -65
  70. package/.framework/functions/cil-agent-ingest.ts +189 -232
  71. package/.framework/functions/cil-agent.ts +433 -177
  72. package/.framework/functions/cil-callmap.ts +642 -430
  73. package/.framework/functions/cil-config.ts +139 -135
  74. package/.framework/functions/cil-context.ts +214 -127
  75. package/.framework/functions/cil-doc.ts +587 -458
  76. package/.framework/functions/cil-embeddings.ts +453 -364
  77. package/.framework/functions/cil-graph.ts +427 -142
  78. package/.framework/functions/cil-ingest.ts +1418 -1154
  79. package/.framework/functions/cil-pipeline.ts +276 -21
  80. package/.framework/functions/cil-project.ts +659 -132
  81. package/.framework/functions/cil-validate.ts +198 -164
  82. package/.framework/functions/debug-auth.ts +57 -55
  83. package/.framework/functions/deliveries.ts +80 -21
  84. package/.framework/functions/embeddings.ts +1023 -318
  85. package/.framework/functions/eval-harness.ts +146 -108
  86. package/.framework/functions/integration-outbound.ts +205 -75
  87. package/.framework/functions/integration-routes.ts +128 -23
  88. package/.framework/functions/integrations.ts +125 -100
  89. package/.framework/functions/invites.ts +1095 -460
  90. package/.framework/functions/item-progress.ts +158 -102
  91. package/.framework/functions/kb.ts +34 -10
  92. package/.framework/functions/logs.ts +133 -133
  93. package/.framework/functions/observability.ts +152 -122
  94. package/.framework/functions/pipeline-executions.ts +147 -132
  95. package/.framework/functions/pipelines.ts +134 -119
  96. package/.framework/functions/prompt-configs.ts +96 -80
  97. package/.framework/functions/roles.ts +112 -82
  98. package/.framework/functions/security.ts +450 -0
  99. package/.framework/functions/system-cron.ts +117 -80
  100. package/.framework/functions/system.ts +158 -98
  101. package/.framework/functions/tests.ts +29 -29
  102. package/.framework/functions/timers.ts +94 -95
  103. package/.framework/functions/trigger-scheduler.ts +10 -0
  104. package/.framework/functions/triggers.ts +179 -149
  105. package/.framework/functions/types.ts +137 -125
  106. package/.framework/mcp/index.ts +133 -0
  107. package/.framework/mcp/load-env.ts +60 -0
  108. package/.framework/mcp/shared/app-manifest.ts +275 -0
  109. package/.framework/mcp/shared/db.ts +477 -0
  110. package/.framework/mcp/shared/kb.ts +118 -0
  111. package/.framework/mcp/tools/architect.ts +431 -0
  112. package/.framework/mcp/tools/cil/context.ts +345 -0
  113. package/.framework/mcp/tools/cil/graph.ts +242 -0
  114. package/.framework/mcp/tools/cil/ingest.ts +1217 -0
  115. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +693 -0
  116. package/.framework/mcp/tools/cil/pipeline.ts +767 -0
  117. package/.framework/mcp/tools/cil/project.ts +791 -0
  118. package/.framework/mcp/tools/cil/retrieval.ts +336 -0
  119. package/.framework/mcp/tools/cil/search-core.ts +454 -0
  120. package/.framework/mcp/tools/cil/search.ts +97 -0
  121. package/.framework/mcp/tools/cil/suggest.ts +186 -0
  122. package/.framework/mcp/tools/cil/validate.ts +1369 -0
  123. package/.framework/mcp/tools/kb/delete.ts +139 -0
  124. package/.framework/mcp/tools/kb/index.ts +52 -0
  125. package/.framework/mcp/tools/kb/ingest.ts +84 -0
  126. package/.framework/mcp/tools/kb/list-types.ts +102 -0
  127. package/.framework/mcp/tools/kb/publish.ts +100 -0
  128. package/.framework/mcp/tools/kb/reindex.ts +86 -0
  129. package/.framework/mcp/tools/kb/revoke.ts +85 -0
  130. package/.framework/mcp/tools/kb/search.ts +101 -0
  131. package/.framework/mcp/tools/kb/upsert.ts +125 -0
  132. package/.framework/mcp/tools/observability.ts +510 -0
  133. package/.framework/migrations/001_core_schema.sql +15 -0
  134. package/.framework/migrations/002_core_rls_and_functions.sql +15 -0
  135. package/.framework/migrations/003_core_system_data.sql +16 -1
  136. package/.framework/migrations/004_core_rpc_and_broker.sql +17 -1
  137. package/.framework/migrations/005_core_observability.sql +17 -1
  138. package/.framework/migrations/006_security_hardening_rls.sql +15 -0
  139. package/.framework/migrations/007_kb_article_list.sql +17 -1
  140. package/.framework/migrations/008_items_target.sql +15 -0
  141. package/.framework/migrations/009_roles_slug_unique.sql +15 -0
  142. package/.framework/migrations/010_auth_user_trigger.sql +15 -0
  143. package/.framework/migrations/011_spine_system_account.sql +16 -0
  144. package/.framework/migrations/012_service_role_grants.sql +16 -0
  145. package/.framework/migrations/013_get_account_apps_role_filter.sql +15 -0
  146. package/.framework/migrations/014_apps_required_roles.sql +16 -0
  147. package/.framework/migrations/015_types_kind_slug_unique.sql +15 -0
  148. package/.framework/migrations/016_cil_types.sql +281 -0
  149. package/.framework/migrations/017_cil_stable_ids.sql +37 -0
  150. package/.framework/migrations/018_runtime_tables.sql +129 -0
  151. package/.framework/migrations/019_agent_prompt_columns.sql +56 -0
  152. package/.framework/migrations/020_schema_reconciliation.sql +67 -0
  153. package/.framework/migrations/021_kb_embedding_lifecycle.sql +31 -0
  154. package/.framework/migrations/032_cil_status_migration.sql +73 -0
  155. package/.framework/migrations/033_cil_versioning.sql +73 -0
  156. package/.framework/migrations/034_match_embeddings_knn.sql +115 -0
  157. package/.framework/migrations/035_rate_limits.sql +55 -0
  158. package/.framework/migrations/036_demo_record_flags.sql +72 -0
  159. package/.framework/migrations/037_kb_types_canonical.sql +244 -0
  160. package/.framework/migrations/038_drop_demo_record_flags.sql +38 -0
  161. package/.framework/migrations/042_registration_hierarchy.sql +309 -0
  162. package/.framework/migrations/043_policy_actor_cleanup.sql +39 -0
  163. package/.framework/migrations/044_match_embeddings_filtered_knn.sql +151 -0
  164. package/.framework/migrations/045_security_critical_rls.sql +139 -0
  165. package/.framework/migrations/046_security_missing_rls.sql +79 -0
  166. package/.framework/migrations/047_people_updated_by.sql +27 -0
  167. package/.framework/migrations/048_watcher_last_seen_at.sql +24 -0
  168. package/.framework/migrations/049_security_blocklist.sql +148 -0
  169. package/.framework/migrations/050_notifications.sql +49 -0
  170. package/.framework/migrations/051_message_agent_fields.sql +74 -0
  171. package/.framework/migrations/052_registration_security.sql +421 -0
  172. package/.framework/migrations/053_builtin_action_seeds.sql +66 -0
  173. package/.framework/migrations/054_kb_ingest_lease.sql +157 -0
  174. package/.framework/migrations/055_type_id_drift_reconciliation.sql +33 -0
  175. package/.framework/migrations/056_slug_column_reconciliation.sql +38 -0
  176. package/.framework/migrations/057_pipelines_slug_identity.sql +14 -0
  177. package/.framework/migrations/058_account_data_field_declarations.sql +53 -0
  178. package/.framework/migrations/059_registration_placement_fixes.sql +269 -0
  179. package/.framework/migrations/060_account_person_record_permissions.sql +38 -0
  180. package/.framework/migrations/061_fk_dedup.sql +32 -0
  181. package/.framework/public/spine-logo.svg +10 -3
  182. package/.framework/scripts/app-install-cli.ts +190 -93
  183. package/.framework/scripts/assemble-frontend.sh +127 -44
  184. package/.framework/scripts/assemble-functions.sh +128 -30
  185. package/.framework/scripts/boundary-check.sh +6 -2
  186. package/.framework/scripts/build-manifest.sh +24 -68
  187. package/.framework/scripts/check-core-integrity.sh +15 -76
  188. package/.framework/scripts/checksum-manifest.mts +343 -0
  189. package/.framework/scripts/cil-migrate-markers.ts +403 -0
  190. package/.framework/scripts/fix-cil-markers.mjs +176 -0
  191. package/.framework/scripts/verify-integrity.sh +21 -57
  192. package/.framework/scripts/verify-manifest.mts +305 -0
  193. package/.framework/seeds/types/funnel_signal_use.json +74 -21
  194. package/.framework/seeds/types/spine_instance.json +73 -21
  195. package/.framework/src/App.tsx +118 -72
  196. package/.framework/src/apps/admin/index.tsx +855 -58
  197. package/.framework/src/components/AppWrapper.tsx +43 -45
  198. package/.framework/src/components/CustomAppLoader.tsx +160 -116
  199. package/.framework/src/components/admin/AdminListPage.tsx +46 -44
  200. package/.framework/src/components/admin/AdminSidebar.tsx +57 -47
  201. package/.framework/src/components/admin/AdminStatsCard.tsx +46 -44
  202. package/.framework/src/components/admin/PageInstructions.tsx +98 -2
  203. package/.framework/src/components/admin/SortableTableHeader.tsx +44 -45
  204. package/.framework/src/components/app-shell/GenericAppShell.tsx +64 -65
  205. package/.framework/src/components/app-shell/GenericDetailPage.tsx +44 -47
  206. package/.framework/src/components/app-shell/GenericListPage.tsx +45 -49
  207. package/.framework/src/components/app-sidebar.tsx +42 -45
  208. package/.framework/src/components/auth/ProtectedRoute.tsx +48 -41
  209. package/.framework/src/components/auth/TurnstileWidget.tsx +27 -0
  210. package/.framework/src/components/kb/KBArticleEditor.tsx +231 -22
  211. package/.framework/src/components/kb/KBArticleList.tsx +251 -10
  212. package/.framework/src/components/layout/AppShell.tsx +51 -45
  213. package/.framework/src/components/layout/Header.tsx +42 -43
  214. package/.framework/src/components/layout/Layout.tsx +46 -46
  215. package/.framework/src/components/layout/Sidebar.tsx +196 -96
  216. package/.framework/src/components/runtime/DataDetailHeader.tsx +55 -30
  217. package/.framework/src/components/runtime/DataDetailPage.tsx +31 -269
  218. package/.framework/src/components/runtime/DataFilters.tsx +49 -74
  219. package/.framework/src/components/runtime/DataHeader.tsx +53 -32
  220. package/.framework/src/components/runtime/DataListPage.tsx +51 -155
  221. package/.framework/src/components/runtime/DataStats.tsx +66 -44
  222. package/.framework/src/components/runtime/DataTable.tsx +49 -149
  223. package/.framework/src/components/runtime/SchemaDetailForm.tsx +45 -75
  224. package/.framework/src/components/runtime/index.ts +119 -16
  225. package/.framework/src/components/search-form.tsx +46 -29
  226. package/.framework/src/components/shared/AgentView.tsx +65 -48
  227. package/.framework/src/components/shared/FieldRenderer.tsx +144 -50
  228. package/.framework/src/components/shared/InviteManager.tsx +207 -97
  229. package/.framework/src/components/shared/MemberList.tsx +97 -0
  230. package/.framework/src/components/shared/SchemaFields.tsx +107 -86
  231. package/.framework/src/components/ui/DataTable.tsx +80 -68
  232. package/.framework/src/components/ui/Form.tsx +157 -146
  233. package/.framework/src/components/ui/ItemCard.tsx +74 -67
  234. package/.framework/src/components/ui/ItemListView.tsx +73 -68
  235. package/.framework/src/components/ui/LoadingSpinner.tsx +43 -48
  236. package/.framework/src/components/ui/Modal.tsx +78 -68
  237. package/.framework/src/components/ui/RichTextEditor.tsx +89 -69
  238. package/.framework/src/components/ui/accordion.tsx +85 -86
  239. package/.framework/src/components/ui/alert-dialog.tsx +197 -184
  240. package/.framework/src/components/ui/alert.tsx +105 -94
  241. package/.framework/src/components/ui/aspect-ratio.tsx +57 -43
  242. package/.framework/src/components/ui/avatar.tsx +122 -107
  243. package/.framework/src/components/ui/badge.tsx +60 -55
  244. package/.framework/src/components/ui/breadcrumb.tsx +127 -128
  245. package/.framework/src/components/ui/button-group.tsx +86 -72
  246. package/.framework/src/components/ui/button.tsx +71 -50
  247. package/.framework/src/components/ui/calendar.tsx +72 -57
  248. package/.framework/src/components/ui/card.tsx +136 -129
  249. package/.framework/src/components/ui/carousel.tsx +226 -107
  250. package/.framework/src/components/ui/chart.tsx +252 -147
  251. package/.framework/src/components/ui/checkbox.tsx +43 -44
  252. package/.framework/src/components/ui/collapsible.tsx +86 -71
  253. package/.framework/src/components/ui/combobox.tsx +282 -249
  254. package/.framework/src/components/ui/command.tsx +158 -146
  255. package/.framework/src/components/ui/context-menu.tsx +239 -240
  256. package/.framework/src/components/ui/dialog.tsx +174 -157
  257. package/.framework/src/components/ui/direction.tsx +72 -56
  258. package/.framework/src/components/ui/drawer.tsx +168 -169
  259. package/.framework/src/components/ui/dropdown-menu.tsx +254 -223
  260. package/.framework/src/components/ui/empty.tsx +131 -120
  261. package/.framework/src/components/ui/field.tsx +205 -173
  262. package/.framework/src/components/ui/hover-card.tsx +71 -72
  263. package/.framework/src/components/ui/input-group.tsx +148 -133
  264. package/.framework/src/components/ui/input-otp.tsx +99 -86
  265. package/.framework/src/components/ui/input.tsx +43 -41
  266. package/.framework/src/components/ui/item.tsx +207 -185
  267. package/.framework/src/components/ui/kbd.tsx +57 -56
  268. package/.framework/src/components/ui/label.tsx +45 -41
  269. package/.framework/src/components/ui/menubar.tsx +268 -236
  270. package/.framework/src/components/ui/native-select.tsx +85 -86
  271. package/.framework/src/components/ui/navigation-menu.tsx +166 -156
  272. package/.framework/src/components/ui/pagination.tsx +131 -141
  273. package/.framework/src/components/ui/popover.tsx +125 -128
  274. package/.framework/src/components/ui/progress.tsx +47 -44
  275. package/.framework/src/components/ui/radio-group.tsx +60 -55
  276. package/.framework/src/components/ui/resizable.tsx +85 -72
  277. package/.framework/src/components/ui/scroll-area.tsx +57 -58
  278. package/.framework/src/components/ui/select.tsx +182 -169
  279. package/.framework/src/components/ui/separator.tsx +42 -43
  280. package/.framework/src/components/ui/sheet.tsx +170 -159
  281. package/.framework/src/components/ui/sidebar.tsx +395 -398
  282. package/.framework/src/components/ui/skeleton.tsx +42 -43
  283. package/.framework/src/components/ui/slider.tsx +61 -44
  284. package/.framework/src/components/ui/sonner.tsx +44 -44
  285. package/.framework/src/components/ui/spinner.tsx +47 -42
  286. package/.framework/src/components/ui/switch.tsx +56 -42
  287. package/.framework/src/components/ui/table-primitives.tsx +272 -132
  288. package/.framework/src/components/ui/table.tsx +140 -142
  289. package/.framework/src/components/ui/tabs.tsx +110 -93
  290. package/.framework/src/components/ui/textarea.tsx +43 -44
  291. package/.framework/src/components/ui/toggle-group.tsx +87 -71
  292. package/.framework/src/components/ui/toggle.tsx +56 -56
  293. package/.framework/src/components/ui/tooltip.tsx +99 -85
  294. package/.framework/src/contexts/AppContext.tsx +166 -114
  295. package/.framework/src/contexts/AuthContext.tsx +232 -137
  296. package/.framework/src/hooks/use-mobile.ts +43 -44
  297. package/.framework/src/hooks/useApi.ts +185 -172
  298. package/.framework/src/hooks/useAppPath.ts +31 -29
  299. package/.framework/src/hooks/useApps.ts +77 -42
  300. package/.framework/src/hooks/useEntityList.ts +66 -29
  301. package/.framework/src/hooks/useEntityRecord.ts +76 -32
  302. package/.framework/src/hooks/useForm.ts +62 -30
  303. package/.framework/src/hooks/useListSchema.ts +60 -43
  304. package/.framework/src/hooks/useSchemaRecord.ts +115 -95
  305. package/.framework/src/lib/api.ts +258 -134
  306. package/.framework/src/lib/registration.ts +181 -0
  307. package/.framework/src/lib/supabase.ts +118 -81
  308. package/.framework/src/lib/utils.ts +266 -266
  309. package/.framework/src/main.tsx +43 -44
  310. package/.framework/src/pages/DashboardPage.tsx +44 -43
  311. package/.framework/src/pages/NoAppPage.tsx +50 -0
  312. package/.framework/src/pages/NotFoundPage.tsx +32 -29
  313. package/.framework/src/pages/SetupPage.tsx +34 -33
  314. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +69 -58
  315. package/.framework/src/pages/admin/AIAgentsPage.tsx +43 -40
  316. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +63 -55
  317. package/.framework/src/pages/admin/APIKeysPage.tsx +44 -42
  318. package/.framework/src/pages/admin/AlertsConfigPage.tsx +117 -94
  319. package/.framework/src/pages/admin/AppDetailPage.tsx +48 -42
  320. package/.framework/src/pages/admin/AppsPage.tsx +45 -42
  321. package/.framework/src/pages/admin/DeliveriesPage.tsx +49 -17
  322. package/.framework/src/pages/admin/DesignedPage.tsx +31 -30
  323. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +58 -0
  324. package/.framework/src/pages/admin/EmbeddingsPage.tsx +49 -0
  325. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +31 -29
  326. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +46 -29
  327. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -29
  328. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +68 -55
  329. package/.framework/src/pages/admin/IntegrationsPage.tsx +45 -42
  330. package/.framework/src/pages/admin/InvitesPage.tsx +60 -44
  331. package/.framework/src/pages/admin/LogsPage.tsx +87 -137
  332. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +31 -29
  333. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +150 -89
  334. package/.framework/src/pages/admin/PipelineDetailPage.tsx +77 -104
  335. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +44 -43
  336. package/.framework/src/pages/admin/PipelinesPage.tsx +59 -145
  337. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +53 -42
  338. package/.framework/src/pages/admin/PromptConfigsPage.tsx +47 -117
  339. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +31 -44
  340. package/.framework/src/pages/admin/RoleDetailPage.tsx +49 -92
  341. package/.framework/src/pages/admin/RolesPage.tsx +47 -164
  342. package/.framework/src/pages/admin/SecurityPage.tsx +310 -0
  343. package/.framework/src/pages/admin/SelectTestPage.tsx +30 -32
  344. package/.framework/src/pages/admin/ShadcnTestPage.tsx +37 -44
  345. package/.framework/src/pages/admin/SimpleDashboard.tsx +32 -44
  346. package/.framework/src/pages/admin/TestRunDetailPage.tsx +97 -44
  347. package/.framework/src/pages/admin/TestingDashboard.tsx +126 -71
  348. package/.framework/src/pages/admin/TimerDetailPage.tsx +67 -55
  349. package/.framework/src/pages/admin/TimersPage.tsx +44 -42
  350. package/.framework/src/pages/admin/TriggerDetailPage.tsx +47 -42
  351. package/.framework/src/pages/admin/TriggersPage.tsx +58 -57
  352. package/.framework/src/pages/admin/TypeDetailPage.tsx +91 -55
  353. package/.framework/src/pages/admin/TypesPage.tsx +45 -42
  354. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +258 -128
  355. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +127 -123
  356. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +308 -235
  357. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +159 -110
  358. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +432 -0
  359. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +200 -178
  360. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +286 -239
  361. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +211 -90
  362. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +156 -143
  363. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +379 -0
  364. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +337 -0
  365. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +219 -214
  366. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  367. package/.framework/src/pages/auth/AuthConfirmPage.tsx +135 -65
  368. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +39 -31
  369. package/.framework/src/pages/auth/LoginPage.tsx +38 -32
  370. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -28
  371. package/.framework/src/pages/auth/RegisterPage.tsx +429 -155
  372. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -30
  373. package/.framework/src/pages/spine-framework/CLIPage.tsx +32 -30
  374. package/.framework/src/types/auth.ts +101 -93
  375. package/.framework/src/types/types.ts +283 -262
  376. package/.framework/templates/project.json +87 -0
  377. package/.framework/templates/spine.config.neutral.json +7 -0
  378. package/.framework/tests/api/api-surface.test.ts +381 -0
  379. package/.framework/tests/fixtures/seed.ts +427 -0
  380. package/.framework/tests/fixtures/teardown.ts +228 -0
  381. package/.framework/tests/reporter.ts +351 -0
  382. package/.framework/tests/setup.ts +135 -0
  383. package/.framework/tests/ui/ui-sweep.ts +278 -0
  384. package/.framework/tests/unit/admin-data-logger.test.ts +310 -0
  385. package/.framework/tests/unit/agent-runner.test.ts +2389 -0
  386. package/.framework/tests/unit/ai-interactions.test.ts +81 -0
  387. package/.framework/tests/unit/app-manifest.test.ts +359 -0
  388. package/.framework/tests/unit/assembly-scripts.test.ts +172 -0
  389. package/.framework/tests/unit/cil-determinism.test.ts +85 -0
  390. package/.framework/tests/unit/core-isolation.test.ts +153 -0
  391. package/.framework/tests/unit/funnel-signals.test.ts +135 -0
  392. package/.framework/tests/unit/install-app.test.ts +1759 -0
  393. package/.framework/tests/unit/invites-security.test.ts +572 -0
  394. package/.framework/tests/unit/kb-ingest-lease.test.ts +287 -0
  395. package/.framework/tests/unit/kb-search.test.ts +119 -0
  396. package/.framework/tests/unit/migrate.test.ts +509 -0
  397. package/.framework/tests/unit/notify.test.ts +136 -0
  398. package/.framework/tests/unit/permissions.test.ts +269 -0
  399. package/.framework/tests/unit/pipeline-runner.test.ts +755 -0
  400. package/.framework/tests/unit/principal-cache.test.ts +138 -0
  401. package/.framework/tests/unit/retrieval-golden.test.ts +520 -0
  402. package/.framework/tests/unit/runtime-isolation.test.ts +642 -0
  403. package/.framework/tests/unit/schema-utils.test.ts +225 -0
  404. package/.framework/tests/unit/trigger-engine.test.ts +513 -0
  405. package/.framework/tests/unit/validate-app.test.ts +527 -0
  406. package/README.md +34 -3
  407. package/bin/spine-framework.cjs +1 -0
  408. package/config/tailwind.config.cjs +7 -0
  409. package/config/tsconfig.functions.json +42 -0
  410. package/config/tsconfig.json +37 -9
  411. package/config/vite.config.ts +31 -2
  412. package/netlify.toml +31 -3
  413. package/package.json +46 -29
  414. package/scripts/assemble-frontend.sh +127 -44
  415. package/scripts/assemble-functions.sh +127 -29
  416. package/scripts/boundary-check.sh +6 -2
  417. package/scripts/build-manifest.sh +24 -68
  418. package/scripts/checksum-manifest.mts +345 -0
  419. package/scripts/dev-clean.sh +86 -0
  420. package/scripts/dev-netlify.sh +49 -0
  421. package/scripts/netlify-dev-wrapper.sh +2 -0
  422. package/scripts/verify-install.ts +358 -0
  423. package/scripts/verify-integrity.sh +21 -57
  424. package/scripts/verify-manifest.mts +305 -0
  425. package/templates/project/gitignore +45 -0
  426. package/{config → templates/project}/package-lock.json +22335 -9366
  427. package/vitest.config.ts +46 -0
  428. package/.framework/public/spine.config.json +0 -91
  429. package/config/deno.lock +0 -108
  430. package/config/tsconfig.node.tsbuildinfo +0 -1
  431. package/config/tsconfig.tsbuildinfo +0 -1
  432. package/config/vite.config.d.ts +0 -2
  433. package/custom/.devin/AGENT.md +0 -357
  434. package/custom/.devin/skills/install-app/SKILL.md +0 -39
  435. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +0 -39
  436. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +0 -36
  437. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +0 -46
  438. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +0 -28
  439. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +0 -38
  440. package/custom/.devin/workflows/app-install.yaml +0 -83
  441. package/custom/README.md +0 -79
  442. package/docs/README.md +0 -15
  443. package/scripts/app-install-cli.ts +0 -286
  444. package/scripts/check-core-integrity.sh +0 -82
  445. package/scripts/ingest-chunks.cjs +0 -202
  446. package/scripts/kb-chunk-parser.cjs +0 -312
  447. package/scripts/kb-chunk-parser.ts +0 -330
  448. package/scripts/kb-ingest-docs.ts +0 -203
  449. package/scripts/load-test-app-install.ts +0 -484
  450. package/scripts/test-login.js +0 -33
  451. package/spine.config.json +0 -91
@@ -1,3 +1,13 @@
1
+ // CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:module_header:module_header"]
2
+ // CIL[DOC-MACRO purpose="Defines imports and dependencies for the KB article list UI."]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide React, utility, and UI component imports for KBArticleList."]
4
+ // CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Import block for hooks, API, utilities, and UI primitives." notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+ // CIL[DOC-AUDIENCE audience="developers"]
10
+
1
11
  import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'
2
12
  import { apiFetch } from '../../lib/api'
3
13
  import { formatDateTime } from '../../lib/utils'
@@ -8,6 +18,24 @@ import { Badge } from '../ui/badge'
8
18
  import { Skeleton } from '../ui/skeleton'
9
19
  import { Plus, Search, Edit, BookOpen, GripVertical, X } from 'lucide-react'
10
20
 
21
+
22
+ // CIL[DOC-VECTOR type="context" content="purpose='Defines imports and dependencies for the KB article list UI.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
23
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
24
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
25
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
26
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
27
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
28
+ // CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:module_header:module_header"]
29
+
30
+
31
+ // CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBArticleListProps:interface"]
32
+ // CIL[DOC-MACRO purpose="Defines the props accepted by the KBArticleList component."]
33
+ // CIL[DOC-RESPONSIBILITY responsibility="Contract between parent and KBArticleList."]
34
+ // CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
35
+ // CIL[DOC-CONTRACT inputs="none" outputs="KBArticleListProps interface" errors="none" side_effects="none"]
36
+ // CIL[DOC-MICRO logic_summary="Lists optional and required props for the component." notable_decisions="[]"]
37
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
38
+ // CIL[DOC-STABILITY stability="stable"]
11
39
  export interface KBArticleListProps {
12
40
  typeSlugs: string[]
13
41
  typeName?: string
@@ -15,7 +43,23 @@ export interface KBArticleListProps {
15
43
  onNew?: () => void
16
44
  onEdit?: (record: KBRecord) => void
17
45
  }
18
-
46
+ // CIL[DOC-VECTOR type="context" content="purpose='Defines the props accepted by the KBArticleList component.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
47
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
48
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
49
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
50
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
51
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
52
+ // CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBArticleListProps:interface"]
53
+
54
+
55
+ // CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBRecord:interface"]
56
+ // CIL[DOC-MACRO purpose="Defines the shape of a knowledge base record."]
57
+ // CIL[DOC-RESPONSIBILITY responsibility="Data model for KB articles."]
58
+ // CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
59
+ // CIL[DOC-CONTRACT inputs="none" outputs="KBRecord interface" errors="none" side_effects="none"]
60
+ // CIL[DOC-MICRO logic_summary="Defines KBRecord fields including id, title, status, and data." notable_decisions="[]"]
61
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
62
+ // CIL[DOC-STABILITY stability="stable"]
19
63
  interface KBRecord {
20
64
  id: string
21
65
  title: string
@@ -27,27 +71,127 @@ interface KBRecord {
27
71
  data: Record<string, any>
28
72
  [key: string]: any
29
73
  }
30
-
74
+ // CIL[DOC-VECTOR type="context" content="purpose='Defines the shape of a knowledge base record.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
75
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
76
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
77
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
78
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
79
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
80
+ // CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBRecord:interface"]
81
+
82
+
83
+ // CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:TreeNode:interface"]
84
+ // CIL[DOC-MACRO purpose="Defines a tree node that extends KBRecord with children."]
85
+ // CIL[DOC-RESPONSIBILITY responsibility="Recursive tree structure contract."]
86
+ // CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
87
+ // CIL[DOC-CONTRACT inputs="none" outputs="TreeNode interface" errors="none" side_effects="none"]
88
+ // CIL[DOC-MICRO logic_summary="Extends KBRecord with a children array." notable_decisions="[]"]
89
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
90
+ // CIL[DOC-STABILITY stability="stable"]
31
91
  interface TreeNode extends KBRecord {
32
92
  children: TreeNode[]
33
93
  }
34
-
94
+ // CIL[DOC-VECTOR type="context" content="purpose='Defines a tree node that extends KBRecord with children.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
95
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
96
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
97
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
98
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
99
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
100
+ // CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:TreeNode:interface"]
101
+
102
+
103
+ // CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:isNullId:function"]
104
+ // CIL[DOC-MACRO purpose="Tests whether a value is a null, undefined, or empty id."]
105
+ // CIL[DOC-RESPONSIBILITY responsibility="Predicate for missing id values."]
106
+ // CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
107
+ // CIL[DOC-CONTRACT inputs="a: string | null | undefined" outputs="boolean (type predicate a is null | undefined)" errors="none" side_effects="none"]
108
+ // CIL[DOC-MICRO logic_summary="Returns true for null, undefined, or empty string." notable_decisions="[]"]
109
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
110
+ // CIL[DOC-STABILITY stability="stable"]
35
111
  function isNullId(a: string | null | undefined): a is null | undefined {
36
112
  return a === null || a === undefined || a === ''
37
113
  }
38
-
114
+ // CIL[DOC-VECTOR type="context" content="purpose='Tests whether a value is a null, undefined, or empty id.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
115
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
116
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
117
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
118
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
119
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
120
+ // CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:isNullId:function"]
121
+
122
+
123
+ // CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sameId:function"]
124
+ // CIL[DOC-MACRO purpose="Compares two id values for equality, treating nullish as equal."]
125
+ // CIL[DOC-RESPONSIBILITY responsibility="Determine id equality for parent and record comparisons."]
126
+ // CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
127
+ // CIL[DOC-CONTRACT inputs="a, b: string | null | undefined" outputs="boolean" errors="none" side_effects="none"]
128
+ // CIL[DOC-MICRO logic_summary="Returns true if values are equal or both nullish." notable_decisions="[]"]
129
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
130
+ // CIL[DOC-STABILITY stability="stable"]
39
131
  function sameId(a: string | null | undefined, b: string | null | undefined): boolean {
40
132
  return a === b || (isNullId(a) && isNullId(b))
41
133
  }
42
-
134
+ // CIL[DOC-VECTOR type="context" content="purpose='Compares two id values for equality, treating nullish as equal.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
135
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
136
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
137
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
138
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
139
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
140
+ // CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sameId:function"]
141
+
142
+
143
+ // CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sameParent:function"]
144
+ // CIL[DOC-MACRO purpose="Checks whether a record's parent_id matches the given parent."]
145
+ // CIL[DOC-RESPONSIBILITY responsibility="Parent equality predicate for tree grouping."]
146
+ // CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
147
+ // CIL[DOC-CONTRACT inputs="record: KBRecord, parentId: string | undefined" outputs="boolean" errors="none" side_effects="none"]
148
+ // CIL[DOC-MICRO logic_summary="Compares record.data.parent_id to parentId using sameId." notable_decisions="[]"]
149
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
150
+ // CIL[DOC-STABILITY stability="stable"]
43
151
  function sameParent(record: KBRecord, parentId: string | undefined): boolean {
44
152
  return sameId(record.data?.parent_id as string | undefined, parentId)
45
153
  }
46
-
154
+ // CIL[DOC-VECTOR type="context" content="purpose='Checks whether a record's parent_id matches the given parent.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
155
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
156
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
157
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
158
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
159
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
160
+ // CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sameParent:function"]
161
+
162
+
163
+ // CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sortByOrder:function"]
164
+ // CIL[DOC-MACRO purpose="Sorts two KB records by their data.order value."]
165
+ // CIL[DOC-RESPONSIBILITY responsibility="Order comparison for tree siblings."]
166
+ // CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
167
+ // CIL[DOC-CONTRACT inputs="a: KBRecord, b: KBRecord" outputs="number" errors="none" side_effects="none"]
168
+ // CIL[DOC-MICRO logic_summary="Subtracts b order from a order, defaulting to MAX_SAFE_INTEGER." notable_decisions="[]"]
169
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
170
+ // CIL[DOC-STABILITY stability="stable"]
47
171
  function sortByOrder(a: KBRecord, b: KBRecord): number {
48
172
  return (a.data?.order ?? Number.MAX_SAFE_INTEGER) - (b.data?.order ?? Number.MAX_SAFE_INTEGER)
49
173
  }
50
-
174
+ // CIL[DOC-VECTOR type="context" content="purpose='Sorts two KB records by their data.order value.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
175
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
176
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
177
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
178
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
179
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
180
+ // CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:sortByOrder:function"]
181
+
182
+ // CIL[BEGIN stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBArticleList:component"]
183
+ // CIL[DOC-MACRO purpose="Renders a searchable, filterable, drag-and-drop knowledge base article list."]
184
+ // CIL[DOC-RESPONSIBILITY responsibility="Display KB articles as a tree or flat list, support search, status/type filters, and reordering via drag-and-drop."]
185
+ // CIL[DOC-CONTEXT module="kb" layer="components" related_files=".framework/src/components/kb/KBArticleList.tsx,.framework/src/components/ui/badge.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
186
+ // CIL[DOC-CONTRACT inputs="typeSlugs: string[], typeName?: string, onSelect?: (record: KBRecord) => void, onNew?: () => void, onEdit?: (record: KBRecord) => void" outputs="JSX" errors="Network or permission errors" side_effects="Fetches data from API, updates state, PATCHes records on drop."]
187
+ // CIL[DOC-MICRO logic_summary="Loads record types, fetches article trees, handles search, builds filtered tree, renders list, and applies drag-and-drop reordering." notable_decisions="[]"]
188
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
189
+ // CIL[DOC-STABILITY stability="stable"]
190
+ // CIL[DOC-NOTE type="param" content="typeSlugs: string[] - allowed knowledge base type slugs"]
191
+ // CIL[DOC-NOTE type="param" content="typeName?: string - display name for the knowledge base"]
192
+ // CIL[DOC-NOTE type="param" content="onSelect?: (record: KBRecord) => void - callback when an article is selected"]
193
+ // CIL[DOC-NOTE type="param" content="onNew?: () => void - callback to create a new article"]
194
+ // CIL[DOC-NOTE type="param" content="onEdit?: (record: KBRecord) => void - callback to edit an article"
51
195
  export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }: KBArticleListProps) {
52
196
  const [typeRecords, setTypeRecords] = useState<any[]>([])
53
197
  const [articles, setArticles] = useState<KBRecord[]>([])
@@ -60,14 +204,25 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
60
204
  const [typeFilter, setTypeFilter] = useState<string>('all')
61
205
  const [dragging, setDragging] = useState<string | null>(null)
62
206
 
207
+
208
+
209
+
63
210
  const typeById = useMemo(() => {
64
211
  const map: Record<string, any> = {}
65
212
  typeRecords.forEach((t) => { map[t.id] = t })
66
213
  return map
67
214
  }, [typeRecords])
68
215
 
216
+
217
+
218
+
219
+
69
220
  const typeSlugsSet = useMemo(() => new Set(typeSlugs), [typeSlugs])
70
221
 
222
+
223
+
224
+
225
+
71
226
  const statusOptions = useMemo(() => {
72
227
  const opts = new Set<string>()
73
228
  typeRecords.forEach((t) => {
@@ -77,22 +232,36 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
77
232
  return ['all', ...Array.from(opts)]
78
233
  }, [typeRecords])
79
234
 
235
+
236
+
237
+
80
238
  const statusLabel = (s: string) => s === 'all' ? 'All' : (s?.charAt(0).toUpperCase() + s?.slice(1))
81
239
 
82
240
  useEffect(() => {
241
+
242
+
243
+
83
244
  let cancelled = false
245
+
84
246
  setLoading(true)
85
247
  apiFetch('/api/types?action=list')
86
248
  .then((r) => r.json())
87
249
  .then((j) => {
88
250
  if (cancelled) return
251
+
252
+
253
+
89
254
  const found = (j.data || []).filter((t: any) => typeSlugsSet.has(t.slug))
255
+
90
256
  setTypeRecords(found)
91
257
  })
92
258
  .catch(() => setTypeRecords([]))
93
259
  return () => { cancelled = true }
94
260
  }, [typeSlugsSet])
95
261
 
262
+
263
+
264
+
96
265
  const loadTree = useCallback(async () => {
97
266
  if (typeRecords.length === 0) return
98
267
  setLoading(true)
@@ -107,6 +276,17 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
107
276
  const record = records[0]
108
277
  return record?.data?.trees || {}
109
278
  }
279
+
280
+
281
+
282
+
283
+
284
+
285
+
286
+
287
+
288
+
289
+
110
290
  const [globalTrees, accountTrees] = await Promise.all([
111
291
  loadCache('KB Article List - Global'),
112
292
  loadCache('KB Article List - Account'),
@@ -125,11 +305,17 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
125
305
  }
126
306
  }, [typeRecords, typeSlugs, typeById])
127
307
 
308
+
309
+
310
+
311
+
128
312
  const handleSearch = useCallback(async (query: string) => {
129
313
  if (typeRecords.length === 0 || query.trim().length < 2) {
130
314
  setSearchResultIds(null)
131
315
  return
132
316
  }
317
+
318
+
133
319
  setSearching(true)
134
320
  setError(null)
135
321
  try {
@@ -158,12 +344,17 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
158
344
  }
159
345
  }, [typeRecords, typeSlugs])
160
346
 
347
+
161
348
  useEffect(() => {
162
349
  loadTree()
163
350
  }, [loadTree])
164
351
 
352
+
353
+
354
+
165
355
  const hasActiveSearch = searchResultIds !== null
166
356
 
357
+
167
358
  const { visibleArticles, roots, byId } = useMemo(() => {
168
359
  let out = articles
169
360
  if (statusFilter !== 'all') out = out.filter((a) => a.status === statusFilter)
@@ -182,6 +373,10 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
182
373
  ancestorSet.add(parentId)
183
374
  current = fullById.get(parentId)
184
375
  }
376
+
377
+
378
+
379
+
185
380
  }
186
381
  out = out.filter((a) => ancestorSet.has(a.id))
187
382
  }
@@ -209,11 +404,17 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
209
404
  return { visibleArticles: out, roots: roots.sort(sortByOrder), byId }
210
405
  }, [articles, statusFilter, typeFilter, searchResultIds])
211
406
 
407
+
408
+
409
+
212
410
  const isTreeMode = useMemo(
213
411
  () => statusFilter === 'all' && typeFilter === 'all',
214
412
  [statusFilter, typeFilter]
215
413
  )
216
414
 
415
+
416
+
417
+
217
418
  const handleDrop = async (itemId: string, targetParentId: string | undefined, insertIndex: number) => {
218
419
  const item = articles.find((a) => a.id === itemId)
219
420
  if (!item) return
@@ -231,6 +432,8 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
231
432
  if (originalIndex !== -1 && insertIndex > originalIndex) {
232
433
  effectiveIndex = insertIndex - 1
233
434
  }
435
+
436
+
234
437
  }
235
438
 
236
439
  const targetChildren = articles
@@ -239,7 +442,7 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
239
442
  const newGroup = [...targetChildren]
240
443
  newGroup.splice(effectiveIndex, 0, item)
241
444
 
242
- const updates: { id: string; type_slug: string; data: any }[] = []
445
+ const updates: { id: string; type_slug?: string; data: any }[] = []
243
446
 
244
447
  newGroup.forEach((a, order) => {
245
448
  const nextData = { ...a.data, order }
@@ -250,7 +453,7 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
250
453
  if (a.data?.order !== order || parentChanged) {
251
454
  updates.push({
252
455
  id: a.id,
253
- type_slug: a.type_slug || typeById[a.type_id]?.slug || 'kb-spine-public',
456
+ type_slug: a.type_slug || typeById[a.type_id]?.slug || undefined,
254
457
  data: nextData,
255
458
  })
256
459
  }
@@ -264,7 +467,7 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
264
467
  if (a.data?.order !== order) {
265
468
  updates.push({
266
469
  id: a.id,
267
- type_slug: a.type_slug || typeById[a.type_id]?.slug || 'kb-spine-public',
470
+ type_slug: a.type_slug || typeById[a.type_id]?.slug || undefined,
268
471
  data: { ...a.data, order },
269
472
  })
270
473
  }
@@ -289,10 +492,15 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
289
492
  }
290
493
  }
291
494
 
495
+
496
+
497
+
292
498
  const DropIndicator = () => (
293
499
  <div className="h-0.5 bg-primary rounded-full my-1" />
294
500
  )
295
501
 
502
+
503
+
296
504
  function getDropIndex(e: React.DragEvent, container: HTMLElement | null): number {
297
505
  if (!container) return 0
298
506
  const itemEls = Array.from(container.children).filter((c) => c.getAttribute('data-item') === 'true')
@@ -304,9 +512,13 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
304
512
  const centerY = rect.top + rect.height / 2 - containerRect.top
305
513
  if (mouseY < centerY) return i
306
514
  }
515
+
307
516
  return itemEls.length
308
517
  }
309
518
 
519
+
520
+
521
+
310
522
  function SortableDropZone({
311
523
  parentId,
312
524
  nodes,
@@ -340,6 +552,7 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
340
552
  if (!e.relatedTarget || !listRef.current?.contains(e.relatedTarget as Node)) {
341
553
  setOver(true)
342
554
  }
555
+
343
556
  }}
344
557
  onDragLeave={(e) => {
345
558
  e.preventDefault()
@@ -359,8 +572,16 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
359
572
  e.preventDefault()
360
573
  e.stopPropagation()
361
574
  setOver(false)
575
+
576
+
577
+
362
578
  const id = e.dataTransfer.getData('text/plain')
579
+
580
+
581
+
582
+
363
583
  const index = computeIndex(e)
584
+
364
585
  setInsertIndex(null)
365
586
  if (id) handleDrop(id, parentId, index)
366
587
  }}
@@ -389,7 +610,11 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
389
610
  onDrop={(e) => {
390
611
  e.preventDefault()
391
612
  e.stopPropagation()
613
+
614
+
615
+
392
616
  const id = e.dataTransfer.getData('text/plain')
617
+
393
618
  if (id) handleDrop(id, node.id, node.children.length)
394
619
  }}
395
620
  className={cn(
@@ -427,6 +652,14 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
427
652
  )
428
653
  }
429
654
 
655
+
656
+
657
+
658
+
659
+
660
+
661
+
662
+
430
663
  const renderFlatRow = (record: KBRecord) => (
431
664
  <div
432
665
  key={record.id}
@@ -555,3 +788,11 @@ export function KBArticleList({ typeSlugs, typeName, onSelect, onNew, onEdit }:
555
788
  </div>
556
789
  )
557
790
  }
791
+ // CIL[DOC-VECTOR type="context" content="purpose='Renders a searchable, filterable, drag-and-drop knowledge base article list.'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/components/ui/button.tsx"]
792
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
793
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
794
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
795
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
796
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
797
+ // CIL[END stable_id="~/.framework/src/components/kb/KBArticleList.tsx:KBArticleList:component"]
798
+
@@ -1,23 +1,16 @@
1
-
2
-
3
-
4
- // CIL[BEGIN chunk_id="appshell_moduleheader_1783929861" type="module_header" identity="imports" parent="none"]
5
- // CIL[DOC-MACRO purpose="Import React, router, and UI components for app shell layout"]
6
- // CIL[DOC-RESPONSIBILITY responsibility="Provide dependencies for AppShell component"]
7
- // CIL[DOC-CONTEXT module="src/components/layout/AppShell" layer="frontend-component" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"\\\"]"]
8
- // CIL[DOC-CONTRACT inputs="none" outputs="React, Link, Sidebar components, Separator, Breadcrumb components" errors="none" side_effects="none"]
9
- // CIL[DOC-MICRO logic_summary="Imports React, router Link, shadcn sidebar, separator and breadcrumb components" notable_decisions="[]"]
10
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
1
+ // CIL[BEGIN stable_id="~/.framework/src/components/layout/AppShell.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/components/layout/AppShell.tsx"]
2
+ // CIL[DOC-MACRO purpose="AppShell layout component module entry point"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide shared application shell imports and component"]
4
+ // CIL[DOC-CONTEXT module="AppShell" layer="component" related_files=".framework/src/components/ui/breadcrumb.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/sidebar.tsx"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Module header with React and UI imports for the AppShell layout component" notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
11
8
  // CIL[DOC-STABILITY stability="stable"]
12
- // CIL[DOC-AUDIENCE audience="developer"]
13
- // CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/components/ui/dialog.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, \."]
14
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
15
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
16
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
17
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
18
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
9
+ // CIL[DOC-AUDIENCE audience="system-ui"]
10
+
19
11
  import * as React from "react"
20
12
  import { Link } from 'react-router-dom'
13
+ import { cn } from "../../lib/utils"
21
14
  import { SidebarProvider, SidebarInset, SidebarTrigger } from "../ui/sidebar"
22
15
  import { Separator } from "../ui/separator"
23
16
  import {
@@ -28,49 +21,56 @@ import {
28
21
  BreadcrumbPage,
29
22
  BreadcrumbSeparator,
30
23
  } from "../ui/breadcrumb"
31
- // CIL[END chunk_id="appshell_moduleheader_1783929861"]
32
- // CIL[BEGIN chunk_id="appshell_appshellprops_1783929861" type="interface" identity="AppShellProps" parent="none"]
33
- // CIL[DOC-MACRO purpose="Define props interface for AppShell component with sidebar and navigation"]
34
- // CIL[DOC-RESPONSIBILITY responsibility="Specify AppShell component contract for professional layout"]
35
- // CIL[DOC-CONTEXT module="src/components/layout/AppShell" layer="frontend-component" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
36
- // CIL[DOC-CONTRACT inputs="none" outputs="AppShellProps interface" errors="none" side_effects="none"]
37
- // CIL[DOC-MICRO logic_summary="Interface with sidebar, children, breadcrumbs, and optional header actions" notable_decisions="[]"]
38
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
39
- // CIL[DOC-STABILITY stability="stable"]
40
- // CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
41
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
42
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
43
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
24
+
25
+ // CIL[DOC-VECTOR type="context" content="purpose='AppShell layout component module entry point'; No verified external callers; imports: .framework/src/components/ui/sidebar.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/breadcrumb.tsx"]
26
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
27
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
28
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
44
29
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
45
30
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
31
+ // CIL[END stable_id="~/.framework/src/components/layout/AppShell.tsx:module_header:module_header"]
32
+
33
+ // CIL[BEGIN stable_id="~/.framework/src/components/layout/AppShell.tsx:appshellprops:interface" type="interface" identity="AppShellProps" parent="~/.framework/src/components/layout/AppShell.tsx:module_header:module_header"]
34
+ // CIL[DOC-MACRO purpose="Props interface for the AppShell layout component"]
35
+ // CIL[DOC-RESPONSIBILITY responsibility="Declare the inputs accepted by AppShell"]
36
+ // CIL[DOC-CONTEXT module="AppShell" layer="component" related_files=".framework/src/components/layout/AppShell.tsx,.framework/src/components/ui/breadcrumb.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/sidebar.tsx"]
37
+ // CIL[DOC-CONTRACT inputs="none" outputs="AppShellProps interface type" errors="none" side_effects="none"]
38
+ // CIL[DOC-MICRO logic_summary="Defines AppShell props including sidebar, children, breadcrumbs, headerActions, banner and mainClassName" notable_decisions="mainClassName overrides the default main padding (p-4 md:p-6 lg:p-8) — apps whose pages self-pad pass a zero/tighter value to close the gap above the page header"]
39
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
40
+ // CIL[DOC-STABILITY stability="stable"]
41
+
46
42
  interface AppShellProps {
47
43
  sidebar: React.ReactNode
48
44
  children: React.ReactNode
49
45
  breadcrumbs?: { title: string; url?: string }[]
50
46
  headerActions?: React.ReactNode
51
47
  banner?: React.ReactNode
48
+ mainClassName?: string
52
49
  }
53
- // CIL[END chunk_id="appshell_appshellprops_1783929861"]
54
- // CIL[BEGIN chunk_id="appshell_appshell_1783929861" type="function" identity="AppShell" parent="none"]
55
- // CIL[DOC-MACRO purpose="Render professional app shell with sidebar, header breadcrumbs and main content"]
56
- // CIL[DOC-RESPONSIBILITY responsibility="Provide complete app layout with navigation and content areas"]
57
- // CIL[DOC-CONTEXT module="src/components/layout/AppShell" layer="frontend-component" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
58
- // CIL[DOC-CONTRACT inputs="none" outputs="JSX app shell layout" errors="none" side_effects="Manages sidebar state and provides navigation structure"]
59
- // CIL[DOC-MICRO logic_summary="SidebarProvider with collapsible sidebar, header with breadcrumbs, and main content area" notable_decisions="[]"]
60
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
61
- // CIL[DOC-STABILITY stability="stable"]
62
- // CIL[DOC-VECTOR type="context" content="Layer: frontend-component. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/RolesPage.tsx, \."]
63
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
64
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
65
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
50
+ // CIL[DOC-VECTOR type="context" content="purpose='Props interface for the AppShell layout component'; No verified external callers; imports: .framework/src/components/ui/sidebar.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/breadcrumb.tsx"]
51
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
52
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
53
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
66
54
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
67
55
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
56
+ // CIL[END stable_id="~/.framework/src/components/layout/AppShell.tsx:appshellprops:interface"]
57
+
58
+ // CIL[BEGIN stable_id="~/.framework/src/components/layout/AppShell.tsx:appshell:function" type="function" identity="AppShell" parent="~/.framework/src/components/layout/AppShell.tsx:module_header:module_header"]
59
+ // CIL[DOC-MACRO purpose="Render the main application shell with sidebar, header and content area"]
60
+ // CIL[DOC-RESPONSIBILITY responsibility="Compose sidebar, breadcrumbs, header actions, banner and children into the app layout"]
61
+ // CIL[DOC-CONTEXT module="AppShell" layer="component" related_files=".framework/src/components/layout/AppShell.tsx,.framework/src/components/ui/breadcrumb.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/sidebar.tsx"]
62
+ // CIL[DOC-CONTRACT inputs="sidebar: React.ReactNode, children: React.ReactNode, breadcrumbs: { title: string; url?: string }[] | undefined, headerActions: React.ReactNode | undefined, banner: React.ReactNode | undefined, mainClassName: string | undefined" outputs="React tree" errors="none" side_effects="none"]
63
+ // CIL[DOC-MICRO logic_summary="Wraps children in a sidebar-aware layout with optional breadcrumbs and header actions" notable_decisions="mainClassName replaces the default main padding (p-4 md:p-6 lg:p-8) entirely via cn() — pass an empty/tight value when pages self-pad to close the gap above the page header"]
64
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
65
+ // CIL[DOC-STABILITY stability="stable"]
66
+
68
67
  export function AppShell({
69
68
  sidebar,
70
69
  children,
71
70
  breadcrumbs,
72
71
  headerActions,
73
72
  banner,
73
+ mainClassName,
74
74
  }: AppShellProps) {
75
75
  return (
76
76
  <SidebarProvider>
@@ -119,11 +119,17 @@ export function AppShell({
119
119
  )}
120
120
  </header>
121
121
 
122
- <main className="flex-1 flex flex-col min-h-0 overflow-auto p-4 md:p-6 lg:p-8">
122
+ <main className={cn("flex-1 flex flex-col min-h-0 overflow-auto", mainClassName ?? "p-4 md:p-6 lg:p-8")}>
123
123
  {children}
124
124
  </main>
125
125
  </SidebarInset>
126
126
  </SidebarProvider>
127
127
  )
128
128
  }
129
- // CIL[END chunk_id="appshell_appshell_1783929861"]
129
+ // CIL[DOC-VECTOR type="context" content="purpose='Render the main application shell with sidebar, header and content area'; No verified external callers; imports: .framework/src/components/ui/sidebar.tsx,.framework/src/components/ui/separator.tsx,.framework/src/components/ui/breadcrumb.tsx"]
130
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
131
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
132
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
133
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
134
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
135
+ // CIL[END stable_id="~/.framework/src/components/layout/AppShell.tsx:appshell:function"]