@uptimizr/collector-server 2.0.1 → 2.2.0

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 (139) hide show
  1. package/AGENTS.md +187 -11
  2. package/README.md +91 -7
  3. package/dist/__tests__/support/registryRequests.d.ts +2 -1
  4. package/dist/__tests__/support/registryRequests.d.ts.map +1 -1
  5. package/dist/__tests__/support/registryRequests.js +17 -1
  6. package/dist/__tests__/support/registryRequests.js.map +1 -1
  7. package/dist/__tests__/support/subscriptionFixtures.d.ts +63 -0
  8. package/dist/__tests__/support/subscriptionFixtures.d.ts.map +1 -0
  9. package/dist/__tests__/support/subscriptionFixtures.js +17 -0
  10. package/dist/__tests__/support/subscriptionFixtures.js.map +1 -0
  11. package/dist/agentReport.d.ts +256 -0
  12. package/dist/agentReport.d.ts.map +1 -0
  13. package/dist/agentReport.js +861 -0
  14. package/dist/agentReport.js.map +1 -0
  15. package/dist/app.d.ts +13 -0
  16. package/dist/app.d.ts.map +1 -1
  17. package/dist/app.js +112 -5
  18. package/dist/app.js.map +1 -1
  19. package/dist/audit.d.ts +5 -1
  20. package/dist/audit.d.ts.map +1 -1
  21. package/dist/audit.js +24 -4
  22. package/dist/audit.js.map +1 -1
  23. package/dist/auth.d.ts +41 -1
  24. package/dist/auth.d.ts.map +1 -1
  25. package/dist/auth.js +47 -0
  26. package/dist/auth.js.map +1 -1
  27. package/dist/cli.js +133 -13
  28. package/dist/cli.js.map +1 -1
  29. package/dist/cliStore.d.ts +31 -2
  30. package/dist/cliStore.d.ts.map +1 -1
  31. package/dist/cliStore.js +34 -0
  32. package/dist/cliStore.js.map +1 -1
  33. package/dist/clickhouseStore.d.ts.map +1 -1
  34. package/dist/clickhouseStore.js +44 -2
  35. package/dist/clickhouseStore.js.map +1 -1
  36. package/dist/config.d.ts +49 -0
  37. package/dist/config.d.ts.map +1 -1
  38. package/dist/config.js +21 -0
  39. package/dist/config.js.map +1 -1
  40. package/dist/connectionLimiter.d.ts +23 -0
  41. package/dist/connectionLimiter.d.ts.map +1 -0
  42. package/dist/connectionLimiter.js +24 -0
  43. package/dist/connectionLimiter.js.map +1 -0
  44. package/dist/duckdbStore.d.ts.map +1 -1
  45. package/dist/duckdbStore.js +44 -1
  46. package/dist/duckdbStore.js.map +1 -1
  47. package/dist/internalDispatch.d.ts +36 -0
  48. package/dist/internalDispatch.d.ts.map +1 -0
  49. package/dist/internalDispatch.js +50 -0
  50. package/dist/internalDispatch.js.map +1 -0
  51. package/dist/memoryStore.d.ts.map +1 -1
  52. package/dist/memoryStore.js +314 -1
  53. package/dist/memoryStore.js.map +1 -1
  54. package/dist/mssqlStore.d.ts.map +1 -1
  55. package/dist/mssqlStore.js +44 -2
  56. package/dist/mssqlStore.js.map +1 -1
  57. package/dist/postgresStore.d.ts.map +1 -1
  58. package/dist/postgresStore.js +44 -2
  59. package/dist/postgresStore.js.map +1 -1
  60. package/dist/projectMetadata.d.ts +82 -0
  61. package/dist/projectMetadata.d.ts.map +1 -0
  62. package/dist/projectMetadata.js +50 -0
  63. package/dist/projectMetadata.js.map +1 -0
  64. package/dist/routes/context.d.ts +135 -0
  65. package/dist/routes/context.d.ts.map +1 -0
  66. package/dist/routes/context.js +306 -0
  67. package/dist/routes/context.js.map +1 -0
  68. package/dist/routes/insights.d.ts +36 -0
  69. package/dist/routes/insights.d.ts.map +1 -0
  70. package/dist/routes/insights.js +810 -0
  71. package/dist/routes/insights.js.map +1 -0
  72. package/dist/routes/live.d.ts +8 -0
  73. package/dist/routes/live.d.ts.map +1 -1
  74. package/dist/routes/live.js +8 -7
  75. package/dist/routes/live.js.map +1 -1
  76. package/dist/routes/mcp.d.ts +36 -0
  77. package/dist/routes/mcp.d.ts.map +1 -0
  78. package/dist/routes/mcp.js +262 -0
  79. package/dist/routes/mcp.js.map +1 -0
  80. package/dist/routes/meta.d.ts +16 -2
  81. package/dist/routes/meta.d.ts.map +1 -1
  82. package/dist/routes/meta.js +699 -10
  83. package/dist/routes/meta.js.map +1 -1
  84. package/dist/routes/metadata.d.ts +31 -0
  85. package/dist/routes/metadata.d.ts.map +1 -0
  86. package/dist/routes/metadata.js +163 -0
  87. package/dist/routes/metadata.js.map +1 -0
  88. package/dist/routes/narrative.d.ts +36 -0
  89. package/dist/routes/narrative.d.ts.map +1 -0
  90. package/dist/routes/narrative.js +95 -0
  91. package/dist/routes/narrative.js.map +1 -0
  92. package/dist/routes/panels.d.ts +44 -0
  93. package/dist/routes/panels.d.ts.map +1 -0
  94. package/dist/routes/panels.js +108 -0
  95. package/dist/routes/panels.js.map +1 -0
  96. package/dist/routes/query-dsl.d.ts +50 -0
  97. package/dist/routes/query-dsl.d.ts.map +1 -0
  98. package/dist/routes/query-dsl.js +359 -0
  99. package/dist/routes/query-dsl.js.map +1 -0
  100. package/dist/routes/query.d.ts +36 -0
  101. package/dist/routes/query.d.ts.map +1 -1
  102. package/dist/routes/query.js +101 -13
  103. package/dist/routes/query.js.map +1 -1
  104. package/dist/routes/subscriptions.d.ts +52 -0
  105. package/dist/routes/subscriptions.d.ts.map +1 -0
  106. package/dist/routes/subscriptions.js +290 -0
  107. package/dist/routes/subscriptions.js.map +1 -0
  108. package/dist/store.d.ts +113 -2
  109. package/dist/store.d.ts.map +1 -1
  110. package/dist/subscriptions/cli.d.ts +36 -0
  111. package/dist/subscriptions/cli.d.ts.map +1 -0
  112. package/dist/subscriptions/cli.js +143 -0
  113. package/dist/subscriptions/cli.js.map +1 -0
  114. package/dist/subscriptions/delivery.d.ts +101 -0
  115. package/dist/subscriptions/delivery.d.ts.map +1 -0
  116. package/dist/subscriptions/delivery.js +165 -0
  117. package/dist/subscriptions/delivery.js.map +1 -0
  118. package/dist/subscriptions/evaluate.d.ts +119 -0
  119. package/dist/subscriptions/evaluate.d.ts.map +1 -0
  120. package/dist/subscriptions/evaluate.js +326 -0
  121. package/dist/subscriptions/evaluate.js.map +1 -0
  122. package/dist/subscriptions/scheduler.d.ts +97 -0
  123. package/dist/subscriptions/scheduler.d.ts.map +1 -0
  124. package/dist/subscriptions/scheduler.js +332 -0
  125. package/dist/subscriptions/scheduler.js.map +1 -0
  126. package/dist/subscriptions/stream.d.ts +40 -0
  127. package/dist/subscriptions/stream.d.ts.map +1 -0
  128. package/dist/subscriptions/stream.js +38 -0
  129. package/dist/subscriptions/stream.js.map +1 -0
  130. package/dist/version.d.ts +3 -0
  131. package/dist/version.d.ts.map +1 -0
  132. package/dist/version.js +25 -0
  133. package/dist/version.js.map +1 -0
  134. package/dist/webhookSignature.d.ts +64 -0
  135. package/dist/webhookSignature.d.ts.map +1 -0
  136. package/dist/webhookSignature.js +91 -0
  137. package/dist/webhookSignature.js.map +1 -0
  138. package/llms.txt +39 -2
  139. package/package.json +17 -14
