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.
- package/.env.example +13 -3
- package/.framework/cli/commands/bootstrap.ts +392 -0
- package/.framework/cli/commands/dev.ts +91 -218
- package/.framework/cli/commands/doctor.ts +132 -26
- package/.framework/cli/commands/generate.ts +38 -298
- package/.framework/cli/commands/init.ts +20 -1
- package/.framework/cli/commands/migrate.ts +36 -30
- package/.framework/cli/commands/migrations.ts +16 -56
- package/.framework/cli/commands/upgrade.ts +35 -0
- package/.framework/cli/commands/validate-schema.ts +147 -0
- package/.framework/cli/context.ts +223 -110
- package/.framework/cli/index.ts +6 -0
- package/.framework/cli/lib/project-files.ts +241 -1
- package/.framework/functions/_shared/agent-runner.ts +1000 -81
- package/.framework/functions/_shared/cil.ts +2 -1
- package/.framework/functions/_shared/db.ts +3 -6
- package/.framework/functions/_shared/hash-api-key.ts +183 -79
- package/.framework/functions/_shared/kb.ts +61 -7
- package/.framework/functions/_shared/logging.ts +562 -224
- package/.framework/functions/_shared/message-sequence.ts +53 -0
- package/.framework/functions/_shared/middleware.ts +47 -44
- package/.framework/functions/_shared/pipeline-runner.ts +150 -37
- package/.framework/functions/_shared/principal.ts +9 -6
- package/.framework/functions/_shared/trigger-engine.ts +149 -40
- package/.framework/functions/admin-data.ts +48 -31
- package/.framework/functions/ai-agents.ts +103 -33
- package/.framework/functions/api-keys.ts +301 -122
- package/.framework/functions/apps.ts +43 -26
- package/.framework/functions/cil-ingest.ts +48 -15
- package/.framework/functions/debug-auth.ts +14 -8
- package/.framework/functions/deliveries.ts +39 -12
- package/.framework/functions/embeddings.ts +145 -76
- package/.framework/functions/integration-outbound.ts +67 -27
- package/.framework/functions/integrations.ts +254 -127
- package/.framework/functions/logs.ts +273 -133
- package/.framework/functions/observability.ts +277 -147
- package/.framework/functions/pipeline-executions.ts +1 -1
- package/.framework/functions/pipeline-runner-background.ts +120 -0
- package/.framework/functions/pipelines.ts +14 -9
- package/.framework/functions/prompt-configs.ts +7 -4
- package/.framework/functions/roles.ts +8 -5
- package/.framework/functions/security.ts +30 -17
- package/.framework/functions/system-cron.ts +250 -128
- package/.framework/functions/tests.ts +7 -6
- package/.framework/functions/timers.ts +310 -107
- package/.framework/functions/trigger-scheduler.ts +65 -5
- package/.framework/functions/triggers.ts +28 -13
- package/.framework/functions/types.ts +13 -10
- package/.framework/migrations/064_episode_leases.sql +196 -0
- package/.framework/migrations/065_execution_tables_updated_at.sql +20 -0
- package/.framework/migrations/066_episode_steal_thread_merge.sql +148 -0
- package/.framework/migrations/067_episode_lease_stale_steal.sql +93 -0
- package/.framework/migrations/068_cron_schedule_timer_rpcs.sql +251 -0
- package/.framework/migrations/069_log_stats_window.sql +54 -0
- package/.framework/migrations/070_app_type_schema_rpcs.sql +166 -0
- package/.framework/migrations/071_timer_interval_keys.sql +96 -0
- package/.framework/migrations/072_slug_autofill.sql +77 -0
- package/.framework/migrations/073_seed_member_roles.sql +26 -0
- package/.framework/schemas/spine.config.schema.json +62 -0
- package/.framework/src/App.tsx +3 -1
- package/.framework/src/apps/admin/index.tsx +1141 -775
- package/.framework/src/components/ErrorBoundary.tsx +136 -0
- package/.framework/src/components/admin/AdminListPage.tsx +81 -73
- package/.framework/src/components/admin/AdminSidebar.tsx +92 -81
- package/.framework/src/components/admin/EntitySelect.tsx +181 -0
- package/.framework/src/components/admin/PageInstructions.tsx +86 -127
- package/.framework/src/components/app-shell/GenericAppShell.tsx +3 -1
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +37 -13
- package/.framework/src/components/app-shell/GenericListPage.tsx +28 -32
- package/.framework/src/components/auth/TurnstileWidget.tsx +9 -6
- package/.framework/src/components/kb/KBArticleEditor.tsx +49 -6
- package/.framework/src/components/layout/Layout.tsx +4 -2
- package/.framework/src/components/layout/Sidebar.tsx +304 -179
- package/.framework/src/components/runtime/DataDetailPage.tsx +67 -35
- package/.framework/src/components/runtime/DataHeader.tsx +96 -48
- package/.framework/src/components/runtime/DataListPage.tsx +3 -26
- package/.framework/src/components/runtime/DataStats.tsx +10 -10
- package/.framework/src/components/runtime/DataTable.tsx +12 -10
- package/.framework/src/components/ui/sheet.tsx +24 -26
- package/.framework/src/components/ui/textarea.tsx +74 -48
- package/.framework/src/hooks/useBranding.ts +47 -0
- package/.framework/src/hooks/useEntityList.ts +12 -9
- package/.framework/src/hooks/useListSchema.ts +108 -58
- package/.framework/src/instructions/README.md +57 -0
- package/.framework/src/instructions/ai-agents.md +69 -0
- package/.framework/src/instructions/alerts.md +80 -0
- package/.framework/src/instructions/api-keys.md +87 -0
- package/.framework/src/instructions/apps.md +77 -0
- package/.framework/src/instructions/concepts/ai-and-prompts.md +150 -0
- package/.framework/src/instructions/concepts/apps-and-renderers.md +162 -0
- package/.framework/src/instructions/concepts/auth-and-api-keys.md +133 -0
- package/.framework/src/instructions/concepts/automation.md +186 -0
- package/.framework/src/instructions/concepts/concurrency-and-idempotency.md +125 -0
- package/.framework/src/instructions/concepts/core-vs-custom.md +124 -0
- package/.framework/src/instructions/concepts/design-schema.md +152 -0
- package/.framework/src/instructions/concepts/integrations-and-webhooks.md +127 -0
- package/.framework/src/instructions/concepts/observability.md +116 -0
- package/.framework/src/instructions/concepts/permissions.md +150 -0
- package/.framework/src/instructions/concepts/runtime-records.md +111 -0
- package/.framework/src/instructions/concepts/scope-and-accounts.md +112 -0
- package/.framework/src/instructions/concepts/spine-way.md +172 -0
- package/.framework/src/instructions/deliveries.md +59 -0
- package/.framework/src/instructions/guide/00-orientation.md +106 -0
- package/.framework/src/instructions/guide/01-install-and-first-run.md +253 -0
- package/.framework/src/instructions/guide/02-project-map.md +147 -0
- package/.framework/src/instructions/guide/03-domain-model.md +223 -0
- package/.framework/src/instructions/guide/04-first-app.md +227 -0
- package/.framework/src/instructions/guide/05-glossary.md +183 -0
- package/.framework/src/instructions/integrations.md +96 -0
- package/.framework/src/instructions/internal/cil-markers.md +83 -0
- package/.framework/src/instructions/invites.md +60 -0
- package/.framework/src/instructions/kb.md +80 -0
- package/.framework/src/instructions/logs.md +77 -0
- package/.framework/src/instructions/observability.md +61 -0
- package/.framework/src/instructions/operations/deployment.md +115 -0
- package/.framework/src/instructions/operations/migrations.md +125 -0
- package/.framework/src/instructions/operations/security-checklist.md +148 -0
- package/.framework/src/instructions/operations/troubleshooting.md +170 -0
- package/.framework/src/instructions/operations/upgrade.md +116 -0
- package/.framework/src/instructions/pipeline-executions.md +62 -0
- package/.framework/src/instructions/pipelines.md +78 -0
- package/.framework/src/instructions/prompts.md +95 -0
- package/.framework/src/instructions/reference/api/admin-data.md +162 -0
- package/.framework/src/instructions/reference/api/auth.md +113 -0
- package/.framework/src/instructions/reference/api/errors-and-envelopes.md +113 -0
- package/.framework/src/instructions/reference/app-manifest.md +150 -0
- package/.framework/src/instructions/reference/cli.md +124 -0
- package/.framework/src/instructions/reference/database.md +132 -0
- package/.framework/src/instructions/reference/design-schema.md +280 -0
- package/.framework/src/instructions/reference/env-vars.md +133 -0
- package/.framework/src/instructions/reference/functions/account-nodes.md +75 -0
- package/.framework/src/instructions/reference/functions/admin-data.md +195 -0
- package/.framework/src/instructions/reference/functions/admin-funnel.md +90 -0
- package/.framework/src/instructions/reference/functions/admin-install-funnel.md +107 -0
- package/.framework/src/instructions/reference/functions/admin-signals.md +102 -0
- package/.framework/src/instructions/reference/functions/ai-agents.md +148 -0
- package/.framework/src/instructions/reference/functions/ai-interactions.md +156 -0
- package/.framework/src/instructions/reference/functions/api-keys.md +130 -0
- package/.framework/src/instructions/reference/functions/apps.md +140 -0
- package/.framework/src/instructions/reference/functions/auth.md +99 -0
- package/.framework/src/instructions/reference/functions/debug-auth.md +91 -0
- package/.framework/src/instructions/reference/functions/deliveries.md +110 -0
- package/.framework/src/instructions/reference/functions/embeddings.md +166 -0
- package/.framework/src/instructions/reference/functions/eval-harness.md +149 -0
- package/.framework/src/instructions/reference/functions/index.md +103 -0
- package/.framework/src/instructions/reference/functions/integration-outbound.md +200 -0
- package/.framework/src/instructions/reference/functions/integration-routes.md +151 -0
- package/.framework/src/instructions/reference/functions/integrations.md +130 -0
- package/.framework/src/instructions/reference/functions/invites.md +182 -0
- package/.framework/src/instructions/reference/functions/item-progress.md +107 -0
- package/.framework/src/instructions/reference/functions/kb.md +166 -0
- package/.framework/src/instructions/reference/functions/logs.md +141 -0
- package/.framework/src/instructions/reference/functions/observability.md +105 -0
- package/.framework/src/instructions/reference/functions/pipeline-executions.md +132 -0
- package/.framework/src/instructions/reference/functions/pipeline-runner-background.md +121 -0
- package/.framework/src/instructions/reference/functions/pipelines.md +136 -0
- package/.framework/src/instructions/reference/functions/prompt-configs.md +121 -0
- package/.framework/src/instructions/reference/functions/roles.md +121 -0
- package/.framework/src/instructions/reference/functions/security.md +140 -0
- package/.framework/src/instructions/reference/functions/system-cron.md +136 -0
- package/.framework/src/instructions/reference/functions/system.md +106 -0
- package/.framework/src/instructions/reference/functions/tests.md +97 -0
- package/.framework/src/instructions/reference/functions/timers.md +117 -0
- package/.framework/src/instructions/reference/functions/trigger-scheduler.md +102 -0
- package/.framework/src/instructions/reference/functions/triggers.md +140 -0
- package/.framework/src/instructions/reference/functions/types.md +146 -0
- package/.framework/src/instructions/reference/seeds.md +126 -0
- package/.framework/src/instructions/reference/shared-modules.md +127 -0
- package/.framework/src/instructions/reference/spine-config.md +114 -0
- package/.framework/src/instructions/roles.md +80 -0
- package/.framework/src/instructions/runtime-detail.md +70 -0
- package/.framework/src/instructions/runtime-list.md +77 -0
- package/.framework/src/instructions/security.md +67 -0
- package/.framework/src/instructions/tasks/add-a-pipeline.md +110 -0
- package/.framework/src/instructions/tasks/add-a-role.md +96 -0
- package/.framework/src/instructions/tasks/add-a-timer.md +114 -0
- package/.framework/src/instructions/tasks/add-a-trigger.md +106 -0
- package/.framework/src/instructions/tasks/add-a-type.md +151 -0
- package/.framework/src/instructions/tasks/add-a-webhook.md +108 -0
- package/.framework/src/instructions/tasks/add-an-ai-agent.md +108 -0
- package/.framework/src/instructions/tasks/add-an-integration.md +124 -0
- package/.framework/src/instructions/tasks/build-a-custom-page.md +118 -0
- package/.framework/src/instructions/tasks/package-and-install-an-app.md +127 -0
- package/.framework/src/instructions/tasks/test-your-code.md +108 -0
- package/.framework/src/instructions/tasks/write-a-function.md +132 -0
- package/.framework/src/instructions/tasks/write-a-migration.md +110 -0
- package/.framework/src/instructions/testing.md +59 -0
- package/.framework/src/instructions/timers.md +82 -0
- package/.framework/src/instructions/triggers.md +69 -0
- package/.framework/src/instructions/types.md +93 -0
- package/.framework/src/lib/branding.ts +128 -0
- package/.framework/src/pages/NoAppPage.tsx +3 -1
- package/.framework/src/pages/NotFoundPage.tsx +62 -31
- package/.framework/src/pages/SetupPage.tsx +5 -2
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +117 -106
- package/.framework/src/pages/admin/AIAgentsPage.tsx +86 -48
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +153 -152
- package/.framework/src/pages/admin/APIKeysPage.tsx +91 -90
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +29 -18
- package/.framework/src/pages/admin/AppDetailPage.tsx +6 -60
- package/.framework/src/pages/admin/AppsPage.tsx +104 -66
- package/.framework/src/pages/admin/DeliveriesPage.tsx +5 -5
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +5 -23
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +5 -26
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +7 -7
- package/.framework/src/pages/admin/IntegrationsPage.tsx +85 -43
- package/.framework/src/pages/admin/LogsPage.tsx +144 -76
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +223 -140
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +134 -113
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +108 -45
- package/.framework/src/pages/admin/PipelinesPage.tsx +160 -115
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +96 -98
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +101 -59
- package/.framework/src/pages/admin/RoleDetailPage.tsx +90 -79
- package/.framework/src/pages/admin/RolesPage.tsx +86 -43
- package/.framework/src/pages/admin/SecurityPage.tsx +1 -1
- package/.framework/src/pages/admin/TestingDashboard.tsx +16 -28
- package/.framework/src/pages/admin/TimerDetailPage.tsx +117 -100
- package/.framework/src/pages/admin/TimersPage.tsx +90 -62
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +90 -83
- package/.framework/src/pages/admin/TriggersPage.tsx +124 -99
- package/.framework/src/pages/admin/TypeDetailPage.tsx +152 -138
- package/.framework/src/pages/admin/TypesPage.tsx +90 -48
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +17 -25
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +17 -27
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +72 -40
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +321 -129
- package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +18 -29
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +26 -38
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +34 -46
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +189 -103
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +246 -136
- package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +11 -22
- package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +9 -20
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +26 -38
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +7 -26
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +3 -1
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +3 -1
- package/.framework/src/pages/auth/LoginPage.tsx +4 -2
- package/.framework/src/pages/auth/RegisterPage.tsx +3 -1
- package/.framework/templates/agent/AGENTS.md +150 -0
- package/.framework/templates/agent/skills/spine-add-ai-agent/SKILL.md +58 -0
- package/.framework/templates/agent/skills/spine-add-automation/SKILL.md +62 -0
- package/.framework/templates/agent/skills/spine-add-integration/SKILL.md +63 -0
- package/.framework/templates/agent/skills/spine-architect/SKILL.md +86 -0
- package/.framework/templates/agent/skills/spine-install-app/SKILL.md +72 -0
- package/.framework/templates/agent/skills/spine-migration/SKILL.md +75 -0
- package/.framework/templates/agent/skills/spine-new-app/SKILL.md +67 -0
- package/.framework/templates/agent/skills/spine-new-function/SKILL.md +65 -0
- package/.framework/templates/agent/skills/spine-new-type/SKILL.md +65 -0
- package/.framework/templates/agent/skills/spine-schema/SKILL.md +77 -0
- package/.framework/templates/agent/skills/spine-test/SKILL.md +67 -0
- package/.framework/templates/agent/skills/spine-troubleshoot/SKILL.md +74 -0
- package/.framework/templates/agent/skills/spine-upgrade/SKILL.md +69 -0
- package/.framework/templates/project.json +5 -1
- package/.framework/tests/unit/account-scoping-gates.test.ts +392 -0
- package/.framework/tests/unit/agent-files.test.ts +355 -0
- package/.framework/tests/unit/agent-runner.test.ts +496 -47
- package/.framework/tests/unit/api-keys-create-scope-gate.test.ts +160 -0
- package/.framework/tests/unit/api-keys-omit-secret-fields.test.ts +38 -0
- package/.framework/tests/unit/bootstrap.test.ts +242 -0
- package/.framework/tests/unit/cli-context-api-key.test.ts +114 -0
- package/.framework/tests/unit/debug-auth.test.ts +38 -0
- package/.framework/tests/unit/deliveries-account-scoping.test.ts +185 -0
- package/.framework/tests/unit/episode-lease.test.ts +695 -0
- package/.framework/tests/unit/integration-outbound-credentials.test.ts +167 -0
- package/.framework/tests/unit/integrations-audit-redaction.test.ts +130 -0
- package/.framework/tests/unit/kb-ingest-lease.test.ts +19 -0
- package/.framework/tests/unit/logging-app-id.test.ts +75 -0
- package/.framework/tests/unit/pipeline-runner-background.test.ts +120 -0
- package/.framework/tests/unit/pipeline-runner.test.ts +153 -1
- package/.framework/tests/unit/principal-cache.test.ts +15 -0
- package/.framework/tests/unit/system-context-denial.test.ts +145 -0
- package/.framework/tests/unit/system-cron.test.ts +240 -0
- package/.framework/tests/unit/timers.test.ts +159 -0
- package/.framework/tests/unit/trigger-engine.test.ts +278 -91
- package/.framework/tests/unit/trigger-scheduler.test.ts +78 -0
- package/README.md +125 -166
- package/config/tsconfig.cli.json +2 -2
- package/netlify.toml +5 -0
- package/package.json +15 -4
- package/templates/project/package-lock.json +2 -2
- package/.framework/docs/admin-routes.md +0 -76
- package/.framework/docs/api-docs-progress.md +0 -38
- package/.framework/docs/api-governance.md +0 -146
- package/.framework/docs/api-testing-results.md +0 -212
- package/.framework/docs/assembly-launch-guide.md +0 -138
- package/.framework/docs/audit-results.md +0 -590
- package/.framework/docs/db-api-inventory.md +0 -95
- package/.framework/docs/gap-remediation-backlog.md +0 -103
- package/.framework/docs/ui-adoption-verification.md +0 -111
- package/.framework/docs/ui-api-coverage.md +0 -84
- package/.framework/docs/v2-compatibility-audit.md +0 -228
- package/.framework/mcp/index.ts +0 -133
- package/.framework/mcp/load-env.ts +0 -60
- package/.framework/mcp/shared/app-manifest.ts +0 -275
- package/.framework/mcp/shared/db.ts +0 -477
- package/.framework/mcp/shared/kb.ts +0 -118
- package/.framework/mcp/tools/architect.ts +0 -431
- package/.framework/mcp/tools/cil/context.ts +0 -345
- package/.framework/mcp/tools/cil/graph.ts +0 -242
- package/.framework/mcp/tools/cil/ingest.ts +0 -1217
- package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +0 -693
- package/.framework/mcp/tools/cil/pipeline.ts +0 -767
- package/.framework/mcp/tools/cil/project.ts +0 -791
- package/.framework/mcp/tools/cil/retrieval.ts +0 -336
- package/.framework/mcp/tools/cil/search-core.ts +0 -454
- package/.framework/mcp/tools/cil/search.ts +0 -97
- package/.framework/mcp/tools/cil/suggest.ts +0 -186
- package/.framework/mcp/tools/cil/validate.ts +0 -1369
- package/.framework/mcp/tools/kb/delete.ts +0 -139
- package/.framework/mcp/tools/kb/index.ts +0 -52
- package/.framework/mcp/tools/kb/ingest.ts +0 -84
- package/.framework/mcp/tools/kb/list-types.ts +0 -102
- package/.framework/mcp/tools/kb/publish.ts +0 -100
- package/.framework/mcp/tools/kb/reindex.ts +0 -86
- package/.framework/mcp/tools/kb/revoke.ts +0 -85
- package/.framework/mcp/tools/kb/search.ts +0 -101
- package/.framework/mcp/tools/kb/upsert.ts +0 -125
- 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"]
|