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,583 @@
1
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_config_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-config"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Own module-level imports, exports, and configuration for cortex.functions.custom_cil-config"]
4
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-config" 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-config" 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
+
20
+
21
+ import { createHandler } from './_shared/middleware'
22
+ import { adminDb } from './_shared/db'
23
+ import { resolveTypeId, resolveLinkTypeId } from './_shared/resolve-ids'
24
+ import { create as adminCreate, update as adminUpdate } from './admin-data'
25
+ import { isSelectedPath } from './_shared/cil'
26
+ import * as fs from 'fs'
27
+ import * as path from 'path'
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_config_module_header_1784235266"]
38
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_config_extractedconfigfield_1784235266" type="interface" identity="extractedconfigfield" parent="none"]
39
+ // CIL[DOC-MACRO purpose="Defines the extractedconfigfield type contract in cortex.functions.custom_cil-config"]
40
+ // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape and allowed fields for extractedconfigfield"]
41
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-config" 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\",\"\\\"]"]
42
+ // CIL[DOC-CONTRACT inputs="none" outputs="type definition for extractedconfigfield" errors="none" side_effects="none"]
43
+ // CIL[DOC-MICRO logic_summary="Declares TypeScript type/interface extractedconfigfield with member definitions" notable_decisions="[]"]
44
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
45
+ // CIL[DOC-STABILITY stability="stable"]
46
+ // 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, \."]
47
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
48
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
49
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
50
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
51
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
52
+ interface ExtractedConfigField {
53
+ field_name: string
54
+ field_type: 'string' | 'number' | 'boolean' | 'json' | 'env' | 'unknown'
55
+ default_value: string
56
+ description: string
57
+ source_file: string
58
+ source_type: 'json' | 'env' | 'sql' | 'ts'
59
+ }
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_config_extractedconfigfield_1784235266"]
71
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_config_config_file_patterns_1784235266" type="variable" identity="config_file_patterns" parent="none"]
72
+ // CIL[DOC-MACRO purpose="Defines config_file_patterns configuration or state in cortex.functions.custom_cil-config"]
73
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for config_file_patterns"]
74
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-config" layer="function" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\"\\\"]"]
75
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of config_file_patterns" errors="none" side_effects="none"]
76
+ // CIL[DOC-MICRO logic_summary="Declares config_file_patterns with initial value or constant binding used by cortex.functions.custom_cil-config" notable_decisions="[]"]
77
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
78
+ // CIL[DOC-STABILITY stability="stable"]
79
+ // 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, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/IntegrationsPage.tsx, custom/apps/portal/pages/ContentPage.tsx, \."]
80
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
81
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
82
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
83
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
84
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
85
+ const CONFIG_FILE_PATTERNS: { glob: RegExp; source_type: ExtractedConfigField['source_type'] }[] = [
86
+ { glob: /spine\.config\.json$/, source_type: 'json' },
87
+ { glob: /\.env(\.example|\.local|\.prod)?$/, source_type: 'env' },
88
+ { glob: /config\.json$/, source_type: 'json' },
89
+ { glob: /settings\.json$/, source_type: 'json' },
90
+ { glob: /manifest\.json$/, source_type: 'json' },
91
+ { glob: /tsconfig[^/]*\.json$/, source_type: 'json' },
92
+ { glob: /migrations\/\d+_.*\.sql$/, source_type: 'sql' },
93
+ ]
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_config_config_file_patterns_1784235266"]
104
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_config_extractfromjson_1784235266" type="function" identity="extractfromjson" parent="none"]
105
+ // CIL[DOC-MACRO purpose="Implements extractfromjson logic in cortex.functions.custom_cil-config"]
106
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute extractfromjson and return its computed result"]
107
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-config" 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\",\"\\\"]"]
108
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
109
+ // CIL[DOC-MICRO logic_summary="Provides extractfromjson with extractFromJson(content: string, sourceFile: string inputs, handling internal flow and returning a result" 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: 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, \."]
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
+ function extractFromJson(content: string, sourceFile: string): ExtractedConfigField[] {
119
+ const fields: ExtractedConfigField[] = []
120
+ try {
121
+ const obj = JSON.parse(content)
122
+ const walk = (node: any, prefix: string) => {
123
+ if (typeof node !== 'object' || node === null || Array.isArray(node)) return
124
+ for (const [k, v] of Object.entries(node)) {
125
+ const fullKey = prefix ? `${prefix}.${k}` : k
126
+ const type = v === null ? 'unknown'
127
+ : typeof v === 'boolean' ? 'boolean'
128
+ : typeof v === 'number' ? 'number'
129
+ : typeof v === 'string' ? 'string'
130
+ : typeof v === 'object' ? 'json'
131
+ : 'unknown'
132
+ fields.push({
133
+ field_name: fullKey,
134
+ field_type: type as ExtractedConfigField['field_type'],
135
+ default_value: v === null ? 'null' : typeof v === 'object' ? JSON.stringify(v).slice(0, 200) : String(v),
136
+ description: '',
137
+ source_file: sourceFile,
138
+ source_type: 'json',
139
+ })
140
+
141
+ if (typeof v === 'object' && v !== null && !Array.isArray(v) && prefix.split('.').length < 2) {
142
+ walk(v, fullKey)
143
+ }
144
+ }
145
+ }
146
+ walk(obj, '')
147
+ } catch {
148
+ }
149
+ return fields
150
+ }
151
+
152
+
153
+
154
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_config_extractfromjson_1784235266"]
155
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_config_extractfromenv_1784235266" type="function" identity="extractfromenv" parent="none"]
156
+ // CIL[DOC-MACRO purpose="Implements extractfromenv logic in cortex.functions.custom_cil-config"]
157
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute extractfromenv and return its computed result"]
158
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-config" 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\"]"]
159
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
160
+ // CIL[DOC-MICRO logic_summary="Provides extractfromenv with extractFromEnv(content: string, sourceFile: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
161
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
162
+ // CIL[DOC-STABILITY stability="stable"]
163
+ // 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."]
164
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
165
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
166
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
167
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
168
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
169
+ function extractFromEnv(content: string, sourceFile: string): ExtractedConfigField[] {
170
+ const fields: ExtractedConfigField[] = []
171
+ const lines = content.split('\n')
172
+ for (const line of lines) {
173
+ const trimmed = line.trim()
174
+ if (!trimmed || trimmed.startsWith('#')) continue
175
+ const eq = trimmed.indexOf('=')
176
+ if (eq === -1) continue
177
+ const key = trimmed.slice(0, eq).trim()
178
+ const val = trimmed.slice(eq + 1).trim()
179
+
180
+ fields.push({
181
+ field_name: key,
182
+ field_type: 'env',
183
+ default_value: val || '',
184
+ description: '',
185
+ source_file: sourceFile,
186
+ source_type: 'env',
187
+ })
188
+ }
189
+ return fields
190
+ }
191
+
192
+
193
+
194
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_config_extractfromenv_1784235266"]
195
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_config_extractfromsql_1784235266" type="function" identity="extractfromsql" parent="none"]
196
+ // CIL[DOC-MACRO purpose="Implements extractfromsql logic in cortex.functions.custom_cil-config"]
197
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute extractfromsql and return its computed result"]
198
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-config" layer="function" related_files="[]"]
199
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
200
+ // CIL[DOC-MICRO logic_summary="Provides extractfromsql with extractFromSql(content: string, sourceFile: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
201
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
202
+ // CIL[DOC-STABILITY stability="stable"]
203
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
204
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
205
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
206
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
207
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
208
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
209
+ function extractFromSql(content: string, sourceFile: string): ExtractedConfigField[] {
210
+
211
+ const fields: ExtractedConfigField[] = []
212
+ const tableRe = /CREATE TABLE(?:\s+IF NOT EXISTS)?\s+(?:\w+\.)?(\w+)\s*\(([^;]+)\)/gis
213
+ let m: RegExpExecArray | null
214
+ while ((m = tableRe.exec(content)) !== null) {
215
+ const tableName = m[1]
216
+ const body = m[2]
217
+ const colRe = /^\s*["']?(\w+)["']?\s+([\w\s[\]()]+?)(?:\s+(?:NOT NULL|DEFAULT|PRIMARY|UNIQUE|REFERENCES|CHECK).*)?,?\s*$/gm
218
+ let cm: RegExpExecArray | null
219
+ while ((cm = colRe.exec(body)) !== null) {
220
+ const colName = cm[1]
221
+ if (['CONSTRAINT', 'PRIMARY', 'UNIQUE', 'CHECK', 'FOREIGN', 'INDEX'].includes(colName.toUpperCase())) continue
222
+ fields.push({
223
+ field_name: `${tableName}.${colName}`,
224
+ field_type: 'unknown',
225
+ default_value: '',
226
+ description: '',
227
+ source_file: sourceFile,
228
+ source_type: 'sql',
229
+ })
230
+ }
231
+ }
232
+ return fields
233
+ }
234
+
235
+
236
+
237
+
238
+
239
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_config_extractfromsql_1784235266"]
240
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_config_walkforconfigfiles_1784235266" type="function" identity="walkforconfigfiles" parent="none"]
241
+ // CIL[DOC-MACRO purpose="Implements walkforconfigfiles logic in cortex.functions.custom_cil-config"]
242
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute walkforconfigfiles and return its computed result"]
243
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-config" layer="function" related_files="[]"]
244
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
245
+ // CIL[DOC-MICRO logic_summary="Provides walkforconfigfiles with walkForConfigFiles(repoPath: string, maxDepth = 3 inputs, handling internal flow and returning a result" 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
+ function walkForConfigFiles(repoPath: string, maxDepth = 3): string[] {
255
+ const results: string[] = []
256
+ const walk = (dir: string, depth: number) => {
257
+ if (depth > maxDepth) return
258
+ let entries: fs.Dirent[]
259
+ try {
260
+ entries = fs.readdirSync(dir, { withFileTypes: true })
261
+ } catch { return }
262
+
263
+ for (const entry of entries) {
264
+ if (entry.name.startsWith('.') && !entry.name.startsWith('.env')) continue
265
+ if (['node_modules', '.git', 'dist', 'build', '.assembled', 'coverage'].includes(entry.name)) continue
266
+ const full = path.join(dir, entry.name)
267
+ if (entry.isDirectory()) {
268
+ walk(full, depth + 1)
269
+ } else {
270
+ const rel = path.relative(repoPath, full)
271
+ const matched = CONFIG_FILE_PATTERNS.some(p => p.glob.test(rel))
272
+ if (matched) results.push(rel)
273
+ }
274
+ }
275
+ }
276
+ walk(repoPath, 0)
277
+ return results
278
+ }
279
+
280
+
281
+
282
+
283
+
284
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_config_walkforconfigfiles_1784235266"]
285
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_config_handler_1784235266" type="variable" identity="handler" parent="none"]
286
+ // CIL[DOC-MACRO purpose="Defines handler configuration or state in cortex.functions.custom_cil-config"]
287
+ // CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for handler"]
288
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-config" layer="function" related_files="[]"]
289
+ // CIL[DOC-CONTRACT inputs="none" outputs="value of handler" errors="none" side_effects="none"]
290
+ // CIL[DOC-MICRO logic_summary="Declares handler with initial value or constant binding used by cortex.functions.custom_cil-config" notable_decisions="[]"]
291
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
292
+ // CIL[DOC-STABILITY stability="stable"]
293
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
294
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
295
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
296
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
297
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
298
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
299
+ export const handler = createHandler(async (ctx, body) => {
300
+ const action = ctx.query?.action || body?.action || 'run'
301
+ const projectId = ctx.query?.project_id || body?.project_id
302
+ if (!projectId) throw new Error('project_id is required')
303
+
304
+
305
+ if (action === 'status') {
306
+ const [configItems, configuresTypeId] = await Promise.all([
307
+ adminDb.from('items').select('id', { count: 'exact' })
308
+ .filter('data->>project_id', 'eq', projectId)
309
+ .filter('data->>kb_type', 'eq', 'cil_config')
310
+ .eq('is_active', true),
311
+ resolveLinkTypeId('cil_configures').catch(() => null),
312
+ ])
313
+
314
+ let linkCount = 0
315
+ if (configuresTypeId && (configItems.count || 0) > 0) {
316
+ const { data: configIds } = await adminDb.from('items').select('id')
317
+ .filter('data->>project_id', 'eq', projectId)
318
+ .filter('data->>kb_type', 'eq', 'cil_config').eq('is_active', true)
319
+ const ids = (configIds || []).map((r: any) => r.id)
320
+ if (ids.length) {
321
+ const { count } = await adminDb.from('links').select('id', { count: 'exact' })
322
+ .eq('link_type_id', configuresTypeId!).in('source_id', ids)
323
+ linkCount = count || 0
324
+ }
325
+ }
326
+
327
+ return {
328
+ project_id: projectId,
329
+ config_items: configItems.count || 0,
330
+ configures_links: linkCount,
331
+ }
332
+ }
333
+
334
+
335
+ if (action === 'extract' || action === 'run') {
336
+
337
+ let repoPath: string = body?.repo_path || ''
338
+ const { data: projectItem } = await adminDb.from('items').select('id, data').eq('id', projectId).maybeSingle()
339
+ if (!repoPath) repoPath = projectItem?.data?.repo_path || ''
340
+ if (!repoPath) throw new Error('repo_path not set on project. Pass repo_path in request body.')
341
+ if (!fs.existsSync(repoPath)) throw new Error(`repo_path does not exist: ${repoPath}`)
342
+
343
+ const force = body?.force ?? false
344
+ const filePath: string | undefined = body?.file_path
345
+ const selectedPaths: string[] = body?.selected_paths || projectItem?.data?.selected_paths || []
346
+ const selectedExtensions: string[] | undefined = body?.selected_extensions || projectItem?.data?.selected_extensions || undefined
347
+ const configTypeId = await resolveTypeId('item', 'cil_config')
348
+
349
+ let configFiles = walkForConfigFiles(repoPath)
350
+ if (filePath) {
351
+ configFiles = configFiles.filter(rel => rel === filePath || rel.startsWith(filePath + '/'))
352
+ }
353
+ if (selectedPaths.length > 0) {
354
+ configFiles = configFiles.filter(rel => isSelectedPath(rel, selectedPaths))
355
+ }
356
+ if (selectedExtensions && selectedExtensions.length > 0) {
357
+ configFiles = configFiles.filter(rel => {
358
+ const ext = path.extname(rel).toLowerCase()
359
+ return selectedExtensions.includes(ext)
360
+ })
361
+ }
362
+ const errors: string[] = []
363
+ let created = 0, updated = 0, skipped = 0
364
+
365
+
366
+ const { data: existingConfigs } = await adminDb.from('items').select('id, data')
367
+ .filter('data->>project_id', 'eq', projectId)
368
+ .filter('data->>kb_type', 'eq', 'cil_config').eq('is_active', true)
369
+
370
+
371
+ const existingBySlug = new Map<string, any>()
372
+ for (const item of existingConfigs || []) {
373
+ const slug = `${item.data?.config_table}::${item.data?.field_name}`
374
+ existingBySlug.set(slug, item)
375
+ }
376
+
377
+
378
+ const allFields: { relFile: string; field: ExtractedConfigField }[] = []
379
+ for (const relFile of configFiles) {
380
+ const absFile = path.join(repoPath, relFile)
381
+ const pattern = CONFIG_FILE_PATTERNS.find(p => p.glob.test(relFile))
382
+ if (!pattern) continue
383
+ try {
384
+ const content = fs.readFileSync(absFile, 'utf-8')
385
+ let rawFields: ExtractedConfigField[] = []
386
+ if (pattern.source_type === 'json') rawFields = extractFromJson(content, relFile)
387
+ else if (pattern.source_type === 'env') rawFields = extractFromEnv(content, relFile)
388
+ else if (pattern.source_type === 'sql') rawFields = extractFromSql(content, relFile)
389
+ for (const field of rawFields) allFields.push({ relFile, field })
390
+ } catch (err) {
391
+ errors.push(`${relFile}: ${err instanceof Error ? err.message : String(err)}`)
392
+ }
393
+ }
394
+
395
+
396
+ const now = new Date().toISOString()
397
+ const toInsert: object[] = []
398
+ const toUpdate: { id: string; data: object }[] = []
399
+
400
+ for (const { relFile, field } of allFields) {
401
+ const slug = `${relFile}::${field.field_name}`
402
+ const existing = existingBySlug.get(slug)
403
+
404
+ if (existing && !force) { skipped++; continue }
405
+
406
+ const itemData = {
407
+ kb_type: 'cil_config',
408
+ project_id: projectId,
409
+ config_table: relFile,
410
+ record_slug: slug,
411
+ field_name: field.field_name,
412
+ field_type: field.field_type,
413
+ default_value: field.default_value,
414
+ description: field.description,
415
+ settings: '',
416
+ current_value_query: '',
417
+ current_value_query_type: field.source_type === 'env' ? 'env' : 'json_path',
418
+ code_edge_chunk_ids: '',
419
+ source_type: field.source_type,
420
+ }
421
+
422
+ if (existing) {
423
+ toUpdate.push({ id: existing.id, data: { ...existing.data, ...itemData } })
424
+ updated++
425
+ } else {
426
+ toInsert.push({ type_id: configTypeId, title: slug, status: 'active', is_active: true, data: itemData, created_at: now, updated_at: now })
427
+ created++
428
+ }
429
+ }
430
+
431
+
432
+ const insertPromises = toInsert.map((record: any) =>
433
+ adminCreate(ctx, { ...record, entity: 'items' }).catch((e: any) => {
434
+ errors.push(`config insert: ${e.message || e}`)
435
+ created--
436
+ })
437
+ )
438
+ const updatePromises = toUpdate.map(({ id, data }) =>
439
+ adminUpdate({ ...ctx, query: { ...(ctx.query || {}), entity: 'items', id } } as any, { data }).catch((e: any) => {
440
+ errors.push(`config update ${id}: ${e.message || e}`)
441
+ })
442
+ )
443
+ await Promise.all([...insertPromises, ...updatePromises])
444
+
445
+ const extractResult = {
446
+ project_id: projectId,
447
+ repo_path: repoPath,
448
+ file_path: filePath || null,
449
+ config_files_scanned: configFiles.length,
450
+ config_items_created: created,
451
+ config_items_updated: updated,
452
+ config_items_skipped: skipped,
453
+ errors,
454
+ }
455
+
456
+
457
+ if (action === 'extract') return extractResult
458
+
459
+
460
+ const linkResult = await runLinkPass(ctx, projectId, errors)
461
+ return {
462
+ ...extractResult,
463
+ ...linkResult,
464
+ }
465
+ }
466
+
467
+
468
+ if (action === 'link') {
469
+ const errors: string[] = []
470
+ const result = await runLinkPass(ctx, projectId, errors)
471
+ return { project_id: projectId, ...result, errors }
472
+ }
473
+
474
+ throw new Error(`Unknown action: ${action}. Valid: extract, link, run, status`)
475
+ })
476
+
477
+
478
+
479
+
480
+
481
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_config_handler_1784235266"]
482
+ // CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_config_runlinkpass_1784235266" type="function" identity="runlinkpass" parent="none"]
483
+ // CIL[DOC-MACRO purpose="Implements runlinkpass logic in cortex.functions.custom_cil-config"]
484
+ // CIL[DOC-RESPONSIBILITY responsibility="Execute runlinkpass and return its computed result"]
485
+ // CIL[DOC-CONTEXT module="cortex.functions.custom_cil-config" layer="function" related_files="[]"]
486
+ // CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
487
+ // CIL[DOC-MICRO logic_summary="Provides runlinkpass with runLinkPass( inputs, handling internal flow and returning a result" notable_decisions="[]"]
488
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
489
+ // CIL[DOC-STABILITY stability="stable"]
490
+ // CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
491
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
492
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
493
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
494
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
495
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
496
+ async function runLinkPass(
497
+ ctx: any,
498
+ projectId: string,
499
+ errors: string[]
500
+ ): Promise<{ configures_links_created: number }> {
501
+ const configuresTypeId = await resolveLinkTypeId('cil_configures').catch(() => null)
502
+ if (!configuresTypeId) return { configures_links_created: 0 }
503
+
504
+
505
+ const [{ data: configItems }, { data: chunkItems }] = await Promise.all([
506
+ adminDb.from('items').select('id, account_id, data')
507
+ .filter('data->>project_id', 'eq', projectId)
508
+ .filter('data->>kb_type', 'eq', 'cil_config').eq('is_active', true),
509
+ adminDb.from('items').select('id, account_id, data')
510
+ .filter('data->>project_id', 'eq', projectId)
511
+ .filter('data->>kb_type', 'eq', 'cil_chunk').eq('is_active', true),
512
+ ])
513
+
514
+ if (!configItems?.length || !chunkItems?.length) return { configures_links_created: 0 }
515
+
516
+
517
+
518
+ const configIds = configItems.map((c: any) => c.id)
519
+ const SUPABASE_IN_LIMIT = 500
520
+ const existingLinkPairs = new Set<string>()
521
+ for (let i = 0; i < configIds.length; i += SUPABASE_IN_LIMIT) {
522
+ const { data: existingLinks } = await adminDb.from('links').select('source_id, target_id')
523
+ .in('source_id', configIds.slice(i, i + SUPABASE_IN_LIMIT))
524
+ .eq('link_type_id', configuresTypeId)
525
+ for (const l of existingLinks || []) {
526
+ existingLinkPairs.add(`${l.source_id}:${l.target_id}`)
527
+ }
528
+ }
529
+
530
+
531
+ const toInsert: { data: Record<string, any>; accountId: string }[] = []
532
+
533
+ for (const configItem of configItems) {
534
+ const fieldName: string = configItem.data?.field_name || ''
535
+ if (!fieldName || fieldName.length < 2) continue
536
+
537
+ const shortName = fieldName.split('.').pop()!
538
+ const isEnv = configItem.data?.source_type === 'env'
539
+ const searchPattern = isEnv
540
+ ? new RegExp(`process\\.env\\.${fieldName}\\b`)
541
+ : new RegExp(`\\b${shortName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`)
542
+
543
+ for (const chunk of chunkItems) {
544
+ const code: string = chunk.data?.code_content || ''
545
+ if (!code) continue
546
+ if (!searchPattern.test(code)) continue
547
+
548
+ const pairKey = `${configItem.id}:${chunk.id}`
549
+ if (existingLinkPairs.has(pairKey)) continue
550
+
551
+ existingLinkPairs.add(pairKey)
552
+ toInsert.push({
553
+ data: {
554
+ source_id: configItem.id,
555
+ source_type: configItem.data?.kb_type,
556
+ target_id: chunk.id,
557
+ target_type: chunk.data?.kb_type,
558
+ link_type_id: configuresTypeId,
559
+ metadata: { field_name: fieldName, matched_in_chunk: chunk.data?.chunk_name || '' },
560
+ },
561
+ accountId: configItem.account_id,
562
+ })
563
+ }
564
+ }
565
+
566
+
567
+ let linksCreated = 0
568
+ const linkPromises = toInsert.map(({ data }) =>
569
+ adminCreate(ctx, { entity: 'links', type_slug: 'link', ...data }).then(() => {
570
+ linksCreated++
571
+ }).catch((e: any) => {
572
+ errors.push(`config-link insert: ${e.message || e}`)
573
+ })
574
+ )
575
+ await Promise.all(linkPromises)
576
+
577
+ return { configures_links_created: linksCreated }
578
+ }
579
+
580
+
581
+
582
+
583
+ // CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_config_runlinkpass_1784235266"]