package/llms.txt CHANGED
@@ -27,12 +27,49 @@
27
27
 
28
28
  ## Key facts
29
29
 
30
- - **CLI:** `uptimizr init | serve | new-project <name> | new-key <projectId> | migrate | regions set|get <sceneId> | help`. `new-key` takes `--capabilities`, `--label`, `--rate-limit-max`, `--rate-limit-window-ms`. Every command targets `COLLECTOR_STORE`.
31
- - **Capabilities:** `ingest` (server-side writes), `query` (aggregates, scene registry, live token, audit), `annotate` (project metadata writes), `query:raw` (raw per-session + live-follow streams). Default `query`.
30
+ - **CLI:** `uptimizr init | serve | new-project <name> | new-key <projectId> | migrate | regions set|get <sceneId> | agent report | help`. `new-key` takes `--capabilities`, `--label`, `--rate-limit-max`, `--rate-limit-window-ms`. Every command targets `COLLECTOR_STORE`.
31
+ - **Scheduled reports:** `uptimizr agent report --skill <attention_hotspots|conversion_investigation|performance_regression_triage|weekly_scene_health|xr_comfort_audit> [--scene] [--window 7d] [--out file|-] [--json file] [--webhook url] [--max-steps n] [--dry-run]` runs the headless agent loop once against the query API and writes Markdown (ADR 0051 §6). Provider config from the environment only, never persisted: `UPTIMIZR_AGENT_PROVIDER` (`anthropic`|`openai`|`scripted`), `UPTIMIZR_AGENT_MODEL`, `UPTIMIZR_AGENT_API_KEY`, `UPTIMIZR_AGENT_ENDPOINT`. Webhooks are signed `X-Uptimizr-Signature: sha256=<hex HMAC-SHA-256 of the raw body>` with `UPTIMIZR_WEBHOOK_SECRET`. Exit codes: 0 ok, 1 usage, 2 provider/delivery, 3 incomplete. Scheduling is the operator's (cron / systemd / GitHub Actions); the collector runs no LLM loop of its own.
32
+ - **Capabilities:** `ingest` (server-side writes), `query` (aggregates, scene registry, live token, audit), `annotate` (project metadata writes), `query:raw` (raw per-session + live-follow streams). `new-key` defaults to `query`; `init` / `new-project` mint one **owner** key (label `owner`) holding `query,query:raw,annotate`.
32
33
  - **Raw data is gated twice:** `ENABLE_RAW_SESSION_RETENTION` **and** a `query:raw` key, or `403`.
