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,2416 @@
1
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_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-ingest"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Own module-level imports, exports, and configuration for cortex.functions.custom_cil-ingest"]
4
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-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-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
+
19
+ import { createHandler } from './_shared/middleware'
20
+ import { adminDb } from './_shared/db'
21
+ import { create as adminCreate, update as adminUpdate } from './admin-data'
22
+ import { FileTreeNode, FileStatus, isSelectedPath, getFileStatus, updateTreeNodeStatus, updateTreeNodeByPath, buildFileTree } from './_shared/cil'
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_module_header_1784235266"]
32
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_collectselectedfiles_1784235266" type="function" identity="collectselectedfiles" parent="none"]
33
+ // CIL[DOC-MACRO purpose="Implements collectselectedfiles logic in cortex.functions.custom_cil-ingest"]
34
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute collectselectedfiles and return its computed result"]
35
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-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\",\"\\\"]"]
36
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
37
+ // CIL[DOC-MICRO logic_summary="Provides collectselectedfiles with collectSelectedFiles(tree: FileTreeNode | null, selectedPaths: string[], selectedExtensions: string[] inputs, handling internal flow and returning a result" notable_decisions="[]"]
38
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
39
+ // CIL[DOC-STABILITY stability="stable"]
40
+ // CIL[DOC-VECTOR type="context" content="Layer: 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, \."]
41
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
42
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
43
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
44
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
45
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
46
+ function collectSelectedFiles(tree: FileTreeNode | null, selectedPaths: string[], selectedExtensions: string[]): string[] {
47
+ const files: string[] = []
48
+ if (!tree) return files
49
+ const walk = (node: FileTreeNode) => {
50
+ if (node.type === 'file') {
51
+ const isSelected = selectedPaths.length === 0 || selectedPaths.some(sp => node.path === sp || node.path.startsWith(sp + '/'))
52
+ const extMatch = selectedExtensions.length === 0 || (node.extension && selectedExtensions.includes(node.extension))
53
+ if (isSelected && extMatch) files.push(node.path)
54
+ } else if (node.children) {
55
+ for (const child of node.children) walk(child)
56
+ }
57
+ }
58
+ walk(tree)
59
+ return files
60
+ }
61
+ import * as fs from 'fs'
62
+ import * as path from 'path'
63
+ import * as crypto from 'crypto'
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_collectselectedfiles_1784235266"]
74
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_ingestrequest_1784235266" type="interface" identity="ingestrequest" parent="none"]
75
+ // CIL[DOC-MACRO purpose="Defines the ingestrequest type contract in cortex.functions.custom_cil-ingest"]
76
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for ingestrequest"]
77
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-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\",\"\\\"]"]
78
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for ingestrequest" errors="none" side_effects="none"]
79
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface ingestrequest with member definitions" notable_decisions="[]"]
80
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
81
+ // CIL[DOC-STABILITY stability="stable"]
82
+ // 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, \."]
83
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
84
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
85
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
86
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
87
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
88
+ interface IngestRequest {
89
+ project_id: string
90
+ globs?: string[]
91
+ exclude_globs?: string[]
92
+ force_reprocess?: boolean
93
+ file_path?: string
94
+ selected_extensions?: string[]
95
+ }
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_ingestrequest_1784235266"]
104
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_sourceset_1784235266" type="interface" identity="sourceset" parent="none"]
105
+ // CIL[DOC-MACRO purpose="Defines the sourceset type contract in cortex.functions.custom_cil-ingest"]
106
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for sourceset"]
107
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-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\",\"\\\"]"]
108
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for sourceset" errors="none" side_effects="none"]
109
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface sourceset with member definitions" notable_decisions="[]"]
110
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
111
+ // CIL[DOC-STABILITY stability="stable"]
112
+ // 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, \."]
113
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
114
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
115
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
116
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
117
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
118
+ interface SourceSet {
119
+ id: string
120
+ name: string
121
+ base_path: string
122
+ globs?: string[]
123
+ exclude_globs?: string[]
124
+ layer?: string
125
+ }
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_sourceset_1784235266"]
134
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_discoveredfile_1784235266" type="interface" identity="discoveredfile" parent="none"]
135
+ // CIL[DOC-MACRO purpose="Defines the discoveredfile type contract in cortex.functions.custom_cil-ingest"]
136
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for discoveredfile"]
137
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-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\",\"\\\"]"]
138
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for discoveredfile" errors="none" side_effects="none"]
139
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface discoveredfile with member definitions" notable_decisions="[]"]
140
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
141
+ // CIL[DOC-STABILITY stability="stable"]
142
+ // 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, \."]
143
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
144
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
145
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
146
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
147
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
148
+ interface DiscoveredFile {
149
+ file_path: string
150
+ language: string
151
+ size_bytes: number
152
+ stored_hash: string
153
+ line_count: number
154
+ has_existing_markers: boolean
155
+ existing_marker_names: string[]
156
+ status: FileStatus
157
+ }
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_discoveredfile_1784235266"]
166
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_chunkproposal_1784235266" type="interface" identity="chunkproposal" parent="none"]
167
+ // CIL[DOC-MACRO purpose="Defines the chunkproposal type contract in cortex.functions.custom_cil-ingest"]
168
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for chunkproposal"]
169
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
170
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for chunkproposal" errors="none" side_effects="none"]
171
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface chunkproposal with member definitions" notable_decisions="[]"]
172
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
173
+ // CIL[DOC-STABILITY stability="stable"]
174
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
175
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
176
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
177
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
178
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
179
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
180
+ interface ChunkProposal {
181
+ name: string
182
+ line_start: number
183
+ line_end: number
184
+ chunk_type: string
185
+ confidence: 'high' | 'low'
186
+ confidence_score: number
187
+ confidence_reasons: string
188
+ existing_marker_match: boolean
189
+ existing_marker_name: string
190
+ code_preview: string
191
+ token_count: number
192
+ }
193
+
194
+
195
+
196
+
197
+
198
+
199
+
200
+
201
+
202
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_chunkproposal_1784235266"]
203
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_language_map_1784235266" type="variable" identity="language_map" parent="none"]
204
+ // CIL[DOC-MACRO purpose="Defines language_map configuration or state in cortex.functions.custom_cil-ingest"]
205
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for language_map"]
206
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
207
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of language_map" errors="none" side_effects="none"]
208
+ // CIL[DOC-MICRO logic_summary="Declares language_map with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
209
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
210
+ // CIL[DOC-STABILITY stability="stable"]
211
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
212
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
213
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
214
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
215
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
216
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
217
+ const LANGUAGE_MAP: Record<string, string> = {
218
+ '.ts': 'typescript',
219
+ '.tsx': 'typescript',
220
+ '.js': 'javascript',
221
+ '.jsx': 'javascript',
222
+ '.sql': 'sql',
223
+ '.py': 'python',
224
+ '.go': 'go',
225
+ '.rs': 'rust',
226
+ '.md': 'markdown',
227
+ '.json': 'json',
228
+ '.css': 'css',
229
+ '.html': 'html',
230
+ '.sh': 'shell',
231
+ }
232
+
233
+
234
+
235
+
236
+
237
+
238
+
239
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_language_map_1784235266"]
240
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_default_globs_1784235266" type="variable" identity="default_globs" parent="none"]
241
+ // CIL[DOC-MACRO purpose="Defines default_globs configuration or state in cortex.functions.custom_cil-ingest"]
242
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for default_globs"]
243
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
244
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of default_globs" errors="none" side_effects="none"]
245
+ // CIL[DOC-MICRO logic_summary="Declares default_globs with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
246
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
247
+ // CIL[DOC-STABILITY stability="stable"]
248
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
249
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
250
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
251
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
252
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
253
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
254
+ const DEFAULT_GLOBS = ['**/*.ts', '**/*.tsx', '**/*.sql']
255
+
256
+
257
+
258
+
259
+
260
+
261
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_default_globs_1784235266"]
262
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_default_exclude_1784235266" type="variable" identity="default_exclude" parent="none"]
263
+ // CIL[DOC-MACRO purpose="Defines default_exclude configuration or state in cortex.functions.custom_cil-ingest"]
264
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for default_exclude"]
265
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
266
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of default_exclude" errors="none" side_effects="none"]
267
+ // CIL[DOC-MICRO logic_summary="Declares default_exclude with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
268
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
269
+ // CIL[DOC-STABILITY stability="stable"]
270
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
271
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
272
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
273
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
274
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
275
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
276
+ const DEFAULT_EXCLUDE = ['node_modules/**', '.git/**', 'dist/**', 'build/**', '.netlify/**', '**/*.min.js', '**/*.d.ts']
277
+
278
+
279
+
280
+
281
+
282
+
283
+
284
+
285
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_default_exclude_1784235266"]
286
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_high_confidence_threshold_1784235266" type="variable" identity="high_confidence_threshold" parent="none"]
287
+ // CIL[DOC-MACRO purpose="Defines high_confidence_threshold configuration or state in cortex.functions.custom_cil-ingest"]
288
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for high_confidence_threshold"]
289
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
290
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of high_confidence_threshold" errors="none" side_effects="none"]
291
+ // CIL[DOC-MICRO logic_summary="Declares high_confidence_threshold with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
292
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
293
+ // CIL[DOC-STABILITY stability="stable"]
294
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
295
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
296
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
297
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
298
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
299
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
300
+ const HIGH_CONFIDENCE_THRESHOLD = 0.80
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
309
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_high_confidence_threshold_1784235266"]
310
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_marker_start_re_1784235266" type="variable" identity="marker_start_re" parent="none"]
311
+ // CIL[DOC-MACRO purpose="Defines marker_start_re configuration or state in cortex.functions.custom_cil-ingest"]
312
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for marker_start_re"]
313
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
314
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of marker_start_re" errors="none" side_effects="none"]
315
+ // CIL[DOC-MICRO logic_summary="Declares marker_start_re with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
316
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
317
+ // CIL[DOC-STABILITY stability="stable"]
318
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
319
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
320
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
321
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
322
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
323
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
324
+ const MARKER_START_RE = /^\/\*\*\s*[─\-]+\s*CHUNK_START:\s*(.+?)\s*[─\-]*\s*\*\/\s*$/
325
+
326
+
327
+
328
+
329
+
330
+
331
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_marker_start_re_1784235266"]
332
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_marker_end_re_1784235266" type="variable" identity="marker_end_re" parent="none"]
333
+ // CIL[DOC-MACRO purpose="Defines marker_end_re configuration or state in cortex.functions.custom_cil-ingest"]
334
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for marker_end_re"]
335
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
336
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of marker_end_re" errors="none" side_effects="none"]
337
+ // CIL[DOC-MICRO logic_summary="Declares marker_end_re with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
338
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
339
+ // CIL[DOC-STABILITY stability="stable"]
340
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
341
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
342
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
343
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
344
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
345
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
346
+ const MARKER_END_RE = /^\/\*\*\s*[─\-]+\s*CHUNK_END:\s*(.+?)\s*[─\-]*\s*\*\/\s*$/
347
+
348
+
349
+
350
+
351
+
352
+
353
+
354
+
355
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_marker_end_re_1784235266"]
356
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_proposal_start_re_1784235266" type="variable" identity="proposal_start_re" parent="none"]
357
+ // CIL[DOC-MACRO purpose="Defines proposal_start_re configuration or state in cortex.functions.custom_cil-ingest"]
358
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for proposal_start_re"]
359
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
360
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of proposal_start_re" errors="none" side_effects="none"]
361
+ // CIL[DOC-MICRO logic_summary="Declares proposal_start_re with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
362
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
363
+ // CIL[DOC-STABILITY stability="stable"]
364
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
365
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
366
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
367
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
368
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
369
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
370
+ const PROPOSAL_START_RE = /^\/\*\*\s*─+\s*CHUNK_START:\s*PROPOSAL\s+(.+?)\s*─+\s*\*\/\s*$/
371
+
372
+
373
+
374
+
375
+
376
+
377
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_proposal_start_re_1784235266"]
378
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_proposal_end_re_1784235266" type="variable" identity="proposal_end_re" parent="none"]
379
+ // CIL[DOC-MACRO purpose="Defines proposal_end_re configuration or state in cortex.functions.custom_cil-ingest"]
380
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for proposal_end_re"]
381
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
382
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of proposal_end_re" errors="none" side_effects="none"]
383
+ // CIL[DOC-MICRO logic_summary="Declares proposal_end_re with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
384
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
385
+ // CIL[DOC-STABILITY stability="stable"]
386
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
387
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
388
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
389
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
390
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
391
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
392
+ const PROPOSAL_END_RE = /^\/\*\*\s*─+\s*CHUNK_END:\s*PROPOSAL\s+(.+?)\s*─+\s*\*\/\s*$/
393
+
394
+
395
+
396
+
397
+
398
+
399
+
400
+
401
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_proposal_end_re_1784235266"]
402
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_rejected_start_re_1784235266" type="variable" identity="rejected_start_re" parent="none"]
403
+ // CIL[DOC-MACRO purpose="Defines rejected_start_re configuration or state in cortex.functions.custom_cil-ingest"]
404
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for rejected_start_re"]
405
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
406
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of rejected_start_re" errors="none" side_effects="none"]
407
+ // CIL[DOC-MICRO logic_summary="Declares rejected_start_re with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
408
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
409
+ // CIL[DOC-STABILITY stability="stable"]
410
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
411
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
412
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
413
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
414
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
415
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
416
+ const REJECTED_START_RE = /^\/\*\*\s*─+\s*CHUNK_START:\s*REJECTED\s+(.+?)\s*─+\s*\*\/\s*$/
417
+
418
+
419
+
420
+
421
+
422
+
423
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_rejected_start_re_1784235266"]
424
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_rejected_end_re_1784235266" type="variable" identity="rejected_end_re" parent="none"]
425
+ // CIL[DOC-MACRO purpose="Defines rejected_end_re configuration or state in cortex.functions.custom_cil-ingest"]
426
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for rejected_end_re"]
427
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
428
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of rejected_end_re" errors="none" side_effects="none"]
429
+ // CIL[DOC-MICRO logic_summary="Declares rejected_end_re with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
430
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
431
+ // CIL[DOC-STABILITY stability="stable"]
432
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
433
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
434
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
435
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
436
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
437
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
438
+ const REJECTED_END_RE = /^\/\*\*\s*─+\s*CHUNK_END:\s*REJECTED\s+(.+?)\s*─+\s*\*\/\s*$/
439
+
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_rejected_end_re_1784235266"]
448
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_any_marker_re_1784235266" type="variable" identity="any_marker_re" parent="none"]
449
+ // CIL[DOC-MACRO purpose="Defines any_marker_re configuration or state in cortex.functions.custom_cil-ingest"]
450
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for any_marker_re"]
451
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
452
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of any_marker_re" errors="none" side_effects="none"]
453
+ // CIL[DOC-MICRO logic_summary="Declares any_marker_re with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
454
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
455
+ // CIL[DOC-STABILITY stability="stable"]
456
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
457
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
458
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
459
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
460
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
461
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
462
+ const ANY_MARKER_RE = /^\/\*\*\s*─+\s*CHUNK_(?:START|END):\s*(?:PROPOSAL\s+|REJECTED\s+)?(.+?)\s*─+\s*\*\/\s*$/
463
+
464
+
465
+
466
+
467
+
468
+
469
+
470
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_any_marker_re_1784235266"]
471
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_chunkstartmarker_1784235266" type="function" identity="chunkstartmarker" parent="none"]
472
+ // CIL[DOC-MACRO purpose="Implements chunkstartmarker logic in cortex.functions.custom_cil-ingest"]
473
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute chunkstartmarker and return its computed result"]
474
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
475
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
476
+ // CIL[DOC-MICRO logic_summary="Provides chunkstartmarker with chunkStartMarker(name: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
477
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
478
+ // CIL[DOC-STABILITY stability="stable"]
479
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
480
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
481
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
482
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
483
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
484
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
485
+ function chunkStartMarker(name: string): string {
486
+ return `/** ─── CHUNK_START: ${name} ─── */`
487
+ }
488
+
489
+
490
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_chunkstartmarker_1784235266"]
491
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_chunkendmarker_1784235266" type="function" identity="chunkendmarker" parent="none"]
492
+ // CIL[DOC-MACRO purpose="Implements chunkendmarker logic in cortex.functions.custom_cil-ingest"]
493
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute chunkendmarker and return its computed result"]
494
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
495
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
496
+ // CIL[DOC-MICRO logic_summary="Provides chunkendmarker with chunkEndMarker(name: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
497
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
498
+ // CIL[DOC-STABILITY stability="stable"]
499
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
500
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
501
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
502
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
503
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
504
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
505
+ function chunkEndMarker(name: string): string {
506
+ return ``
507
+ }
508
+
509
+
510
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_chunkendmarker_1784235266"]
511
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_proposalstartmarker_1784235266" type="function" identity="proposalstartmarker" parent="none"]
512
+ // CIL[DOC-MACRO purpose="Implements proposalstartmarker logic in cortex.functions.custom_cil-ingest"]
513
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute proposalstartmarker and return its computed result"]
514
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
515
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
516
+ // CIL[DOC-MICRO logic_summary="Provides proposalstartmarker with proposalStartMarker(name: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
517
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
518
+ // CIL[DOC-STABILITY stability="stable"]
519
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
520
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
521
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
522
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
523
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
524
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
525
+ function proposalStartMarker(name: string): string {
526
+ return ``
527
+ }
528
+
529
+
530
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_proposalstartmarker_1784235266"]
531
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_proposalendmarker_1784235266" type="function" identity="proposalendmarker" parent="none"]
532
+ // CIL[DOC-MACRO purpose="Implements proposalendmarker logic in cortex.functions.custom_cil-ingest"]
533
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute proposalendmarker and return its computed result"]
534
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
535
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
536
+ // CIL[DOC-MICRO logic_summary="Provides proposalendmarker with proposalEndMarker(name: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
537
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
538
+ // CIL[DOC-STABILITY stability="stable"]
539
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
540
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
541
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
542
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
543
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
544
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
545
+ function proposalEndMarker(name: string): string {
546
+ return ``
547
+ }
548
+
549
+
550
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_proposalendmarker_1784235266"]
551
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_rejectedstartmarker_1784235266" type="function" identity="rejectedstartmarker" parent="none"]
552
+ // CIL[DOC-MACRO purpose="Implements rejectedstartmarker logic in cortex.functions.custom_cil-ingest"]
553
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute rejectedstartmarker and return its computed result"]
554
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
555
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
556
+ // CIL[DOC-MICRO logic_summary="Provides rejectedstartmarker with rejectedStartMarker(name: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
557
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
558
+ // CIL[DOC-STABILITY stability="stable"]
559
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
560
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
561
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
562
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
563
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
564
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
565
+ function rejectedStartMarker(name: string): string {
566
+ return ``
567
+ }
568
+
569
+
570
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_rejectedstartmarker_1784235266"]
571
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_rejectedendmarker_1784235266" type="function" identity="rejectedendmarker" parent="none"]
572
+ // CIL[DOC-MACRO purpose="Implements rejectedendmarker logic in cortex.functions.custom_cil-ingest"]
573
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute rejectedendmarker and return its computed result"]
574
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
575
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
576
+ // CIL[DOC-MICRO logic_summary="Provides rejectedendmarker with rejectedEndMarker(name: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
577
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
578
+ // CIL[DOC-STABILITY stability="stable"]
579
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
580
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
581
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
582
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
583
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
584
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
585
+ function rejectedEndMarker(name: string): string {
586
+ return ``
587
+ }
588
+
589
+
590
+
591
+
592
+
593
+
594
+
595
+
596
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_rejectedendmarker_1784235266"]
597
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_markerinsertidx_1784235266" type="function" identity="markerinsertidx" parent="none"]
598
+ // CIL[DOC-MACRO purpose="Implements markerinsertidx logic in cortex.functions.custom_cil-ingest"]
599
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute markerinsertidx and return its computed result"]
600
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
601
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
602
+ // CIL[DOC-MICRO logic_summary="Provides markerinsertidx with markerInsertIdx(_lines: string[], lineStart: number inputs, handling internal flow and returning a result" notable_decisions="[]"]
603
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
604
+ // CIL[DOC-STABILITY stability="stable"]
605
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
606
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
607
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
608
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
609
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
610
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
611
+ function markerInsertIdx(_lines: string[], lineStart: number): number {
612
+ return lineStart - 1
613
+ }
614
+
615
+
616
+
617
+
618
+
619
+
620
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_markerinsertidx_1784235266"]
621
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_markerendinsertidx_1784235266" type="function" identity="markerendinsertidx" parent="none"]
622
+ // CIL[DOC-MACRO purpose="Implements markerendinsertidx logic in cortex.functions.custom_cil-ingest"]
623
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute markerendinsertidx and return its computed result"]
624
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
625
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
626
+ // CIL[DOC-MICRO logic_summary="Provides markerendinsertidx with markerEndInsertIdx(_lines: string[], lineEnd: number inputs, handling internal flow and returning a result" notable_decisions="[]"]
627
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
628
+ // CIL[DOC-STABILITY stability="stable"]
629
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
630
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
631
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
632
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
633
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
634
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
635
+ function markerEndInsertIdx(_lines: string[], lineEnd: number): number {
636
+ return lineEnd
637
+ }
638
+
639
+
640
+
641
+
642
+
643
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_markerendinsertidx_1784235266"]
644
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_computefilehash_1784235266" type="function" identity="computefilehash" parent="none"]
645
+ // CIL[DOC-MACRO purpose="Implements computefilehash logic in cortex.functions.custom_cil-ingest"]
646
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute computefilehash and return its computed result"]
647
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
648
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
649
+ // CIL[DOC-MICRO logic_summary="Provides computefilehash with computeFileHash(content: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
650
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
651
+ // CIL[DOC-STABILITY stability="stable"]
652
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
653
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
654
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
655
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
656
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
657
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
658
+ function computeFileHash(content: string): string {
659
+ return crypto.createHash('sha256').update(content).digest('hex').slice(0, 16)
660
+ }
661
+
662
+
663
+
664
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_computefilehash_1784235266"]
665
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_modulenamefrompath_1784235266" type="function" identity="modulenamefrompath" parent="none"]
666
+ // CIL[DOC-MACRO purpose="Implements modulenamefrompath logic in cortex.functions.custom_cil-ingest"]
667
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute modulenamefrompath and return its computed result"]
668
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
669
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
670
+ // CIL[DOC-MICRO logic_summary="Provides modulenamefrompath with moduleNameFromPath(relPath: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
671
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
672
+ // CIL[DOC-STABILITY stability="stable"]
673
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
674
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
675
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
676
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
677
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
678
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
679
+ function moduleNameFromPath(relPath: string): string {
680
+ return path.basename(relPath, path.extname(relPath))
681
+ }
682
+
683
+
684
+
685
+
686
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_modulenamefrompath_1784235266"]
687
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_normalisechunkcontent_1784235266" type="function" identity="normalisechunkcontent" parent="none"]
688
+ // CIL[DOC-MACRO purpose="Implements normalisechunkcontent logic in cortex.functions.custom_cil-ingest"]
689
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute normalisechunkcontent and return its computed result"]
690
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
691
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
692
+ // CIL[DOC-MICRO logic_summary="Provides normalisechunkcontent with normaliseChunkContent(raw: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
693
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
694
+ // CIL[DOC-STABILITY stability="stable"]
695
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
696
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
697
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
698
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
699
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
700
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
701
+ function normaliseChunkContent(raw: string): string {
702
+ const lines = raw.replace(/\r\n/g, '\n').split('\n')
703
+ const filtered = lines.filter(line => {
704
+ const trimmed = line.trim()
705
+ return !trimmed.match(/^\/\/\s*[─\-]+ CHUNK_(START|END):/)
706
+ })
707
+ const collapsed: string[] = []
708
+ let lastBlank = false
709
+ for (const line of filtered) {
710
+ const isBlank = line.trim() === ''
711
+ if (isBlank && lastBlank) continue
712
+ collapsed.push(line)
713
+ lastBlank = isBlank
714
+ }
715
+ return collapsed.join('\n').trim()
716
+ }
717
+
718
+
719
+
720
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_normalisechunkcontent_1784235266"]
721
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_computechunkhash_1784235266" type="function" identity="computechunkhash" parent="none"]
722
+ // CIL[DOC-MACRO purpose="Implements computechunkhash logic in cortex.functions.custom_cil-ingest"]
723
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute computechunkhash and return its computed result"]
724
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
725
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
726
+ // CIL[DOC-MICRO logic_summary="Provides computechunkhash with computeChunkHash(codeContent: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
727
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
728
+ // CIL[DOC-STABILITY stability="stable"]
729
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
730
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
731
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
732
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
733
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
734
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
735
+ function computeChunkHash(codeContent: string): string {
736
+ return crypto.createHash('sha256').update(normaliseChunkContent(codeContent)).digest('hex').slice(0, 16)
737
+ }
738
+
739
+
740
+
741
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_computechunkhash_1784235266"]
742
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_estimatetokens_1784235266" type="function" identity="estimatetokens" parent="none"]
743
+ // CIL[DOC-MACRO purpose="Implements estimatetokens logic in cortex.functions.custom_cil-ingest"]
744
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute estimatetokens and return its computed result"]
745
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
746
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
747
+ // CIL[DOC-MICRO logic_summary="Provides estimatetokens with estimateTokens(text: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
748
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
749
+ // CIL[DOC-STABILITY stability="stable"]
750
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
751
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
752
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
753
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
754
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
755
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
756
+ function estimateTokens(text: string): number {
757
+ return Math.ceil(text.length / 4)
758
+ }
759
+
760
+
761
+
762
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_estimatetokens_1784235266"]
763
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_detectlanguage_1784235266" type="function" identity="detectlanguage" parent="none"]
764
+ // CIL[DOC-MACRO purpose="Implements detectlanguage logic in cortex.functions.custom_cil-ingest"]
765
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute detectlanguage and return its computed result"]
766
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
767
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
768
+ // CIL[DOC-MICRO logic_summary="Provides detectlanguage with detectLanguage(filePath: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
769
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
770
+ // CIL[DOC-STABILITY stability="stable"]
771
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
772
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
773
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
774
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
775
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
776
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
777
+ function detectLanguage(filePath: string): string {
778
+ const ext = path.extname(filePath).toLowerCase()
779
+ return LANGUAGE_MAP[ext] || 'unknown'
780
+ }
781
+
782
+
783
+
784
+
785
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_detectlanguage_1784235266"]
786
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_matchesglob_1784235266" type="function" identity="matchesglob" parent="none"]
787
+ // CIL[DOC-MACRO purpose="Implements matchesglob logic in cortex.functions.custom_cil-ingest"]
788
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute matchesglob and return its computed result"]
789
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
790
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
791
+ // CIL[DOC-MICRO logic_summary="Provides matchesglob with matchesGlob(filePath: string, pattern: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
792
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
793
+ // CIL[DOC-STABILITY stability="stable"]
794
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
795
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
796
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
797
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
798
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
799
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
800
+ function matchesGlob(filePath: string, pattern: string): boolean {
801
+ const regexStr = pattern
802
+ .replace(/\./g, '\\.')
803
+ .replace(/\*\*/g, '__DOUBLESTAR__')
804
+ .replace(/\*/g, '[^/]*')
805
+ .replace(/\?/g, '[^/]')
806
+ .replace(/__DOUBLESTAR__/g, '.*')
807
+ const re = new RegExp('^' + regexStr + '$')
808
+ return re.test(filePath)
809
+ }
810
+
811
+
812
+
813
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_matchesglob_1784235266"]
814
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_shouldinclude_1784235266" type="function" identity="shouldinclude" parent="none"]
815
+ // CIL[DOC-MACRO purpose="Implements shouldinclude logic in cortex.functions.custom_cil-ingest"]
816
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute shouldinclude and return its computed result"]
817
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
818
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
819
+ // CIL[DOC-MICRO logic_summary="Provides shouldinclude with shouldInclude(filePath: string, globs: string[], excludeGlobs: string[] inputs, handling internal flow and returning a result" notable_decisions="[]"]
820
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
821
+ // CIL[DOC-STABILITY stability="stable"]
822
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
823
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
824
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
825
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
826
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
827
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
828
+ function shouldInclude(filePath: string, globs: string[], excludeGlobs: string[]): boolean {
829
+ const normalised = filePath.replace(/\\/g, '/')
830
+ const included = globs.some(g => matchesGlob(normalised, g) || matchesGlob(path.basename(normalised), g))
831
+ const excluded = excludeGlobs.some(g => matchesGlob(normalised, g))
832
+ return included && !excluded
833
+ }
834
+
835
+
836
+
837
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_shouldinclude_1784235266"]
838
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_walkedfile_1784235266" type="interface" identity="walkedfile" parent="none"]
839
+ // CIL[DOC-MACRO purpose="Defines the walkedfile type contract in cortex.functions.custom_cil-ingest"]
840
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for walkedfile"]
841
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
842
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for walkedfile" errors="none" side_effects="none"]
843
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface walkedfile with member definitions" notable_decisions="[]"]
844
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
845
+ // CIL[DOC-STABILITY stability="stable"]
846
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
847
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
848
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
849
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
850
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
851
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
852
+ interface WalkedFile {
853
+ path: string
854
+ absPath: string
855
+ size: number
856
+ extension: string
857
+ language: string
858
+ }
859
+
860
+
861
+
862
+
863
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_walkedfile_1784235266"]
864
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_walkdir_1784235266" type="function" identity="walkdir" parent="none"]
865
+ // CIL[DOC-MACRO purpose="Implements walkdir logic in cortex.functions.custom_cil-ingest"]
866
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute walkdir and return its computed result"]
867
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
868
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
869
+ // CIL[DOC-MICRO logic_summary="Provides walkdir with walkDir(dir: string, base: string, globs: string[], excludeGlobs: string[] inputs, handling internal flow and returning a result" notable_decisions="[]"]
870
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
871
+ // CIL[DOC-STABILITY stability="stable"]
872
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
873
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
874
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
875
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
876
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
877
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
878
+ function walkDir(dir: string, base: string, globs: string[], excludeGlobs: string[]): WalkedFile[] {
879
+ const results: WalkedFile[] = []
880
+ let entries: fs.Dirent[]
881
+ try {
882
+ entries = fs.readdirSync(dir, { withFileTypes: true })
883
+ } catch {
884
+ return results
885
+ }
886
+ for (const entry of entries) {
887
+ const full = path.join(dir, entry.name)
888
+ const rel = path.relative(base, full).replace(/\\/g, '/')
889
+ if (entry.isDirectory()) {
890
+
891
+ if (excludeGlobs.some(g => matchesGlob(rel, g) || matchesGlob(rel + '/', g))) continue
892
+ results.push(...walkDir(full, base, globs, excludeGlobs))
893
+ } else if (entry.isFile()) {
894
+ if (shouldInclude(rel, globs, excludeGlobs)) {
895
+ try {
896
+ const size = fs.statSync(full).size
897
+ const extension = path.extname(rel).toLowerCase()
898
+ results.push({ path: rel, absPath: full, size, extension, language: detectLanguage(rel) })
899
+ } catch {
900
+ }
901
+ }
902
+ }
903
+ }
904
+ return results
905
+ }
906
+
907
+
908
+
909
+
910
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_walkdir_1784235266"]
911
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_parseexistingmarkers_1784235266" type="function" identity="parseexistingmarkers" parent="none"]
912
+ // CIL[DOC-MACRO purpose="Implements parseexistingmarkers logic in cortex.functions.custom_cil-ingest"]
913
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute parseexistingmarkers and return its computed result"]
914
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
915
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
916
+ // CIL[DOC-MICRO logic_summary="Provides parseexistingmarkers with parseExistingMarkers(lines: string[] inputs, handling internal flow and returning a result" notable_decisions="[]"]
917
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
918
+ // CIL[DOC-STABILITY stability="stable"]
919
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
920
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
921
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
922
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
923
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
924
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
925
+ function parseExistingMarkers(lines: string[]): { name: string; line_start: number; line_end: number }[] {
926
+ const markers: { name: string; line_start: number; line_end: number }[] = []
927
+ const stack: { name: string; line_start: number }[] = []
928
+ for (let i = 0; i < lines.length; i++) {
929
+ const line = lines[i]
930
+ const startMatch = line.match(MARKER_START_RE)
931
+ const endMatch = line.match(MARKER_END_RE)
932
+ if (startMatch) {
933
+ stack.push({ name: startMatch[1], line_start: i + 1 })
934
+ } else if (endMatch && stack.length > 0) {
935
+ const opened = stack.pop()!
936
+ markers.push({ name: opened.name, line_start: opened.line_start, line_end: i + 1 })
937
+ }
938
+ }
939
+ return markers
940
+ }
941
+
942
+
943
+
944
+
945
+
946
+
947
+
948
+
949
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_parseexistingmarkers_1784235266"]
950
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_extractedjsdoc_1784235266" type="interface" identity="extractedjsdoc" parent="none"]
951
+ // CIL[DOC-MACRO purpose="Defines the extractedjsdoc type contract in cortex.functions.custom_cil-ingest"]
952
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for extractedjsdoc"]
953
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
954
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for extractedjsdoc" errors="none" side_effects="none"]
955
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface extractedjsdoc with member definitions" notable_decisions="[]"]
956
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
957
+ // CIL[DOC-STABILITY stability="stable"]
958
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
959
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
960
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
961
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
962
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
963
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
964
+ interface ExtractedJsDoc {
965
+ raw: string
966
+ description: string
967
+ params: string
968
+ returns: string
969
+ throws: string
970
+ side_effects: string
971
+ stability: string
972
+ macro: string
973
+ micro: string
974
+ input_spec: string
975
+ output_spec: string
976
+
977
+ called_by: string
978
+ calls: string
979
+ tags: string
980
+ complexity: string
981
+ error_handling: string
982
+ depends_on: string
983
+ depended_by: string
984
+ see_also: string
985
+ module: string
986
+ audience: string
987
+ layer: string
988
+ is_cil_generated: boolean
989
+ }
990
+
991
+
992
+
993
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_extractedjsdoc_1784235266"]
994
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_extractjsdocabove_1784235266" type="function" identity="extractjsdocabove" parent="none"]
995
+ // CIL[DOC-MACRO purpose="Implements extractjsdocabove logic in cortex.functions.custom_cil-ingest"]
996
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute extractjsdocabove and return its computed result"]
997
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
998
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
999
+ // CIL[DOC-MICRO logic_summary="Provides extractjsdocabove with extractJsDocAbove(lines: string[], lineStart: number inputs, handling internal flow and returning a result" notable_decisions="[]"]
1000
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
1001
+ // CIL[DOC-STABILITY stability="stable"]
1002
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
1003
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
1004
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
1005
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
1006
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
1007
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
1008
+ function extractJsDocAbove(lines: string[], lineStart: number): ExtractedJsDoc | null {
1009
+
1010
+ let endIdx = lineStart - 2
1011
+ while (endIdx >= 0) {
1012
+ const t = lines[endIdx].trim()
1013
+ if (t === '') { endIdx--; continue }
1014
+
1015
+ if (/CHUNK_(?:START|END):/.test(t)) { endIdx--; continue }
1016
+ break
1017
+ }
1018
+ if (endIdx < 0) return null
1019
+
1020
+ const endTrimmed = lines[endIdx].trim()
1021
+
1022
+ if (!endTrimmed.endsWith('*/')) return null
1023
+
1024
+
1025
+ let startIdx = endIdx
1026
+ for (let i = endIdx; i >= 0; i--) {
1027
+ const t = lines[i].trim()
1028
+ if (t.startsWith('/**') || t.startsWith('/*')) { startIdx = i; break }
1029
+ if (i === 0) return null
1030
+ }
1031
+
1032
+
1033
+ const bodyLines: string[] = []
1034
+ for (let i = startIdx; i <= endIdx; i++) {
1035
+ const raw = lines[i]
1036
+ const stripped = raw.trim()
1037
+ .replace(/^\/\*\*?/, '').replace(/\*\/$/, '')
1038
+ .replace(/^\*\s?/, '')
1039
+ .trim()
1040
+ bodyLines.push(stripped)
1041
+ }
1042
+
1043
+ const raw = bodyLines.join('\n').trim()
1044
+ if (!raw) return null
1045
+
1046
+
1047
+ const get = (tags: string[]): string => {
1048
+ for (const tag of tags) {
1049
+ const re = new RegExp(`@${tag}\\s+(.+?)(?=\\n@|$)`, 'si')
1050
+ const m = raw.match(re)
1051
+ if (m) return m[1].replace(/\n\s*\*?\s*/g, ' ').trim()
1052
+ }
1053
+ return ''
1054
+ }
1055
+
1056
+
1057
+ const descMatch = raw.match(/^([\s\S]*?)(?=@\w|$)/)
1058
+ const description = descMatch ? descMatch[1].trim() : ''
1059
+
1060
+
1061
+ const paramLines: string[] = []
1062
+ for (const m of raw.matchAll(/@param\s+(.+?)(?=\n@|\n\n|$)/gsi)) {
1063
+ paramLines.push(m[1].replace(/\n\s*\*?\s*/g, ' ').trim())
1064
+ }
1065
+
1066
+ return {
1067
+ raw,
1068
+ description,
1069
+ params: paramLines.join('; '),
1070
+ returns: get(['returns', 'return']),
1071
+ throws: get(['throws', 'throw']),
1072
+ side_effects: get(['sideEffects', 'side-effects', 'sideeffects']),
1073
+ stability: get(['stability']),
1074
+ macro: get(['macro']),
1075
+ micro: get(['micro']),
1076
+ input_spec: get(['inputSpec', 'inputs', 'input_spec']),
1077
+ output_spec: get(['outputSpec', 'outputs', 'output_spec']),
1078
+
1079
+ called_by: get(['calledBy', 'called_by']),
1080
+ calls: get(['calls']),
1081
+ tags: get(['tags']),
1082
+ complexity: get(['complexity']),
1083
+ error_handling: get(['errorHandling', 'error_handling']),
1084
+ depends_on: get(['dependsOn', 'depends_on']),
1085
+ depended_by: get(['dependedBy', 'depended_by']),
1086
+ see_also: get(['seeAlso', 'see_also']),
1087
+ module: get(['module']),
1088
+ audience: get(['audience']),
1089
+ layer: get(['layer']),
1090
+ is_cil_generated: raw.includes('@cil-generated'),
1091
+ }
1092
+ }
1093
+
1094
+
1095
+
1096
+
1097
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_extractjsdocabove_1784235266"]
1098
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_extractfilejsdoc_1784235266" type="function" identity="extractfilejsdoc" parent="none"]
1099
+ // CIL[DOC-MACRO purpose="Implements extractfilejsdoc logic in cortex.functions.custom_cil-ingest"]
1100
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute extractfilejsdoc and return its computed result"]
1101
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
1102
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
1103
+ // CIL[DOC-MICRO logic_summary="Provides extractfilejsdoc with extractFileJsDoc(lines: string[] inputs, handling internal flow and returning a result" notable_decisions="[]"]
1104
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
1105
+ // CIL[DOC-STABILITY stability="stable"]
1106
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
1107
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
1108
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
1109
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
1110
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
1111
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
1112
+ function extractFileJsDoc(lines: string[]): string {
1113
+ let inBlock = false
1114
+ const bodyLines: string[] = []
1115
+ for (const line of lines) {
1116
+ const t = line.trim()
1117
+ if (!inBlock) {
1118
+ if (t.startsWith('/**') || t.startsWith('/*')) { inBlock = true; bodyLines.push(t); continue }
1119
+ if (t !== '' && !t.startsWith('//')) break
1120
+ } else {
1121
+ bodyLines.push(t)
1122
+ if (t.endsWith('*/')) break
1123
+ }
1124
+ }
1125
+ return bodyLines.join('\n')
1126
+ }
1127
+
1128
+
1129
+
1130
+
1131
+
1132
+
1133
+
1134
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_extractfilejsdoc_1784235266"]
1135
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_rawproposal_1784235266" type="interface" identity="rawproposal" parent="none"]
1136
+ // CIL[DOC-MACRO purpose="Defines the rawproposal type contract in cortex.functions.custom_cil-ingest"]
1137
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for rawproposal"]
1138
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
1139
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for rawproposal" errors="none" side_effects="none"]
1140
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface rawproposal with member definitions" notable_decisions="[]"]
1141
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
1142
+ // CIL[DOC-STABILITY stability="stable"]
1143
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
1144
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
1145
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
1146
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
1147
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
1148
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
1149
+ interface RawProposal {
1150
+ name: string
1151
+ line_start: number
1152
+ line_end: number
1153
+
1154
+
1155
+
1156
+ marker_line_end: number
1157
+ chunk_type: string
1158
+ confidence_score: number
1159
+ confidence_reasons: string[]
1160
+ existing_jsdoc?: ExtractedJsDoc | null
1161
+ }
1162
+
1163
+
1164
+
1165
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_rawproposal_1784235266"]
1166
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_proposechunksfromsource_1784235266" type="function" identity="proposechunksfromsource" parent="none"]
1167
+ // CIL[DOC-MACRO purpose="Implements proposechunksfromsource logic in cortex.functions.custom_cil-ingest"]
1168
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute proposechunksfromsource and return its computed result"]
1169
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
1170
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
1171
+ // CIL[DOC-MICRO logic_summary="Provides proposechunksfromsource with proposeChunksFromSource(lines: string[], language: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
1172
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
1173
+ // CIL[DOC-STABILITY stability="stable"]
1174
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
1175
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
1176
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
1177
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
1178
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
1179
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
1180
+ function proposeChunksFromSource(lines: string[], language: string): RawProposal[] {
1181
+ const proposals: RawProposal[] = []
1182
+ if (!['typescript', 'javascript'].includes(language)) return proposals
1183
+
1184
+
1185
+ let jsDocStart = -1, jsDocEnd = -1
1186
+ for (let i = 0; i < lines.length; i++) {
1187
+ const t = lines[i].trim()
1188
+ if (t === '') continue
1189
+ if ((t.startsWith('/**') || t.startsWith('/*')) && jsDocStart === -1) {
1190
+ jsDocStart = i
1191
+ } else if (jsDocStart !== -1 && t.endsWith('*/') && jsDocEnd === -1) {
1192
+ jsDocEnd = i
1193
+ } else if (jsDocStart === -1 && !t.startsWith('//') && !t.startsWith('/*')) {
1194
+ break
1195
+ }
1196
+ }
1197
+
1198
+ const headerStart = jsDocStart >= 0 ? jsDocStart : 0
1199
+ let headerEnd = jsDocEnd >= 0 ? jsDocEnd : headerStart - 1
1200
+
1201
+
1202
+
1203
+ const DECL_RE = /^(?:export\s+)?(?:async\s+)?(?:function|class|interface)\s+\w+/
1204
+ const EXPORT_DECL_RE = /^export\s+(?:default\s+)?(?:async\s+)?(?:function|class|interface|type|const|let|var)\s+\w+/
1205
+ const startScan = Math.max(headerEnd + 1, 0)
1206
+
1207
+ for (let i = startScan; i < lines.length; i++) {
1208
+ const t = lines[i].trim()
1209
+ if (t === '' || t.startsWith('//')) continue
1210
+ if (t.startsWith('import')) continue
1211
+ if (EXPORT_DECL_RE.test(lines[i]) || DECL_RE.test(lines[i])) {
1212
+ headerEnd = i - 1
1213
+ break
1214
+ }
1215
+ }
1216
+
1217
+
1218
+ while (headerEnd > headerStart && lines[headerEnd].trim() === '') {
1219
+ headerEnd--
1220
+ }
1221
+
1222
+ if (headerEnd >= headerStart) {
1223
+ proposals.push({
1224
+ name: '__module_header__',
1225
+ line_start: headerStart + 1,
1226
+ line_end: headerEnd + 1,
1227
+ marker_line_end: headerEnd + 1,
1228
+ chunk_type: 'module_header',
1229
+ confidence_score: 0.99,
1230
+ confidence_reasons: ['file-level JSDoc, imports, and module setup'],
1231
+ existing_jsdoc: null,
1232
+ })
1233
+ }
1234
+
1235
+
1236
+ const scanStart = headerEnd >= 0 ? headerEnd + 1 : 0
1237
+
1238
+
1239
+ const patterns: { re: RegExp; type: string; baseScore: number; nameGroup: number }[] = [
1240
+
1241
+ { re: /^export\s+(?:default\s+)?(?:async\s+)?function\s+(\w+)/m, type: 'function', baseScore: 0.92, nameGroup: 1 },
1242
+
1243
+ { re: /^export\s+const\s+(\w+)\s*[=:]/m, type: 'constant', baseScore: 0.85, nameGroup: 1 },
1244
+
1245
+ { re: /^export\s+(?:let|var)\s+(\w+)\s*[=:]/m, type: 'constant', baseScore: 0.82, nameGroup: 1 },
1246
+
1247
+ { re: /^export\s+(?:default\s+)?(?:abstract\s+)?class\s+(\w+)/m, type: 'class', baseScore: 0.90, nameGroup: 1 },
1248
+
1249
+ { re: /^export\s+interface\s+(\w+)/m, type: 'interface', baseScore: 0.90, nameGroup: 1 },
1250
+
1251
+ { re: /^export\s+type\s+(\w+)/m, type: 'type', baseScore: 0.88, nameGroup: 1 },
1252
+
1253
+ { re: /^(?:async\s+)?function\s+(\w+)/m, type: 'function', baseScore: 0.78, nameGroup: 1 },
1254
+
1255
+ { re: /^(?:abstract\s+)?class\s+(\w+)/m, type: 'class', baseScore: 0.80, nameGroup: 1 },
1256
+
1257
+ { re: /^interface\s+(\w+)/m, type: 'interface', baseScore: 0.80, nameGroup: 1 },
1258
+
1259
+ { re: /^type\s+(\w+)\s*=/m, type: 'type', baseScore: 0.78, nameGroup: 1 },
1260
+
1261
+ { re: /^(?:const|let|var)\s+(\w+)\s*[=:]/m, type: 'constant', baseScore: 0.70, nameGroup: 1 },
1262
+ ]
1263
+
1264
+
1265
+ let lineIdx = scanStart
1266
+ while (lineIdx < lines.length) {
1267
+ const line = lines[lineIdx]
1268
+ let matched = false
1269
+
1270
+ for (const { re, type, baseScore, nameGroup } of patterns) {
1271
+ const m = line.match(re)
1272
+ if (m) {
1273
+ const name = m[nameGroup]
1274
+ if (!name) { lineIdx++; break }
1275
+
1276
+
1277
+
1278
+
1279
+
1280
+ let braceDepth = 0
1281
+ let parenDepth = 0
1282
+ let angleDepth = 0
1283
+ let endLine = lineIdx
1284
+ let foundOpen = false
1285
+ let inString = false
1286
+ let stringChar = ''
1287
+
1288
+ for (let j = lineIdx; j < Math.min(lines.length, lineIdx + 500); j++) {
1289
+ const l = lines[j]
1290
+ let inLineComment = false
1291
+ let inBlockComment = false
1292
+ for (let ci = 0; ci < l.length; ci++) {
1293
+ const c = l[ci]
1294
+ const next = l[ci + 1]
1295
+ const prev = l[ci - 1]
1296
+
1297
+ if (inString) {
1298
+ if (c === stringChar && prev !== '\\') inString = false
1299
+ continue
1300
+ }
1301
+
1302
+ if (inLineComment) continue
1303
+ if (inBlockComment) {
1304
+ if (c === '*' && next === '/') { inBlockComment = false; ci++ }
1305
+ continue
1306
+ }
1307
+
1308
+ if (c === '/' && next === '/') { inLineComment = true; ci++; continue }
1309
+ if (c === '/' && next === '*') { inBlockComment = true; ci++; continue }
1310
+
1311
+ if (c === '"' || c === "'") { inString = true; stringChar = c; continue }
1312
+ if (c === '`') { inString = true; stringChar = '`'; continue }
1313
+
1314
+
1315
+ if (c === '(') { parenDepth++; continue }
1316
+ if (c === ')') { parenDepth--; continue }
1317
+ if (c === '<' && prev !== '=' && next !== '=') { angleDepth++; continue }
1318
+ if (c === '>' && prev !== '=' && next !== '=') { angleDepth--; continue }
1319
+
1320
+ if (c === '{') {
1321
+ if (!foundOpen && (parenDepth !== 0 || angleDepth !== 0)) {
1322
+
1323
+ continue
1324
+ }
1325
+ braceDepth++; foundOpen = true
1326
+ }
1327
+ if (c === '}') {
1328
+ if (!foundOpen) continue
1329
+ braceDepth--
1330
+ }
1331
+ }
1332
+
1333
+ if (foundOpen && braceDepth === 0) {
1334
+ endLine = j
1335
+ break
1336
+ }
1337
+ }
1338
+
1339
+
1340
+ const lineCount = endLine - lineIdx + 1
1341
+ if (lineCount < 3) { lineIdx++; matched = true; break }
1342
+
1343
+ const confidenceReasons: string[] = []
1344
+ let score = baseScore
1345
+
1346
+
1347
+ const existingJsDoc = extractJsDocAbove(lines, lineIdx + 1)
1348
+
1349
+
1350
+ if (line.includes('export')) { score += 0.05; confidenceReasons.push('exported symbol') }
1351
+
1352
+ if (existingJsDoc) { score += 0.10; confidenceReasons.push('has JSDoc') }
1353
+
1354
+ if (lineCount > 200) { score -= 0.10; confidenceReasons.push('very large (>200 lines)') }
1355
+
1356
+ if (!line.match(/function\s+\w+/) && !line.match(/class\s+\w+/) && !line.match(/interface\s+\w+/)) {
1357
+ score -= 0.05; confidenceReasons.push('arrow/assigned function')
1358
+ }
1359
+
1360
+ score = Math.min(0.99, Math.max(0.1, score))
1361
+
1362
+ proposals.push({
1363
+ name,
1364
+ line_start: lineIdx + 1,
1365
+ line_end: endLine + 1,
1366
+ marker_line_end: endLine + 1, // set here; never modified by gap-filling below
1367
+ chunk_type: type,
1368
+ confidence_score: score,
1369
+ confidence_reasons: confidenceReasons,
1370
+ existing_jsdoc: existingJsDoc,
1371
+ })
1372
+
1373
+ lineIdx = endLine + 1
1374
+ matched = true
1375
+ break
1376
+ }
1377
+ }
1378
+
1379
+ if (!matched) lineIdx++
1380
+ }
1381
+
1382
+
1383
+ const deduped: RawProposal[] = []
1384
+ for (const p of proposals.sort((a, b) => b.confidence_score - a.confidence_score)) {
1385
+ const overlaps = deduped.some(d =>
1386
+ Math.max(d.line_start, p.line_start) <= Math.min(d.line_end, p.line_end)
1387
+ )
1388
+ if (!overlaps) deduped.push(p)
1389
+ }
1390
+
1391
+ const sorted = deduped.sort((a, b) => a.line_start - b.line_start)
1392
+
1393
+ if (sorted.length === 0) return []
1394
+
1395
+
1396
+
1397
+
1398
+
1399
+
1400
+
1401
+ for (let i = sorted.length - 1; i >= 0; i--) {
1402
+ const curr = sorted[i]
1403
+ const prevEnd = i > 0 ? sorted[i - 1].marker_line_end : 0
1404
+ let foundComment = false
1405
+ let candidateStart = curr.line_start
1406
+ for (let j = curr.line_start - 2; j >= prevEnd; j--) {
1407
+ const t = lines[j].trim()
1408
+ if (t === '') continue
1409
+ if (t.startsWith('/**') || t.startsWith('/*') || t.startsWith('*')) {
1410
+ foundComment = true
1411
+ candidateStart = j + 1
1412
+ continue
1413
+ }
1414
+ break
1415
+ }
1416
+ if (foundComment) curr.line_start = candidateStart
1417
+ }
1418
+
1419
+
1420
+ sorted[0].line_start = 1
1421
+
1422
+
1423
+
1424
+
1425
+ for (let i = 1; i < sorted.length; i++) {
1426
+ const prev = sorted[i - 1]
1427
+ const curr = sorted[i]
1428
+ if (curr.line_start > prev.line_end + 1) {
1429
+ prev.line_end = curr.line_start - 1
1430
+ }
1431
+ }
1432
+
1433
+
1434
+ const last = sorted[sorted.length - 1]
1435
+ if (last.line_end < lines.length) {
1436
+ last.line_end = lines.length
1437
+ }
1438
+
1439
+ return sorted
1440
+ }
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_proposechunksfromsource_1784235266"]
1447
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_pass1discover_1784235266" type="function" identity="pass1discover" parent="none"]
1448
+ // CIL[DOC-MACRO purpose="Implements pass1discover logic in cortex.functions.custom_cil-ingest"]
1449
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute pass1discover and return its computed result"]
1450
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
1451
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
1452
+ // CIL[DOC-MICRO logic_summary="Provides pass1discover with pass1Discover( inputs, handling internal flow and returning a result" notable_decisions="[]"]
1453
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
1454
+ // CIL[DOC-STABILITY stability="stable"]
1455
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
1456
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
1457
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
1458
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
1459
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
1460
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
1461
+ async function pass1Discover(
1462
+ ctx: any,
1463
+ projectId: string,
1464
+ repoPath: string,
1465
+ globs: string[],
1466
+ excludeGlobs: string[],
1467
+ _forceReprocess: boolean,
1468
+ sourceSets?: SourceSet[]
1469
+ ): Promise<{ files_discovered: number; errors: string[]; file_tree: FileTreeNode }> {
1470
+ const errors: string[] = []
1471
+ let filesDiscovered = 0
1472
+
1473
+
1474
+ const discoveryTargets: { sourceSetId?: string; layer?: string; basePath: string; globs: string[]; excludeGlobs: string[] }[] = []
1475
+ if (sourceSets && sourceSets.length > 0) {
1476
+ for (const ss of sourceSets) {
1477
+ const basePath = path.isAbsolute(ss.base_path) ? ss.base_path : path.join(repoPath, ss.base_path)
1478
+ discoveryTargets.push({
1479
+ sourceSetId: ss.id,
1480
+ layer: ss.layer || 'app-specific',
1481
+ basePath,
1482
+ globs: ss.globs && ss.globs.length > 0 ? ss.globs : globs,
1483
+ excludeGlobs: ss.exclude_globs && ss.exclude_globs.length > 0 ? ss.exclude_globs : excludeGlobs,
1484
+ })
1485
+ }
1486
+ } else {
1487
+ discoveryTargets.push({ basePath: repoPath, globs, excludeGlobs })
1488
+ }
1489
+
1490
+
1491
+ const treeRecords: { file_path: string; language: string; status?: FileStatus; extension: string }[] = []
1492
+
1493
+ for (const target of discoveryTargets) {
1494
+ const files = walkDir(target.basePath, target.basePath, target.globs, target.excludeGlobs)
1495
+ filesDiscovered += files.length
1496
+ for (const file of files) {
1497
+ treeRecords.push({
1498
+ file_path: file.path,
1499
+ language: file.language,
1500
+ extension: file.extension,
1501
+ })
1502
+ }
1503
+ }
1504
+
1505
+
1506
+ const fileTree = buildFileTree(treeRecords)
1507
+
1508
+ const { data: projItem } = await adminDb
1509
+ .from('items').select('id, data').eq('id', projectId).maybeSingle()
1510
+ if (projItem) {
1511
+ const updateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: projItem.id } }
1512
+ await adminUpdate(updateCtx, {
1513
+ data: {
1514
+ ...projItem.data,
1515
+ file_tree: fileTree,
1516
+ ingestion_status: 'in_progress',
1517
+ file_count: filesDiscovered,
1518
+ last_ingested_at: new Date().toISOString(),
1519
+ },
1520
+ }).catch(() => { /* non-fatal */ })
1521
+ }
1522
+
1523
+ return {
1524
+ files_discovered: filesDiscovered,
1525
+ errors,
1526
+ file_tree: fileTree,
1527
+ }
1528
+ }
1529
+
1530
+
1531
+
1532
+
1533
+
1534
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_pass1discover_1784235266"]
1535
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_pass2chunk_1784235266" type="function" identity="pass2chunk" parent="none"]
1536
+ // CIL[DOC-MACRO purpose="Implements pass2chunk logic in cortex.functions.custom_cil-ingest"]
1537
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute pass2chunk and return its computed result"]
1538
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
1539
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
1540
+ // CIL[DOC-MICRO logic_summary="Provides pass2chunk with pass2Chunk( inputs, handling internal flow and returning a result" notable_decisions="[]"]
1541
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
1542
+ // CIL[DOC-STABILITY stability="stable"]
1543
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
1544
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
1545
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
1546
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
1547
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
1548
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
1549
+ async function pass2Chunk(
1550
+ ctx: any,
1551
+ projectId: string,
1552
+ repoPath: string,
1553
+ globs: string[],
1554
+ excludeGlobs: string[],
1555
+ forceReprocess: boolean,
1556
+ filePath?: string,
1557
+ selectedPaths?: string[],
1558
+ selectedExtensions?: string[]
1559
+ ): Promise<{
1560
+ files_processed: number
1561
+ chunks_auto_approved: number
1562
+ chunks_queued_for_review: number
1563
+ markers_written: number
1564
+ errors: string[]
1565
+ }> {
1566
+ const errors: string[] = []
1567
+ let filesProcessed = 0, chunksAutoApproved = 0, chunksQueued = 0, markersWritten = 0
1568
+
1569
+
1570
+
1571
+
1572
+ const { data: projItem } = await adminDb.from('items').select('id, data').eq('id', projectId).maybeSingle()
1573
+ const fileTree = (projItem?.data?.file_tree as FileTreeNode) || null
1574
+
1575
+
1576
+ let targetFiles: string[] = []
1577
+ if (filePath) {
1578
+ targetFiles = [filePath]
1579
+ } else if (fileTree) {
1580
+ targetFiles = collectSelectedFiles(fileTree, selectedPaths || [], selectedExtensions || [])
1581
+ } else {
1582
+
1583
+ targetFiles = walkDir(repoPath, repoPath, globs, excludeGlobs).map(f => f.path)
1584
+ }
1585
+
1586
+
1587
+ const { data: allFileItems } = await adminDb
1588
+ .from('items')
1589
+ .select('id, title, data')
1590
+ .filter('data->>project_id', 'eq', projectId)
1591
+ .filter('data->>kb_type', 'eq', 'cil_file')
1592
+ .eq('is_active', true)
1593
+
1594
+ const existingByPath = new Map<string, { id: string; title: string; data: any }>()
1595
+ for (const item of allFileItems || []) {
1596
+ const fp = item.data?.file_path as string || item.title
1597
+ if (fp) existingByPath.set(fp, item)
1598
+ }
1599
+
1600
+
1601
+
1602
+ const fileItems: { id: string; title: string; data: any }[] = []
1603
+ for (const relPath of targetFiles) {
1604
+ let fileItem = existingByPath.get(relPath)
1605
+ if (!fileItem) {
1606
+ const language = detectLanguage(path.join(repoPath, relPath))
1607
+ const extension = path.extname(relPath).toLowerCase()
1608
+ try {
1609
+ const newFile = await adminCreate(ctx, {
1610
+ entity: 'items',
1611
+ type_slug: 'cil_file',
1612
+ title: relPath,
1613
+ status: 'active',
1614
+ is_active: true,
1615
+ data: {
1616
+ kb_type: 'cil_file',
1617
+ project_id: projectId,
1618
+ file_path: relPath,
1619
+ language,
1620
+ extension,
1621
+ stored_hash: null,
1622
+ has_existing_markers: false,
1623
+ existing_marker_names: [],
1624
+ existing_marker_count: 0,
1625
+ line_count: 0,
1626
+ status: 'discovered',
1627
+ ingestion_pass: 1,
1628
+ chunk_count: 0,
1629
+ is_dead_code: false,
1630
+ git_last_commit: null,
1631
+ existing_marker_agreement_count: 0,
1632
+ existing_marker_disagreement_count: 0,
1633
+ },
1634
+ })
1635
+ const fileData = newFile.data || newFile
1636
+ fileItem = { id: newFile.id, title: relPath, data: fileData }
1637
+ if (fileTree) updateTreeNodeByPath(fileTree, relPath, { id: newFile.id, status: 'discovered' })
1638
+ } catch (err) {
1639
+ errors.push(`${relPath}: create failed: ${err instanceof Error ? err.message : String(err)}`)
1640
+ continue
1641
+ }
1642
+ }
1643
+ if (fileItem) {
1644
+ const status = getFileStatus(fileItem)
1645
+ if (forceReprocess || status === 'discovered') {
1646
+ fileItems.push(fileItem)
1647
+ }
1648
+ }
1649
+ }
1650
+
1651
+
1652
+ const { data: existingChunkRows } = await adminDb
1653
+ .from('items')
1654
+ .select('data->file_id, data->chunk_name')
1655
+ .filter('data->>project_id', 'eq', projectId)
1656
+ .filter('data->>kb_type', 'eq', 'cil_chunk')
1657
+ .eq('is_active', true)
1658
+
1659
+ const alreadyChunkedFileIds = new Set(
1660
+ (existingChunkRows || []).map((r: any) => r.file_id).filter(Boolean)
1661
+ )
1662
+
1663
+ const existingChunkKeys = new Set(
1664
+ (existingChunkRows || [])
1665
+ .filter((r: any) => r.file_id && r.chunk_name)
1666
+ .map((r: any) => `${r.file_id}::${r.chunk_name}`)
1667
+ )
1668
+
1669
+
1670
+ const chunksToInsert: object[] = []
1671
+ const proposalsToInsert: object[] = []
1672
+
1673
+ const fileUpdates: { id: string; data: Record<string, unknown> }[] = []
1674
+
1675
+ for (const fileItem of fileItems || []) {
1676
+ const relPath: string = fileItem.data?.file_path || fileItem.title
1677
+ const absPath = path.join(repoPath, relPath)
1678
+ const language = fileItem.data?.language || 'unknown'
1679
+
1680
+ if (!['typescript', 'javascript'].includes(language)) continue
1681
+
1682
+
1683
+ if (!forceReprocess && alreadyChunkedFileIds.has(fileItem.id)) continue
1684
+
1685
+ try {
1686
+ const content = fs.readFileSync(absPath, 'utf-8')
1687
+ const lines = content.split('\n')
1688
+ const fileHash = computeFileHash(content)
1689
+
1690
+
1691
+ const existingMarkers = parseExistingMarkers(lines)
1692
+ const hasExistingMarkers = existingMarkers.length > 0
1693
+
1694
+
1695
+ const rawProposals = proposeChunksFromSource(lines, language)
1696
+
1697
+ const approvedChunks: { name: string; line_start: number; line_end: number; marker_line_end: number; chunk_type: string; is_proposal: boolean }[] = []
1698
+
1699
+ for (const proposal of rawProposals) {
1700
+
1701
+
1702
+
1703
+ let contentStart = proposal.line_start - 1
1704
+ if (proposal.existing_jsdoc) {
1705
+ for (let i = proposal.line_start - 2; i >= 0; i--) {
1706
+ const t = lines[i].trim()
1707
+ if (t === '' || /CHUNK_(?:START|END):|@cil-generated/.test(t)) continue
1708
+ if (t.startsWith('/**') || t.startsWith('/*')) { contentStart = i; break }
1709
+ if (!t.startsWith('*')) break
1710
+ }
1711
+ }
1712
+ const codeLines = lines.slice(contentStart, proposal.line_end)
1713
+ const codeContent = codeLines.join('\n')
1714
+ const codePreview = codeLines.slice(0, 8).join('\n')
1715
+ const tokenCount = estimateTokens(codeContent)
1716
+ const contentHash = computeChunkHash(codeContent)
1717
+
1718
+
1719
+ const overlappingMarker = existingMarkers.find(m =>
1720
+ Math.abs(m.line_start - proposal.line_start) <= 3
1721
+ )
1722
+ const existingMarkerMatch = !!overlappingMarker
1723
+ const existingMarkerName = overlappingMarker?.name || ''
1724
+
1725
+
1726
+ let score = proposal.confidence_score
1727
+ let reasons = proposal.confidence_reasons
1728
+ if (existingMarkerMatch) {
1729
+ if (overlappingMarker!.name === proposal.name) {
1730
+ score = Math.min(0.99, score + 0.08)
1731
+ reasons = [...reasons, 'matches existing marker name+position']
1732
+ } else {
1733
+ score = Math.min(0.99, score + 0.04)
1734
+ reasons = [...reasons, 'matches existing marker position']
1735
+ }
1736
+ }
1737
+
1738
+ const isHighConfidence = score >= HIGH_CONFIDENCE_THRESHOLD
1739
+
1740
+ if (isHighConfidence) {
1741
+
1742
+ const chunkKey = `${fileItem.id}::${proposal.name}`
1743
+ if (!forceReprocess && existingChunkKeys.has(chunkKey)) {
1744
+ approvedChunks.push({ name: proposal.name, line_start: proposal.line_start, line_end: proposal.line_end, marker_line_end: proposal.marker_line_end, chunk_type: proposal.chunk_type, is_proposal: false })
1745
+ chunksAutoApproved++
1746
+ continue
1747
+ }
1748
+
1749
+ const existingMarkerAgreement = existingMarkerMatch
1750
+ ? (overlappingMarker!.name === proposal.name ? 'agreed' : 'disagreed')
1751
+ : 'none'
1752
+
1753
+
1754
+ const jd = proposal.existing_jsdoc
1755
+ const hasSourceDoc = !!(jd && (jd.description || jd.params || jd.returns))
1756
+
1757
+
1758
+ const docConfidence = jd?.is_cil_generated ? 'ai_generated' : hasSourceDoc ? 'from_source' : 'unverified_legacy'
1759
+
1760
+
1761
+ const inputSpec = jd?.input_spec || jd?.params || ''
1762
+
1763
+ const outputSpec = jd?.output_spec || jd?.returns || ''
1764
+
1765
+ const sentences = (jd?.description || '').split(/(?<=[.!?])\s+/)
1766
+ const macro = jd?.macro || sentences[0] || ''
1767
+ const micro = jd?.micro || sentences[1] || ''
1768
+
1769
+ const isModuleHeader = proposal.chunk_type === 'module_header'
1770
+ const moduleName = isModuleHeader ? moduleNameFromPath(relPath) : ''
1771
+
1772
+ const layer = jd?.layer || fileItem.data?.layer || (isModuleHeader ? 'shared-core' : 'app-specific')
1773
+
1774
+ const baseChunkData: Record<string, any> = {
1775
+ kb_type: 'cil_chunk',
1776
+ chunk_name: proposal.name,
1777
+ file_id: fileItem.id,
1778
+ project_id: projectId,
1779
+ file_path: relPath,
1780
+ source_set_id: fileItem.data?.source_set_id || null,
1781
+ layer,
1782
+ line_start: proposal.line_start,
1783
+ line_end: proposal.line_end,
1784
+ chunk_type: proposal.chunk_type,
1785
+ stored_hash: contentHash,
1786
+ boundary_confidence: 'high',
1787
+ boundary_source: 'ast_auto',
1788
+ review_status: 'approved',
1789
+ doc_confidence: docConfidence,
1790
+ is_dead_code: false,
1791
+ macro,
1792
+ micro,
1793
+ input_spec: inputSpec,
1794
+ output_spec: outputSpec,
1795
+ side_effects: jd?.side_effects || '',
1796
+ stability: jd?.stability || 'internal',
1797
+ throws: jd?.throws || '',
1798
+
1799
+ called_by: jd?.called_by || '',
1800
+ calls: jd?.calls || '',
1801
+ tags: jd?.tags || '',
1802
+ complexity: jd?.complexity || '',
1803
+ error_handling: jd?.error_handling || '',
1804
+ depends_on: jd?.depends_on || '',
1805
+ depended_by: jd?.depended_by || '',
1806
+ test_unit_path: null,
1807
+ test_e2e_path: null,
1808
+ token_count: tokenCount,
1809
+ existing_marker_agreement: existingMarkerAgreement,
1810
+ code_content: codeContent,
1811
+ }
1812
+
1813
+ if (isModuleHeader) {
1814
+ baseChunkData.module = jd?.module || moduleName
1815
+ baseChunkData.audience = jd?.audience || 'both'
1816
+ baseChunkData.layer = layer
1817
+ baseChunkData.stability = jd?.stability || 'stable'
1818
+
1819
+
1820
+ baseChunkData.description = jd?.description || ''
1821
+ baseChunkData.see_also = jd?.see_also || ''
1822
+ }
1823
+
1824
+ chunksToInsert.push({
1825
+ entity: 'items',
1826
+ type_slug: 'cil_chunk',
1827
+ title: `${relPath}::${proposal.name}`,
1828
+ status: 'active',
1829
+ is_active: true,
1830
+ data: baseChunkData,
1831
+ })
1832
+ existingChunkKeys.add(chunkKey)
1833
+
1834
+ approvedChunks.push({ name: proposal.name, line_start: proposal.line_start, line_end: proposal.line_end, marker_line_end: proposal.marker_line_end, chunk_type: proposal.chunk_type, is_proposal: false })
1835
+ chunksAutoApproved++
1836
+ } else {
1837
+ proposalsToInsert.push({
1838
+ entity: 'items',
1839
+ type_slug: 'cil_chunk_proposal',
1840
+ title: `PROPOSAL: ${relPath}::${proposal.name}`,
1841
+ status: 'active',
1842
+ is_active: true,
1843
+ data: {
1844
+ kb_type: 'cil_chunk_proposal',
1845
+ file_id: fileItem.id,
1846
+ project_id: projectId,
1847
+ file_path: relPath,
1848
+ proposed_name: proposal.name,
1849
+ line_start: proposal.line_start,
1850
+ line_end: proposal.line_end,
1851
+ marker_line_end: proposal.marker_line_end,
1852
+ chunk_type: proposal.chunk_type,
1853
+ confidence_score: score,
1854
+ confidence_reasons: reasons.join('; '),
1855
+ existing_marker_match: existingMarkerMatch,
1856
+ existing_marker_name: existingMarkerName,
1857
+ review_status: 'pending_review',
1858
+ reviewed_by: null,
1859
+ reviewed_at: null,
1860
+ adjusted_line_start: null,
1861
+ adjusted_line_end: null,
1862
+ token_count: tokenCount,
1863
+ code_preview: codePreview,
1864
+ },
1865
+ })
1866
+
1867
+
1868
+
1869
+ approvedChunks.push({ name: proposal.name, line_start: proposal.line_start, line_end: proposal.line_end, marker_line_end: proposal.marker_line_end, chunk_type: proposal.chunk_type, is_proposal: true })
1870
+ chunksQueued++
1871
+ }
1872
+ }
1873
+
1874
+
1875
+
1876
+
1877
+
1878
+
1879
+ if (approvedChunks.length > 0) {
1880
+ let resultLines = [...lines]
1881
+
1882
+ const sorted = [...approvedChunks].sort((a, b) => b.line_start - a.line_start)
1883
+
1884
+ for (const chunk of sorted) {
1885
+ const startLine = resultLines[chunk.line_start - 1]
1886
+
1887
+ if (startLine && ANY_MARKER_RE.test(startLine.trim())) continue
1888
+
1889
+ const startMarker = chunk.is_proposal ? proposalStartMarker(chunk.name) : chunkStartMarker(chunk.name)
1890
+ const endMarker = chunk.is_proposal ? proposalEndMarker(chunk.name) : chunkEndMarker(chunk.name)
1891
+ const startIdx = markerInsertIdx(resultLines, chunk.line_start)
1892
+
1893
+ const endIdx = markerEndInsertIdx(resultLines, chunk.marker_line_end)
1894
+
1895
+ resultLines.splice(endIdx, 0, endMarker)
1896
+ resultLines.splice(startIdx, 0, startMarker)
1897
+ markersWritten++
1898
+ }
1899
+
1900
+ fs.writeFileSync(absPath, resultLines.join('\n'), 'utf-8')
1901
+ }
1902
+
1903
+
1904
+ fileUpdates.push({
1905
+ id: fileItem.id,
1906
+ data: {
1907
+ ...fileItem.data,
1908
+ stored_hash: fileHash,
1909
+ line_count: lines.length,
1910
+ has_existing_markers: hasExistingMarkers,
1911
+ existing_marker_names: existingMarkers.map(m => m.name),
1912
+ existing_marker_count: existingMarkers.length,
1913
+ chunk_count: approvedChunks.length,
1914
+ ingestion_pass: 2,
1915
+ status: 'pass2_complete',
1916
+ last_status_at: new Date().toISOString(),
1917
+ existing_marker_agreement_count: approvedChunks.filter(c => {
1918
+ const em = existingMarkers.find(m => Math.abs(m.line_start - c.line_start) <= 3)
1919
+ return em && em.name === c.name
1920
+ }).length,
1921
+ existing_marker_disagreement_count: approvedChunks.filter(c => {
1922
+ const em = existingMarkers.find(m => Math.abs(m.line_start - c.line_start) <= 3)
1923
+ return em && em.name !== c.name
1924
+ }).length,
1925
+ },
1926
+ })
1927
+
1928
+ if (fileTree) {
1929
+ updateTreeNodeStatus(fileTree, fileItem.id, 'pass2_complete')
1930
+ }
1931
+
1932
+ filesProcessed++
1933
+ } catch (err) {
1934
+ errors.push(`${relPath}: ${err instanceof Error ? err.message : String(err)}`)
1935
+ }
1936
+ }
1937
+
1938
+
1939
+
1940
+ const PARALLEL_INSERT = 10
1941
+ const PARALLEL_UPDATE = 20
1942
+
1943
+ for (let i = 0; i < chunksToInsert.length; i += PARALLEL_INSERT) {
1944
+ const batch = chunksToInsert.slice(i, i + PARALLEL_INSERT)
1945
+ await Promise.all(batch.map(record =>
1946
+ adminCreate(ctx, record as any).catch((e: any) =>
1947
+ errors.push(`chunk insert failed: ${e.message}`)
1948
+ )
1949
+ ))
1950
+ }
1951
+
1952
+ for (let i = 0; i < proposalsToInsert.length; i += PARALLEL_INSERT) {
1953
+ const batch = proposalsToInsert.slice(i, i + PARALLEL_INSERT)
1954
+ await Promise.all(batch.map(record =>
1955
+ adminCreate(ctx, record as any).catch((e: any) =>
1956
+ errors.push(`proposal insert failed: ${e.message}`)
1957
+ )
1958
+ ))
1959
+ }
1960
+
1961
+
1962
+ for (let i = 0; i < fileUpdates.length; i += PARALLEL_UPDATE) {
1963
+ const batch = fileUpdates.slice(i, i + PARALLEL_UPDATE)
1964
+ await Promise.all(batch.map(({ id, data }) => {
1965
+ const updateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id } }
1966
+ return adminUpdate(updateCtx, { data }).catch((e: any) =>
1967
+ errors.push(`file update ${id} failed: ${e.message}`)
1968
+ )
1969
+ }))
1970
+ }
1971
+
1972
+
1973
+ if (projItem) {
1974
+ const updateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: projItem.id } }
1975
+ await adminUpdate(updateCtx, {
1976
+ data: {
1977
+ ...projItem.data,
1978
+ file_tree: fileTree,
1979
+ ingestion_status: chunksQueued > 0 ? 'in_progress' : 'complete',
1980
+ chunk_count: chunksAutoApproved,
1981
+ last_ingested_at: new Date().toISOString(),
1982
+ },
1983
+ }).catch(() => { /* non-fatal */ })
1984
+ }
1985
+
1986
+ return {
1987
+ files_processed: filesProcessed,
1988
+ chunks_auto_approved: chunksAutoApproved,
1989
+ chunks_queued_for_review: chunksQueued,
1990
+ markers_written: markersWritten,
1991
+ errors,
1992
+ }
1993
+ }
1994
+
1995
+
1996
+
1997
+
1998
+
1999
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_pass2chunk_1784235266"]
2000
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_ingest_handler_1784235266" type="variable" identity="handler" parent="none"]
2001
+ // CIL[DOC-MACRO purpose="Defines handler configuration or state in cortex.functions.custom_cil-ingest"]
2002
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for handler"]
2003
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-ingest" layer="function" related_files="[]"]
2004
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of handler" errors="none" side_effects="none"]
2005
+ // CIL[DOC-MICRO logic_summary="Declares handler with initial value or constant binding used by cortex.functions.custom_cil-ingest" notable_decisions="[]"]
2006
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
2007
+ // CIL[DOC-STABILITY stability="stable"]
2008
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
2009
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
2010
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
2011
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
2012
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
2013
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
2014
+ export const handler = createHandler(async (ctx, body) => {
2015
+ const action = ctx.query?.action
2016
+ const req = body as IngestRequest
2017
+
2018
+ if (!req?.project_id) throw new Error('project_id is required')
2019
+
2020
+
2021
+ const { data: projectItem, error: projectError } = await adminDb
2022
+ .from('items')
2023
+ .select('id, title, data')
2024
+ .eq('id', req.project_id)
2025
+ .maybeSingle()
2026
+
2027
+ if (projectError || !projectItem) throw new Error(`Project not found: ${req.project_id}`)
2028
+
2029
+ const repoPath: string = projectItem.data?.repo_path
2030
+
2031
+
2032
+ const DISK_ACTIONS = ['pass1', 'pass2', 'reindex_chunk']
2033
+ if (DISK_ACTIONS.includes(action || '')) {
2034
+ if (!repoPath) throw new Error('Project has no repo_path configured')
2035
+ if (!fs.existsSync(repoPath)) {
2036
+ throw new Error(`Repository path does not exist on this machine: ${repoPath}`)
2037
+ }
2038
+ }
2039
+
2040
+ const globs = req.globs || DEFAULT_GLOBS
2041
+ const excludeGlobs = req.exclude_globs || DEFAULT_EXCLUDE
2042
+ const forceReprocess = req.force_reprocess ?? false
2043
+ const sourceSets: SourceSet[] | undefined = projectItem.data?.source_sets
2044
+
2045
+
2046
+ if (action === 'pass1') {
2047
+ if (!ctx.accountId) throw new Error('account_id required — user must be authenticated')
2048
+
2049
+ const discoverGlobs = req.file_path ? [req.file_path] : globs
2050
+ const discoverExcludes = req.file_path ? [] : excludeGlobs
2051
+ const result = await pass1Discover(ctx, req.project_id, repoPath, discoverGlobs, discoverExcludes, forceReprocess, sourceSets)
2052
+ return {
2053
+ action: 'pass1',
2054
+ project_id: req.project_id,
2055
+ repo_path: repoPath,
2056
+ file_path: req.file_path || null,
2057
+ source_sets_used: sourceSets ? sourceSets.length : 0,
2058
+ ...result,
2059
+ }
2060
+ }
2061
+
2062
+
2063
+ if (action === 'pass2') {
2064
+ if (!ctx.accountId) throw new Error('account_id required — user must be authenticated')
2065
+ const selectedPaths = projectItem.data?.selected_paths as string[] | undefined
2066
+ const selectedExtensions = req.selected_extensions || (projectItem.data?.selected_extensions as string[] | undefined)
2067
+ const result = await pass2Chunk(ctx, req.project_id, repoPath, globs, excludeGlobs, forceReprocess, req.file_path, selectedPaths, selectedExtensions)
2068
+ return {
2069
+ action: 'pass2',
2070
+ project_id: req.project_id,
2071
+ repo_path: repoPath,
2072
+ file_path: req.file_path || null,
2073
+ confidence_threshold: HIGH_CONFIDENCE_THRESHOLD,
2074
+ ...result,
2075
+ }
2076
+ }
2077
+
2078
+
2079
+
2080
+
2081
+
2082
+
2083
+
2084
+
2085
+ if (action === 'promote_proposal') {
2086
+ const proposalId = body?.proposal_id
2087
+ if (!proposalId) throw new Error('proposal_id is required')
2088
+
2089
+ const { data: proposal } = await adminDb
2090
+ .from('items')
2091
+ .select('id, data')
2092
+ .eq('id', proposalId)
2093
+ .maybeSingle()
2094
+
2095
+ if (!proposal) throw new Error(`Proposal not found: ${proposalId}`)
2096
+
2097
+ const pd = proposal.data || {}
2098
+ const fileId = pd.file_id
2099
+ if (!fileId) throw new Error('Proposal has no file_id')
2100
+
2101
+ const chunkName = body?.adjusted_name || pd.proposed_name || 'Unknown'
2102
+ const chunkType = pd.chunk_type || 'function'
2103
+ const projectId = pd.project_id || req.project_id
2104
+
2105
+
2106
+ const { data: fileItem } = await adminDb
2107
+ .from('items').select('id, data').eq('id', fileId).maybeSingle()
2108
+ if (!fileItem) throw new Error(`File not found: ${fileId}`)
2109
+
2110
+ const relPath: string = fileItem.data?.file_path || fileItem.title
2111
+ const effectiveRepoPath: string = repoPath || body?.repo_path || ''
2112
+ if (!effectiveRepoPath) {
2113
+ throw new Error(
2114
+ `Project has no repo_path configured. ` +
2115
+ `Pass repo_path in the request body to override, or update the project record.`
2116
+ )
2117
+ }
2118
+ const absPath = path.join(effectiveRepoPath, relPath)
2119
+ if (!fs.existsSync(absPath)) throw new Error(`Source file not found on disk: ${absPath}`)
2120
+
2121
+ const fileContent = fs.readFileSync(absPath, 'utf-8')
2122
+ const resultLines = fileContent.split('\n')
2123
+
2124
+
2125
+
2126
+ const proposalStartText = proposalStartMarker(chunkName)
2127
+ const proposalEndText = proposalEndMarker(chunkName)
2128
+ const startIdx = resultLines.findIndex(l => l.trim() === proposalStartText.trim())
2129
+ const endIdx = resultLines.findIndex(l => l.trim() === proposalEndText.trim())
2130
+
2131
+ let markerReplaced = false
2132
+ if (startIdx !== -1) { resultLines[startIdx] = chunkStartMarker(chunkName); markerReplaced = true }
2133
+ if (endIdx !== -1) { resultLines[endIdx] = chunkEndMarker(chunkName); markerReplaced = true }
2134
+ if (markerReplaced) fs.writeFileSync(absPath, resultLines.join('\n'), 'utf-8')
2135
+
2136
+
2137
+
2138
+
2139
+ const actualStart = startIdx !== -1 ? startIdx + 1 : (pd.line_start || 1)
2140
+ const actualEnd = endIdx !== -1 ? endIdx + 1 : (pd.line_end || actualStart)
2141
+
2142
+ const codeLines = resultLines.slice(actualStart, actualEnd - 1)
2143
+ const codeContent = codeLines.join('\n')
2144
+ const tokenCount = estimateTokens(codeContent)
2145
+ const contentHash = computeChunkHash(codeContent)
2146
+
2147
+ if (!ctx.accountId) throw new Error('account_id required — user must be authenticated')
2148
+
2149
+
2150
+ const newChunk = await adminCreate(ctx, {
2151
+ entity: 'items',
2152
+ type_slug: 'cil_chunk',
2153
+ title: `${relPath}::${chunkName}`,
2154
+ status: 'active',
2155
+ is_active: true,
2156
+ data: {
2157
+ kb_type: 'cil_chunk',
2158
+ chunk_name: chunkName,
2159
+ file_id: fileId,
2160
+ project_id: projectId,
2161
+ file_path: relPath,
2162
+ line_start: actualStart,
2163
+ line_end: actualEnd,
2164
+ chunk_type: chunkType,
2165
+ stored_hash: contentHash,
2166
+ boundary_confidence: 'human_verified',
2167
+ boundary_source: 'ast_approved',
2168
+ review_status: 'approved',
2169
+ doc_confidence: 'unverified_legacy',
2170
+ is_dead_code: false,
2171
+ macro: '',
2172
+ micro: '',
2173
+ input_spec: '',
2174
+ output_spec: '',
2175
+ side_effects: '',
2176
+ stability: 'internal',
2177
+ test_unit_path: null,
2178
+ test_e2e_path: null,
2179
+ token_count: tokenCount,
2180
+ existing_marker_agreement: 'none',
2181
+ code_content: codeContent,
2182
+ },
2183
+ })
2184
+ if (!newChunk?.id) throw new Error('Failed to create chunk record')
2185
+
2186
+
2187
+ const propUpdateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: proposalId } }
2188
+ await adminUpdate(propUpdateCtx, {
2189
+ is_active: false,
2190
+ data: { ...pd, review_status: 'approved', promoted_chunk_id: newChunk.id },
2191
+ })
2192
+
2193
+ return {
2194
+ action: 'promote_proposal',
2195
+ proposal_id: proposalId,
2196
+ chunk_id: newChunk?.id,
2197
+ chunk_name: chunkName,
2198
+ file_path: relPath,
2199
+ marker_replaced: markerReplaced,
2200
+ }
2201
+ }
2202
+
2203
+
2204
+
2205
+
2206
+
2207
+
2208
+
2209
+
2210
+ if (action === 'reject_proposal') {
2211
+ const proposalId = body?.proposal_id
2212
+ if (!proposalId) throw new Error('proposal_id is required')
2213
+
2214
+ const { data: proposal } = await adminDb
2215
+ .from('items')
2216
+ .select('id, data')
2217
+ .eq('id', proposalId)
2218
+ .maybeSingle()
2219
+
2220
+ if (!proposal) throw new Error(`Proposal not found: ${proposalId}`)
2221
+
2222
+ const pd = proposal.data || {}
2223
+ const fileId = pd.file_id
2224
+ if (!fileId) throw new Error('Proposal has no file_id')
2225
+
2226
+ const chunkName = pd.proposed_name || 'Unknown'
2227
+
2228
+ const { data: fileItem } = await adminDb
2229
+ .from('items').select('id, data').eq('id', fileId).maybeSingle()
2230
+ if (!fileItem) throw new Error(`File not found: ${fileId}`)
2231
+
2232
+ const relPath: string = fileItem.data?.file_path || fileItem.title
2233
+ const effectiveRepoPath: string = repoPath || body?.repo_path || ''
2234
+ if (!effectiveRepoPath) {
2235
+ throw new Error(
2236
+ `Project has no repo_path configured. ` +
2237
+ `Pass repo_path in the request body to override, or update the project record.`
2238
+ )
2239
+ }
2240
+ const absPath = path.join(effectiveRepoPath, relPath)
2241
+ if (!fs.existsSync(absPath)) throw new Error(`Source file not found on disk: ${absPath}`)
2242
+
2243
+ const fileContent = fs.readFileSync(absPath, 'utf-8')
2244
+ const resultLines = fileContent.split('\n')
2245
+
2246
+
2247
+ const proposalStartText = proposalStartMarker(chunkName)
2248
+ const proposalEndText = proposalEndMarker(chunkName)
2249
+ let markerReplaced = false
2250
+ for (let i = 0; i < resultLines.length; i++) {
2251
+ const t = resultLines[i].trim()
2252
+ if (t === proposalStartText.trim()) { resultLines[i] = rejectedStartMarker(chunkName); markerReplaced = true }
2253
+ if (t === proposalEndText.trim()) { resultLines[i] = rejectedEndMarker(chunkName); markerReplaced = true }
2254
+ }
2255
+ if (markerReplaced) fs.writeFileSync(absPath, resultLines.join('\n'), 'utf-8')
2256
+
2257
+
2258
+ const propUpdateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: proposalId } }
2259
+ await adminUpdate(propUpdateCtx, {
2260
+ is_active: false,
2261
+ data: { ...pd, review_status: 'rejected' },
2262
+ })
2263
+
2264
+ return {
2265
+ action: 'reject_proposal',
2266
+ proposal_id: proposalId,
2267
+ chunk_name: chunkName,
2268
+ file_path: relPath,
2269
+ marker_replaced: markerReplaced,
2270
+ }
2271
+ }
2272
+
2273
+
2274
+ if (action === 'status') {
2275
+ const { count: fileCount } = await adminDb
2276
+ .from('items').select('id', { count: 'exact' })
2277
+ .filter('data->>project_id', 'eq', req.project_id)
2278
+ .filter('data->>kb_type', 'eq', 'cil_file').eq('is_active', true)
2279
+
2280
+ const { count: chunkCount } = await adminDb
2281
+ .from('items').select('id', { count: 'exact' })
2282
+ .filter('data->>project_id', 'eq', req.project_id)
2283
+ .filter('data->>kb_type', 'eq', 'cil_chunk').eq('is_active', true)
2284
+
2285
+ const { count: proposalCount } = await adminDb
2286
+ .from('items').select('id', { count: 'exact' })
2287
+ .filter('data->>project_id', 'eq', req.project_id)
2288
+ .filter('data->>kb_type', 'eq', 'cil_chunk_proposal')
2289
+ .filter('data->>review_status', 'eq', 'pending_review')
2290
+ .eq('is_active', true)
2291
+
2292
+ return {
2293
+ project_id: req.project_id,
2294
+ file_count: fileCount || 0,
2295
+ chunk_count: chunkCount || 0,
2296
+ pending_review_count: proposalCount || 0,
2297
+ ingestion_status: projectItem.data?.ingestion_status || 'not_started',
2298
+ }
2299
+ }
2300
+
2301
+
2302
+
2303
+
2304
+
2305
+
2306
+
2307
+
2308
+ if (action === 'reindex_chunk') {
2309
+ const chunkId = body?.chunk_id
2310
+ if (!chunkId) throw new Error('chunk_id is required')
2311
+
2312
+ const { data: chunk } = await adminDb
2313
+ .from('items').select('id, data').eq('id', chunkId).maybeSingle()
2314
+ if (!chunk) throw new Error(`Chunk not found: ${chunkId}`)
2315
+
2316
+ const cd = chunk.data || {}
2317
+ const fileId = cd.file_id
2318
+ const relPath: string = cd.file_path
2319
+ const lineStart: number = cd.line_start || 0
2320
+ const lineEnd: number = cd.line_end || 0
2321
+
2322
+ if (!relPath || !lineStart || !lineEnd) {
2323
+ throw new Error('Chunk is missing file_path / line_start / line_end — cannot reindex')
2324
+ }
2325
+
2326
+ const absPath = path.join(repoPath, relPath)
2327
+ if (!fs.existsSync(absPath)) {
2328
+ throw new Error(`Source file not found on disk: ${absPath}`)
2329
+ }
2330
+
2331
+ const fileContent = fs.readFileSync(absPath, 'utf-8')
2332
+ const lines = fileContent.split('\n')
2333
+
2334
+ const codeLines = lines.slice(lineStart - 1, lineEnd)
2335
+ const codeContent = codeLines.join('\n')
2336
+ const tokenCount = estimateTokens(codeContent)
2337
+ const contentHash = computeChunkHash(codeContent)
2338
+
2339
+
2340
+ const chunkUpdateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: chunkId } }
2341
+ await adminUpdate(chunkUpdateCtx, {
2342
+ data: {
2343
+ ...cd,
2344
+ code_content: codeContent,
2345
+ stored_hash: contentHash,
2346
+ token_count: tokenCount,
2347
+ hash_updated_at: new Date().toISOString(),
2348
+ },
2349
+ })
2350
+
2351
+
2352
+ if (fileId) {
2353
+ const fileHash = computeFileHash(fileContent)
2354
+ const fileUpdateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: fileId } }
2355
+ await adminUpdate(fileUpdateCtx, { data: { stored_hash: fileHash } })
2356
+ }
2357
+
2358
+ const result: Record<string, any> = {
2359
+ action: 'reindex_chunk',
2360
+ chunk_id: chunkId,
2361
+ chunk_name: cd.chunk_name || '',
2362
+ file_path: relPath,
2363
+ new_hash: contentHash,
2364
+ token_count: tokenCount,
2365
+ embed_triggered: false,
2366
+ doc_triggered: false,
2367
+ }
2368
+
2369
+
2370
+ if (body?.also_embed) {
2371
+ try {
2372
+ const base = process.env.URL || 'http://localhost:8888'
2373
+ const embedRes = await fetch(`${base}/.netlify/functions/cil-embeddings?action=embed_chunk`, {
2374
+ method: 'POST',
2375
+ headers: { 'Content-Type': 'application/json' },
2376
+ body: JSON.stringify({ chunk_id: chunkId, force_regenerate: true }),
2377
+ })
2378
+ result.embed_triggered = embedRes.ok
2379
+ if (!embedRes.ok) {
2380
+ const errText = await embedRes.text()
2381
+ result.embed_error = errText.slice(0, 200)
2382
+ }
2383
+ } catch (err) {
2384
+ result.embed_error = err instanceof Error ? err.message : String(err)
2385
+ }
2386
+ }
2387
+
2388
+
2389
+ if (body?.also_doc) {
2390
+ try {
2391
+ const base = process.env.URL || 'http://localhost:8888'
2392
+ const docRes = await fetch(`${base}/.netlify/functions/cil-doc?action=doc_chunk`, {
2393
+ method: 'POST',
2394
+ headers: { 'Content-Type': 'application/json' },
2395
+ body: JSON.stringify({ chunk_id: chunkId, model: body?.model || 'gpt-4o-mini', force: true }),
2396
+ })
2397
+ result.doc_triggered = docRes.ok
2398
+ if (!docRes.ok) {
2399
+ const errText = await docRes.text()
2400
+ result.doc_error = errText.slice(0, 200)
2401
+ }
2402
+ } catch (err) {
2403
+ result.doc_error = err instanceof Error ? err.message : String(err)
2404
+ }
2405
+ }
2406
+
2407
+ return result
2408
+ }
2409
+
2410
+ throw new Error(`Unknown action: ${action}. Valid actions: pass1, pass2, status, promote_proposal, reject_proposal, reindex_chunk`)
2411
+ })
2412
+
2413
+
2414
+
2415
+
2416
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_ingest_handler_1784235266"]