spine-framework 0.4.4 → 0.5.0-rc.4

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 (283) hide show
  1. package/.env.example +13 -3
  2. package/.framework/cli/commands/bootstrap.ts +392 -0
  3. package/.framework/cli/commands/dev.ts +91 -218
  4. package/.framework/cli/commands/doctor.ts +132 -26
  5. package/.framework/cli/commands/generate.ts +38 -298
  6. package/.framework/cli/commands/init.ts +20 -1
  7. package/.framework/cli/commands/migrate.ts +36 -30
  8. package/.framework/cli/commands/migrations.ts +16 -56
  9. package/.framework/cli/commands/upgrade.ts +35 -0
  10. package/.framework/cli/commands/validate-schema.ts +147 -0
  11. package/.framework/cli/context.ts +223 -110
  12. package/.framework/cli/index.ts +6 -0
  13. package/.framework/cli/lib/project-files.ts +241 -1
  14. package/.framework/functions/_shared/hash-api-key.ts +183 -79
  15. package/.framework/functions/_shared/logging.ts +562 -224
  16. package/.framework/functions/_shared/middleware.ts +47 -44
  17. package/.framework/functions/admin-data.ts +39 -28
  18. package/.framework/functions/ai-agents.ts +10 -6
  19. package/.framework/functions/api-keys.ts +301 -122
  20. package/.framework/functions/apps.ts +43 -26
  21. package/.framework/functions/cil-ingest.ts +48 -15
  22. package/.framework/functions/debug-auth.ts +14 -8
  23. package/.framework/functions/deliveries.ts +39 -12
  24. package/.framework/functions/embeddings.ts +145 -76
  25. package/.framework/functions/integration-outbound.ts +67 -27
  26. package/.framework/functions/integrations.ts +254 -127
  27. package/.framework/functions/logs.ts +273 -133
  28. package/.framework/functions/observability.ts +277 -147
  29. package/.framework/functions/pipeline-executions.ts +1 -1
  30. package/.framework/functions/pipelines.ts +14 -9
  31. package/.framework/functions/prompt-configs.ts +7 -4
  32. package/.framework/functions/roles.ts +8 -5
  33. package/.framework/functions/security.ts +30 -17
  34. package/.framework/functions/system-cron.ts +240 -127
  35. package/.framework/functions/tests.ts +7 -6
  36. package/.framework/functions/timers.ts +310 -107
  37. package/.framework/functions/triggers.ts +28 -13
  38. package/.framework/functions/types.ts +13 -10
  39. package/.framework/migrations/069_log_stats_window.sql +54 -0
  40. package/.framework/migrations/070_app_type_schema_rpcs.sql +166 -0
  41. package/.framework/migrations/071_timer_interval_keys.sql +96 -0
  42. package/.framework/migrations/072_slug_autofill.sql +77 -0
  43. package/.framework/migrations/073_seed_member_roles.sql +26 -0
  44. package/.framework/src/apps/admin/index.tsx +1141 -775
  45. package/.framework/src/components/ErrorBoundary.tsx +136 -0
  46. package/.framework/src/components/admin/AdminListPage.tsx +81 -73
  47. package/.framework/src/components/admin/AdminSidebar.tsx +88 -79
  48. package/.framework/src/components/admin/EntitySelect.tsx +181 -0
  49. package/.framework/src/components/admin/PageInstructions.tsx +86 -127
  50. package/.framework/src/components/app-shell/GenericDetailPage.tsx +37 -13
  51. package/.framework/src/components/app-shell/GenericListPage.tsx +28 -32
  52. package/.framework/src/components/layout/Sidebar.tsx +300 -177
  53. package/.framework/src/components/runtime/DataDetailPage.tsx +67 -35
  54. package/.framework/src/components/runtime/DataHeader.tsx +96 -48
  55. package/.framework/src/components/runtime/DataListPage.tsx +3 -26
  56. package/.framework/src/components/runtime/DataStats.tsx +10 -10
  57. package/.framework/src/components/runtime/DataTable.tsx +12 -10
  58. package/.framework/src/components/ui/sheet.tsx +24 -26
  59. package/.framework/src/components/ui/textarea.tsx +74 -48
  60. package/.framework/src/hooks/useEntityList.ts +12 -9
  61. package/.framework/src/hooks/useListSchema.ts +108 -58
  62. package/.framework/src/instructions/README.md +57 -0
  63. package/.framework/src/instructions/ai-agents.md +69 -0
  64. package/.framework/src/instructions/alerts.md +80 -0
  65. package/.framework/src/instructions/api-keys.md +87 -0
  66. package/.framework/src/instructions/apps.md +77 -0
  67. package/.framework/src/instructions/concepts/ai-and-prompts.md +150 -0
  68. package/.framework/src/instructions/concepts/apps-and-renderers.md +162 -0
  69. package/.framework/src/instructions/concepts/auth-and-api-keys.md +133 -0
  70. package/.framework/src/instructions/concepts/automation.md +186 -0
  71. package/.framework/src/instructions/concepts/concurrency-and-idempotency.md +125 -0
  72. package/.framework/src/instructions/concepts/core-vs-custom.md +124 -0
  73. package/.framework/src/instructions/concepts/design-schema.md +152 -0
  74. package/.framework/src/instructions/concepts/integrations-and-webhooks.md +127 -0
  75. package/.framework/src/instructions/concepts/observability.md +116 -0
  76. package/.framework/src/instructions/concepts/permissions.md +150 -0
  77. package/.framework/src/instructions/concepts/runtime-records.md +111 -0
  78. package/.framework/src/instructions/concepts/scope-and-accounts.md +112 -0
  79. package/.framework/src/instructions/concepts/spine-way.md +172 -0
  80. package/.framework/src/instructions/deliveries.md +59 -0
  81. package/.framework/src/instructions/guide/00-orientation.md +106 -0
  82. package/.framework/src/instructions/guide/01-install-and-first-run.md +253 -0
  83. package/.framework/src/instructions/guide/02-project-map.md +147 -0
  84. package/.framework/src/instructions/guide/03-domain-model.md +223 -0
  85. package/.framework/src/instructions/guide/04-first-app.md +227 -0
  86. package/.framework/src/instructions/guide/05-glossary.md +183 -0
  87. package/.framework/src/instructions/integrations.md +96 -0
  88. package/.framework/src/instructions/internal/cil-markers.md +83 -0
  89. package/.framework/src/instructions/invites.md +60 -0
  90. package/.framework/src/instructions/kb.md +80 -0
  91. package/.framework/src/instructions/logs.md +77 -0
  92. package/.framework/src/instructions/observability.md +61 -0
  93. package/.framework/src/instructions/operations/deployment.md +115 -0
  94. package/.framework/src/instructions/operations/migrations.md +125 -0
  95. package/.framework/src/instructions/operations/security-checklist.md +148 -0
  96. package/.framework/src/instructions/operations/troubleshooting.md +170 -0
  97. package/.framework/src/instructions/operations/upgrade.md +116 -0
  98. package/.framework/src/instructions/pipeline-executions.md +62 -0
  99. package/.framework/src/instructions/pipelines.md +78 -0
  100. package/.framework/src/instructions/prompts.md +95 -0
  101. package/.framework/src/instructions/reference/api/admin-data.md +162 -0
  102. package/.framework/src/instructions/reference/api/auth.md +113 -0
  103. package/.framework/src/instructions/reference/api/errors-and-envelopes.md +113 -0
  104. package/.framework/src/instructions/reference/app-manifest.md +150 -0
  105. package/.framework/src/instructions/reference/cli.md +124 -0
  106. package/.framework/src/instructions/reference/database.md +132 -0
  107. package/.framework/src/instructions/reference/design-schema.md +280 -0
  108. package/.framework/src/instructions/reference/env-vars.md +133 -0
  109. package/.framework/src/instructions/reference/functions/account-nodes.md +75 -0
  110. package/.framework/src/instructions/reference/functions/admin-data.md +195 -0
  111. package/.framework/src/instructions/reference/functions/admin-funnel.md +90 -0
  112. package/.framework/src/instructions/reference/functions/admin-install-funnel.md +107 -0
  113. package/.framework/src/instructions/reference/functions/admin-signals.md +102 -0
  114. package/.framework/src/instructions/reference/functions/ai-agents.md +148 -0
  115. package/.framework/src/instructions/reference/functions/ai-interactions.md +156 -0
  116. package/.framework/src/instructions/reference/functions/api-keys.md +130 -0
  117. package/.framework/src/instructions/reference/functions/apps.md +140 -0
  118. package/.framework/src/instructions/reference/functions/auth.md +99 -0
  119. package/.framework/src/instructions/reference/functions/debug-auth.md +91 -0
  120. package/.framework/src/instructions/reference/functions/deliveries.md +110 -0
  121. package/.framework/src/instructions/reference/functions/embeddings.md +166 -0
  122. package/.framework/src/instructions/reference/functions/eval-harness.md +149 -0
  123. package/.framework/src/instructions/reference/functions/index.md +103 -0
  124. package/.framework/src/instructions/reference/functions/integration-outbound.md +200 -0
  125. package/.framework/src/instructions/reference/functions/integration-routes.md +151 -0
  126. package/.framework/src/instructions/reference/functions/integrations.md +130 -0
  127. package/.framework/src/instructions/reference/functions/invites.md +182 -0
  128. package/.framework/src/instructions/reference/functions/item-progress.md +107 -0
  129. package/.framework/src/instructions/reference/functions/kb.md +166 -0
  130. package/.framework/src/instructions/reference/functions/logs.md +141 -0
  131. package/.framework/src/instructions/reference/functions/observability.md +105 -0
  132. package/.framework/src/instructions/reference/functions/pipeline-executions.md +132 -0
  133. package/.framework/src/instructions/reference/functions/pipeline-runner-background.md +121 -0
  134. package/.framework/src/instructions/reference/functions/pipelines.md +136 -0
  135. package/.framework/src/instructions/reference/functions/prompt-configs.md +121 -0
  136. package/.framework/src/instructions/reference/functions/roles.md +121 -0
  137. package/.framework/src/instructions/reference/functions/security.md +140 -0
  138. package/.framework/src/instructions/reference/functions/system-cron.md +136 -0
  139. package/.framework/src/instructions/reference/functions/system.md +106 -0
  140. package/.framework/src/instructions/reference/functions/tests.md +97 -0
  141. package/.framework/src/instructions/reference/functions/timers.md +117 -0
  142. package/.framework/src/instructions/reference/functions/trigger-scheduler.md +102 -0
  143. package/.framework/src/instructions/reference/functions/triggers.md +140 -0
  144. package/.framework/src/instructions/reference/functions/types.md +146 -0
  145. package/.framework/src/instructions/reference/seeds.md +126 -0
  146. package/.framework/src/instructions/reference/shared-modules.md +127 -0
  147. package/.framework/src/instructions/reference/spine-config.md +114 -0
  148. package/.framework/src/instructions/roles.md +80 -0
  149. package/.framework/src/instructions/runtime-detail.md +70 -0
  150. package/.framework/src/instructions/runtime-list.md +77 -0
  151. package/.framework/src/instructions/security.md +67 -0
  152. package/.framework/src/instructions/tasks/add-a-pipeline.md +110 -0
  153. package/.framework/src/instructions/tasks/add-a-role.md +96 -0
  154. package/.framework/src/instructions/tasks/add-a-timer.md +114 -0
  155. package/.framework/src/instructions/tasks/add-a-trigger.md +106 -0
  156. package/.framework/src/instructions/tasks/add-a-type.md +151 -0
  157. package/.framework/src/instructions/tasks/add-a-webhook.md +108 -0
  158. package/.framework/src/instructions/tasks/add-an-ai-agent.md +108 -0
  159. package/.framework/src/instructions/tasks/add-an-integration.md +124 -0
  160. package/.framework/src/instructions/tasks/build-a-custom-page.md +118 -0
  161. package/.framework/src/instructions/tasks/package-and-install-an-app.md +127 -0
  162. package/.framework/src/instructions/tasks/test-your-code.md +108 -0
  163. package/.framework/src/instructions/tasks/write-a-function.md +132 -0
  164. package/.framework/src/instructions/tasks/write-a-migration.md +110 -0
  165. package/.framework/src/instructions/testing.md +59 -0
  166. package/.framework/src/instructions/timers.md +82 -0
  167. package/.framework/src/instructions/triggers.md +69 -0
  168. package/.framework/src/instructions/types.md +93 -0
  169. package/.framework/src/pages/NotFoundPage.tsx +62 -31
  170. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +117 -106
  171. package/.framework/src/pages/admin/AIAgentsPage.tsx +86 -48
  172. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +153 -152
  173. package/.framework/src/pages/admin/APIKeysPage.tsx +91 -90
  174. package/.framework/src/pages/admin/AlertsConfigPage.tsx +29 -18
  175. package/.framework/src/pages/admin/AppDetailPage.tsx +6 -60
  176. package/.framework/src/pages/admin/AppsPage.tsx +104 -66
  177. package/.framework/src/pages/admin/DeliveriesPage.tsx +5 -5
  178. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +5 -23
  179. package/.framework/src/pages/admin/EmbeddingsPage.tsx +5 -26
  180. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +7 -7
  181. package/.framework/src/pages/admin/IntegrationsPage.tsx +85 -43
  182. package/.framework/src/pages/admin/LogsPage.tsx +144 -76
  183. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +223 -140
  184. package/.framework/src/pages/admin/PipelineDetailPage.tsx +134 -113
  185. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +108 -45
  186. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -115
  187. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +96 -98
  188. package/.framework/src/pages/admin/PromptConfigsPage.tsx +101 -59
  189. package/.framework/src/pages/admin/RoleDetailPage.tsx +90 -79
  190. package/.framework/src/pages/admin/RolesPage.tsx +86 -43
  191. package/.framework/src/pages/admin/SecurityPage.tsx +1 -1
  192. package/.framework/src/pages/admin/TestingDashboard.tsx +16 -28
  193. package/.framework/src/pages/admin/TimerDetailPage.tsx +117 -100
  194. package/.framework/src/pages/admin/TimersPage.tsx +90 -62
  195. package/.framework/src/pages/admin/TriggerDetailPage.tsx +90 -83
  196. package/.framework/src/pages/admin/TriggersPage.tsx +124 -99
  197. package/.framework/src/pages/admin/TypeDetailPage.tsx +152 -138
  198. package/.framework/src/pages/admin/TypesPage.tsx +90 -48
  199. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +17 -25
  200. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +17 -27
  201. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +72 -40
  202. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +321 -129
  203. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +18 -29
  204. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +26 -38
  205. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +34 -46
  206. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +189 -103
  207. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +246 -136
  208. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +11 -22
  209. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +9 -20
  210. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +26 -38
  211. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +7 -26
  212. package/.framework/templates/agent/AGENTS.md +150 -0
  213. package/.framework/templates/agent/skills/spine-add-ai-agent/SKILL.md +58 -0
  214. package/.framework/templates/agent/skills/spine-add-automation/SKILL.md +62 -0
  215. package/.framework/templates/agent/skills/spine-add-integration/SKILL.md +63 -0
  216. package/.framework/templates/agent/skills/spine-architect/SKILL.md +86 -0
  217. package/.framework/templates/agent/skills/spine-install-app/SKILL.md +72 -0
  218. package/.framework/templates/agent/skills/spine-migration/SKILL.md +75 -0
  219. package/.framework/templates/agent/skills/spine-new-app/SKILL.md +67 -0
  220. package/.framework/templates/agent/skills/spine-new-function/SKILL.md +65 -0
  221. package/.framework/templates/agent/skills/spine-new-type/SKILL.md +65 -0
  222. package/.framework/templates/agent/skills/spine-schema/SKILL.md +77 -0
  223. package/.framework/templates/agent/skills/spine-test/SKILL.md +67 -0
  224. package/.framework/templates/agent/skills/spine-troubleshoot/SKILL.md +74 -0
  225. package/.framework/templates/agent/skills/spine-upgrade/SKILL.md +69 -0
  226. package/.framework/templates/project.json +4 -1
  227. package/.framework/tests/unit/account-scoping-gates.test.ts +392 -0
  228. package/.framework/tests/unit/agent-files.test.ts +355 -0
  229. package/.framework/tests/unit/agent-runner.test.ts +479 -44
  230. package/.framework/tests/unit/api-keys-create-scope-gate.test.ts +160 -0
  231. package/.framework/tests/unit/api-keys-omit-secret-fields.test.ts +38 -0
  232. package/.framework/tests/unit/bootstrap.test.ts +242 -0
  233. package/.framework/tests/unit/cli-context-api-key.test.ts +114 -0
  234. package/.framework/tests/unit/debug-auth.test.ts +38 -0
  235. package/.framework/tests/unit/deliveries-account-scoping.test.ts +185 -0
  236. package/.framework/tests/unit/integration-outbound-credentials.test.ts +167 -0
  237. package/.framework/tests/unit/integrations-audit-redaction.test.ts +130 -0
  238. package/.framework/tests/unit/logging-app-id.test.ts +75 -0
  239. package/.framework/tests/unit/system-context-denial.test.ts +145 -0
  240. package/.framework/tests/unit/system-cron.test.ts +240 -0
  241. package/.framework/tests/unit/timers.test.ts +159 -0
  242. package/README.md +125 -166
  243. package/config/tsconfig.cli.json +2 -2
  244. package/package.json +15 -4
  245. package/templates/project/package-lock.json +2 -2
  246. package/.framework/docs/admin-routes.md +0 -76
  247. package/.framework/docs/api-docs-progress.md +0 -38
  248. package/.framework/docs/api-governance.md +0 -146
  249. package/.framework/docs/api-testing-results.md +0 -212
  250. package/.framework/docs/assembly-launch-guide.md +0 -138
  251. package/.framework/docs/audit-results.md +0 -590
  252. package/.framework/docs/db-api-inventory.md +0 -95
  253. package/.framework/docs/gap-remediation-backlog.md +0 -103
  254. package/.framework/docs/ui-adoption-verification.md +0 -111
  255. package/.framework/docs/ui-api-coverage.md +0 -84
  256. package/.framework/docs/v2-compatibility-audit.md +0 -228
  257. package/.framework/mcp/index.ts +0 -133
  258. package/.framework/mcp/load-env.ts +0 -60
  259. package/.framework/mcp/shared/app-manifest.ts +0 -275
  260. package/.framework/mcp/shared/db.ts +0 -477
  261. package/.framework/mcp/shared/kb.ts +0 -118
  262. package/.framework/mcp/tools/architect.ts +0 -431
  263. package/.framework/mcp/tools/cil/context.ts +0 -345
  264. package/.framework/mcp/tools/cil/graph.ts +0 -242
  265. package/.framework/mcp/tools/cil/ingest.ts +0 -1217
  266. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +0 -693
  267. package/.framework/mcp/tools/cil/pipeline.ts +0 -767
  268. package/.framework/mcp/tools/cil/project.ts +0 -791
  269. package/.framework/mcp/tools/cil/retrieval.ts +0 -336
  270. package/.framework/mcp/tools/cil/search-core.ts +0 -454
  271. package/.framework/mcp/tools/cil/search.ts +0 -97
  272. package/.framework/mcp/tools/cil/suggest.ts +0 -186
  273. package/.framework/mcp/tools/cil/validate.ts +0 -1369
  274. package/.framework/mcp/tools/kb/delete.ts +0 -139
  275. package/.framework/mcp/tools/kb/index.ts +0 -52
  276. package/.framework/mcp/tools/kb/ingest.ts +0 -84
  277. package/.framework/mcp/tools/kb/list-types.ts +0 -102
  278. package/.framework/mcp/tools/kb/publish.ts +0 -100
  279. package/.framework/mcp/tools/kb/reindex.ts +0 -86
  280. package/.framework/mcp/tools/kb/revoke.ts +0 -85
  281. package/.framework/mcp/tools/kb/search.ts +0 -101
  282. package/.framework/mcp/tools/kb/upsert.ts +0 -125
  283. package/.framework/mcp/tools/observability.ts +0 -510