34
+ - **Query DSL (ADR 0051 §3):** `POST /api/v1/query` — and `GET /api/v1/query?q=<url-encoded JSON>` for GET-only clients — runs **any** registry metric from one closed, validated JSON document: `{ v, metric, range: { since, until }, filters?, dimensions?, limit?, format? }`. `range` is required, `format` defaults to `table`, `dimensions` must be the metric's own grain. No SQL and no free-form expression; anything outside the registry's vocabulary is a `400` whose `issues[].accepted` names what would have worked. `compare` / `segment` / `order` / `explain` / `filters.event` / `filters.device` parse but are not answered yet.
33
35
  - **Result envelopes:** `format=full | table | summary` on every aggregate endpoint (ADR 0051 §2) — `summary` is the bounded, LLM-affordable digest.
34
36
  - **Filters:** `since`, `until`, `bins`, `limit`, `scene`, `session`, `cameraMode`, `source`, `cellSize`, and `region=<id>` to drill a spatial query into a named place.
35
37
  - **Audit retention:** `AUDIT_RETENTION_DAYS` (default `30`, `0` = forever); `AUDIT_DASHBOARD_REQUESTS` to also record dashboard traffic.
36
38
  - **Stores:** `COLLECTOR_STORE=duckdb` (default, single-file, single-writer, `DUCKDB_PATH`) | `memory` | `postgres` | `mssql` | `clickhouse` — identical analytics on all four (parity suite).
37
39
  - **Required:** `VISITOR_HASH_SECRET`. The server fails fast without it; the raw IP is never stored.
40
+ - **Hosted MCP:** `COLLECTOR_MCP_HTTP=1` serves the Model Context Protocol over Streamable HTTP at `POST`/`GET`/`DELETE` `/mcp` (off by default) — the same server `@uptimizr/mcp` runs over stdio, so a remote agent needs only a URL + `x-api-key` (or `Authorization: Bearer`). Bounded by `COLLECTOR_MCP_MAX_SESSIONS` (50) and `COLLECTOR_MCP_SESSION_TTL_MS` (30 min); tool calls are audited with `surface: mcp-http`.
38
41
  - **Bins:** `uptimizr` (`dist/cli.js`) and the legacy `uptimizr-collector` (`dist/server.js`).
