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,773 @@
1
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_module_header_1784235266" type="module_header" identity="module_header" parent="none"]
2
+ // CIL[DOC-MACRO purpose="Module header and top-level exports for cortex.functions.custom_cil-agent-ingest"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Own module-level imports, exports, and configuration for cortex.functions.custom_cil-agent-ingest"]
4
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/components/ui/table-primitives.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="module exports and side effects" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Declares module scope, imports dependencies, and exports public surface of cortex.functions.custom_cil-agent-ingest" 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: function. Direct callers: 0. Direct calls: 0. Related files: .framework/migrations/015_simplify_apps_table.sql, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/components/ui/table-primitives.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
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
+
17
+
18
+ import { createHandler } from './_shared/middleware'
19
+ import { adminDb } from './_shared/db'
20
+ import { create as adminCreate, update as adminUpdate } from './admin-data'
21
+ import { resolveTypeId } from './_shared/resolve-ids'
22
+ import * as fs from 'fs'
23
+ import * as path from 'path'
24
+ import * as crypto from 'crypto'
25
+
26
+
27
+
28
+
29
+
30
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_module_header_1784235266"]
31
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_agentingestrequest_1784235266" type="interface" identity="agentingestrequest" parent="none"]
32
+ // CIL[DOC-MACRO purpose="Defines the agentingestrequest type contract in cortex.functions.custom_cil-agent-ingest"]
33
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for agentingestrequest"]
34
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
35
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for agentingestrequest" errors="none" side_effects="none"]
36
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface agentingestrequest with member definitions" notable_decisions="[]"]
37
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
38
+ // CIL[DOC-STABILITY stability="stable"]
39
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/migrations/015_simplify_apps_table.sql, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
40
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
41
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
42
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
43
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
44
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
45
+ interface AgentIngestRequest {
46
+ project_id: string
47
+ file_id?: string
48
+ file_path?: string
49
+ file_hash?: string
50
+ markers?: AgentParsedMarker[]
51
+ chunks?: Array<{
52
+ chunk_id: string
53
+ documentation: Record<string, any>
54
+ metadata?: Record<string, any>
55
+ }>
56
+ file_ids?: string[]
57
+ new_file_path?: string
58
+ }
59
+
60
+
61
+
62
+
63
+
64
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_agentingestrequest_1784235266"]
65
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_agentparsedmarker_1784235266" type="interface" identity="agentparsedmarker" parent="none"]
66
+ // CIL[DOC-MACRO purpose="Defines the agentparsedmarker type contract in cortex.functions.custom_cil-agent-ingest"]
67
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for agentparsedmarker"]
68
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
69
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for agentparsedmarker" errors="none" side_effects="none"]
70
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface agentparsedmarker with member definitions" notable_decisions="[]"]
71
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
72
+ // CIL[DOC-STABILITY stability="stable"]
73
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/migrations/015_simplify_apps_table.sql, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
74
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
75
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
76
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
77
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
78
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
79
+ interface AgentParsedMarker {
80
+ chunk_id: string
81
+ start_line: number
82
+ end_line: number
83
+ type: string
84
+ identity: string
85
+ parent: string
86
+ attributes?: Record<string, string>
87
+ }
88
+
89
+
90
+
91
+
92
+
93
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_agentparsedmarker_1784235266"]
94
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_agentparseddocs_1784235266" type="interface" identity="agentparseddocs" parent="none"]
95
+ // CIL[DOC-MACRO purpose="Defines the agentparseddocs type contract in cortex.functions.custom_cil-agent-ingest"]
96
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for agentparseddocs"]
97
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
98
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for agentparseddocs" errors="none" side_effects="none"]
99
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface agentparseddocs with member definitions" notable_decisions="[]"]
100
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
101
+ // CIL[DOC-STABILITY stability="stable"]
102
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/migrations/015_simplify_apps_table.sql, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
103
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
104
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
105
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
106
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
107
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
108
+ interface AgentParsedDocs {
109
+ macro?: string
110
+ responsibility?: string
111
+ context?: Record<string, any>
112
+ contract?: Record<string, any>
113
+ micro?: Record<string, any>
114
+ examples?: Record<string, any>
115
+ confidence?: { pass: string; score: number; flags: string[] }
116
+ stability?: string
117
+ audience?: string
118
+ raw: Record<string, string>
119
+ }
120
+
121
+
122
+
123
+
124
+
125
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_agentparseddocs_1784235266"]
126
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_computefilehash_1784235266" type="function" identity="computefilehash" parent="none"]
127
+ // CIL[DOC-MACRO purpose="Implements computefilehash logic in cortex.functions.custom_cil-agent-ingest"]
128
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute computefilehash and return its computed result"]
129
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/migrations/015_simplify_apps_table.sql\"]"]
130
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
131
+ // CIL[DOC-MICRO logic_summary="Provides computefilehash with computeFileHash(content: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
132
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
133
+ // CIL[DOC-STABILITY stability="stable"]
134
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/migrations/015_simplify_apps_table.sql."]
135
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
136
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
137
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
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
+ function computeFileHash(content: string): string {
141
+ return crypto.createHash('sha256').update(content, 'utf8').digest('hex')
142
+ }
143
+
144
+
145
+
146
+
147
+
148
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_computefilehash_1784235266"]
149
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_estimatetokens_1784235266" type="function" identity="estimatetokens" parent="none"]
150
+ // CIL[DOC-MACRO purpose="Implements estimatetokens logic in cortex.functions.custom_cil-agent-ingest"]
151
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute estimatetokens and return its computed result"]
152
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[]"]
153
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
154
+ // CIL[DOC-MICRO logic_summary="Provides estimatetokens with estimateTokens(text: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
155
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
156
+ // CIL[DOC-STABILITY stability="stable"]
157
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
158
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
159
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
160
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
161
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
162
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
163
+ function estimateTokens(text: string): number {
164
+ return Math.ceil(text.length / 4)
165
+ }
166
+
167
+
168
+
169
+
170
+
171
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_estimatetokens_1784235266"]
172
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_normaliseagentchunkcontent_1784235266" type="function" identity="normaliseagentchunkcontent" parent="none"]
173
+ // CIL[DOC-MACRO purpose="Implements normaliseagentchunkcontent logic in cortex.functions.custom_cil-agent-ingest"]
174
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute normaliseagentchunkcontent and return its computed result"]
175
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[]"]
176
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
177
+ // CIL[DOC-MICRO logic_summary="Provides normaliseagentchunkcontent with normaliseAgentChunkContent(raw: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
178
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
179
+ // CIL[DOC-STABILITY stability="stable"]
180
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
181
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
182
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
183
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
184
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
185
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
186
+ function normaliseAgentChunkContent(raw: string): string {
187
+ const lines = raw.replace(/\r\n/g, '\n').split('\n')
188
+ const filtered = lines.filter(line => {
189
+ const trimmed = line.trim()
190
+ return !trimmed.match(/^(?:(?:\/\/|--|#)\s*|<!--\s*)CIL\[(BEGIN|END)/) && !trimmed.match(/^(?:(?:\/\/|--|#)\s*|<!--\s*)CIL\[DOC-/)
191
+ })
192
+ const collapsed: string[] = []
193
+ let lastBlank = false
194
+ for (const line of filtered) {
195
+ const isBlank = line.trim() === ''
196
+ if (isBlank && lastBlank) continue
197
+ collapsed.push(line)
198
+ lastBlank = isBlank
199
+ }
200
+ return collapsed.join('\n').trim()
201
+ }
202
+
203
+
204
+
205
+
206
+
207
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_normaliseagentchunkcontent_1784235266"]
208
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_computeagentchunkhash_1784235266" type="function" identity="computeagentchunkhash" parent="none"]
209
+ // CIL[DOC-MACRO purpose="Implements computeagentchunkhash logic in cortex.functions.custom_cil-agent-ingest"]
210
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute computeagentchunkhash and return its computed result"]
211
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[]"]
212
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
213
+ // CIL[DOC-MICRO logic_summary="Provides computeagentchunkhash with computeAgentChunkHash(codeContent: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
214
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
215
+ // CIL[DOC-STABILITY stability="stable"]
216
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
217
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
218
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
219
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
220
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
221
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
222
+ function computeAgentChunkHash(codeContent: string): string {
223
+ return crypto.createHash('sha256').update(normaliseAgentChunkContent(codeContent)).digest('hex').slice(0, 16)
224
+ }
225
+
226
+
227
+
228
+
229
+
230
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_computeagentchunkhash_1784235266"]
231
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_parseagentattributes_1784235266" type="function" identity="parseagentattributes" parent="none"]
232
+ // CIL[DOC-MACRO purpose="Implements parseagentattributes logic in cortex.functions.custom_cil-agent-ingest"]
233
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute parseagentattributes and return its computed result"]
234
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[]"]
235
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
236
+ // CIL[DOC-MICRO logic_summary="Provides parseagentattributes with parseAgentAttributes(attrString: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
237
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
238
+ // CIL[DOC-STABILITY stability="stable"]
239
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
240
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
241
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
242
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
243
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
244
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
245
+ function parseAgentAttributes(attrString: string): Record<string, string> {
246
+ const attrs: Record<string, string> = {}
247
+ const regex = /(\w+)="([^"]*)"/g
248
+ let match: RegExpExecArray | null
249
+ while ((match = regex.exec(attrString)) !== null) {
250
+ attrs[match[1]] = match[2]
251
+ }
252
+ return attrs
253
+ }
254
+
255
+
256
+
257
+
258
+
259
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_parseagentattributes_1784235266"]
260
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_parseagentcilmarkers_1784235266" type="function" identity="parseagentcilmarkers" parent="none"]
261
+ // CIL[DOC-MACRO purpose="Implements parseagentcilmarkers logic in cortex.functions.custom_cil-agent-ingest"]
262
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute parseagentcilmarkers and return its computed result"]
263
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[]"]
264
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
265
+ // CIL[DOC-MICRO logic_summary="Provides parseagentcilmarkers with parseAgentCilMarkers(lines: string[] inputs, handling internal flow and returning a result" notable_decisions="[]"]
266
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
267
+ // CIL[DOC-STABILITY stability="stable"]
268
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
269
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
270
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
271
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
272
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
273
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
274
+ function parseAgentCilMarkers(lines: string[]): AgentParsedMarker[] {
275
+ const markers: AgentParsedMarker[] = []
276
+ const stack: { line: number; attrs: Record<string, string> }[] = []
277
+
278
+ for (let i = 0; i < lines.length; i++) {
279
+ const trimmed = lines[i].trim()
280
+ const beginMatch = trimmed.match(/^(?:\/\/|--|#)\s*CIL\[BEGIN\s+(.+)\]$/) || trimmed.match(/^<!--\s*CIL\[BEGIN\s+(.+)\]\s*-->$/)
281
+ const endMatch = trimmed.match(/^(?:\/\/|--|#)\s*CIL\[END\s+chunk_id="([^"]+)"\]$/) || trimmed.match(/^<!--\s*CIL\[END\s+chunk_id="([^"]+)"\]\s*-->$/)
282
+
283
+ if (beginMatch) {
284
+ const attrs = parseAgentAttributes(beginMatch[1])
285
+ stack.push({ line: i + 1, attrs })
286
+ } else if (endMatch && stack.length > 0) {
287
+ const opened = stack.pop()!
288
+ markers.push({
289
+ chunk_id: endMatch[1],
290
+ start_line: opened.line,
291
+ end_line: i + 1,
292
+ type: opened.attrs.type || 'unknown',
293
+ identity: opened.attrs.identity || '',
294
+ parent: opened.attrs.parent || 'none',
295
+ attributes: opened.attrs,
296
+ })
297
+ }
298
+ }
299
+
300
+ return markers
301
+ }
302
+
303
+
304
+
305
+
306
+
307
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_parseagentcilmarkers_1784235266"]
308
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_parseagentcildocs_1784235266" type="function" identity="parseagentcildocs" parent="none"]
309
+ // CIL[DOC-MACRO purpose="Implements parseagentcildocs logic in cortex.functions.custom_cil-agent-ingest"]
310
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute parseagentcildocs and return its computed result"]
311
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[]"]
312
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
313
+ // CIL[DOC-MICRO logic_summary="Provides parseagentcildocs with parseAgentCilDocs(lines: string[], startLine: number, endLine: number inputs, handling internal flow and returning a result" notable_decisions="[]"]
314
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
315
+ // CIL[DOC-STABILITY stability="stable"]
316
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
317
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
318
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
319
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
320
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
321
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
322
+ function parseAgentCilDocs(lines: string[], startLine: number, endLine: number): AgentParsedDocs {
323
+ const docs: AgentParsedDocs = { raw: {} }
324
+ for (let i = startLine - 1; i < endLine - 1; i++) {
325
+ const trimmed = lines[i].trim()
326
+ const match = trimmed.match(/^(?:\/\/|--|#)\s*CIL\[DOC-(\w+)\s+(.+)\]$/) || trimmed.match(/^<!--\s*CIL\[DOC-(\w+)\s+(.+)\]\s*-->$/)
327
+ if (!match) continue
328
+ const key = match[1]
329
+ const content = match[2]
330
+ docs.raw[key] = content
331
+
332
+ const attrs = parseAgentAttributes(content)
333
+
334
+ switch (key) {
335
+ case 'MACRO':
336
+ docs.macro = attrs.purpose || content.replace(/^purpose="|"$/g, '')
337
+ break
338
+ case 'RESPONSIBILITY':
339
+ docs.responsibility = attrs.responsibility || content.replace(/^responsibility="|"$/g, '')
340
+ break
341
+ case 'CONTEXT':
342
+ docs.context = attrs
343
+ break
344
+ case 'CONTRACT':
345
+ docs.contract = attrs
346
+ break
347
+ case 'MICRO':
348
+ docs.micro = attrs
349
+ break
350
+ case 'EXAMPLES':
351
+ docs.examples = attrs
352
+ break
353
+ case 'EXPORTS':
354
+ docs.examples = { ...docs.examples, exports: attrs }
355
+ break
356
+ case 'CONFIDENCE':
357
+ docs.confidence = {
358
+ pass: attrs.pass || 'first',
359
+ score: parseFloat(attrs.score || '0'),
360
+ flags: attrs.flags ? attrs.flags.split(',').map((s: string) => s.trim()).filter(Boolean) : [],
361
+ }
362
+ break
363
+ case 'STABILITY':
364
+ docs.stability = attrs.stability || content.replace(/^stability="|"$/g, '')
365
+ break
366
+ case 'AUDIENCE':
367
+ docs.audience = attrs.audience || content.replace(/^audience="|"$/g, '')
368
+ break
369
+ }
370
+ }
371
+ return docs
372
+ }
373
+
374
+
375
+
376
+
377
+
378
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_parseagentcildocs_1784235266"]
379
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_mapagentdocstochunkdata_1784235266" type="function" identity="mapagentdocstochunkdata" parent="none"]
380
+ // CIL[DOC-MACRO purpose="Implements mapagentdocstochunkdata logic in cortex.functions.custom_cil-agent-ingest"]
381
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute mapagentdocstochunkdata and return its computed result"]
382
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[]"]
383
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
384
+ // CIL[DOC-MICRO logic_summary="Provides mapagentdocstochunkdata with mapAgentDocsToChunkData(docs: AgentParsedDocs inputs, handling internal flow and returning a result" notable_decisions="[]"]
385
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
386
+ // CIL[DOC-STABILITY stability="stable"]
387
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
388
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
389
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
390
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
391
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
392
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
393
+ function mapAgentDocsToChunkData(docs: AgentParsedDocs): Record<string, any> {
394
+ return {
395
+ macro: docs.macro || docs.raw.MACRO || '',
396
+ micro: docs.micro?.logic_summary || docs.responsibility || '',
397
+ description: docs.macro || '',
398
+ input_spec: docs.contract?.inputs || '',
399
+ output_spec: docs.contract?.outputs || '',
400
+ side_effects: docs.contract?.side_effects || '',
401
+ throws: docs.contract?.errors || '',
402
+ module: docs.context?.module || '',
403
+ layer: docs.context?.layer || '',
404
+ doc_confidence: docs.confidence?.pass === 'second' ? 'ai_generated' : 'from_source',
405
+ confidence_score: docs.confidence?.score || 0,
406
+ confidence_flags: docs.confidence?.flags || [],
407
+ see_also: docs.context?.related_files || '',
408
+ tags: docs.micro?.notable_decisions || '',
409
+ depends_on: docs.contract?.dependencies || '',
410
+ stability: docs.stability || '',
411
+ audience: docs.audience || '',
412
+ }
413
+ }
414
+
415
+
416
+
417
+
418
+
419
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_mapagentdocstochunkdata_1784235266"]
420
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_handler_1784235266" type="variable" identity="handler" parent="none"]
421
+ // CIL[DOC-MACRO purpose="Defines handler configuration or state in cortex.functions.custom_cil-agent-ingest"]
422
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for handler"]
423
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-agent-ingest" layer="function" related_files="[]"]
424
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of handler" errors="none" side_effects="none"]
425
+ // CIL[DOC-MICRO logic_summary="Declares handler with initial value or constant binding used by cortex.functions.custom_cil-agent-ingest" notable_decisions="[]"]
426
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
427
+ // CIL[DOC-STABILITY stability="stable"]
428
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
429
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
430
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
431
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
432
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
433
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
434
+ export const handler = createHandler(async (ctx, body) => {
435
+ const action = ctx.query?.action
436
+ const req = body as AgentIngestRequest
437
+
438
+ if (!req?.project_id) throw new Error('project_id is required')
439
+
440
+ const { data: projectItem, error: projectError } = await adminDb
441
+ .from('items')
442
+ .select('id, title, data')
443
+ .eq('id', req.project_id)
444
+ .maybeSingle()
445
+
446
+ if (projectError || !projectItem) throw new Error(`Project not found: ${req.project_id}`)
447
+
448
+ const repoPath: string = projectItem.data?.repo_path || ''
449
+
450
+
451
+ if (action === 'get_selected_files') {
452
+ const selectedPaths = projectItem.data?.selected_paths as string[] | undefined || []
453
+ const selectedExtensions = req.selected_extensions || (projectItem.data?.selected_extensions as string[] | undefined) || []
454
+
455
+ const { data: files } = await adminDb.from('items').select('id, title, data')
456
+ .filter('data->>kb_type', 'eq', 'cil_file')
457
+ .filter('data->>project_id', 'eq', req.project_id)
458
+ .eq('is_active', true)
459
+
460
+ const result = (files || []).map((f: any) => {
461
+ const fd = f.data || {}
462
+ const filePath = fd.file_path || f.title
463
+ const absolutePath = repoPath ? path.join(repoPath, filePath.replace(/^\//, '')) : filePath
464
+ const isSelected = selectedPaths.length === 0 || selectedPaths.some(sp => filePath === sp || filePath.startsWith(sp + '/'))
465
+ const extMatch = selectedExtensions.length === 0 || (fd.extension && selectedExtensions.includes(fd.extension))
466
+ let currentHash = null
467
+ if (isSelected && extMatch && fs.existsSync(absolutePath)) {
468
+ currentHash = computeFileHash(fs.readFileSync(absolutePath, 'utf-8'))
469
+ }
470
+ return {
471
+ file_id: f.id,
472
+ file_path: filePath,
473
+ stored_hash: fd.stored_hash || null,
474
+ current_hash: currentHash,
475
+ language: fd.language || 'unknown',
476
+ status: fd.status || 'not_started',
477
+ is_selected: isSelected,
478
+ extension_matches: extMatch,
479
+ }
480
+ })
481
+
482
+ return {
483
+ action: 'get_selected_files',
484
+ project_id: req.project_id,
485
+ repo_path: repoPath,
486
+ files: result.filter((f: any) => f.is_selected && f.extension_matches),
487
+ }
488
+ }
489
+
490
+
491
+ if (action === 'store_markers') {
492
+ const fileId = req.file_id
493
+ const filePath = req.file_path
494
+ const fileHash = req.file_hash
495
+ const markers = req.markers
496
+
497
+ if (!fileId) throw new Error('file_id is required')
498
+ if (!filePath) throw new Error('file_path is required')
499
+ if (!fileHash) throw new Error('file_hash is required')
500
+ if (!markers || !Array.isArray(markers)) throw new Error('markers array is required')
501
+
502
+ if (!repoPath) throw new Error('Project has no repo_path configured')
503
+ const absolutePath = path.join(repoPath, filePath.replace(/^\//, ''))
504
+ if (!fs.existsSync(absolutePath)) throw new Error(`Source file not found on disk: ${absolutePath}`)
505
+
506
+ const content = fs.readFileSync(absolutePath, 'utf-8')
507
+ const computedHash = computeFileHash(content)
508
+ if (computedHash !== fileHash) throw new Error(`Hash mismatch: provided ${fileHash} != computed ${computedHash}`)
509
+
510
+ const lines = content.split('\n')
511
+ const parsed = parseAgentCilMarkers(lines)
512
+ const parsedById = new Map(parsed.map(m => [m.chunk_id, m]))
513
+
514
+ const providedIds = new Set(markers.map(m => m.chunk_id))
515
+ const sourceIds = new Set(parsed.map(m => m.chunk_id))
516
+ const missingInSource = markers.filter(m => !sourceIds.has(m.chunk_id))
517
+ const extraInSource = parsed.filter(m => !providedIds.has(m.chunk_id))
518
+ if (missingInSource.length > 0 || extraInSource.length > 0) {
519
+ throw new Error(
520
+ `Marker mismatch: missing_in_source=[${missingInSource.map(m => m.chunk_id).join(',')}], extra_in_source=[${extraInSource.map(m => m.chunk_id).join(',')}]`
521
+ )
522
+ }
523
+
524
+ const chunkTypeId = await resolveTypeId('item', 'cil_chunk')
525
+
526
+ const { data: existingChunks } = await adminDb.from('items').select('id, data')
527
+ .filter('data->>kb_type', 'eq', 'cil_chunk')
528
+ .filter('data->>file_id', 'eq', fileId)
529
+ .eq('is_active', true)
530
+ const existingByChunkId = new Map((existingChunks || []).map((c: any) => [c.data?.chunk_id || c.id, c]))
531
+
532
+ const now = new Date().toISOString()
533
+ const results: any[] = []
534
+ const errors: string[] = []
535
+
536
+ for (const m of markers) {
537
+ const parsed = parsedById.get(m.chunk_id)!
538
+ const codeContent = lines.slice(m.start_line, m.end_line - 1).join('\n')
539
+ const docs = parseAgentCilDocs(lines, m.start_line, m.end_line)
540
+ const docFields = mapAgentDocsToChunkData(docs)
541
+ const chunkHash = computeAgentChunkHash(codeContent)
542
+ const tokenCount = estimateTokens(codeContent)
543
+
544
+ const baseData = {
545
+ kb_type: 'cil_chunk',
546
+ chunk_id: m.chunk_id,
547
+ chunk_name: m.identity,
548
+ file_id: fileId,
549
+ project_id: req.project_id,
550
+ file_path: filePath,
551
+ chunk_type: m.type,
552
+ parent_id: m.parent === 'none' ? null : m.parent,
553
+ line_start: m.start_line,
554
+ line_end: m.end_line,
555
+ stored_hash: chunkHash,
556
+ code_content: codeContent,
557
+ token_count: tokenCount,
558
+ is_dead_code: false,
559
+ review_status: 'approved',
560
+ boundary_confidence: 'high',
561
+ boundary_source: 'agent_markers',
562
+ ...docFields,
563
+ }
564
+
565
+ const existing = existingByChunkId.get(m.chunk_id)
566
+ if (existing) {
567
+ const newData = { ...existing.data, ...baseData, updated_at: now }
568
+ const updateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: existing.id } }
569
+ await adminUpdate(updateCtx, { data: newData, title: `${filePath}::${m.identity}` })
570
+ .then(() => results.push({ chunk_id: m.chunk_id, action: 'updated', id: existing.id }))
571
+ .catch((e: any) => errors.push(`${m.chunk_id}: ${e.message}`))
572
+ } else {
573
+ await adminCreate(ctx, {
574
+ entity: 'items',
575
+ type_slug: 'cil_chunk',
576
+ title: `${filePath}::${m.identity}`,
577
+ status: 'active',
578
+ is_active: true,
579
+ data: baseData,
580
+ })
581
+ .then((newChunk: any) => results.push({ chunk_id: m.chunk_id, action: 'created', id: newChunk.id }))
582
+ .catch((e: any) => errors.push(`${m.chunk_id}: ${e.message}`))
583
+ }
584
+ }
585
+
586
+ const { data: fileItem } = await adminDb.from('items').select('id, data').eq('id', fileId).maybeSingle()
587
+ if (fileItem) {
588
+ const newFileData = {
589
+ ...fileItem.data,
590
+ stored_hash: computedHash,
591
+ line_count: lines.length,
592
+ chunk_count: markers.length,
593
+ has_existing_markers: true,
594
+ existing_marker_names: markers.map(m => m.identity),
595
+ ingestion_pass: 2,
596
+ status: 'pass2_complete',
597
+ last_status_at: now,
598
+ }
599
+ const updateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: fileId } }
600
+ await adminUpdate(updateCtx, { data: newFileData }).catch((e: any) => errors.push(`file_update: ${e.message}`))
601
+ }
602
+
603
+ return {
604
+ action: 'store_markers',
605
+ project_id: req.project_id,
606
+ file_id: fileId,
607
+ file_path: filePath,
608
+ file_hash: computedHash,
609
+ chunk_count: markers.length,
610
+ created: results.filter(r => r.action === 'created').length,
611
+ updated: results.filter(r => r.action === 'updated').length,
612
+ errors: errors.length > 0 ? errors : undefined,
613
+ results,
614
+ }
615
+ }
616
+
617
+
618
+ if (action === 'update_documentation') {
619
+ const chunks = req.chunks
620
+ if (!chunks || !Array.isArray(chunks)) throw new Error('chunks array is required')
621
+
622
+ const now = new Date().toISOString()
623
+ const results: any[] = []
624
+
625
+ for (const c of chunks) {
626
+ const { data: chunk } = await adminDb.from('items').select('id, data').eq('id', c.chunk_id).maybeSingle()
627
+ if (!chunk) {
628
+ results.push({ chunk_id: c.chunk_id, ok: false, error: 'Chunk not found' })
629
+ continue
630
+ }
631
+
632
+ const newData = { ...chunk.data, ...c.documentation, ...(c.metadata || {}), doc_updated_at: now }
633
+ const updateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: c.chunk_id } }
634
+ await adminUpdate(updateCtx, { data: newData })
635
+ .then(() => results.push({ chunk_id: c.chunk_id, ok: true, error: null }))
636
+ .catch((e: any) => results.push({ chunk_id: c.chunk_id, ok: false, error: e.message }))
637
+ }
638
+
639
+ return {
640
+ action: 'update_documentation',
641
+ project_id: req.project_id,
642
+ ok: results.every(r => r.ok),
643
+ updated: results.filter(r => r.ok).length,
644
+ failed: results.filter(r => !r.ok).length,
645
+ results,
646
+ }
647
+ }
648
+
649
+
650
+ if (action === 'detect_changes') {
651
+ if (!repoPath) throw new Error('Project has no repo_path configured')
652
+
653
+ let q = adminDb.from('items').select('id, title, data')
654
+ .filter('data->>kb_type', 'eq', 'cil_file')
655
+ .filter('data->>project_id', 'eq', req.project_id)
656
+ .eq('is_active', true)
657
+ if (req.file_ids && req.file_ids.length > 0) q = (q as any).in('id', req.file_ids)
658
+
659
+ const { data: files } = await q
660
+ const changed: any[] = []
661
+ const unchanged: any[] = []
662
+ const missing: any[] = []
663
+
664
+ for (const f of files || []) {
665
+ const fd = f.data || {}
666
+ const filePath = fd.file_path || f.title
667
+ const absolutePath = path.join(repoPath, filePath.replace(/^\//, ''))
668
+ const storedHash = fd.stored_hash || null
669
+
670
+ if (!fs.existsSync(absolutePath)) {
671
+ missing.push({ file_id: f.id, file_path: filePath })
672
+ continue
673
+ }
674
+
675
+ const content = fs.readFileSync(absolutePath, 'utf-8')
676
+ const currentHash = computeFileHash(content)
677
+ if (storedHash && storedHash === currentHash) {
678
+ unchanged.push({ file_id: f.id, file_path: filePath })
679
+ } else {
680
+ changed.push({ file_id: f.id, file_path: filePath, stored_hash: storedHash, current_hash: currentHash })
681
+ }
682
+ }
683
+
684
+ return {
685
+ action: 'detect_changes',
686
+ project_id: req.project_id,
687
+ changed_count: changed.length,
688
+ unchanged_count: unchanged.length,
689
+ missing_count: missing.length,
690
+ changed,
691
+ unchanged,
692
+ missing,
693
+ }
694
+ }
695
+
696
+
697
+ if (action === 'mark_dead') {
698
+ const fileId = req.file_id
699
+ if (!fileId) throw new Error('file_id is required')
700
+
701
+ const now = new Date().toISOString()
702
+ const { data: fileItem } = await adminDb.from('items').select('id, title, data').eq('id', fileId).maybeSingle()
703
+ if (!fileItem) throw new Error(`File not found: ${fileId}`)
704
+
705
+ const updateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: fileId } }
706
+ await adminUpdate(updateCtx, {
707
+ is_active: false,
708
+ data: { ...fileItem.data, is_dead_code: true },
709
+ })
710
+
711
+ const { data: chunks } = await adminDb.from('items').select('id')
712
+ .filter('data->>kb_type', 'eq', 'cil_chunk')
713
+ .filter('data->>file_id', 'eq', fileId)
714
+
715
+ for (const c of chunks || []) {
716
+ const chunkUpdateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: c.id } }
717
+ await adminUpdate(chunkUpdateCtx, { is_active: false }).catch(() => { /* non-fatal */ })
718
+ }
719
+
720
+ return {
721
+ action: 'mark_dead',
722
+ project_id: req.project_id,
723
+ file_id: fileId,
724
+ file_path: fileItem.data?.file_path || fileItem.title || '',
725
+ chunks_marked_dead: chunks?.length || 0,
726
+ }
727
+ }
728
+
729
+
730
+ if (action === 'update_file_path') {
731
+ const fileId = req.file_id
732
+ const newFilePath = req.new_file_path
733
+ if (!fileId) throw new Error('file_id is required')
734
+ if (!newFilePath) throw new Error('new_file_path is required')
735
+
736
+ const now = new Date().toISOString()
737
+ const { data: fileItem } = await adminDb.from('items').select('id, title, data').eq('id', fileId).maybeSingle()
738
+ if (!fileItem) throw new Error(`File not found: ${fileId}`)
739
+
740
+ const oldPath = fileItem.data?.file_path || fileItem.title || ''
741
+ const newData = { ...fileItem.data, file_path: newFilePath }
742
+
743
+ const updateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: fileId } }
744
+ await adminUpdate(updateCtx, { title: newFilePath, data: newData })
745
+
746
+ const { data: chunks } = await adminDb.from('items').select('id, data')
747
+ .filter('data->>kb_type', 'eq', 'cil_chunk')
748
+ .filter('data->>file_id', 'eq', fileId)
749
+
750
+ for (const c of chunks || []) {
751
+ const cd = c.data || {}
752
+ const chunkUpdateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: c.id } }
753
+ await adminUpdate(chunkUpdateCtx, {
754
+ data: { ...cd, file_path: newFilePath },
755
+ }).catch(() => { /* non-fatal */ })
756
+ }
757
+
758
+ return {
759
+ action: 'update_file_path',
760
+ project_id: req.project_id,
761
+ file_id: fileId,
762
+ old_path: oldPath,
763
+ new_path: newFilePath,
764
+ chunks_updated: chunks?.length || 0,
765
+ }
766
+ }
767
+
768
+ throw new Error(`Unknown action: ${action}. Valid actions: get_selected_files, store_markers, update_documentation, detect_changes, mark_dead, update_file_path`)
769
+ })
770
+
771
+
772
+
773
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_agent_ingest_handler_1784235266"]