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,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"]