42
+
43
+ ## Session narrative (`query:raw`)
44
+
45
+ - `GET /api/v1/sessions/:id/narrative` — an ordered, compacted account of what one session did (scene changes, mesh dwell, interactions, perf dips, errors, end reason, then a totals entry), timestamps relative to the session start, bounded by `maxEntries` (default 200, hard cap 1000). Params: `minDwellMs`, `fpsThreshold`, `maxEntries`, `format=full|table|text`.
46
+ - Gated twice — `ENABLE_RAW_SESSION_RETENTION` **and** a `query:raw` key; either missing is `403`, an unknown session is `404`.
47
+ - `format=text` (this route only) is one line per entry — the cheapest way to put a whole session in a model's context.
48
+ - A projection, not the raw stream: no `visitorId`, URL or page metadata, no positions or rays, no `device` detail beyond the engine, custom-event property keys only (ADR 0003).
49
+ ## Conditional subscriptions (ADR 0051 §6)
50
+
51
+ - GET/POST /api/v1/subscriptions, GET/PATCH/DELETE /api/v1/subscriptions/:id,
52
+ GET /api/v1/subscriptions/:id/events, POST /api/v1/subscriptions/:id/test[?deliver=true],
53
+ GET /api/v1/subscriptions/stream?token= (SSE, live-token auth).
54
+ - Reads need `query`; every write and `test` needs `annotate`.
55
+ - Predicate kinds: threshold, anomaly, movers, new_value, presence. `every` >= 1m,
56
+ `window` >= 1h. 100 subscriptions per project; last 100 firings retained each.
57
+ - A webhook secret is write-only and never returned. Webhook egress is disabled until
58
+ COLLECTOR_WEBHOOK_ALLOWED_HOSTS names the hosts the collector may POST to.
59
+ - Bodies are signed `X-Uptimizr-Signature: sha256=<hex>` over the raw body, with
60
+ `X-Uptimizr-Delivery` for dedupe; 3 attempts with backoff.
61
+
62
+ ## Pinned panels (ADR 0051 §7)
63
+
64
+ - GET /api/v1/panels (needs `query`), POST /api/v1/panels, PUT /api/v1/panels/:id,
65
+ DELETE /api/v1/panels/:id (each needs `annotate`, each audited). OpenAPI operation ids
66
+ `list_panels`, `pin_panel`, `update_panel`, `unpin_panel` under the `panels` tag.
67
+ - A spec is `{ v, title, query, chart, encoding?, span, note? }` — **data**, drawn with panel
68
+ components `@uptimizr/react` already ships, so no module is loaded and nothing is evaluated.
69
+ `query.range` may be the literal `"inherit"` (follow the dashboard's filter bar) or an explicit
70
+ `{ since, until }`.
71
+ - Validated twice: `panelSpecV1Schema` for the shape, then `validatePanelSpec` for the vocabulary
72
+ (does the metric exist, does the chart suit its grain, do the encoding columns exist). A failure
73
+ is `400 { error, issues }` — the same body `POST /api/v1/query` answers with.
74
+ - Listed **oldest first** (grid positions, not a feed). `PUT` is a full replacement and keeps the
75
+ row's id and original authorship; an unknown id is `404`. `409` past 50 panels per project.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uptimizr/collector-server",
3
- "version": "2.0.1",
3
+ "version": "2.2.0",
4
4
  "description": "Uptimizr ingestion + query API (Fastify). Self-hostable collector for the OSS data-collector.",
5
5
  "keywords": [
6
6
  "uptimizr",
@@ -43,22 +43,25 @@
43
43
  "@fastify/cors": "^11.3.0",
44
44
  "@fastify/helmet": "^13.1.1",
45
45
  "@fastify/rate-limit": "^11.2.0",
46
- "@fastify/static": "^10.1.3",
47
- "fastify": "^5.12.3",
46
+ "@fastify/static": "^10.1.4",
47
+ "@modelcontextprotocol/sdk": "^1.30.0",
48
+ "fastify": "^5.12.5",
48
49
  "fastify-type-provider-zod": "^7.0.0",
49
- "zod": "^4.5.4",
50
- "@uptimizr/db-clickhouse": "2.0.1",
51
- "@uptimizr/db": "2.0.0",
52
- "@uptimizr/db-postgres": "2.0.1",
53
- "@uptimizr/metrics": "0.1.0",
54
- "@uptimizr/schema": "1.1.0",
55
- "@uptimizr/db-mssql": "2.0.1"
50
+ "zod": "^4.6.5",
51
+ "@uptimizr/db-mssql": "2.1.0",
52
+ "@uptimizr/agent-core": "1.2.0",
53
+ "@uptimizr/db-postgres": "2.1.0",
54
+ "@uptimizr/db-clickhouse": "2.1.0",
55
+ "@uptimizr/db": "2.1.0",
56
+ "@uptimizr/mcp": "1.2.0",
57
+ "@uptimizr/schema": "1.2.0",
58
+ "@uptimizr/metrics": "0.2.0"
56
59
  },
57
60
  "devDependencies": {
58
- "@seriousme/openapi-schema-validator": "^2.9.1",
59
- "@types/node": "^26.4.1",
60
- "tsx": "^4.23.13",
61
- "vitest": "^4.1.11"
61
+ "@seriousme/openapi-schema-validator": "^2.10.0",
62
+ "@types/node": "^26.6.2",
63
+ "tsx": "^4.23.15",
64
+ "vitest": "^5.0.1"
62
65
  },
63
66
  "scripts": {
64
67
  "build": "tsc -p tsconfig.json",