@@ -1,454 +0,0 @@
1
- /**
2
- * @module search-core
3
- * @audience both
4
- * @layer shared-core
5
- * @stability stable
6
- *
7
- * This module provides core search functionalities for the application, leveraging the admin database for data retrieval and manipulation. It serves as a critical component in the overall architecture, facilitating efficient search operations across various datasets. INVARIANT: The module assumes that the database is always accessible and properly configured for search queries.
8
- *
9
- * @seeAlso db.js (provides the database connection and operations needed for search functionality.)
10
- * @seeAlso shared.js (contains shared utilities that may be used across different modules.)
11
- *
12
- * @cil-generated
13
- */
14
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/mcp/tools/cil/search-core.ts"]
15
- // CIL[DOC-MACRO purpose="Provides core search operations over the CIL chunk index"]
16
- // CIL[DOC-RESPONSIBILITY responsibility="Expose title, content, semantic and hybrid search utilities for CIL chunks"]
17
- // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts"]
18
- // CIL[DOC-CONTRACT inputs="N/A" outputs="N/A" errors="Database and network failures propagate to caller" side_effects="N/A"]
19
- // CIL[DOC-MICRO logic_summary="Imports adminDb and exports normalizeIdentifier, buildSearchResult, titleSearch, contentSearch, embedQuery, semanticSearch and hybridSearch" notable_decisions="[]"]
20
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
21
- // CIL[DOC-STABILITY stability="stable"]
22
- // CIL[DOC-AUDIENCE audience="both"]
23
- import { adminDb } from '../../shared/db.js'
24
- // CIL[DOC-VECTOR type="context" content="purpose='Provides core search operations over the CIL chunk index'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
25
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
26
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
27
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
28
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
29
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
30
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:module_header:module_header"]
31
-
32
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:normalizeIdentifier:function" type="function" identity="normalizeIdentifier" parent="~/.framework/mcp/tools/cil/search-core.ts"]
33
- // CIL[DOC-MACRO purpose="Normalize a string identifier to lowercase alphanumeric"]
34
- // CIL[DOC-RESPONSIBILITY responsibility="Sanitize raw strings for consistent identifier comparison"]
35
- // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
36
- // CIL[DOC-CONTRACT inputs="s: string" outputs="string" errors="N/A" side_effects="none"]
37
- // CIL[DOC-MICRO logic_summary="Converts input to lowercase and removes all non-alphanumeric characters" notable_decisions="[]"]
38
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
39
- // CIL[DOC-STABILITY stability="internal"]
40
- /**
41
- * Normalizes a string identifier by converting it to lowercase and removing all non-alphanumeric characters. This function ensures that identifiers are consistent and suitable for further processing.
42
- *
43
- * @inputSpec
44
- * s: string (required) — the string identifier to normalize.
45
- * @outputSpec string — the normalized identifier consisting only of lowercase alphanumeric characters.
46
- * @sideEffects none
47
- * @stability internal
48
- * @cil-generated
49
- */
50
- export const normalizeIdentifier = (s: string) =>
51
- s.toLowerCase().replace(/[^a-z0-9]/g, '')
52
- // CIL[DOC-VECTOR type="context" content="purpose='Normalize a string identifier to lowercase alphanumeric'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
53
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
54
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
55
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
56
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
57
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
58
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:normalizeIdentifier:function"]
59
-
60
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:SearchResult:interface" type="interface" identity="SearchResult" parent="~/.framework/mcp/tools/cil/search-core.ts"]
61
- // CIL[DOC-MACRO purpose="Defines the typed shape of a CIL search result"]
62
- // CIL[DOC-RESPONSIBILITY responsibility="Standardize chunk metadata, scoring and content fields returned by search APIs"]
63
- // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
64
- // CIL[DOC-CONTRACT inputs="N/A" outputs="N/A" errors="N/A" side_effects="N/A"]
65
- // CIL[DOC-MICRO logic_summary="Declares fields including stable_id, macro, micro, code_content, match_type and similarity" notable_decisions="[]"]
66
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
67
- // CIL[DOC-STABILITY stability="internal"]
68
- /**
69
- * The SearchResult interface defines the structure of a search result object, encapsulating various attributes related to search outcomes. It exists to standardize the representation of search results across the application.
70
- *
71
- * @sideEffects none
72
- * @stability internal
73
- * @cil-generated
74
- */
75
- export interface SearchResult {
76
- id: string
77
- stable_id: string
78
- version_id: string | null
79
- chunk_name: string
80
- file_path: string
81
- chunk_type: string
82
- source_set_id: string | null
83
- layer: string | null
84
- macro: string
85
- micro: string
86
- input_spec: string
87
- output_spec: string
88
- side_effects: string
89
- stability: string
90
- tags: string
91
- complexity: string
92
- doc_confidence: string
93
- validation_errors: string[]
94
- code_content: string
95
- similarity: number | null
96
- match_type: 'content' | 'semantic' | 'text'
97
- }
98
- // CIL[DOC-VECTOR type="context" content="purpose='Defines the typed shape of a CIL search result'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
99
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
100
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
101
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
102
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
103
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
104
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:SearchResult:interface"]
105
-
106
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:buildSearchResult:function" type="function" identity="buildSearchResult" parent="~/.framework/mcp/tools/cil/search-core.ts"]
107
- // CIL[DOC-MACRO purpose="Construct a SearchResult object from a raw chunk row"]
108
- // CIL[DOC-RESPONSIBILITY responsibility="Map database chunk fields into a typed search result with sensible defaults"]
109
- // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
110
- // CIL[DOC-CONTRACT inputs="chunk: any, match_type: SearchResult['match_type'], similarity: number | null (optional)" outputs="SearchResult" errors="N/A" side_effects="none"]
111
- // CIL[DOC-MICRO logic_summary="Extracts chunk.data, applies defaults for missing metadata, and assembles the SearchResult" notable_decisions="[]"]
112
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
113
- // CIL[DOC-STABILITY stability="internal"]
114
- /**
115
- * Builds a structured search result object from a given chunk of data, encapsulating various attributes for search functionality. This function is essential for transforming raw data into a standardized format for search results.
116
- *
117
- * @macro Function that constructs a search result object from a data chunk.
118
- * @micro Extracts properties from the chunk and assigns default values where necessary.
119
- * @inputSpec
120
- * - chunk: any (required) — the data chunk containing search-related information.
121
- * - match_type: SearchResult['match_type'] (required) — the type of match for the search result.
122
- * - similarity: number | null (optional[nullable]) — a similarity score associated with the search result.
123
- * @outputSpec SearchResult — an object containing structured search result data.
124
- * @sideEffects none
125
- * @stability internal
126
- * @cil-generated
127
- */
128
- export function buildSearchResult(
129
- chunk: any,
130
- match_type: SearchResult['match_type'],
131
- similarity: number | null = null,
132
- ): SearchResult {
133
- const d = chunk.data || {}
134
- return {
135
- id: chunk.id,
136
- stable_id: d.stable_id || '',
137
- version_id: d.version_id || null,
138
- chunk_name: d.chunk_name || '',
139
- file_path: d.file_path || '',
140
- chunk_type: d.chunk_type || '',
141
- source_set_id: d.source_set_id || null,
142
- layer: d.layer || null,
143
- macro: d.macro || '',
144
- micro: d.micro || '',
145
- input_spec: d.input_spec || '',
146
- output_spec: d.output_spec || '',
147
- side_effects: d.side_effects || '',
148
- stability: d.stability || 'unknown',
149
- tags: d.tags || '',
150
- complexity: d.complexity || '',
151
- doc_confidence: d.doc_confidence || 'unverified_legacy',
152
- validation_errors: d.doc_validation_errors || [],
153
- code_content: d.code_content || '',
154
- similarity,
155
- match_type,
156
- }
157
- }
158
- // CIL[DOC-VECTOR type="context" content="purpose='Construct a SearchResult object from a raw chunk row'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
159
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
160
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
161
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
162
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
163
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
164
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:buildSearchResult:function"]
165
-
166
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:titleSearch:function" type="function" identity="titleSearch" parent="~/.framework/mcp/tools/cil/search-core.ts"]
167
- // CIL[DOC-MACRO purpose="Case-insensitive title substring search over CIL chunks"]
168
- // CIL[DOC-RESPONSIBILITY responsibility="Return chunks whose title contains the query"]
169
- // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
170
- // CIL[DOC-CONTRACT inputs="q: string, project_id?: string, limit?: number" outputs="Promise<SearchResult[]>" errors="Database errors propagate" side_effects="Queries the items table"]
171
- // CIL[DOC-MICRO logic_summary="Builds a Supabase query for active cil_chunks, optionally filters by project_id and maps rows to SearchResult" notable_decisions="[]"]
172
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
173
- // CIL[DOC-STABILITY stability="internal"]
174
- export async function titleSearch({
175
- q,
176
- project_id,
177
- limit = 10,
178
- }: {
179
- q: string
180
- project_id?: string
181
- limit?: number
182
- }): Promise<SearchResult[]> {
183
- let qb = adminDb
184
- .from('items')
185
- .select('id, title, data')
186
- .filter('data->>kb_type', 'eq', 'cil_chunk')
187
- .eq('is_active', true)
188
- .ilike('title', `%${q}%`)
189
- .limit(limit)
190
- if (project_id) qb = (qb as any).filter('data->>project_id', 'eq', project_id)
191
-
192
- const { data } = await qb
193
- return (data || []).map((c: any) => buildSearchResult(c, 'text', null))
194
- }
195
- // CIL[DOC-VECTOR type="context" content="purpose='Case-insensitive title substring search over CIL chunks'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
196
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
197
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
198
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
199
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
200
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
201
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:titleSearch:function"]
202
-
203
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:contentSearch:function" type="function" identity="contentSearch" parent="~/.framework/mcp/tools/cil/search-core.ts"]
204
- // CIL[DOC-MACRO purpose="Score CIL chunks by keyword presence across metadata and code"]
205
- // CIL[DOC-RESPONSIBILITY responsibility="Find the most relevant chunks for a free-text query using term scoring"]
206
- // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
207
- // CIL[DOC-CONTRACT inputs="q: string, project_id?: string, limit?: number" outputs="Promise<SearchResult[]>" errors="N/A" side_effects="Queries the items table; may call titleSearch as fallback"]
208
- // CIL[DOC-MICRO logic_summary="Fetches active chunks, scores matches in title, macro, micro, tags and code, boosts exact phrases, returns top results or titleSearch fallback" notable_decisions="[]"]
209
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
210
- // CIL[DOC-STABILITY stability="internal"]
211
- export async function contentSearch({
212
- q,
213
- project_id,
214
- limit = 10,
215
- }: {
216
- q: string
217
- project_id?: string
218
- limit?: number
219
- }): Promise<SearchResult[]> {
220
- const pageLimit = 5000
221
- let qb = adminDb
222
- .from('items')
223
- .select('id, title, data')
224
- .filter('data->>kb_type', 'eq', 'cil_chunk')
225
- .eq('is_active', true)
226
- .order('updated_at', { ascending: false })
227
- .limit(pageLimit)
228
- if (project_id) qb = (qb as any).filter('data->>project_id', 'eq', project_id)
229
-
230
- const { data: allChunks } = await qb
231
-
232
- const terms = q.toLowerCase().split(/\s+/).filter(Boolean)
233
- const normalizedTerms = terms
234
- .map((t) => normalizeIdentifier(t))
235
- .filter((t) => t.length >= 2)
236
-
237
- if (normalizedTerms.length === 0) return titleSearch({ q, project_id, limit })
238
-
239
- const scored = (allChunks || [])
240
- .map((c: any) => {
241
- const title = (c.title || '').toLowerCase()
242
- const macro = (c.data?.macro || '').toLowerCase()
243
- const micro = (c.data?.micro || '').toLowerCase()
244
- const tags = (c.data?.tags || '').toLowerCase()
245
- const codeContent = (c.data?.code_content || '').toLowerCase()
246
-
247
- const normTitle = normalizeIdentifier(title)
248
- const normMacro = normalizeIdentifier(macro)
249
- const normMicro = normalizeIdentifier(micro)
250
- const normTags = normalizeIdentifier(tags)
251
- const normCode = normalizeIdentifier(codeContent)
252
-
253
- let score = 0
254
- for (const term of normalizedTerms) {
255
- if (normTitle.includes(term)) score += 3
256
- if (normMacro.includes(term)) score += 2
257
- if (normMicro.includes(term)) score += 1
258
- if (normTags.includes(term)) score += 1
259
- if (normCode.includes(term)) {
260
- const count = normCode.split(term).length - 1
261
- score += Math.min(count, 3)
262
- }
263
- }
264
-
265
- const phrase = q.toLowerCase()
266
- const normPhrase = normalizeIdentifier(phrase)
267
- if (codeContent.includes(phrase) || normCode.includes(normPhrase)) score += 5
268
-
269
- return { chunk: c, score }
270
- })
271
- .filter(({ score }) => score > 0)
272
- .sort((a, b) => b.score - a.score)
273
- .slice(0, limit)
274
-
275
- if (scored.length === 0) return titleSearch({ q, project_id, limit })
276
-
277
- const maxScore = scored[0].score || 1
278
- return scored.map(({ chunk, score }) =>
279
- buildSearchResult(chunk, 'content', score / maxScore),
280
- )
281
- }
282
- // CIL[DOC-VECTOR type="context" content="purpose='Score CIL chunks by keyword presence across metadata and code'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
283
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
284
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
285
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
286
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
287
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
288
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:contentSearch:function"]
289
-
290
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:embedQuery:function" type="function" identity="embedQuery" parent="~/.framework/mcp/tools/cil/search-core.ts"]
291
- // CIL[DOC-MACRO purpose="Fetch an OpenAI embedding vector for a query string"]
292
- // CIL[DOC-RESPONSIBILITY responsibility="Convert a search query into a JSON array vector string for semantic search"]
293
- // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
294
- // CIL[DOC-CONTRACT inputs="q: string" outputs="Promise<string | null>" errors="Returns null on any API or parsing failure" side_effects="POST to the OpenAI embeddings endpoint"]
295
- // CIL[DOC-MICRO logic_summary="Sends the query to the embeddings endpoint and serializes the returned vector as a JSON array string" notable_decisions="[]"]
296
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
297
- // CIL[DOC-STABILITY stability="internal"]
298
- /**
299
- * The embedQuery function sends a query string to an external API to retrieve its embedding vector. It exists to facilitate the integration of OpenAI's embedding capabilities into the application.
300
- *
301
- * @macro Async function that retrieves text embeddings from an external API.
302
- * @micro Constructs a POST request to the embeddings endpoint with the query string as input.
303
- * @inputSpec
304
- * - q: string (required) — the query string to be embedded.
305
- * @outputSpec Promise<string | null> — returns the embedding vector as a string in JSON array format or null if an error occurs.
306
- * @sideEffects makes an external API call to OpenAI's embeddings endpoint
307
- * @stability internal
308
- * @calls fetch
309
- * @errorHandling returns null on any error during the API call or response processing
310
- * @cil-generated
311
- */
312
- async function embedQuery(q: string): Promise<string | null> {
313
- const apiKey = process.env.OPENAI_API_KEY || process.env.LLM_API_KEY
314
- const baseUrl = process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1'
315
- if (!apiKey) return null
316
- try {
317
- const res = await fetch(`${baseUrl}/embeddings`, {
318
- method: 'POST',
319
- headers: {
320
- 'Content-Type': 'application/json',
321
- Authorization: `Bearer ${apiKey}`,
322
- },
323
- body: JSON.stringify({ model: 'text-embedding-3-small', input: [q] }),
324
- })
325
- if (!res.ok) return null
326
- const j: any = await res.json()
327
- const vec = j.data?.[0]?.embedding
328
- if (!Array.isArray(vec)) return null
329
- return `[${vec.join(',')}]`
330
- } catch {
331
- return null
332
- }
333
- }
334
- // CIL[DOC-VECTOR type="context" content="purpose='Fetch an OpenAI embedding vector for a query string'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
335
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
336
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
337
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
338
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
339
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
340
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:embedQuery:function"]
341
-
342
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:semanticSearch:function" type="function" identity="semanticSearch" parent="~/.framework/mcp/tools/cil/search-core.ts"]
343
- // CIL[DOC-MACRO purpose="Semantic search over CIL chunks using vector similarity"]
344
- // CIL[DOC-RESPONSIBILITY responsibility="Return chunks semantically similar to the query using the match_embeddings RPC"]
345
- // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
346
- // CIL[DOC-CONTRACT inputs="q: string, project_id?: string, limit?: number" outputs="Promise<SearchResult[]>" errors="Returns empty array on RPC failure or missing data" side_effects="Calls embedQuery and adminDb RPC"]
347
- // CIL[DOC-MICRO logic_summary="Embeds the query, calls match_embeddings, fetches chunk records by id and maps results" notable_decisions="[]"]
348
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
349
- // CIL[DOC-STABILITY stability="internal"]
350
- export async function semanticSearch({
351
- q,
352
- project_id,
353
- limit = 10,
354
- }: {
355
- q: string
356
- project_id?: string
357
- limit?: number
358
- }): Promise<SearchResult[]> {
359
- const vector = await embedQuery(q)
360
- if (!vector) return []
361
-
362
- const matchCount = limit * 3
363
- let rpcResult: { data: any; error: any } | null = null
364
- try {
365
- rpcResult = await adminDb.rpc('match_embeddings', {
366
- query_embedding: vector,
367
- match_count: matchCount,
368
- filter_account_ids: null,
369
- filter_vector_type: null,
370
- similarity_threshold: 0.15,
371
- filter_item_types: ['cil_chunk'],
372
- })
373
- } catch (err: any) {
374
- console.error('match_embeddings rpc failed:', err?.message || String(err))
375
- return []
376
- }
377
-
378
- const { data, error } = rpcResult || { data: null, error: 'rpc call failed' }
379
- if (error || !data || !data.length) return []
380
-
381
- const docIds = data.map((d: any) => d.document_id)
382
- let chunkQb = adminDb
383
- .from('items')
384
- .select('id, title, data')
385
- .filter('data->>kb_type', 'eq', 'cil_chunk')
386
- .eq('is_active', true)
387
- .in('data->>stable_id', docIds)
388
- if (project_id)
389
- chunkQb = (chunkQb as any).filter('data->>project_id', 'eq', project_id)
390
-
391
- const { data: chunks } = await chunkQb
392
- const chunkMap = new Map((chunks || []).map((c: any) => [c.data?.stable_id, c]))
393
-
394
- return (data as any[])
395
- .map((d: any) => {
396
- const c = chunkMap.get(d.document_id)
397
- if (!c) return null
398
- return buildSearchResult(c, 'semantic', d.similarity)
399
- })
400
- .filter(Boolean)
401
- .slice(0, limit) as SearchResult[]
402
- }
403
- // CIL[DOC-VECTOR type="context" content="purpose='Semantic search over CIL chunks using vector similarity'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
404
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
405
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
406
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
407
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
408
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
409
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:semanticSearch:function"]
410
-
411
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search-core.ts:hybridSearch:function" type="function" identity="hybridSearch" parent="~/.framework/mcp/tools/cil/search-core.ts"]
412
- // CIL[DOC-MACRO purpose="Combine content and semantic search results into a single ranked list"]
413
- // CIL[DOC-RESPONSIBILITY responsibility="Merge and rank content-based and vector-based search results"]
414
- // CIL[DOC-CONTEXT module=".framework/mcp/tools/cil" layer="shared-core" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/cil/search-core.ts"]
415
- // CIL[DOC-CONTRACT inputs="q: string, project_id?: string, limit?: number" outputs="Promise<SearchResult[]>" errors="N/A" side_effects="Calls contentSearch and semanticSearch"]
416
- // CIL[DOC-MICRO logic_summary="Runs both search strategies in parallel, merges results by id, sorts by similarity and slices to limit" notable_decisions="[]"]
417
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
418
- // CIL[DOC-STABILITY stability="internal"]
419
- export async function hybridSearch({
420
- q,
421
- project_id,
422
- limit = 10,
423
- }: {
424
- q: string
425
- project_id?: string
426
- limit?: number
427
- }): Promise<SearchResult[]> {
428
- const [content, semantic] = await Promise.all([
429
- contentSearch({ q, project_id, limit }),
430
- semanticSearch({ q, project_id, limit }),
431
- ])
432
-
433
- const byId = new Map<string, SearchResult>()
434
- for (const r of content) {
435
- byId.set(r.id, r)
436
- }
437
- for (const r of semantic) {
438
- const existing = byId.get(r.id)
439
- if (!existing || (r.similarity ?? 0) > (existing.similarity ?? 0)) {
440
- byId.set(r.id, r)
441
- }
442
- }
443
-
444
- return Array.from(byId.values())
445
- .sort((a, b) => (b.similarity ?? 0) - (a.similarity ?? 0))
446
- .slice(0, limit)
447
- }
448
- // CIL[DOC-VECTOR type="context" content="purpose='Combine content and semantic search results into a single ranked list'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
449
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
450
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
451
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
452
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
453
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
454
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search-core.ts:hybridSearch:function"]
@@ -1,97 +0,0 @@
1
- /**
2
- * @module search
3
- * @audience both
4
- * @layer shared-core
5
- * @stability stable
6
- *
7
- * This module provides search functionality for the MCP framework, enabling content, semantic, and title-based searches. It acts as a bridge between the search core and the server, facilitating efficient query handling. INVARIANT: The search functions must always return results in a consistent format.
8
- *
9
- * @seeAlso search-core.js (contains the core search logic)
10
- * @seeAlso @mcp/sdk (provides the server interface)
11
- *
12
- * @cil-generated
13
- */
14
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/mcp/tools/cil/search.ts"]
15
- // CIL[DOC-MACRO purpose="Provides search functionality for the MCP framework"]
16
- // CIL[DOC-RESPONSIBILITY responsibility="Bridge the CIL search core and the MCP server by exporting the register function"]
17
- // CIL[DOC-CONTEXT module="mcp-tools-cil" layer="shared-core" related_files=".framework/mcp/tools/cil/search-core.ts"]
18
- // CIL[DOC-CONTRACT inputs="N/A" outputs="N/A" errors="N/A" side_effects="N/A"]
19
- // CIL[DOC-MICRO logic_summary="Imports McpServer, zod and the search core, then exposes a register function for the MCP tool" notable_decisions="[]"]
20
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
21
- // CIL[DOC-STABILITY stability="stable"]
22
- // CIL[DOC-AUDIENCE audience="both"]
23
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
24
- import { z } from 'zod'
25
- import { contentSearch, semanticSearch, titleSearch } from './search-core.js'
26
- // CIL[DOC-VECTOR type="context" content="purpose='Provides search functionality for the MCP framework'; No verified external callers; imports: .framework/mcp/tools/cil/search-core.ts"]
27
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
28
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
29
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
30
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
31
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
32
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search.ts:module_header:module_header"]
33
-
34
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/cil/search.ts:register:function" type="function" identity="register" parent="~/.framework/mcp/tools/cil/search.ts"]
35
- // CIL[DOC-MACRO purpose="Register the spine_cil_search_chunks MCP tool and dispatch queries"]
36
- // CIL[DOC-RESPONSIBILITY responsibility="Implement the tool handler that selects search mode and formats JSON results"]
37
- // CIL[DOC-CONTEXT module="mcp-tools-cil" layer="shared-core" related_files=".framework/mcp/tools/cil/search-core.ts,.framework/mcp/tools/cil/search.ts"]
38
- // CIL[DOC-CONTRACT inputs="server: McpServer" outputs="void" errors="Database and network failures propagate to caller" side_effects="registers tool on server and calls search functions"]
39
- // CIL[DOC-MICRO logic_summary="Use server.registerTool with a zod schema, then dispatch semantic, text or hybrid search and return JSON text" notable_decisions="Hybrid merges content and semantic by similarity; falls back to title search if empty"]
40
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
41
- // CIL[DOC-STABILITY stability="stable"]
42
- export function register(server: McpServer) {
43
-
44
- server.registerTool(
45
- 'spine_cil_search_chunks',
46
- {
47
- description: 'Search for code chunks by purpose, behaviour, or name. Uses hybrid semantic + text search over all embedded chunks. Returns chunk_name, file_path, macro (purpose), chunk_type, doc_confidence, and similarity score.',
48
- inputSchema: z.object({
49
- q: z.string().describe('Search query — describe what the chunk does, e.g. "authenticate user and check roles"'),
50
- project_id: z.string().optional().describe('Limit to a specific project UUID'),
51
- mode: z.enum(['hybrid', 'semantic', 'text']).default('hybrid').optional().describe('hybrid = semantic + content; semantic = embedding only; text = name/path substring'),
52
- limit: z.number().int().min(1).max(50).default(10).optional().describe('Max results to return'),
53
- }),
54
- },
55
- async ({ q, project_id, mode, limit }) => {
56
- let results: any[] = []
57
-
58
- if (mode === 'semantic') {
59
- results = await semanticSearch({ q, project_id, limit })
60
- if (results.length === 0) results = await contentSearch({ q, project_id, limit })
61
- } else if (mode === 'text') {
62
- results = await titleSearch({ q, project_id, limit })
63
- } else {
64
- const [content, semantic] = await Promise.all([
65
- contentSearch({ q, project_id, limit }),
66
- semanticSearch({ q, project_id, limit }),
67
- ])
68
- const byId = new Map<string, any>()
69
- for (const r of content) byId.set(r.id, r)
70
- for (const r of semantic) {
71
- const existing = byId.get(r.id)
72
- if (!existing || (r.similarity ?? 0) > (existing.similarity ?? 0)) {
73
- byId.set(r.id, r)
74
- }
75
- }
76
- results = Array.from(byId.values())
77
- .sort((a, b) => (b.similarity ?? 0) - (a.similarity ?? 0))
78
- .slice(0, limit ?? 10)
79
- if (results.length === 0) results = await titleSearch({ q, project_id, limit })
80
- }
81
-
82
- return {
83
- content: [{
84
- type: 'text',
85
- text: JSON.stringify({ query: q, mode: mode ?? 'hybrid', count: results.length, results }, null, 2),
86
- }],
87
- }
88
- }
89
- )
90
- }
91
- // CIL[DOC-VECTOR type="context" content="purpose='Register the spine_cil_search_chunks MCP tool and dispatch queries'; No verified external callers; imports: .framework/mcp/tools/cil/search-core.ts"]
92
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
93
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
94
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
95
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
96
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
97
- // CIL[END stable_id="~/.framework/mcp/tools/cil/search.ts:register:function"]