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
@@ -0,0 +1,699 @@
1
+ // CIL[BEGIN chunk_id="cildashboardpage_module_header_1784193942" type="module_header" identity="module_header" parent="none"]
2
+ // CIL[DOC-MACRO purpose="Import dependencies and icons for the CIL dashboard page"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Provides module imports and icon references used by the page"]
4
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="module imports" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Imports React hooks, router, apiFetch, app path hook, UI components, and lucide icons" notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+ // CIL[DOC-AUDIENCE audience="developer"]
10
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/principal.ts, \."]
11
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
12
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
13
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
14
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
15
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
16
+ import { useEffect, useState, useCallback } from 'react'
17
+ import { useParams } from 'react-router-dom'
18
+ import { apiFetch } from '@core/lib/api'
19
+ import { Card, CardContent, CardHeader, CardTitle } from '@core/components/ui/card'
20
+ import { Button } from '@core/components/ui/button'
21
+ import { Badge } from '@core/components/ui/badge'
22
+ import { Skeleton } from '@core/components/ui/skeleton'
23
+ import { Progress } from '@core/components/ui/progress'
24
+ import {
25
+ CheckCircle2,
26
+ XCircle,
27
+ AlertTriangle,
28
+ Clock,
29
+ ChevronRight,
30
+ RefreshCw,
31
+ FileCode2,
32
+ Layers,
33
+ Zap,
34
+ Sparkles,
35
+ GitGraph,
36
+ Hash,
37
+ DollarSign,
38
+ Bot,
39
+ Search,
40
+ Play,
41
+ Settings2,
42
+ } from 'lucide-react'
43
+
44
+
45
+
46
+ import { PageInstructions } from '../../../components/admin/PageInstructions'
47
+ // CIL[END chunk_id="cildashboardpage_module_header_1784193942"]
48
+ // CIL[BEGIN chunk_id="cildashboardpage_projectstats_1784193942" type="interface" identity="ProjectStats" parent="none"]
49
+ // CIL[DOC-MACRO purpose="Define the ProjectStats data shape"]
50
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for project-level ingestion statistics"]
51
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
52
+ // CIL[DOC-CONTRACT inputs="none" outputs="ProjectStats type definition" errors="none" side_effects="none"]
53
+ // CIL[DOC-MICRO logic_summary="Declares file count, chunk count, proposal counts, ingestion cost, and last ingestion timestamp" notable_decisions="[]"]
54
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
55
+ // CIL[DOC-STABILITY stability="stable"]
56
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
57
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
58
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
59
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
60
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
61
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
62
+ interface ProjectStats {
63
+ file_count: number
64
+ chunk_count: number
65
+ proposal_count: number
66
+ approved_count: number
67
+ pending_review_count: number
68
+ total_ingestion_cost_usd: number
69
+ last_ingested_at: string | null
70
+ }
71
+
72
+ // CIL[END chunk_id="cildashboardpage_projectstats_1784193942"]
73
+ // CIL[BEGIN chunk_id="cildashboardpage_embedstatus_1784193942" type="interface" identity="EmbedStatus" parent="none"]
74
+ // CIL[DOC-MACRO purpose="Define the EmbedStatus data shape"]
75
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for chunk embedding coverage"]
76
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
77
+ // CIL[DOC-CONTRACT inputs="none" outputs="EmbedStatus type definition" errors="none" side_effects="none"]
78
+ // CIL[DOC-MICRO logic_summary="Declares total, embedded, unembedded counts and coverage percentage" notable_decisions="[]"]
79
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
80
+ // CIL[DOC-STABILITY stability="stable"]
81
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
82
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
83
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
84
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
85
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
86
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
87
+ interface EmbedStatus {
88
+ total_chunks: number
89
+ embedded_chunks: number
90
+ coverage_pct: number
91
+ unembedded_chunks: number
92
+ }
93
+
94
+ // CIL[END chunk_id="cildashboardpage_embedstatus_1784193942"]
95
+ // CIL[BEGIN chunk_id="cildashboardpage_docstatus_1784193942" type="interface" identity="DocStatus" parent="none"]
96
+ // CIL[DOC-MACRO purpose="Define the DocStatus data shape"]
97
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for documentation coverage"]
98
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
99
+ // CIL[DOC-CONTRACT inputs="none" outputs="DocStatus type definition" errors="none" side_effects="none"]
100
+ // CIL[DOC-MICRO logic_summary="Declares total, documented, undocumented, AI-generated, human-verified counts and coverage percentage" notable_decisions="[]"]
101
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
102
+ // CIL[DOC-STABILITY stability="stable"]
103
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
104
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
105
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
106
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
107
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
108
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
109
+ interface DocStatus {
110
+ total_chunks: number
111
+ documented_count: number
112
+ undocumented_count: number
113
+ ai_generated_count: number
114
+ human_verified_count: number
115
+ coverage_pct: number
116
+ }
117
+
118
+ // CIL[END chunk_id="cildashboardpage_docstatus_1784193942"]
119
+ // CIL[BEGIN chunk_id="cildashboardpage_callmapstatus_1784193942" type="interface" identity="CallmapStatus" parent="none"]
120
+ // CIL[DOC-MACRO purpose="Define the CallmapStatus data shape"]
121
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for call graph link counts"]
122
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
123
+ // CIL[DOC-CONTRACT inputs="none" outputs="CallmapStatus type definition" errors="none" side_effects="none"]
124
+ // CIL[DOC-MICRO logic_summary="Declares import, call, export, and tested-by link counts" notable_decisions="[]"]
125
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
126
+ // CIL[DOC-STABILITY stability="stable"]
127
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
128
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
129
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
130
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
131
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
132
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
133
+ interface CallmapStatus {
134
+ import_links: number
135
+ call_links: number
136
+ export_links: number
137
+ total_links: number
138
+ tested_by_links?: number
139
+ }
140
+
141
+ // CIL[END chunk_id="cildashboardpage_callmapstatus_1784193942"]
142
+ // CIL[BEGIN chunk_id="cildashboardpage_configstatus_1784193942" type="interface" identity="ConfigStatus" parent="none"]
143
+ // CIL[DOC-MACRO purpose="Define the ConfigStatus data shape"]
144
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for config extraction status"]
145
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
146
+ // CIL[DOC-CONTRACT inputs="none" outputs="ConfigStatus type definition" errors="none" side_effects="none"]
147
+ // CIL[DOC-MICRO logic_summary="Declares config item count and configures link count" notable_decisions="[]"]
148
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
149
+ // CIL[DOC-STABILITY stability="stable"]
150
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
151
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
152
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
153
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
154
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
155
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
156
+ interface ConfigStatus {
157
+ config_items: number
158
+ configures_links: number
159
+ }
160
+
161
+ // CIL[END chunk_id="cildashboardpage_configstatus_1784193942"]
162
+ // CIL[BEGIN chunk_id="cildashboardpage_dashboarddata_1784193942" type="interface" identity="DashboardData" parent="none"]
163
+ // CIL[DOC-MACRO purpose="Aggregate dashboard data types into a single view model"]
164
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide a TypeScript type contract for the dashboard's combined data state"]
165
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
166
+ // CIL[DOC-CONTRACT inputs="none" outputs="DashboardData type definition" errors="none" side_effects="none"]
167
+ // CIL[DOC-MICRO logic_summary="Groups project, embed, doc, callmap, and config status objects" notable_decisions="[]"]
168
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
169
+ // CIL[DOC-STABILITY stability="stable"]
170
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
171
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
172
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
173
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
174
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
175
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
176
+ interface DashboardData {
177
+ project: { id: string; title: string; data: ProjectStats } | null
178
+ embed: EmbedStatus | null
179
+ doc: DocStatus | null
180
+ callmap: CallmapStatus | null
181
+ config: ConfigStatus | null
182
+ }
183
+
184
+
185
+
186
+ // CIL[END chunk_id="cildashboardpage_dashboarddata_1784193942"]
187
+ // CIL[BEGIN chunk_id="cildashboardpage_passcard_1784193942" type="function" identity="PassCard" parent="none"]
188
+ // CIL[DOC-MACRO purpose="Render a pipeline pass card with status, label, description, and metric"]
189
+ // CIL[DOC-RESPONSIBILITY responsibility="Display a single pipeline step's completion status and metric as a clickable card"]
190
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
191
+ // CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="none" side_effects="none"]
192
+ // CIL[DOC-MICRO logic_summary="Selects a status color and icon config and renders a compact status card with an optional link" notable_decisions="[]"]
193
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
194
+ // CIL[DOC-STABILITY stability="stable"]
195
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
196
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
197
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
198
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
199
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
200
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
201
+ function PassCard({
202
+ number,
203
+ label,
204
+ icon: Icon,
205
+ description,
206
+ status,
207
+ metric,
208
+ href,
209
+ }: {
210
+ number: string
211
+ label: string
212
+ icon: React.ElementType
213
+ description: string
214
+ status: 'complete' | 'partial' | 'empty' | 'unknown'
215
+ metric: string
216
+ href?: string
217
+ }) {
218
+ const statusConfig = {
219
+ complete: { color: 'text-green-600', bg: 'bg-green-50 border-green-200', dot: 'bg-green-500', icon: CheckCircle2 },
220
+ partial: { color: 'text-amber-600', bg: 'bg-amber-50 border-amber-200', dot: 'bg-amber-500', icon: AlertTriangle },
221
+ empty: { color: 'text-slate-400', bg: 'bg-slate-50 border-slate-200', dot: 'bg-slate-300', icon: Clock },
222
+ unknown: { color: 'text-slate-400', bg: 'bg-slate-50 border-slate-200', dot: 'bg-slate-300', icon: Clock },
223
+ }[status]
224
+
225
+ const StatusIcon = statusConfig.icon
226
+
227
+ return (
228
+ <div className={`rounded-lg border p-3 ${statusConfig.bg} flex items-start gap-3`}>
229
+ <div className={`mt-0.5 h-7 w-7 rounded-md flex items-center justify-center shrink-0 ${status === 'complete' ? 'bg-green-100' : status === 'partial' ? 'bg-amber-100' : 'bg-slate-100'}`}>
230
+ <Icon className={`h-4 w-4 ${statusConfig.color}`} />
231
+ </div>
232
+ <div className="flex-1 min-w-0">
233
+ <div className="flex items-center gap-1.5">
234
+ <span className="text-xs font-bold text-muted-foreground">Pass {number}</span>
235
+ <StatusIcon className={`h-3 w-3 ${statusConfig.color}`} />
236
+ </div>
237
+ <div className="text-sm font-medium truncate">{label}</div>
238
+ <div className="text-xs text-muted-foreground">{description}</div>
239
+ <div className={`text-xs font-mono mt-1 font-semibold ${statusConfig.color}`}>{metric}</div>
240
+ </div>
241
+ {href && (
242
+ <a href={href} className="shrink-0 text-xs text-muted-foreground hover:text-foreground">
243
+ <ChevronRight className="h-4 w-4" />
244
+ </a>
245
+ )}
246
+ </div>
247
+ )
248
+ }
249
+
250
+
251
+
252
+ // CIL[END chunk_id="cildashboardpage_passcard_1784193942"]
253
+ // CIL[BEGIN chunk_id="cildashboardpage_stattile_1784193942" type="function" identity="StatTile" parent="none"]
254
+ // CIL[DOC-MACRO purpose="Render a numeric statistic tile with label and optional subtext"]
255
+ // CIL[DOC-RESPONSIBILITY responsibility="Display a single dashboard metric inside a styled Card"]
256
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
257
+ // CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="none" side_effects="none"]
258
+ // CIL[DOC-MICRO logic_summary="Renders a Card with a large value, label, optional sub, and icon" notable_decisions="[]"]
259
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
260
+ // CIL[DOC-STABILITY stability="stable"]
261
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
262
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
263
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
264
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
265
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
266
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
267
+ function StatTile({
268
+ label,
269
+ value,
270
+ sub,
271
+ icon: Icon,
272
+ accent = false,
273
+ }: {
274
+ label: string
275
+ value: string | number
276
+ sub?: string
277
+ icon: React.ElementType
278
+ accent?: boolean
279
+ }) {
280
+ return (
281
+ <Card className={accent ? 'border-indigo-200 bg-indigo-50/50' : ''}>
282
+ <CardContent className="pt-4 pb-3">
283
+ <div className="flex items-start justify-between">
284
+ <div>
285
+ <div className={`text-2xl font-bold tabular-nums ${accent ? 'text-indigo-700' : ''}`}>{value}</div>
286
+ <div className="text-xs text-muted-foreground mt-0.5">{label}</div>
287
+ {sub && <div className="text-xs text-muted-foreground mt-0.5">{sub}</div>}
288
+ </div>
289
+ <Icon className={`h-5 w-5 mt-1 ${accent ? 'text-indigo-400' : 'text-muted-foreground/50'}`} />
290
+ </div>
291
+ </CardContent>
292
+ </Card>
293
+ )
294
+ }
295
+
296
+
297
+
298
+ // CIL[END chunk_id="cildashboardpage_stattile_1784193942"]
299
+ // CIL[BEGIN chunk_id="cildashboardpage_coveragebar_1784193942" type="function" identity="CoverageBar" parent="none"]
300
+ // CIL[DOC-MACRO purpose="Render a labeled progress bar for coverage metrics"]
301
+ // CIL[DOC-RESPONSIBILITY responsibility="Display a percentage coverage value with a Progress bar"]
302
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
303
+ // CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="none" side_effects="none"]
304
+ // CIL[DOC-MICRO logic_summary="Renders a label, percentage, and shadcn Progress component" notable_decisions="[]"]
305
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
306
+ // CIL[DOC-STABILITY stability="stable"]
307
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
308
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
309
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
310
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
311
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
312
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
313
+ function CoverageBar({ label, pct, color = 'bg-indigo-500' }: { label: string; pct: number; color?: string }) {
314
+ return (
315
+ <div className="space-y-1">
316
+ <div className="flex items-center justify-between text-xs">
317
+ <span className="text-muted-foreground">{label}</span>
318
+ <span className="font-mono font-semibold">{pct}%</span>
319
+ </div>
320
+ <Progress value={pct} className="h-2" />
321
+ </div>
322
+ )
323
+ }
324
+
325
+
326
+
327
+ // CIL[END chunk_id="cildashboardpage_coveragebar_1784193942"]
328
+ // CIL[BEGIN chunk_id="cildashboardpage_driftalertcard_1784193942" type="function" identity="DriftAlertCard" parent="none"]
329
+ // CIL[DOC-MACRO purpose="Check stored chunk hashes and list drifted chunks for a project"]
330
+ // CIL[DOC-RESPONSIBILITY responsibility="Fetch chunk records, validate stored hashes, and render drift alerts with links"]
331
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
332
+ // CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="API or validation errors are swallowed" side_effects="Calls /api/admin-data and /api/cil-validate; sets local state"]
333
+ // CIL[DOC-MICRO logic_summary="Lists cil_chunk items for the project, calls the validate endpoint, and displays any drifted chunks or an all-current status" notable_decisions="[]"]
334
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
335
+ // CIL[DOC-STABILITY stability="stable"]
336
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
337
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
338
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
339
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
340
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
341
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
342
+ function DriftAlertCard({ projectId, appPath }: { projectId: string; appPath: (p: string) => string }) {
343
+ const [driftChunks, setDriftChunks] = useState<any[] | null>(null)
344
+ const [checking, setChecking] = useState(false)
345
+
346
+ const checkDrift = async () => {
347
+ setChecking(true)
348
+ try {
349
+
350
+ const res = await apiFetch(`/api/admin-data?action=list&entity=items&type_slug=cil_chunk&limit=200`)
351
+ const data = await res.json()
352
+ const chunks = (data?.data || data || []).filter(
353
+ (c: any) => c.data?.project_id === projectId && c.data?.stored_hash
354
+ )
355
+
356
+ if (!chunks.length) { setDriftChunks([]); return }
357
+
358
+
359
+ const validateRes = await apiFetch('/api/cil-validate?action=validate', {
360
+ method: 'POST',
361
+ headers: { 'Content-Type': 'application/json' },
362
+ body: JSON.stringify({
363
+ chunks: chunks.slice(0, 50).map((c: any) => ({
364
+ chunk_id: c.id,
365
+ chunk_name: c.data?.chunk_name || '',
366
+ content: c.data?.code_content || '',
367
+ })),
368
+ }),
369
+ })
370
+ const vData = await validateRes.json()
371
+ const results = vData?.results || vData?.data?.results || []
372
+ setDriftChunks(results.filter((r: any) => r.status === 'drift_detected'))
373
+ } finally {
374
+ setChecking(false)
375
+ }
376
+ }
377
+
378
+ return (
379
+ <Card>
380
+ <CardHeader className="pb-2">
381
+ <div className="flex items-center justify-between">
382
+ <CardTitle className="text-sm flex items-center gap-1.5">
383
+ <Hash className="h-4 w-4" /> Hash Drift
384
+ </CardTitle>
385
+ <Button size="sm" variant="outline" onClick={checkDrift} disabled={checking} className="h-7 text-xs">
386
+ {checking ? <RefreshCw className="h-3 w-3 animate-spin" /> : <Hash className="h-3 w-3" />}
387
+ {checking ? 'Checking…' : 'Check Now'}
388
+ </Button>
389
+ </div>
390
+ </CardHeader>
391
+ <CardContent>
392
+ {driftChunks === null && (
393
+ <p className="text-xs text-muted-foreground">Click "Check Now" to validate all stored hashes against current code_content.</p>
394
+ )}
395
+ {driftChunks?.length === 0 && (
396
+ <div className="flex items-center gap-1.5 text-sm text-green-600">
397
+ <CheckCircle2 className="h-4 w-4" /> All hashes current
398
+ </div>
399
+ )}
400
+ {driftChunks && driftChunks.length > 0 && (
401
+ <div className="space-y-1.5">
402
+ <div className="flex items-center gap-1.5 text-sm text-red-600 mb-2">
403
+ <XCircle className="h-4 w-4" /> {driftChunks.length} chunk{driftChunks.length !== 1 ? 's' : ''} with drift
404
+ </div>
405
+ {driftChunks.slice(0, 5).map((r: any) => (
406
+ <a
407
+ key={r.chunk_id}
408
+ href={appPath(`/cil/${projectId}/chunks/${r.chunk_id}`)}
409
+ className="flex items-center gap-2 text-xs hover:bg-red-50 rounded p-1 group"
410
+ >
411
+ <XCircle className="h-3 w-3 text-red-500 shrink-0" />
412
+ <span className="font-mono truncate">{r.chunk_name}</span>
413
+ <ChevronRight className="h-3 w-3 text-muted-foreground opacity-0 group-hover:opacity-100 ml-auto" />
414
+ </a>
415
+ ))}
416
+ {driftChunks.length > 5 && (
417
+ <p className="text-xs text-muted-foreground">…and {driftChunks.length - 5} more</p>
418
+ )}
419
+ </div>
420
+ )}
421
+ </CardContent>
422
+ </Card>
423
+ )
424
+ }
425
+
426
+
427
+
428
+ // CIL[END chunk_id="cildashboardpage_driftalertcard_1784193942"]
429
+ // CIL[BEGIN chunk_id="cildashboardpage_cildashboardpage_1784193942" type="component" identity="CILDashboardPage" parent="none"]
430
+ // CIL[DOC-MACRO purpose="Render the CIL project dashboard page"]
431
+ // CIL[DOC-RESPONSIBILITY responsibility="Fetch project status and display pipeline passes, coverage, stats, graph links, drift alerts, and quick actions"]
432
+ // CIL[DOC-CONTEXT module="cortex:cil-dashboard" layer="presentation" related_files="[]"]
433
+ // CIL[DOC-CONTRACT inputs="none" outputs="JSX.Element" errors="Failed requests are ignored; empty states shown" side_effects="Calls /api/cil-project, /api/cil-embeddings, /api/cil-doc, /api/cil-callmap, and /api/cil-config; updates local state"]
434
+ // CIL[DOC-MICRO logic_summary="Loads project, embedding, documentation, callmap, and config statuses in parallel, then renders stat tiles, coverage bars, pass cards, graph links, drift alerts, and quick action buttons" notable_decisions="[]"]
435
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
436
+ // CIL[DOC-STABILITY stability="stable"]
437
+ // CIL[DOC-VECTOR type="context" content="Layer: presentation. Direct callers: 0. Direct calls: 0. Related files: none."]
438
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
439
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
440
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
441
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
442
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
443
+ export default function CILDashboardPage() {
444
+ const { id: projectId } = useParams<{ id: string }>()
445
+ const appPath = (path: string) => '/spine-framework/admin' + (path.startsWith('/') ? path : '/' + path)
446
+ const [data, setData] = useState<DashboardData>({ project: null, embed: null, doc: null, callmap: null, config: null })
447
+ const [loading, setLoading] = useState(true)
448
+
449
+ const load = useCallback(async () => {
450
+ if (!projectId) return
451
+ setLoading(true)
452
+ try {
453
+ const [projectRes, embedRes, docRes, callmapRes, configRes] = await Promise.allSettled([
454
+ apiFetch(`/api/cil-project?action=get&id=${projectId}`).then(r => r.json()),
455
+ apiFetch(`/api/cil-embeddings?action=status&project_id=${projectId}`).then(r => r.json()),
456
+ apiFetch(`/api/cil-doc?action=gap_report&project_id=${projectId}`).then(r => r.json()),
457
+ apiFetch(`/api/cil-callmap?action=status&project_id=${projectId}`).then(r => r.json()),
458
+ apiFetch(`/api/cil-config?action=status&project_id=${projectId}`).then(r => r.json()),
459
+ ])
460
+
461
+ setData({
462
+ project: projectRes.status === 'fulfilled' ? (projectRes.value?.project || projectRes.value?.data?.project) : null,
463
+ embed: embedRes.status === 'fulfilled' ? (embedRes.value?.data || embedRes.value) : null,
464
+ doc: docRes.status === 'fulfilled' ? (docRes.value?.data || docRes.value) : null,
465
+ callmap: callmapRes.status === 'fulfilled' ? (callmapRes.value?.data || callmapRes.value) : null,
466
+ config: configRes.status === 'fulfilled' ? (configRes.value?.data || configRes.value) : null,
467
+ })
468
+ } finally {
469
+ setLoading(false)
470
+ }
471
+ }, [projectId])
472
+
473
+ useEffect(() => { load() }, [load])
474
+
475
+ if (loading) {
476
+ return (
477
+ <div className="p-6 space-y-4">
478
+ <Skeleton className="h-6 w-48" />
479
+ <div className="grid grid-cols-4 gap-4">{Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className="h-24" />)}</div>
480
+ <div className="grid grid-cols-2 gap-4">{Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className="h-32" />)}</div>
481
+ </div>
482
+ )
483
+ }
484
+
485
+ const project = data.project
486
+ const stats: ProjectStats = project?.data || { file_count: 0, chunk_count: 0, proposal_count: 0, approved_count: 0, pending_review_count: 0, total_ingestion_cost_usd: 0, last_ingested_at: null }
487
+ const embed = data.embed || { total_chunks: 0, embedded_chunks: 0, coverage_pct: 0, unembedded_chunks: 0 }
488
+ const doc = data.doc || { total_chunks: 0, documented_count: 0, undocumented_count: 0, ai_generated_count: 0, human_verified_count: 0, coverage_pct: 0 }
489
+ const callmap = data.callmap || { import_links: 0, call_links: 0, export_links: 0, total_links: 0, tested_by_links: 0 }
490
+ const config = data.config || { config_items: 0, configures_links: 0 }
491
+
492
+ const lastIngested = stats.last_ingested_at
493
+ ? new Date(stats.last_ingested_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })
494
+ : 'Never'
495
+
496
+
497
+ const pass1Status = stats.file_count > 0 ? 'complete' : 'empty'
498
+ const pass2Status = stats.chunk_count > 0 ? 'complete' : (stats.file_count > 0 ? 'partial' : 'empty')
499
+ const pass3Status = embed.coverage_pct === 100 ? 'complete' : (embed.embedded_chunks > 0 ? 'partial' : 'empty') as any
500
+ const pass4Status = doc.coverage_pct === 100 ? 'complete' : (doc.documented_count > 0 ? 'partial' : 'empty') as any
501
+ const pass4bStatus = callmap.total_links > 0 ? 'complete' : 'empty' as any
502
+ const pass5Status = config.config_items > 0 ? (config.configures_links > 0 ? 'complete' : 'partial') : 'empty' as any
503
+
504
+ return (
505
+ <div className="p-6 space-y-6 max-w-5xl">
506
+ {}
507
+ <div className="flex items-center gap-2 text-sm text-muted-foreground">
508
+ <a href={appPath('/cil')} className="hover:underline">Code Intelligence</a>
509
+ <ChevronRight className="h-3 w-3" />
510
+ <span>{project?.title || 'Project'}</span>
511
+ <ChevronRight className="h-3 w-3" />
512
+ <span>Dashboard</span>
513
+ </div>
514
+
515
+ {}
516
+ <div className="flex items-start justify-between flex-wrap gap-4">
517
+ <div>
518
+ <h1 className="text-2xl font-bold">{project?.title || 'Project Dashboard'}</h1>
519
+ <p className="text-xs text-muted-foreground font-mono mt-0.5">Last ingested: {lastIngested}</p>
520
+ </div>
521
+ <div className="flex items-center gap-2">
522
+ <Button size="sm" variant="outline" onClick={load} className="h-8 text-xs">
523
+ <RefreshCw className="h-3 w-3 mr-1" /> Refresh
524
+ </Button>
525
+ <Button size="sm" asChild className="h-8 text-xs">
526
+ <a href={appPath(`/cil/${projectId}/ingest`)}>
527
+ <Play className="h-3 w-3 mr-1" /> Run Pipeline
528
+ </a>
529
+ </Button>
530
+ </div>
531
+ </div>
532
+
533
+ <PageInstructions
534
+ description="Review CIL project health and ingestion coverage."
535
+ sections={[
536
+ { title: 'What this page is for', content: 'This page is the project-level overview for a CIL project. It displays stats, coverage, pipeline status, graph links, and drift alerts.' },
537
+ { title: 'How to read the cards', content: 'The top tiles show Files, Chunks, Pending Review, and cumulative LLM Cost. The Coverage card shows embedding and documentation coverage plus AI-generated, human-verified, and undocumented counts.' },
538
+ { title: 'How to read the pipeline', content: 'Pass cards summarize Discover Files, AST Chunk, Embed Chunks, AI Document, Call Map, and Config Extract. Each card shows status, counts, and a link to the relevant step.' },
539
+ { title: 'Important notes', content: 'Use Refresh to reload the dashboard and Run Pipeline to start or continue ingestion. A drift alert appears when stored hashes differ from current code.' },
540
+ ]}
541
+ />
542
+
543
+ {}
544
+ <div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
545
+ <StatTile label="Files" value={stats.file_count.toLocaleString()} icon={FileCode2} />
546
+ <StatTile label="Chunks" value={stats.chunk_count.toLocaleString()} icon={Layers} accent />
547
+ <StatTile
548
+ label="Pending Review"
549
+ value={stats.pending_review_count}
550
+ icon={AlertTriangle}
551
+ />
552
+ <StatTile
553
+ label="LLM Cost"
554
+ value={`$${(stats.total_ingestion_cost_usd ?? 0).toFixed(4)}`}
555
+ sub="cumulative"
556
+ icon={DollarSign}
557
+ />
558
+ </div>
559
+
560
+ {}
561
+ <Card>
562
+ <CardHeader className="pb-2">
563
+ <CardTitle className="text-sm">Coverage</CardTitle>
564
+ </CardHeader>
565
+ <CardContent className="space-y-3">
566
+ <CoverageBar label={`Embeddings — ${embed.embedded_chunks} / ${embed.total_chunks} chunks`} pct={embed.coverage_pct} color="bg-indigo-500" />
567
+ <CoverageBar label={`Documentation — ${doc.documented_count} / ${doc.total_chunks} chunks`} pct={doc.coverage_pct} color="bg-emerald-500" />
568
+ <div className="pt-1 grid grid-cols-3 gap-3 text-xs text-center text-muted-foreground">
569
+ <div>
570
+ <div className="font-semibold text-blue-600">{doc.ai_generated_count}</div>
571
+ <div>AI Generated</div>
572
+ </div>
573
+ <div>
574
+ <div className="font-semibold text-green-600">{doc.human_verified_count}</div>
575
+ <div>Human Verified</div>
576
+ </div>
577
+ <div>
578
+ <div className="font-semibold text-slate-500">{doc.undocumented_count}</div>
579
+ <div>Undocumented</div>
580
+ </div>
581
+ </div>
582
+ </CardContent>
583
+ </Card>
584
+
585
+ {}
586
+ <div>
587
+ <h2 className="text-sm font-medium text-muted-foreground uppercase tracking-wide mb-3">Pipeline Status</h2>
588
+ <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
589
+ <PassCard
590
+ number="1" label="Discover Files" icon={FileCode2}
591
+ description="Walk repo, register cil_file items, compute hashes"
592
+ status={pass1Status}
593
+ metric={`${stats.file_count.toLocaleString()} files registered`}
594
+ href={appPath(`/cil/${projectId}/ingest`)}
595
+ />
596
+ <PassCard
597
+ number="2" label="AST Chunk" icon={Layers}
598
+ description="Parse files, propose chunk boundaries, write markers"
599
+ status={pass2Status}
600
+ metric={`${stats.chunk_count.toLocaleString()} chunks · ${stats.pending_review_count} pending`}
601
+ href={appPath(`/cil/${projectId}/ingest`)}
602
+ />
603
+ <PassCard
604
+ number="3" label="Embed Chunks" icon={Zap}
605
+ description="Semantic + structural + contract vector embeddings"
606
+ status={pass3Status}
607
+ metric={`${embed.coverage_pct}% coverage · ${embed.embedded_chunks} / ${embed.total_chunks}`}
608
+ href={appPath(`/cil/${projectId}/ingest`)}
609
+ />
610
+ <PassCard
611
+ number="4" label="AI Document" icon={Sparkles}
612
+ description="LLM-generated macro / micro / contract fields"
613
+ status={pass4Status}
614
+ metric={`${doc.coverage_pct}% coverage · $${(stats.total_ingestion_cost_usd ?? 0).toFixed(4)} spent`}
615
+ href={appPath(`/cil/${projectId}/ingest`)}
616
+ />
617
+ <PassCard
618
+ number="4b" label="Call Map" icon={GitGraph}
619
+ description="Import + call edges between files and chunks"
620
+ status={pass4bStatus}
621
+ metric={`${callmap.call_links.toLocaleString()} calls · ${callmap.import_links.toLocaleString()} imports`}
622
+ href={appPath(`/cil/${projectId}/graph`)}
623
+ />
624
+ <PassCard
625
+ number="5" label="Config Extract" icon={Settings2}
626
+ description="Config field contracts + cil_configures links"
627
+ status={pass5Status}
628
+ metric={`${config.config_items.toLocaleString()} config items · ${config.configures_links.toLocaleString()} links`}
629
+ href={appPath(`/cil/${projectId}/ingest`)}
630
+ />
631
+ </div>
632
+ </div>
633
+
634
+ {}
635
+ <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
636
+ {}
637
+ <Card>
638
+ <CardHeader className="pb-2">
639
+ <CardTitle className="text-sm flex items-center gap-1.5">
640
+ <GitGraph className="h-4 w-4" /> Graph Links
641
+ </CardTitle>
642
+ </CardHeader>
643
+ <CardContent className="space-y-2">
644
+ {[
645
+ { label: 'Import links (file→file)', value: callmap.import_links },
646
+ { label: 'Call links (chunk→chunk)', value: callmap.call_links },
647
+ { label: 'Export links', value: callmap.export_links },
648
+ { label: 'Tested-by links', value: callmap.tested_by_links ?? 0 },
649
+ ].map(item => (
650
+ <div key={item.label} className="flex justify-between text-sm">
651
+ <span className="text-muted-foreground">{item.label}</span>
652
+ <span className="font-mono font-medium">{item.value.toLocaleString()}</span>
653
+ </div>
654
+ ))}
655
+ <div className="pt-2 flex gap-2">
656
+ <Button size="sm" variant="outline" className="flex-1 h-7 text-xs" asChild>
657
+ <a href={appPath(`/cil/${projectId}/graph`)}>
658
+ <GitGraph className="h-3 w-3 mr-1" /> View Graph
659
+ </a>
660
+ </Button>
661
+ </div>
662
+ </CardContent>
663
+ </Card>
664
+
665
+ {}
666
+ <DriftAlertCard projectId={projectId!} appPath={appPath} />
667
+ </div>
668
+
669
+ {}
670
+ <div>
671
+ <h2 className="text-sm font-medium text-muted-foreground uppercase tracking-wide mb-3">Quick Actions</h2>
672
+ <div className="flex flex-wrap gap-2">
673
+ <Button size="sm" variant="outline" asChild>
674
+ <a href={appPath(`/cil/search`)}>
675
+ <Search className="h-3.5 w-3.5 mr-1.5" /> Search Chunks
676
+ </a>
677
+ </Button>
678
+ <Button size="sm" variant="outline" asChild>
679
+ <a href={appPath(`/cil/${projectId}/agent`)}>
680
+ <Bot className="h-3.5 w-3.5 mr-1.5" /> Ask CIL Agent
681
+ </a>
682
+ </Button>
683
+ <Button size="sm" variant="outline" asChild>
684
+ <a href={appPath(`/cil/${projectId}/files`)}>
685
+ <Layers className="h-3.5 w-3.5 mr-1.5" /> Browse Files
686
+ </a>
687
+ </Button>
688
+ <Button size="sm" variant="outline" asChild>
689
+ <a href={appPath(`/cil/${projectId}/ingest`)}>
690
+ <Play className="h-3.5 w-3.5 mr-1.5" /> Run Ingestion
691
+ </a>
692
+ </Button>
693
+ </div>
694
+ </div>
695
+ </div>
696
+ )
697
+ }
698
+
699
+ // CIL[END chunk_id="cildashboardpage_cildashboardpage_1784193942"]