spine-framework 0.4.3 → 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 (320) 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/agent-runner.ts +1000 -81
  15. package/.framework/functions/_shared/cil.ts +2 -1
  16. package/.framework/functions/_shared/db.ts +3 -6
  17. package/.framework/functions/_shared/hash-api-key.ts +183 -79
  18. package/.framework/functions/_shared/kb.ts +61 -7
  19. package/.framework/functions/_shared/logging.ts +562 -224
  20. package/.framework/functions/_shared/message-sequence.ts +53 -0
  21. package/.framework/functions/_shared/middleware.ts +47 -44
  22. package/.framework/functions/_shared/pipeline-runner.ts +150 -37
  23. package/.framework/functions/_shared/principal.ts +9 -6
  24. package/.framework/functions/_shared/trigger-engine.ts +149 -40
  25. package/.framework/functions/admin-data.ts +48 -31
  26. package/.framework/functions/ai-agents.ts +103 -33
  27. package/.framework/functions/api-keys.ts +301 -122
  28. package/.framework/functions/apps.ts +43 -26
  29. package/.framework/functions/cil-ingest.ts +48 -15
  30. package/.framework/functions/debug-auth.ts +14 -8
  31. package/.framework/functions/deliveries.ts +39 -12
  32. package/.framework/functions/embeddings.ts +145 -76
  33. package/.framework/functions/integration-outbound.ts +67 -27
  34. package/.framework/functions/integrations.ts +254 -127
  35. package/.framework/functions/logs.ts +273 -133
  36. package/.framework/functions/observability.ts +277 -147
  37. package/.framework/functions/pipeline-executions.ts +1 -1
  38. package/.framework/functions/pipeline-runner-background.ts +120 -0
  39. package/.framework/functions/pipelines.ts +14 -9
  40. package/.framework/functions/prompt-configs.ts +7 -4
  41. package/.framework/functions/roles.ts +8 -5
  42. package/.framework/functions/security.ts +30 -17
  43. package/.framework/functions/system-cron.ts +250 -128
  44. package/.framework/functions/tests.ts +7 -6
  45. package/.framework/functions/timers.ts +310 -107
  46. package/.framework/functions/trigger-scheduler.ts +65 -5
  47. package/.framework/functions/triggers.ts +28 -13
  48. package/.framework/functions/types.ts +13 -10
  49. package/.framework/migrations/064_episode_leases.sql +196 -0
  50. package/.framework/migrations/065_execution_tables_updated_at.sql +20 -0
  51. package/.framework/migrations/066_episode_steal_thread_merge.sql +148 -0
  52. package/.framework/migrations/067_episode_lease_stale_steal.sql +93 -0
  53. package/.framework/migrations/068_cron_schedule_timer_rpcs.sql +251 -0
  54. package/.framework/migrations/069_log_stats_window.sql +54 -0
  55. package/.framework/migrations/070_app_type_schema_rpcs.sql +166 -0
  56. package/.framework/migrations/071_timer_interval_keys.sql +96 -0
  57. package/.framework/migrations/072_slug_autofill.sql +77 -0
  58. package/.framework/migrations/073_seed_member_roles.sql +26 -0
  59. package/.framework/schemas/spine.config.schema.json +62 -0
  60. package/.framework/src/App.tsx +3 -1
  61. package/.framework/src/apps/admin/index.tsx +1141 -775
  62. package/.framework/src/components/ErrorBoundary.tsx +136 -0
  63. package/.framework/src/components/admin/AdminListPage.tsx +81 -73
  64. package/.framework/src/components/admin/AdminSidebar.tsx +92 -81
  65. package/.framework/src/components/admin/EntitySelect.tsx +181 -0
  66. package/.framework/src/components/admin/PageInstructions.tsx +86 -127
  67. package/.framework/src/components/app-shell/GenericAppShell.tsx +3 -1
  68. package/.framework/src/components/app-shell/GenericDetailPage.tsx +37 -13
  69. package/.framework/src/components/app-shell/GenericListPage.tsx +28 -32
  70. package/.framework/src/components/auth/TurnstileWidget.tsx +9 -6
  71. package/.framework/src/components/kb/KBArticleEditor.tsx +49 -6
  72. package/.framework/src/components/layout/Layout.tsx +4 -2
  73. package/.framework/src/components/layout/Sidebar.tsx +304 -179
  74. package/.framework/src/components/runtime/DataDetailPage.tsx +67 -35
  75. package/.framework/src/components/runtime/DataHeader.tsx +96 -48
  76. package/.framework/src/components/runtime/DataListPage.tsx +3 -26
  77. package/.framework/src/components/runtime/DataStats.tsx +10 -10
  78. package/.framework/src/components/runtime/DataTable.tsx +12 -10
  79. package/.framework/src/components/ui/sheet.tsx +24 -26
  80. package/.framework/src/components/ui/textarea.tsx +74 -48
  81. package/.framework/src/hooks/useBranding.ts +47 -0
  82. package/.framework/src/hooks/useEntityList.ts +12 -9
  83. package/.framework/src/hooks/useListSchema.ts +108 -58
  84. package/.framework/src/instructions/README.md +57 -0
  85. package/.framework/src/instructions/ai-agents.md +69 -0
  86. package/.framework/src/instructions/alerts.md +80 -0
  87. package/.framework/src/instructions/api-keys.md +87 -0
  88. package/.framework/src/instructions/apps.md +77 -0
  89. package/.framework/src/instructions/concepts/ai-and-prompts.md +150 -0
  90. package/.framework/src/instructions/concepts/apps-and-renderers.md +162 -0
  91. package/.framework/src/instructions/concepts/auth-and-api-keys.md +133 -0
  92. package/.framework/src/instructions/concepts/automation.md +186 -0
  93. package/.framework/src/instructions/concepts/concurrency-and-idempotency.md +125 -0
  94. package/.framework/src/instructions/concepts/core-vs-custom.md +124 -0
  95. package/.framework/src/instructions/concepts/design-schema.md +152 -0
  96. package/.framework/src/instructions/concepts/integrations-and-webhooks.md +127 -0
  97. package/.framework/src/instructions/concepts/observability.md +116 -0
  98. package/.framework/src/instructions/concepts/permissions.md +150 -0
  99. package/.framework/src/instructions/concepts/runtime-records.md +111 -0
  100. package/.framework/src/instructions/concepts/scope-and-accounts.md +112 -0
  101. package/.framework/src/instructions/concepts/spine-way.md +172 -0
  102. package/.framework/src/instructions/deliveries.md +59 -0
  103. package/.framework/src/instructions/guide/00-orientation.md +106 -0
  104. package/.framework/src/instructions/guide/01-install-and-first-run.md +253 -0
  105. package/.framework/src/instructions/guide/02-project-map.md +147 -0
  106. package/.framework/src/instructions/guide/03-domain-model.md +223 -0
  107. package/.framework/src/instructions/guide/04-first-app.md +227 -0
  108. package/.framework/src/instructions/guide/05-glossary.md +183 -0
  109. package/.framework/src/instructions/integrations.md +96 -0
  110. package/.framework/src/instructions/internal/cil-markers.md +83 -0
  111. package/.framework/src/instructions/invites.md +60 -0
  112. package/.framework/src/instructions/kb.md +80 -0
  113. package/.framework/src/instructions/logs.md +77 -0
  114. package/.framework/src/instructions/observability.md +61 -0
  115. package/.framework/src/instructions/operations/deployment.md +115 -0
  116. package/.framework/src/instructions/operations/migrations.md +125 -0
  117. package/.framework/src/instructions/operations/security-checklist.md +148 -0
  118. package/.framework/src/instructions/operations/troubleshooting.md +170 -0
  119. package/.framework/src/instructions/operations/upgrade.md +116 -0
  120. package/.framework/src/instructions/pipeline-executions.md +62 -0
  121. package/.framework/src/instructions/pipelines.md +78 -0
  122. package/.framework/src/instructions/prompts.md +95 -0
  123. package/.framework/src/instructions/reference/api/admin-data.md +162 -0
  124. package/.framework/src/instructions/reference/api/auth.md +113 -0
  125. package/.framework/src/instructions/reference/api/errors-and-envelopes.md +113 -0
  126. package/.framework/src/instructions/reference/app-manifest.md +150 -0
  127. package/.framework/src/instructions/reference/cli.md +124 -0
  128. package/.framework/src/instructions/reference/database.md +132 -0
  129. package/.framework/src/instructions/reference/design-schema.md +280 -0
  130. package/.framework/src/instructions/reference/env-vars.md +133 -0
  131. package/.framework/src/instructions/reference/functions/account-nodes.md +75 -0
  132. package/.framework/src/instructions/reference/functions/admin-data.md +195 -0
  133. package/.framework/src/instructions/reference/functions/admin-funnel.md +90 -0
  134. package/.framework/src/instructions/reference/functions/admin-install-funnel.md +107 -0
  135. package/.framework/src/instructions/reference/functions/admin-signals.md +102 -0
  136. package/.framework/src/instructions/reference/functions/ai-agents.md +148 -0
  137. package/.framework/src/instructions/reference/functions/ai-interactions.md +156 -0
  138. package/.framework/src/instructions/reference/functions/api-keys.md +130 -0
  139. package/.framework/src/instructions/reference/functions/apps.md +140 -0
  140. package/.framework/src/instructions/reference/functions/auth.md +99 -0
  141. package/.framework/src/instructions/reference/functions/debug-auth.md +91 -0
  142. package/.framework/src/instructions/reference/functions/deliveries.md +110 -0
  143. package/.framework/src/instructions/reference/functions/embeddings.md +166 -0
  144. package/.framework/src/instructions/reference/functions/eval-harness.md +149 -0
  145. package/.framework/src/instructions/reference/functions/index.md +103 -0
  146. package/.framework/src/instructions/reference/functions/integration-outbound.md +200 -0
  147. package/.framework/src/instructions/reference/functions/integration-routes.md +151 -0
  148. package/.framework/src/instructions/reference/functions/integrations.md +130 -0
  149. package/.framework/src/instructions/reference/functions/invites.md +182 -0
  150. package/.framework/src/instructions/reference/functions/item-progress.md +107 -0
  151. package/.framework/src/instructions/reference/functions/kb.md +166 -0
  152. package/.framework/src/instructions/reference/functions/logs.md +141 -0
  153. package/.framework/src/instructions/reference/functions/observability.md +105 -0
  154. package/.framework/src/instructions/reference/functions/pipeline-executions.md +132 -0
  155. package/.framework/src/instructions/reference/functions/pipeline-runner-background.md +121 -0
  156. package/.framework/src/instructions/reference/functions/pipelines.md +136 -0
  157. package/.framework/src/instructions/reference/functions/prompt-configs.md +121 -0
  158. package/.framework/src/instructions/reference/functions/roles.md +121 -0
  159. package/.framework/src/instructions/reference/functions/security.md +140 -0
  160. package/.framework/src/instructions/reference/functions/system-cron.md +136 -0
  161. package/.framework/src/instructions/reference/functions/system.md +106 -0
  162. package/.framework/src/instructions/reference/functions/tests.md +97 -0
  163. package/.framework/src/instructions/reference/functions/timers.md +117 -0
  164. package/.framework/src/instructions/reference/functions/trigger-scheduler.md +102 -0
  165. package/.framework/src/instructions/reference/functions/triggers.md +140 -0
  166. package/.framework/src/instructions/reference/functions/types.md +146 -0
  167. package/.framework/src/instructions/reference/seeds.md +126 -0
  168. package/.framework/src/instructions/reference/shared-modules.md +127 -0
  169. package/.framework/src/instructions/reference/spine-config.md +114 -0
  170. package/.framework/src/instructions/roles.md +80 -0
  171. package/.framework/src/instructions/runtime-detail.md +70 -0
  172. package/.framework/src/instructions/runtime-list.md +77 -0
  173. package/.framework/src/instructions/security.md +67 -0
  174. package/.framework/src/instructions/tasks/add-a-pipeline.md +110 -0
  175. package/.framework/src/instructions/tasks/add-a-role.md +96 -0
  176. package/.framework/src/instructions/tasks/add-a-timer.md +114 -0
  177. package/.framework/src/instructions/tasks/add-a-trigger.md +106 -0
  178. package/.framework/src/instructions/tasks/add-a-type.md +151 -0
  179. package/.framework/src/instructions/tasks/add-a-webhook.md +108 -0
  180. package/.framework/src/instructions/tasks/add-an-ai-agent.md +108 -0
  181. package/.framework/src/instructions/tasks/add-an-integration.md +124 -0
  182. package/.framework/src/instructions/tasks/build-a-custom-page.md +118 -0
  183. package/.framework/src/instructions/tasks/package-and-install-an-app.md +127 -0
  184. package/.framework/src/instructions/tasks/test-your-code.md +108 -0
  185. package/.framework/src/instructions/tasks/write-a-function.md +132 -0
  186. package/.framework/src/instructions/tasks/write-a-migration.md +110 -0
  187. package/.framework/src/instructions/testing.md +59 -0
  188. package/.framework/src/instructions/timers.md +82 -0
  189. package/.framework/src/instructions/triggers.md +69 -0
  190. package/.framework/src/instructions/types.md +93 -0
  191. package/.framework/src/lib/branding.ts +128 -0
  192. package/.framework/src/pages/NoAppPage.tsx +3 -1
  193. package/.framework/src/pages/NotFoundPage.tsx +62 -31
  194. package/.framework/src/pages/SetupPage.tsx +5 -2
  195. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +117 -106
  196. package/.framework/src/pages/admin/AIAgentsPage.tsx +86 -48
  197. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +153 -152
  198. package/.framework/src/pages/admin/APIKeysPage.tsx +91 -90
  199. package/.framework/src/pages/admin/AlertsConfigPage.tsx +29 -18
  200. package/.framework/src/pages/admin/AppDetailPage.tsx +6 -60
  201. package/.framework/src/pages/admin/AppsPage.tsx +104 -66
  202. package/.framework/src/pages/admin/DeliveriesPage.tsx +5 -5
  203. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +5 -23
  204. package/.framework/src/pages/admin/EmbeddingsPage.tsx +5 -26
  205. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +7 -7
  206. package/.framework/src/pages/admin/IntegrationsPage.tsx +85 -43
  207. package/.framework/src/pages/admin/LogsPage.tsx +144 -76
  208. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +223 -140
  209. package/.framework/src/pages/admin/PipelineDetailPage.tsx +134 -113
  210. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +108 -45
  211. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -115
  212. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +96 -98
  213. package/.framework/src/pages/admin/PromptConfigsPage.tsx +101 -59
  214. package/.framework/src/pages/admin/RoleDetailPage.tsx +90 -79
  215. package/.framework/src/pages/admin/RolesPage.tsx +86 -43
  216. package/.framework/src/pages/admin/SecurityPage.tsx +1 -1
  217. package/.framework/src/pages/admin/TestingDashboard.tsx +16 -28
  218. package/.framework/src/pages/admin/TimerDetailPage.tsx +117 -100
  219. package/.framework/src/pages/admin/TimersPage.tsx +90 -62
  220. package/.framework/src/pages/admin/TriggerDetailPage.tsx +90 -83
  221. package/.framework/src/pages/admin/TriggersPage.tsx +124 -99
  222. package/.framework/src/pages/admin/TypeDetailPage.tsx +152 -138
  223. package/.framework/src/pages/admin/TypesPage.tsx +90 -48
  224. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +17 -25
  225. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +17 -27
  226. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +72 -40
  227. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +321 -129
  228. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +18 -29
  229. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +26 -38
  230. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +34 -46
  231. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +189 -103
  232. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +246 -136
  233. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +11 -22
  234. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +9 -20
  235. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +26 -38
  236. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +7 -26
  237. package/.framework/src/pages/auth/AuthConfirmPage.tsx +3 -1
  238. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +3 -1
  239. package/.framework/src/pages/auth/LoginPage.tsx +4 -2
  240. package/.framework/src/pages/auth/RegisterPage.tsx +3 -1
  241. package/.framework/templates/agent/AGENTS.md +150 -0
  242. package/.framework/templates/agent/skills/spine-add-ai-agent/SKILL.md +58 -0
  243. package/.framework/templates/agent/skills/spine-add-automation/SKILL.md +62 -0
  244. package/.framework/templates/agent/skills/spine-add-integration/SKILL.md +63 -0
  245. package/.framework/templates/agent/skills/spine-architect/SKILL.md +86 -0
  246. package/.framework/templates/agent/skills/spine-install-app/SKILL.md +72 -0
  247. package/.framework/templates/agent/skills/spine-migration/SKILL.md +75 -0
  248. package/.framework/templates/agent/skills/spine-new-app/SKILL.md +67 -0
  249. package/.framework/templates/agent/skills/spine-new-function/SKILL.md +65 -0
  250. package/.framework/templates/agent/skills/spine-new-type/SKILL.md +65 -0
  251. package/.framework/templates/agent/skills/spine-schema/SKILL.md +77 -0
  252. package/.framework/templates/agent/skills/spine-test/SKILL.md +67 -0
  253. package/.framework/templates/agent/skills/spine-troubleshoot/SKILL.md +74 -0
  254. package/.framework/templates/agent/skills/spine-upgrade/SKILL.md +69 -0
  255. package/.framework/templates/project.json +5 -1
  256. package/.framework/tests/unit/account-scoping-gates.test.ts +392 -0
  257. package/.framework/tests/unit/agent-files.test.ts +355 -0
  258. package/.framework/tests/unit/agent-runner.test.ts +496 -47
  259. package/.framework/tests/unit/api-keys-create-scope-gate.test.ts +160 -0
  260. package/.framework/tests/unit/api-keys-omit-secret-fields.test.ts +38 -0
  261. package/.framework/tests/unit/bootstrap.test.ts +242 -0
  262. package/.framework/tests/unit/cli-context-api-key.test.ts +114 -0
  263. package/.framework/tests/unit/debug-auth.test.ts +38 -0
  264. package/.framework/tests/unit/deliveries-account-scoping.test.ts +185 -0
  265. package/.framework/tests/unit/episode-lease.test.ts +695 -0
  266. package/.framework/tests/unit/integration-outbound-credentials.test.ts +167 -0
  267. package/.framework/tests/unit/integrations-audit-redaction.test.ts +130 -0
  268. package/.framework/tests/unit/kb-ingest-lease.test.ts +19 -0
  269. package/.framework/tests/unit/logging-app-id.test.ts +75 -0
  270. package/.framework/tests/unit/pipeline-runner-background.test.ts +120 -0
  271. package/.framework/tests/unit/pipeline-runner.test.ts +153 -1
  272. package/.framework/tests/unit/principal-cache.test.ts +15 -0
  273. package/.framework/tests/unit/system-context-denial.test.ts +145 -0
  274. package/.framework/tests/unit/system-cron.test.ts +240 -0
  275. package/.framework/tests/unit/timers.test.ts +159 -0
  276. package/.framework/tests/unit/trigger-engine.test.ts +278 -91
  277. package/.framework/tests/unit/trigger-scheduler.test.ts +78 -0
  278. package/README.md +125 -166
  279. package/config/tsconfig.cli.json +2 -2
  280. package/netlify.toml +5 -0
  281. package/package.json +15 -4
  282. package/templates/project/package-lock.json +2 -2
  283. package/.framework/docs/admin-routes.md +0 -76
  284. package/.framework/docs/api-docs-progress.md +0 -38
  285. package/.framework/docs/api-governance.md +0 -146
  286. package/.framework/docs/api-testing-results.md +0 -212
  287. package/.framework/docs/assembly-launch-guide.md +0 -138
  288. package/.framework/docs/audit-results.md +0 -590
  289. package/.framework/docs/db-api-inventory.md +0 -95
  290. package/.framework/docs/gap-remediation-backlog.md +0 -103
  291. package/.framework/docs/ui-adoption-verification.md +0 -111
  292. package/.framework/docs/ui-api-coverage.md +0 -84
  293. package/.framework/docs/v2-compatibility-audit.md +0 -228
  294. package/.framework/mcp/index.ts +0 -133
  295. package/.framework/mcp/load-env.ts +0 -60
  296. package/.framework/mcp/shared/app-manifest.ts +0 -275
  297. package/.framework/mcp/shared/db.ts +0 -477
  298. package/.framework/mcp/shared/kb.ts +0 -118
  299. package/.framework/mcp/tools/architect.ts +0 -431
  300. package/.framework/mcp/tools/cil/context.ts +0 -345
  301. package/.framework/mcp/tools/cil/graph.ts +0 -242
  302. package/.framework/mcp/tools/cil/ingest.ts +0 -1217
  303. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +0 -693
  304. package/.framework/mcp/tools/cil/pipeline.ts +0 -767
  305. package/.framework/mcp/tools/cil/project.ts +0 -791
  306. package/.framework/mcp/tools/cil/retrieval.ts +0 -336
  307. package/.framework/mcp/tools/cil/search-core.ts +0 -454
  308. package/.framework/mcp/tools/cil/search.ts +0 -97
  309. package/.framework/mcp/tools/cil/suggest.ts +0 -186
  310. package/.framework/mcp/tools/cil/validate.ts +0 -1369
  311. package/.framework/mcp/tools/kb/delete.ts +0 -139
  312. package/.framework/mcp/tools/kb/index.ts +0 -52
  313. package/.framework/mcp/tools/kb/ingest.ts +0 -84
  314. package/.framework/mcp/tools/kb/list-types.ts +0 -102
  315. package/.framework/mcp/tools/kb/publish.ts +0 -100
  316. package/.framework/mcp/tools/kb/reindex.ts +0 -86
  317. package/.framework/mcp/tools/kb/revoke.ts +0 -85
  318. package/.framework/mcp/tools/kb/search.ts +0 -101
  319. package/.framework/mcp/tools/kb/upsert.ts +0 -125
  320. package/.framework/mcp/tools/observability.ts +0 -510
@@ -1,510 +0,0 @@
1
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/observability.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/mcp/tools/observability.ts"]
2
- // CIL[DOC-MACRO purpose="MCP tool registration module for observability logs and metrics"]
3
- // CIL[DOC-RESPONSIBILITY responsibility="Imports dependencies and exports the register function that wires observability MCP tools to an McpServer"]
4
- // CIL[DOC-CONTEXT module="observability" layer="mcp-tools" related_files=".framework/mcp/shared/db.ts"]
5
- // CIL[DOC-CONTRACT inputs="McpServer instance via register" outputs="MCP tool handlers for volume, error rate, latency, pipeline, top actors, AI support, and logs" errors="Throws from adminDb RPC or query errors via throwDbError" side_effects="None at module load"]
6
- // CIL[DOC-MICRO logic_summary="Sets up zod schemas and adminDb RPC calls for observability data" notable_decisions="[]"]
7
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
- // CIL[DOC-STABILITY stability="stable"]
9
- // CIL[DOC-AUDIENCE audience="framework-maintainers"]
10
-
11
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
12
- import { z } from 'zod'
13
- import { adminDb } from '../shared/db.js'
14
- import { resolveTypeId } from '../shared/db.js'
15
- // CIL[DOC-VECTOR type="context" content="purpose='MCP tool registration module for observability logs and metrics'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
16
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
17
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
18
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
19
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
20
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
21
- // CIL[END stable_id="~/.framework/mcp/tools/observability.ts:module_header:module_header"]
22
-
23
-
24
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/observability.ts:mapLogRow:function" type="function" identity="mapLogRow" parent="~/.framework/mcp/tools/observability.ts"]
25
- // CIL[DOC-MACRO purpose="Map a raw log database row to a normalized client-facing log object"]
26
- // CIL[DOC-RESPONSIBILITY responsibility="Transform database column names to the expected client log field names"]
27
- // CIL[DOC-CONTEXT module="observability" layer="mcp-tools" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/observability.ts"]
28
- // CIL[DOC-CONTRACT inputs="row: any database log row" outputs="normalized log object" errors="None" side_effects="None"]
29
- // CIL[DOC-MICRO logic_summary="Returns an object mapping row columns to the names expected by consumers" notable_decisions="[]"]
30
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
31
- // CIL[DOC-STABILITY stability="stable"]
32
- function mapLogRow(row: any) {
33
- return {
34
- id: row.id,
35
- event_type: row.level,
36
- actor_id: row.person_id,
37
- target_type: row.source_type,
38
- target_id: row.source_id,
39
- action: row.source,
40
- span_name: row.span_name,
41
- trace_id: row.trace_id,
42
- span_id: row.span_id,
43
- parent_span_id: row.parent_span_id,
44
- duration_ms: row.duration_ms,
45
- outcome: row.outcome,
46
- event_category: row.event_category,
47
- kind: row.kind,
48
- message: row.message,
49
- details: row.context,
50
- metadata: row.metadata,
51
- created_at: row.created_at,
52
- }
53
- }
54
- // CIL[DOC-VECTOR type="context" content="purpose='Map a raw log database row to a normalized client-facing log object'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
55
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
56
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
57
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
58
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
59
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
60
- // CIL[END stable_id="~/.framework/mcp/tools/observability.ts:mapLogRow:function"]
61
-
62
-
63
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/observability.ts:textResponse:function" type="function" identity="textResponse" parent="~/.framework/mcp/tools/observability.ts"]
64
- // CIL[DOC-MACRO purpose="Wrap any value in an MCP text content response"]
65
- // CIL[DOC-RESPONSIBILITY responsibility="Format JSON-serialized payloads for MCP text tool responses"]
66
- // CIL[DOC-CONTEXT module="observability" layer="mcp-tools" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/observability.ts"]
67
- // CIL[DOC-CONTRACT inputs="obj: any" outputs="MCP content array with type text" errors="May throw if JSON.stringify receives circular input" side_effects="None"]
68
- // CIL[DOC-MICRO logic_summary="Stringify object and return an MCP text content wrapper" notable_decisions="[]"]
69
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
70
- // CIL[DOC-STABILITY stability="stable"]
71
- function textResponse(obj: any) {
72
- return {
73
- content: [{
74
- type: 'text' as const,
75
- text: JSON.stringify(obj, null, 2),
76
- }],
77
- }
78
- }
79
- // CIL[DOC-VECTOR type="context" content="purpose='Wrap any value in an MCP text content response'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
80
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
81
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
82
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
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
- // CIL[END stable_id="~/.framework/mcp/tools/observability.ts:textResponse:function"]
86
-
87
-
88
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/observability.ts:throwDbError:function" type="function" identity="throwDbError" parent="~/.framework/mcp/tools/observability.ts"]
89
- // CIL[DOC-MACRO purpose="Convert an unknown error into a JavaScript Error with a readable message"]
90
- // CIL[DOC-RESPONSIBILITY responsibility="Provide uniform database error handling for tool handlers"]
91
- // CIL[DOC-CONTEXT module="observability" layer="mcp-tools" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/observability.ts"]
92
- // CIL[DOC-CONTRACT inputs="error: any" outputs="Throws Error" errors="Throws Error for any error input" side_effects="None"]
93
- // CIL[DOC-MICRO logic_summary="Coerce error to string and throw" notable_decisions="[]"]
94
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
95
- // CIL[DOC-STABILITY stability="stable"]
96
- function throwDbError(error: any) {
97
- const msg = error && typeof error === 'object'
98
- ? (error.message || JSON.stringify(error))
99
- : String(error)
100
- throw new Error(msg)
101
- }
102
- // CIL[DOC-VECTOR type="context" content="purpose='Convert an unknown error into a JavaScript Error with a readable message'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
103
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
104
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
105
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
106
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
107
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
108
- // CIL[END stable_id="~/.framework/mcp/tools/observability.ts:throwDbError:function"]
109
-
110
-
111
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/observability.ts:defaultRange:function" type="function" identity="defaultRange" parent="~/.framework/mcp/tools/observability.ts"]
112
- // CIL[DOC-MACRO purpose="Return a default 24-hour ISO date range ending at now"]
113
- // CIL[DOC-RESPONSIBILITY responsibility="Provide fallback from/to timestamps for time-bucketed metric queries"]
114
- // CIL[DOC-CONTEXT module="observability" layer="mcp-tools" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/observability.ts"]
115
- // CIL[DOC-CONTRACT inputs="None" outputs="{ from: ISO string, to: ISO string }" errors="None" side_effects="None"]
116
- // CIL[DOC-MICRO logic_summary="Compute yesterday by subtracting 24 hours from now" notable_decisions="[]"]
117
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
118
- // CIL[DOC-STABILITY stability="stable"]
119
- function defaultRange() {
120
- const now = new Date()
121
- const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000).toISOString()
122
- return { from: yesterday, to: now.toISOString() }
123
- }
124
- // CIL[DOC-VECTOR type="context" content="purpose='Return a default 24-hour ISO date range ending at now'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
125
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
126
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
127
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
128
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
129
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
130
- // CIL[END stable_id="~/.framework/mcp/tools/observability.ts:defaultRange:function"]
131
-
132
-
133
-
134
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/observability.ts:bucketToGranularity:constant" type="constant" identity="bucketToGranularity" parent="~/.framework/mcp/tools/observability.ts"]
135
- // CIL[DOC-MACRO purpose="Map friendly bucket names to SQL interval strings"]
136
- // CIL[DOC-RESPONSIBILITY responsibility="Translate hour/day/week inputs to PostgreSQL granularity literals"]
137
- // CIL[DOC-CONTEXT module="observability" layer="mcp-tools" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/observability.ts"]
138
- // CIL[DOC-CONTRACT inputs="bucket string key" outputs="PostgreSQL interval string" errors="None" side_effects="None"]
139
- // CIL[DOC-MICRO logic_summary="Lookup Record<string,string> with default 1 hour" notable_decisions="[]"]
140
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
141
- // CIL[DOC-STABILITY stability="stable"]
142
- const bucketToGranularity: Record<string, string> = {
143
- hour: '1 hour',
144
- day: '1 day',
145
- week: '1 week',
146
- }
147
- // CIL[DOC-VECTOR type="context" content="purpose='Map friendly bucket names to SQL interval strings'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
148
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
149
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
150
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
151
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
152
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
153
- // CIL[END stable_id="~/.framework/mcp/tools/observability.ts:bucketToGranularity:constant"]
154
-
155
-
156
-
157
-
158
- // CIL[BEGIN stable_id="~/.framework/mcp/tools/observability.ts:register:function" type="function" identity="register" parent="~/.framework/mcp/tools/observability.ts"]
159
- // CIL[DOC-MACRO purpose="Register all observability MCP tools on a server instance"]
160
- // CIL[DOC-RESPONSIBILITY responsibility="Expose metrics, logs, and AI support query tools to MCP clients"]
161
- // CIL[DOC-CONTEXT module="observability" layer="mcp-tools" related_files=".framework/mcp/shared/db.ts,.framework/mcp/tools/observability.ts"]
162
- // CIL[DOC-CONTRACT inputs="server: McpServer" outputs="Registered tool handlers with zod input schemas" errors="Throws on database RPC or query errors" side_effects="Adds ten tool handlers to the McpServer"]
163
- // CIL[DOC-MICRO logic_summary="Defines ten tools using zod and adminDb RPC or queries: event volume, error rate, latency percentiles, pipeline stats, top actors, AI support metrics, log search, log list, log for target, log stats" notable_decisions="['latency_percentiles returns avg_handler_duration because percentile RPCs are not yet available']"]
164
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
165
- // CIL[DOC-STABILITY stability="stable"]
166
- export function register(server: McpServer) {
167
- server.registerTool(
168
- 'spine_observability_event_volume',
169
- {
170
- description: 'Get request count over time, bucketed by hour/day/week.',
171
- inputSchema: z.object({
172
- account_id: z.string().uuid(),
173
- from: z.string().datetime().optional(),
174
- to: z.string().datetime().optional(),
175
- bucket: z.enum(['hour', 'day', 'week']).default('hour'),
176
- }),
177
- },
178
- async ({ account_id, from, to, bucket }) => {
179
- const range = defaultRange()
180
- const { data, error } = await adminDb.rpc('get_metric_series', {
181
- p_account_id: account_id,
182
- p_metric_name: 'request_count',
183
- p_granularity: bucketToGranularity[bucket] || '1 hour',
184
- p_date_from: from || range.from,
185
- p_date_to: to || range.to,
186
- })
187
- if (error) throwDbError(error)
188
- return textResponse({ action: 'event_volume', data: data || [] })
189
- }
190
- )
191
-
192
- server.registerTool(
193
- 'spine_observability_error_rate',
194
- {
195
- description: 'Get error rate over time for an account and date range.',
196
- inputSchema: z.object({
197
- account_id: z.string().uuid(),
198
- from: z.string().datetime().optional(),
199
- to: z.string().datetime().optional(),
200
- bucket: z.enum(['hour', 'day', 'week']).default('hour'),
201
- }),
202
- },
203
- async ({ account_id, from, to, bucket }) => {
204
- const range = defaultRange()
205
- const { data, error } = await adminDb.rpc('get_metric_series', {
206
- p_account_id: account_id,
207
- p_metric_name: 'error_rate',
208
- p_granularity: bucketToGranularity[bucket] || '1 hour',
209
- p_date_from: from || range.from,
210
- p_date_to: to || range.to,
211
- })
212
- if (error) throwDbError(error)
213
- return textResponse({ action: 'error_rate', data: data || [] })
214
- }
215
- )
216
-
217
- server.registerTool(
218
- 'spine_observability_latency_percentiles',
219
- {
220
- description: 'Get handler latency (average duration_ms) over time. Percentile RPCs are not yet available; this returns the avg_handler_duration metric series.',
221
- inputSchema: z.object({
222
- account_id: z.string().uuid(),
223
- from: z.string().datetime().optional(),
224
- to: z.string().datetime().optional(),
225
- bucket: z.enum(['hour', 'day', 'week']).default('hour'),
226
- }),
227
- },
228
- async ({ account_id, from, to, bucket }) => {
229
- const range = defaultRange()
230
- const { data, error } = await adminDb.rpc('get_metric_series', {
231
- p_account_id: account_id,
232
- p_metric_name: 'avg_handler_duration',
233
- p_granularity: bucketToGranularity[bucket] || '1 hour',
234
- p_date_from: from || range.from,
235
- p_date_to: to || range.to,
236
- })
237
- if (error) throwDbError(error)
238
- return textResponse({ action: 'latency_percentiles', data: data || [] })
239
- }
240
- )
241
-
242
- server.registerTool(
243
- 'spine_observability_pipeline_stats',
244
- {
245
- description: 'Get pipeline failure rate over time.',
246
- inputSchema: z.object({
247
- account_id: z.string().uuid(),
248
- from: z.string().datetime().optional(),
249
- to: z.string().datetime().optional(),
250
- bucket: z.enum(['hour', 'day', 'week']).default('hour'),
251
- }),
252
- },
253
- async ({ account_id, from, to, bucket }) => {
254
- const range = defaultRange()
255
- const { data, error } = await adminDb.rpc('get_metric_series', {
256
- p_account_id: account_id,
257
- p_metric_name: 'pipeline_failure_rate',
258
- p_granularity: bucketToGranularity[bucket] || '1 hour',
259
- p_date_from: from || range.from,
260
- p_date_to: to || range.to,
261
- })
262
- if (error) throwDbError(error)
263
- return textResponse({ action: 'pipeline_stats', data: data || [] })
264
- }
265
- )
266
-
267
- server.registerTool(
268
- 'spine_observability_top_actors',
269
- {
270
- description: 'Get the top business outcomes by span_name/outcome count.',
271
- inputSchema: z.object({
272
- account_id: z.string().uuid(),
273
- from: z.string().datetime().optional(),
274
- to: z.string().datetime().optional(),
275
- }),
276
- },
277
- async ({ account_id, from, to }) => {
278
- const range = defaultRange()
279
- const { data, error } = await adminDb.rpc('get_business_outcomes', {
280
- p_account_id: account_id,
281
- p_date_from: from || range.from,
282
- p_date_to: to || range.to,
283
- })
284
- if (error) throwDbError(error)
285
- return textResponse({ action: 'business_outcomes', data: data || [] })
286
- }
287
- )
288
-
289
- server.registerTool(
290
- 'spine_observability_ai_support_metrics',
291
- {
292
- description: 'Get AI support metrics and knowledge gap analysis for an account.',
293
- inputSchema: z.object({
294
- account_id: z.string().uuid(),
295
- from: z.string().datetime().optional(),
296
- to: z.string().datetime().optional(),
297
- }),
298
- },
299
- async ({ account_id, from, to }) => {
300
- const now = new Date()
301
- const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000).toISOString()
302
- const fromDate = from || thirtyDaysAgo
303
- const toDate = to || now.toISOString()
304
-
305
- const feedbackTypeId = await resolveTypeId('item', 'ai_feedback_record')
306
-
307
- const [feedbackResult, resolvedResult, escalatedResult] = await Promise.allSettled([
308
- adminDb
309
- .from('items')
310
- .select('data')
311
- .eq('account_id', account_id)
312
- .eq('type_id', feedbackTypeId)
313
- .gte('created_at', fromDate)
314
- .lte('created_at', toDate)
315
- .limit(5000),
316
- adminDb
317
- .from('items')
318
- .select('id', { count: 'exact', head: true })
319
- .eq('account_id', account_id)
320
- .eq('status', 'resolved')
321
- .eq('data->>aim_escalation_reason', 'none')
322
- .gte('created_at', fromDate)
323
- .lte('created_at', toDate),
324
- adminDb
325
- .from('items')
326
- .select('id', { count: 'exact', head: true })
327
- .eq('account_id', account_id)
328
- .eq('status', 'human_assigned')
329
- .gte('created_at', fromDate)
330
- .lte('created_at', toDate),
331
- ])
332
-
333
- const feedbackRows = feedbackResult.status === 'fulfilled' ? (feedbackResult.value.data || []) : []
334
- const aiAttempted = feedbackRows.length
335
- const notHelpful = feedbackRows.filter((r: any) => r.data?.customer_feedback === 'not_helpful').length
336
- const kbCreated = feedbackRows.filter((r: any) => r.data?.kb_article_id).length
337
- const kbReuseCount = feedbackRows.reduce((sum: number, r: any) => sum + (Number(r.data?.reuse_count) || 0), 0)
338
- const knowledgeGaps = feedbackRows.filter(
339
- (r: any) => r.data?.kb_candidate === false && r.data?.customer_feedback === 'not_helpful'
340
- ).length
341
- const aiResolved = resolvedResult.status === 'fulfilled' ? (resolvedResult.value.count || 0) : 0
342
- const escalated = escalatedResult.status === 'fulfilled' ? (escalatedResult.value.count || 0) : 0
343
- const thumbsDownRate = aiAttempted > 0 ? notHelpful / aiAttempted : 0
344
-
345
- return textResponse({
346
- action: 'ai_support_metrics',
347
- period: { from: fromDate, to: toDate },
348
- ai_attempted: aiAttempted,
349
- ai_resolved: aiResolved,
350
- human_escalations: escalated,
351
- thumbs_down_rate: Math.round(thumbsDownRate * 1000) / 1000,
352
- kb_articles_created: kbCreated,
353
- kb_reuse_count: kbReuseCount,
354
- knowledge_gaps: knowledgeGaps,
355
- })
356
- }
357
- )
358
-
359
- server.registerTool(
360
- 'spine_logs_search',
361
- {
362
- description: 'Full-text search over log messages for an account.',
363
- inputSchema: z.object({
364
- account_id: z.string().uuid(),
365
- query: z.string(),
366
- event_type: z.string().optional(),
367
- target_type: z.string().optional(),
368
- limit: z.number().int().min(1).max(1000).default(50),
369
- offset: z.number().int().min(0).default(0),
370
- }),
371
- },
372
- async ({ account_id, query, event_type, target_type, limit, offset }) => {
373
- let q = adminDb
374
- .from('logs')
375
- .select('*')
376
- .eq('account_id', account_id)
377
- .ilike('message', `%${query}%`)
378
- .order('created_at', { ascending: false })
379
-
380
- if (event_type) q = q.eq('level', event_type)
381
- if (target_type) q = q.eq('source_type', target_type)
382
-
383
- const { data, error } = await q.range(offset, offset + limit - 1)
384
- if (error) throwDbError(error)
385
- return textResponse({ action: 'search', data: (data || []).map(mapLogRow) })
386
- }
387
- )
388
-
389
- server.registerTool(
390
- 'spine_logs_for_account',
391
- {
392
- description: 'List log entries for an account with optional filtering and pagination.',
393
- inputSchema: z.object({
394
- account_id: z.string().uuid(),
395
- event_type: z.string().optional(),
396
- target_type: z.string().optional(),
397
- source: z.string().optional(),
398
- source_id: z.string().optional(),
399
- actor_id: z.string().uuid().optional(),
400
- date_from: z.string().datetime().optional(),
401
- date_to: z.string().datetime().optional(),
402
- trace_id: z.string().optional(),
403
- limit: z.number().int().min(1).max(1000).default(100),
404
- offset: z.number().int().min(0).default(0),
405
- }),
406
- },
407
- async ({ account_id, event_type, target_type, source, source_id, actor_id, date_from, date_to, trace_id, limit, offset }) => {
408
- let q = adminDb
409
- .from('logs')
410
- .select('*', { count: 'exact' })
411
- .eq('account_id', account_id)
412
- .order('created_at', { ascending: false })
413
-
414
- if (event_type) q = q.eq('level', event_type)
415
- if (target_type) q = q.eq('source_type', target_type)
416
- if (source) q = q.eq('source', source)
417
- if (source_id) q = q.eq('source_id', source_id)
418
- if (actor_id) q = q.eq('person_id', actor_id)
419
- if (date_from) q = q.gte('created_at', date_from)
420
- if (date_to) q = q.lte('created_at', date_to)
421
- if (trace_id) q = q.eq('trace_id', trace_id)
422
-
423
- const { data, error, count } = await q.range(offset, offset + limit - 1)
424
- if (error) throwDbError(error)
425
- return textResponse({
426
- action: 'account',
427
- data: (data || []).map(mapLogRow),
428
- total: count || 0,
429
- })
430
- }
431
- )
432
-
433
- server.registerTool(
434
- 'spine_logs_for_target',
435
- {
436
- description: 'List log entries for a specific target entity.',
437
- inputSchema: z.object({
438
- account_id: z.string().uuid(),
439
- target_type: z.string(),
440
- target_id: z.string(),
441
- event_type: z.string().optional(),
442
- limit: z.number().int().min(1).max(1000).default(100),
443
- offset: z.number().int().min(0).default(0),
444
- }),
445
- },
446
- async ({ account_id, target_type, target_id, event_type, limit, offset }) => {
447
- let q = adminDb
448
- .from('logs')
449
- .select('*')
450
- .eq('account_id', account_id)
451
- .eq('source_type', target_type)
452
- .eq('source_id', target_id)
453
- .order('created_at', { ascending: false })
454
-
455
- if (event_type) q = q.eq('level', event_type)
456
-
457
- const { data, error } = await q.range(offset, offset + limit - 1)
458
- if (error) throwDbError(error)
459
- return textResponse({ action: 'target', data: (data || []).map(mapLogRow) })
460
- }
461
- )
462
-
463
- server.registerTool(
464
- 'spine_logs_stats',
465
- {
466
- description: 'Aggregate log counts by type and source for an account and optional filters.',
467
- inputSchema: z.object({
468
- account_id: z.string().uuid(),
469
- event_type: z.string().optional(),
470
- target_type: z.string().optional(),
471
- source: z.string().optional(),
472
- source_id: z.string().optional(),
473
- actor_id: z.string().uuid().optional(),
474
- query: z.string().optional(),
475
- date_from: z.string().datetime().optional(),
476
- date_to: z.string().datetime().optional(),
477
- }),
478
- },
479
- async ({ account_id, event_type, target_type, source, source_id, actor_id, query, date_from, date_to }) => {
480
- const { data, error } = await adminDb.rpc('get_log_stats', {
481
- p_account_id: account_id,
482
- p_level: event_type || null,
483
- p_source: source || null,
484
- p_source_type: target_type || null,
485
- p_source_id: source_id || null,
486
- p_person_id: actor_id || null,
487
- p_query: query || null,
488
- p_date_from: date_from || null,
489
- p_date_to: date_to || null,
490
- })
491
- if (error) throwDbError(error)
492
- return textResponse({ action: 'stats', data: data?.[0] || {
493
- total: 0,
494
- error_count: 0,
495
- user_action_count: 0,
496
- event_type_count: 0,
497
- levels: [],
498
- sources: [],
499
- source_types: [],
500
- }})
501
- }
502
- )
503
- }
504
- // CIL[DOC-VECTOR type="context" content="purpose='Register all observability MCP tools on a server instance'; No verified external callers; imports: .framework/mcp/shared/db.ts"]
505
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
506
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
507
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
508
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
509
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
510
- // CIL[END stable_id="~/.framework/mcp/tools/observability.ts:register:function"]