@uptimizr/db 1.0.2 → 2.0.1

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 (85) hide show
  1. package/AGENTS.md +103 -1
  2. package/README.md +100 -3
  3. package/dist/cli/createProject.js +23 -6
  4. package/dist/cli/createProject.js.map +1 -1
  5. package/dist/cli/seed.js +14 -4
  6. package/dist/cli/seed.js.map +1 -1
  7. package/dist/duckdb/audit.d.ts +13 -0
  8. package/dist/duckdb/audit.d.ts.map +1 -0
  9. package/dist/duckdb/audit.js +67 -0
  10. package/dist/duckdb/audit.js.map +1 -0
  11. package/dist/duckdb/migrations.d.ts.map +1 -1
  12. package/dist/duckdb/migrations.js +97 -0
  13. package/dist/duckdb/migrations.js.map +1 -1
  14. package/dist/duckdb/projects.d.ts +9 -5
  15. package/dist/duckdb/projects.d.ts.map +1 -1
  16. package/dist/duckdb/projects.js +54 -24
  17. package/dist/duckdb/projects.js.map +1 -1
  18. package/dist/duckdb/queries.d.ts +7 -0
  19. package/dist/duckdb/queries.d.ts.map +1 -1
  20. package/dist/duckdb/queries.js +10 -1
  21. package/dist/duckdb/queries.js.map +1 -1
  22. package/dist/duckdb/sceneRegions.d.ts +24 -0
  23. package/dist/duckdb/sceneRegions.d.ts.map +1 -0
  24. package/dist/duckdb/sceneRegions.js +72 -0
  25. package/dist/duckdb/sceneRegions.js.map +1 -0
  26. package/dist/index.d.ts +8 -2
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +18 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/metadata.d.ts +195 -9
  31. package/dist/metadata.d.ts.map +1 -1
  32. package/dist/metadata.js +192 -0
  33. package/dist/metadata.js.map +1 -1
  34. package/dist/parity/compare.d.ts +22 -0
  35. package/dist/parity/compare.d.ts.map +1 -1
  36. package/dist/parity/compare.js +31 -0
  37. package/dist/parity/compare.js.map +1 -1
  38. package/dist/query/aggregations.d.ts +8 -0
  39. package/dist/query/aggregations.d.ts.map +1 -1
  40. package/dist/query/aggregations.js +78 -0
  41. package/dist/query/aggregations.js.map +1 -1
  42. package/dist/query/coerce.d.ts +94 -0
  43. package/dist/query/coerce.d.ts.map +1 -0
  44. package/dist/query/coerce.js +191 -0
  45. package/dist/query/coerce.js.map +1 -0
  46. package/dist/query/summary/cluster.d.ts +78 -0
  47. package/dist/query/summary/cluster.d.ts.map +1 -0
  48. package/dist/query/summary/cluster.js +200 -0
  49. package/dist/query/summary/cluster.js.map +1 -0
  50. package/dist/query/summary/columns.d.ts +66 -0
  51. package/dist/query/summary/columns.d.ts.map +1 -0
  52. package/dist/query/summary/columns.js +98 -0
  53. package/dist/query/summary/columns.js.map +1 -0
  54. package/dist/query/summary/format.d.ts +31 -0
  55. package/dist/query/summary/format.d.ts.map +1 -0
  56. package/dist/query/summary/format.js +119 -0
  57. package/dist/query/summary/format.js.map +1 -0
  58. package/dist/query/summary/index.d.ts +19 -0
  59. package/dist/query/summary/index.d.ts.map +1 -0
  60. package/dist/query/summary/index.js +16 -0
  61. package/dist/query/summary/index.js.map +1 -0
  62. package/dist/query/summary/reading.d.ts +26 -0
  63. package/dist/query/summary/reading.d.ts.map +1 -0
  64. package/dist/query/summary/reading.js +169 -0
  65. package/dist/query/summary/reading.js.map +1 -0
  66. package/dist/query/summary/schema.d.ts +217 -0
  67. package/dist/query/summary/schema.d.ts.map +1 -0
  68. package/dist/query/summary/schema.js +167 -0
  69. package/dist/query/summary/schema.js.map +1 -0
  70. package/dist/query/summary/stats.d.ts +33 -0
  71. package/dist/query/summary/stats.d.ts.map +1 -0
  72. package/dist/query/summary/stats.js +73 -0
  73. package/dist/query/summary/stats.js.map +1 -0
  74. package/dist/query/summary/summarize.d.ts +57 -0
  75. package/dist/query/summary/summarize.d.ts.map +1 -0
  76. package/dist/query/summary/summarize.js +424 -0
  77. package/dist/query/summary/summarize.js.map +1 -0
  78. package/dist/query/summary/types.d.ts +223 -0
  79. package/dist/query/summary/types.d.ts.map +1 -0
  80. package/dist/query/summary/types.js +8 -0
  81. package/dist/query/summary/types.js.map +1 -0
  82. package/dist/query/types.d.ts +13 -0
  83. package/dist/query/types.d.ts.map +1 -1
  84. package/llms.txt +7 -3
  85. package/package.json +8 -2
package/AGENTS.md CHANGED
@@ -9,7 +9,9 @@ The OSS storage contracts plus the single-file **DuckDB** store (ADR 0020):
9
9
 
10
10
  - **DuckDB** — one persisted `.duckdb` file holding both events and metadata. A wide `events`
11
11
  table (hot fields promoted to columns; the full event preserved as JSON in `payload` so reads
12
- stay replay-complete) plus `projects` / `api_keys` (stored only as SHA-256 hashes).
12
+ stay replay-complete) plus `projects` / `api_keys` (stored only as SHA-256 hashes, each key
13
+ carrying a capability set, an optional label and an optional per-key rate limit) and the
14
+ `agent_audit` trail.
13
15
  - **Engine-neutral contracts** — the dialect-agnostic query layer (`buildX` + `Dialect`), the
14
16
  neutral event-row mapper (`toEventRow`, `formatUtcTimestamp`), and the metadata types
15
17
  (`Project`, `ApiKeyRecord`, `SceneRepresentation*`). An optional, separately-licensed
@@ -64,12 +66,112 @@ every tool (collector + CLIs) shares one canonical file regardless of cwd.
64
66
  - A new aggregation = a pure `buildX(projectId, opts, dialect)` builder returning a `QuerySpec`
65
67
  (`{ query, query_params }`), run with `runDuckdbQuery`. Keep builders pure, dialect-agnostic,
66
68
  and unit-tested without a live database; add a `PARITY_CASES` entry so both engines stay equal.
69
+ - **A new aggregation is not done until it has a metric-registry entry** (see below). The build
70
+ fails without one.
67
71
  - Validate events upstream at the collector boundary; this layer assumes valid input.
68
72
  - API keys are only ever stored as SHA-256 hashes — never persist raw keys.
73
+ - **Key capabilities are a set, not a role** (ADR 0051 §7): `ingest`, `query`, `annotate`,
74
+ `query:raw`, persisted as a canonical comma-separated token list in `api_keys.capabilities`.
75
+ Always read it with `parseApiKeyCapabilities(capabilities, capability)` so a key issued before
76
+ the set existed still resolves via the legacy singular column; always write it with
77
+ `toApiKeyColumns()` so ordering, validation and the per-key rate-limit columns stay consistent
78
+ across all four engines. `query:raw` is only ever honoured by a collector running with
79
+ `ENABLE_RAW_SESSION_RETENTION` (ADR 0003).
80
+ - **The audit log records key ids, never keys.** `agent_audit` rows carry `key_id`; serialize
81
+ parameters with `serializeAuditParams()` (drops credential-shaped keys, bounds the document)
82
+ before they reach a store, and clamp the endpoint with `clampAuditTool()`.
69
83
  - **Single-writer store.** DuckDB allows only one read-write process per file; assume a single
70
84
  collector per `.duckdb` file. Back up = copy the file. Multi-writer / horizontal scale is the
71
85
  optional ClickHouse scale tier, not this package.
72
86
 
87
+ ## Metric registry (ADR 0051 §1)
88
+
89
+ [`@uptimizr/metrics`](../metrics) is the semantic layer over the aggregations: one
90
+ `MetricDefinition` per exported `build*` (plus two builder-less resource entries — `session_meta`,
91
+ `scene_representation`) declaring id, title, agent-facing description, builder, collector endpoint,
92
+ `grain`, `dimensions`, `filters`, the output `row` Zod schema, per-column semantics (unit /
93
+ measure / label / axis / `rateOf`), row `limits`, `interpretation`, `caveats`, `sourceChannels`
94
+ (the ADR 0012 capture dials that must be on for the metric to have data), `related` metrics,
95
+ `comparable` semantics and a `category`. `DimensionId` / `FilterId` are closed unions declared
96
+ once; `FILTER_TARGETS` maps each filter to the `query/types.ts` option field it drives.
97
+
98
+ ```ts
99
+ import { getMetric, allMetrics, METRIC_IDS } from "@uptimizr/metrics";
100
+ ```
101
+
102
+ Its own **package**, not a subpath here, because this one depends on the ~37 MB
103
+ `@duckdb/node-api` native binding and the registry's consumers (`@uptimizr/agent-core`,
104
+ `@uptimizr/mcp`, `@uptimizr/react`) can never use a database driver. `@uptimizr/metrics` imports
105
+ **only** `zod` plus a type-only `@uptimizr/schema` declaration, performs no I/O and holds no store
106
+ or dialect reference.
107
+
108
+ ### Numeric coercion at the store edge (ADR 0051 §2)
109
+
110
+ Numeric columns are strict `z.number()` — the schema describes the API, not the wire. Every
111
+ `build*` tags its `QuerySpec` with the metric id, and each store's runner (`runDuckdbQuery`,
112
+ `runClickhouseQuery`, `runPostgresQuery`, `runMssqlQuery`) calls `coerceRows(spec.metric, rows)` at
113
+ the one point rows leave the driver, so a string-encoded 64-bit integer or decimal becomes a number
114
+ before any consumer sees it. `null` passes through — an aggregate over an empty set is "no
115
+ samples", not `0`, which is why nine perf/resource metrics declare nullable columns.
116
+
117
+ - **Do not** reintroduce `z.coerce.number()` in `registry.ts`: a registry test proves that
118
+ string-encoded rows _fail_ the strict schema and _pass_ after `coerceRows`, which is what pins
119
+ the work to the edge.
120
+ - A new store must call `coerceRows` in its runner; the parity suite asserts
121
+ `typeof === "number"` for every registry-numeric column on every engine (`numericColumnsForSpec`).
122
+ - Junk in a numeric column throws under a test runner and is left untouched with a one-per-column
123
+ warning in production (`coerceRows(..., { strict })` pins either).
124
+
125
+ **Rules for agents:**
126
+
127
+ - A `build*` aggregation added here must also be added to `AGGREGATION_BUILDER_NAMES` in
128
+ `@uptimizr/metrics`, and given a registry entry. Missing the entry is a **compile error**
129
+ (`NoUnregisteredAggregations` names the missing builder); missing the list entry fails this
130
+ package's `registry.test.ts` at runtime and names it too.
131
+ - **Never import `@uptimizr/db` from `@uptimizr/metrics`.** The dependency runs one way only —
132
+ that is the whole point of the split. The builder-name list is literal data for that reason.
133
+ - The 20 ids that are already `@uptimizr/agent-core` tool names (`top_meshes`, `perf_summary`,
134
+ `list_sessions`, …) are frozen — renaming one breaks every MCP client.
135
+ - `row` must match what the SQL actually projects, not what `types.ts` declares. It is also the
136
+ collector's **response schema**, so an undeclared column is stripped from the API and a `null` in
137
+ a non-nullable one is a 500. Four suites enforce this: `@uptimizr/metrics`' `registry.test.ts`
138
+ (coverage, internal consistency), this package's `registry.test.ts` (the builder link, plus `row`
139
+ parsing against real DuckDB output over the parity fixtures and the string-encoded ClickHouse
140
+ shape through `coerceRows`), the collector's `registryRoutes.test.ts` (endpoint exists;
141
+ querystring keys === `filters`) and its `queryResponseSchemas.test.ts` (every endpoint, against a
142
+ seeded store, an empty one, and the in-memory store).
143
+
144
+ ### Result envelopes (ADR 0051 §2, `@uptimizr/db/summary`)
145
+
146
+ `summarizeRows(metric, rows, ctx)` and `tableResult(metric, rows, ctx)` build the collector's
147
+ `format=table | summary` envelopes. Pure, registry-driven, browser-safe; the collector calls them
148
+ from one `preSerialization` hook, so no route handler knows they exist.
149
+
150
+ ```ts
151
+ import { summarizeRows, tableResult, clusterCells, wilsonInterval } from "@uptimizr/db/summary";
152
+ ```
153
+
154
+ The `grain` selects the shape — `ranked` (top rows + `rest`), `series` (first/last/min/max/trend/
155
+ slope over the `axis` column), `clusters` (`clusterCells`: deterministic greedy merge of adjacent
156
+ occupied cells above a density threshold, 8-neighbourhood in 2D / 26 in 3D), or `record` (the single
157
+ row plus its `rateOf` rates). Everything is bounded by `limits.maxSummaryRows`.
158
+
159
+ **Rules for agents:**
160
+
161
+ - A metric's summary comes from its **column semantics**, never from a per-metric special case. If a
162
+ metric summarises badly, fix its `unit` / `measure` / `label` / `axis` / `rateOf` declarations.
163
+ - A `bucket`-grain metric must declare exactly one `axis: true` column, and no other grain may
164
+ declare one (`@uptimizr/metrics`' `registry.test.ts`). `label` cannot stand in — `mesh_trend`
165
+ labels rows by mesh.
166
+ - **`reading` is templated, never model-written**, and must never contain `undefined` or `NaN`; run
167
+ every value through `format.ts`'s total formatters.
168
+ - Report `total`/`share` only for an **additive** unit. Summing FPS, a ratio or a percentile across
169
+ rows is meaningless, and a share derived from it is worse than none.
170
+ - Clustering must stay a pure function of the cell _set_: accumulate in sorted coordinate order so a
171
+ reordered input is bit-identical (`summary.test.ts` rotates every fixture).
172
+ - Adding `format` to a metric's `filters` and to the collector's querystring is one change — the
173
+ collector's `registryRoutes.test.ts` fails if they drift.
174
+
73
175
  ## Cross-engine parity (ADR 0020)
74
176
 
75
177
  The dialect-agnostic aggregations (`buildX(projectId, opts, dialect)`) are rendered per engine
package/README.md CHANGED
@@ -7,10 +7,17 @@ The OSS storage contracts plus the single-file **DuckDB** store:
7
7
  table (hot fields like camera `position`/`direction`, pointer `screen`, `mesh`, `fps` promoted to
8
8
  columns; the full event preserved as JSON in `payload` so reads stay replay-complete) plus a
9
9
  dedicated `node_samples` table for high-cardinality `node_transform` rows, and `projects` /
10
- `api_keys` (stored only as SHA-256 hashes, with `query` / `ingest` capability).
10
+ `api_keys` (stored only as SHA-256 hashes, each carrying a **capability set** —
11
+ `query` / `query:raw` / `annotate` / `ingest` — an optional label and an optional per-key rate
12
+ limit), plus an `agent_audit` trail of what each key asked for (ADR 0051 §7).
11
13
  - **Engine-neutral contracts** — the dialect-agnostic query layer (`buildX` + `Dialect`), the
12
14
  neutral event-row mappers (`toEventRow`, `toNodeSampleRow`, `formatUtcTimestamp`), and the
13
- metadata types (`Project`, `ApiKeyRecord`, `ResolvedApiKey`, `SceneRepresentation*`).
15
+ metadata types (`Project`, `ApiKeyRecord`, `ResolvedApiKey`, `SceneRepresentation*`,
16
+ `SceneRegionRecord` / `SceneRegionSummary`).
17
+ - **Scene registry metadata** — `scene_representations` (one proxy per scene) and
18
+ `scene_regions` (named, labelled boxes per scene, keyed `(project_id, scene_id, region_id)`).
19
+ `duckdbPutSceneRegions` replaces a scene's whole set in one transaction; `duckdbGetSceneRegions`
20
+ / `duckdbListSceneRegions` read it back.
14
21
 
15
22
  This package carries **no ClickHouse/Postgres dependency**. Optional scale adapters such as
16
23
  `@uptimizr/db-clickhouse` compose these contracts behind the same interface. Server/Node only — no
@@ -63,6 +70,95 @@ CLIs all share one canonical file regardless of which package they run from. The
63
70
  its backend with `COLLECTOR_STORE` (`duckdb` by default; `clickhouse` and `memory` are also wired in
64
71
  `@uptimizr/collector-server`).
65
72
 
73
+ ## Metric registry (`@uptimizr/metrics`)
74
+
75
+ The semantic layer over these aggregations — **what every aggregation means** — lives in its own
76
+ package, [`@uptimizr/metrics`](../metrics). It is a `Readonly<Record<MetricId, MetricDefinition>>`
77
+ with one entry per exported `build*` aggregation (plus two builder-less "resource" entries for the
78
+ session descriptor and the scene representation), declaring the metric's id, title, agent-facing
79
+ description, the builder behind it, its collector endpoint, result `grain`, group-by `dimensions`,
80
+ accepted `filters`, the output `row` schema (Zod), per-column semantics (unit, measure, label,
81
+ `rateOf`), row `limits`, how to read the result (`interpretation`), the `caveats` that make it
82
+ untrustworthy, the capture channels that feed it (`sourceChannels`, ADR 0012), `related` metrics
83
+ and comparison semantics. `DimensionId` and `FilterId` are closed unions declared once, and
84
+ `FILTER_TARGETS` maps each filter to the option field in `query/types.ts` it drives. (ADR 0051 §1.)
85
+
86
+ ```ts
87
+ import { METRIC_REGISTRY, getMetric, allMetrics } from "@uptimizr/metrics";
88
+
89
+ const metric = getMetric("top_meshes");
90
+ metric?.endpoint; // { method: "GET", path: "/api/v1/meshes/top" }
91
+ metric?.row.parse(row); // validates one result row
92
+ ```
93
+
94
+ It is a **separate package**, not a subpath of this one, because this package depends on
95
+ `@duckdb/node-api` — a ~37 MB native binding — while the registry's consumers
96
+ (`@uptimizr/agent-core`, `@uptimizr/mcp`, `@uptimizr/react`) run in a browser or over `npx` and
97
+ can never use a database driver. `@uptimizr/metrics` imports nothing but `zod` and a _type-only_
98
+ declaration from `@uptimizr/schema`, so it is pure data with no I/O.
99
+
100
+ ### Numbers are numbers (ADR 0051 §2)
101
+
102
+ Every numeric column in a `row` schema is a strict `z.number()`, because that is what the collector
103
+ actually emits. Engines disagree about the wire — ClickHouse renders 64-bit integers and decimals
104
+ as JSON **strings** over HTTP, `pg` returns `int8`/`numeric` as strings without a type parser — so
105
+ each store's query runner normalises them at the single point rows leave its driver:
106
+
107
+ ```ts
108
+ import { coerceRows, numericColumns } from "@uptimizr/db";
109
+
110
+ coerceRows("top_meshes", [{ mesh: "box", count: "42" }]); // [{ mesh: "box", count: 42 }]
111
+ numericColumns(getMetric("top_meshes")!.row); // ["count"]
112
+ ```
113
+
114
+ `build*` aggregations tag their `QuerySpec` with the metric id, so `runDuckdbQuery`,
115
+ `runClickhouseQuery`, `runPostgresQuery` and `runMssqlQuery` each apply `coerceRows` with no work
116
+ at the call site. `null` stays `null` — an aggregate over an empty set is "no samples", never `0`.
117
+ A value that is neither a number, `null`, nor a finite numeric string **throws** under a test runner
118
+ and is left untouched with a one-per-column warning in production; pass `{ strict }` to pin either.
119
+ The parity suites assert `typeof === "number"` for every registry-numeric column on every engine.
120
+
121
+ > **A new aggregation is not done until it has a registry entry.** Add the `build*` name to
122
+ > `AGGREGATION_BUILDER_NAMES` and a `MetricDefinition` to `METRIC_REGISTRY` in
123
+ > `@uptimizr/metrics`; its `NoUnregisteredAggregations` guard fails to typecheck and names the
124
+ > missing builder. This package's `src/__tests__/registry.test.ts` then asserts at runtime that
125
+ > `AGGREGATION_BUILDER_NAMES` is exactly the set of `build*` exports, and parses every `row`
126
+ > schema against real DuckDB output over the parity fixtures; the collector's
127
+ > `registryRoutes.test.ts` asserts that every `endpoint.path` is served and that its Zod
128
+ > querystring keys equal the registry `filters`.
129
+
130
+ ### Result envelopes (`@uptimizr/db/summary`, ADR 0051 §2)
131
+
132
+ The registry knows enough about a metric to **summarise** it, so the collector's
133
+ `format=table | summary` envelopes are built here rather than in a route handler. Pure, browser-safe
134
+ functions with no store and no I/O — published on their own subpath for the same reason the registry
135
+ is, and re-exported from the package root for Node consumers:
136
+
137
+ ```ts
138
+ import { summarizeRows, tableResult, clusterCells } from "@uptimizr/db/summary";
139
+
140
+ tableResult("top_meshes", rows, { range, filters, limit });
141
+ // { meta: { metric, range, filters, sampleSize, rows, truncated, limits }, rows }
142
+
143
+ summarizeRows("top_meshes", rows, { range, filters });
144
+ // { kind: "ranked", total, measure, top: [{ label, value, share, … }], rest, reading, caveats, … }
145
+ ```
146
+
147
+ The metric's `grain` picks the shape: `ranked` top rows for a leaderboard, a `series`
148
+ (first/last/min/max/trend/slope over the column flagged `axis`) for a time bucket, merged `clusters`
149
+ for a `bin`/`voxel` grid (`clusterCells` — a deterministic greedy merge of adjacent occupied cells
150
+ above a density threshold, 8-neighbourhood in 2D and 26 in 3D), and the `record` itself plus its
151
+ `rateOf` rates for a single-row metric. Everything is capped at `limits.maxSummaryRows`.
152
+
153
+ Two invariants worth knowing before extending it:
154
+
155
+ - **`reading` is templated, not generated.** It is assembled from `ColumnSemantics` alone, so the
156
+ same rows always produce the same sentence. Every number goes through total formatters — a
157
+ `reading` containing `undefined` or `NaN` is a test failure.
158
+ - **Shares are only claimed where they are true.** `total`, `share` and the Wilson `confidence` note
159
+ appear only when the measure's unit is additive; an FPS or ratio measure reports `null` and says
160
+ so in the `reading` rather than summing values that cannot be summed.
161
+
66
162
  ## Extending
67
163
 
68
164
  - **New columns / tables:** append a migration to `DUCKDB_MIGRATIONS`. Forward-only and additive —
@@ -73,7 +169,8 @@ its backend with `COLLECTOR_STORE` (`duckdb` by default; `clickhouse` and `memor
73
169
  `QuerySpec` (`{ query, query_params }`) using the `Dialect` fragments (never hard-code
74
170
  engine-specific SQL). Run it with `runDuckdbQuery(db, buildX(..., duckdbDialect))`; the scale
75
171
  path runs the _same_ builder with `clickhouseDialect`. Add a `PARITY_CASES` entry so both engines
76
- stay provably equal. Builders are pure and unit-tested without a live database.
172
+ stay provably equal, **and a `METRIC_REGISTRY` entry so consumers know what it means**. Builders
173
+ are pure and unit-tested without a live database.
77
174
 
78
175
  ## Develop
79
176
 
@@ -3,6 +3,7 @@ import { createApiKey as duckdbCreateApiKey, createProject as duckdbCreateProjec
3
3
  import { createDuckdbClient } from "../duckdb/client.js";
4
4
  import { migrateDuckdb } from "../duckdb/migrations.js";
5
5
  import { readDbSettings } from "../env.js";
6
+ import { parseCapabilityList } from "../metadata.js";
6
7
  /**
7
8
  * Create a project and issue an API key, then print the pair. Unlike `seed.ts`
8
9
  * (which writes the single demo project into the root `.env`), this CLI is meant
@@ -12,20 +13,36 @@ import { readDbSettings } from "../env.js";
12
13
  *
13
14
  * ```bash
14
15
  * pnpm --filter @uptimizr/db run new-project -- "My Scene"
16
+ * pnpm --filter @uptimizr/db run new-project -- --capabilities query,query:raw "My Scene"
15
17
  * ```
16
18
  *
19
+ * The key is read-only (`query`) by default. Session replay and the live
20
+ * per-session follow additionally need `query:raw` (#309, ADR 0051 §7), which
21
+ * the collector only honours when `ENABLE_RAW_SESSION_RETENTION` is on
22
+ * (ADR 0003).
23
+ *
17
24
  * Targets the OSS DuckDB store.
18
25
  */
19
26
  async function main() {
20
- const name = process.argv
21
- .slice(2)
22
- .filter((arg) => arg !== "--")
23
- .join(" ")
24
- .trim() || "Playground Project";
27
+ const args = process.argv.slice(2).filter((arg) => arg !== "--");
28
+ let capabilities = ["query"];
29
+ const words = [];
30
+ for (let i = 0; i < args.length; i += 1) {
31
+ const arg = args[i];
32
+ if (arg === "--capabilities" || arg.startsWith("--capabilities=")) {
33
+ const value = arg.includes("=") ? arg.slice(arg.indexOf("=") + 1) : args[++i];
34
+ if (!value)
35
+ throw new Error("Missing value for --capabilities");
36
+ capabilities = parseCapabilityList(value);
37
+ continue;
38
+ }
39
+ words.push(arg);
40
+ }
41
+ const name = words.join(" ").trim() || "Playground Project";
25
42
  const db = await createDuckdbClient(readDbSettings().duckdb.path);
26
43
  await migrateDuckdb(db);
27
44
  const project = await duckdbCreateProject(db, name);
28
- const { key } = await duckdbCreateApiKey(db, project.id);
45
+ const { key } = await duckdbCreateApiKey(db, project.id, { capabilities });
29
46
  await db.close();
30
47
  printResult(project.id, project.name, key);
31
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createProject.js","sourceRoot":"","sources":["../../src/cli/createProject.ts"],"names":[],"mappings":";AACA,OAAO,EACL,YAAY,IAAI,kBAAkB,EAClC,aAAa,IAAI,mBAAmB,GACrC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GACR,OAAO,CAAC,IAAI;SACT,KAAK,CAAC,CAAC,CAAC;SACR,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC;SAC7B,IAAI,CAAC,GAAG,CAAC;SACT,IAAI,EAAE,IAAI,oBAAoB,CAAC;IAEpC,MAAM,EAAE,GAAG,MAAM,kBAAkB,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,aAAa,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,kBAAkB,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACzD,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACjB,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,WAAW,CAAC,SAAiB,EAAE,IAAY,EAAE,MAAc;IAClE,OAAO,CAAC,KAAK,CAAC,sBAAsB,SAAS,KAAK,IAAI,GAAG,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,kDAAkD,MAAM,EAAE,CAAC,CAAC;IAC1E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"createProject.js","sourceRoot":"","sources":["../../src/cli/createProject.ts"],"names":[],"mappings":";AACA,OAAO,EACL,YAAY,IAAI,kBAAkB,EAClC,aAAa,IAAI,mBAAmB,GACrC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAyB,MAAM,gBAAgB,CAAC;AAE5E;;;;;;;;;;;;;;;;;;GAkBG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;IACjE,IAAI,YAAY,GAAuB,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACrB,IAAI,GAAG,KAAK,gBAAgB,IAAI,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAClE,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9E,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAChE,YAAY,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,oBAAoB,CAAC;IAE5D,MAAM,EAAE,GAAG,MAAM,kBAAkB,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,aAAa,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,kBAAkB,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3E,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACjB,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,WAAW,CAAC,SAAiB,EAAE,IAAY,EAAE,MAAc;IAClE,OAAO,CAAC,KAAK,CAAC,sBAAsB,SAAS,KAAK,IAAI,GAAG,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,kDAAkD,MAAM,EAAE,CAAC,CAAC;IAC1E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/cli/seed.js CHANGED
@@ -133,14 +133,24 @@ async function main() {
133
133
  const baseName = args[0] ?? "Demo Project";
134
134
  const db = await createDuckdbClient(readDbSettings().duckdb.path);
135
135
  await migrateDuckdb(db);
136
+ // Local development seed: the demo projects back the playground + dashboard,
137
+ // whose session replay and live-follow read raw per-session streams
138
+ // (`query:raw`, #309, ADR 0051 §7) and whose "Register scene regions" button is
139
+ // a metadata write (`annotate`). The collector still only honours `query:raw`
140
+ // when `ENABLE_RAW_SESSION_RETENTION` is on, which the repo's `.env.example`
141
+ // sets for local dev. This is the same owner set `uptimizr init` /
142
+ // `uptimizr new-project` mint, and the one `scripts/playground-new.mjs` and
143
+ // `scripts/scene-new.mjs` already ask for. Narrower, agent-scoped keys come
144
+ // from `uptimizr new-key`, which still defaults to `query` alone.
145
+ const devCapabilities = { capabilities: ["query", "query:raw", "annotate"] };
136
146
  const viewer = await createProject(db, `${baseName} (Viewer)`);
137
- const viewerKey = (await createApiKey(db, viewer.id)).key;
147
+ const viewerKey = (await createApiKey(db, viewer.id, devCapabilities)).key;
138
148
  const walkable = await createProject(db, `${baseName} (Walkable)`);
139
- const walkableKey = (await createApiKey(db, walkable.id)).key;
149
+ const walkableKey = (await createApiKey(db, walkable.id, devCapabilities)).key;
140
150
  const showcase = await createProject(db, `${baseName} (Showcase)`);
141
- const showcaseKey = (await createApiKey(db, showcase.id)).key;
151
+ const showcaseKey = (await createApiKey(db, showcase.id, devCapabilities)).key;
142
152
  const gallery = await createProject(db, `${baseName} (Gallery)`);
143
- const galleryKey = (await createApiKey(db, gallery.id)).key;
153
+ const galleryKey = (await createApiKey(db, gallery.id, devCapabilities)).key;
144
154
  await db.close();
145
155
  console.log(`✓ project created: ${viewer.id} (${viewer.name})`);
146
156
  console.log(` API key (store securely, shown once): ${viewerKey}`);
@@ -1 +1 @@
1
- {"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/cli/seed.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/cli/seed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;GAIG;AACH,SAAS,YAAY,CAAC,KAAa;IACjC,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,SAAS,CAAC;QACR,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAAC,IAAY,EAAE,GAAW,EAAE,KAAa;IACzD,MAAM,IAAI,GAAG,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,IAAI,IAAI,CAAC;AACxF,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ,CAAC,IAAY,EAAE,IAA4B;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,kDAAkD,CAAC,CAAC;QACxF,OAAO;IACT,CAAC;IAED,IAAI,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IACD,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAE7B,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC;AACvE,CAAC;AAyBD,2FAA2F;AAC3F,MAAM,WAAW,GAAc;IAC7B,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,gBAAgB;IACvB,WAAW,EAAE,8EAA8E;IAC3F,UAAU,EAAE,QAAQ;IACpB,OAAO,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC;IAC5E,aAAa,EAAE,SAAS;IACxB,OAAO,EAAE,IAAI;CACd,CAAC;AACF,MAAM,YAAY,GAAc;IAC9B,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,uBAAuB;IAC9B,WAAW,EACT,yFAAyF;IAC3F,UAAU,EAAE,cAAc;IAC1B,OAAO,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC;IAC3C,aAAa,EAAE,SAAS;IACxB,OAAO,EAAE,IAAI;CACd,CAAC;AACF,MAAM,cAAc,GAAc;IAChC,EAAE,EAAE,UAAU;IACd,KAAK,EAAE,6BAA6B;IACpC,WAAW,EACT,+FAA+F;IACjG,UAAU,EAAE,QAAQ;IACpB,OAAO,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC;IAC3C,aAAa,EAAE,SAAS;IACxB,OAAO,EAAE,KAAK;CACf,CAAC;AACF,MAAM,aAAa,GAAc;IAC/B,EAAE,EAAE,SAAS;IACb,KAAK,EAAE,gCAAgC;IACvC,WAAW,EACT,mJAAmJ;IACrJ,UAAU,EAAE,cAAc;IAC1B,OAAO,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC;IAC3C,aAAa,EAAE,SAAS;IACxB,OAAO,EAAE,KAAK;CACf,CAAC;AAEF;;;;GAIG;AACH,SAAS,aAAa,CAAC,IAAY,EAAE,OAAwB;IAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;IAC9D,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,IAAI,GAAoB,EAAE,CAAC;IAC/B,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;YACvE,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,IAAI,GAAG,MAAyB,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9C,iFAAiF;IACjF,iFAAiF;IACjF,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAClF,CAAC;IACF,MAAM,IAAI,GAAG;QACX,GAAG,IAAI,CAAC,MAAM,CACZ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,IAAI,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CACjF;QACD,GAAG,OAAO;KACX,CAAC;IACF,aAAa,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAElE,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,MAAM,kBAAkB,YAAY,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,cAAc,CAAC;IAC3C,MAAM,EAAE,GAAG,MAAM,kBAAkB,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,aAAa,CAAC,EAAE,CAAC,CAAC;IAExB,6EAA6E;IAC7E,oEAAoE;IACpE,gFAAgF;IAChF,8EAA8E;IAC9E,6EAA6E;IAC7E,mEAAmE;IACnE,4EAA4E;IAC5E,4EAA4E;IAC5E,kEAAkE;IAClE,MAAM,eAAe,GAAG,EAAE,YAAY,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,EAAW,CAAC;IACtF,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE,GAAG,QAAQ,WAAW,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,CAAC,MAAM,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3E,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE,GAAG,QAAQ,aAAa,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,CAAC,MAAM,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC;IAC/E,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE,GAAG,QAAQ,aAAa,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,CAAC,MAAM,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC;IAC/E,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE,GAAG,QAAQ,YAAY,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,CAAC,MAAM,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC;IAC7E,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IAEjB,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,2CAA2C,SAAS,EAAE,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,2CAA2C,WAAW,EAAE,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,2CAA2C,WAAW,EAAE,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,2CAA2C,UAAU,EAAE,CAAC,CAAC;IAErE,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE;QACb,eAAe,EAAE,MAAM,CAAC,EAAE;QAC1B,YAAY,EAAE,SAAS;QACvB,mBAAmB,EAAE,SAAS;QAC9B,wBAAwB,EAAE,QAAQ,CAAC,EAAE;QACrC,qBAAqB,EAAE,WAAW;KACnC,CAAC,CAAC;IACH,aAAa,CAAC,IAAI,EAAE;QAClB,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE;QACtF,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE;QAC7F,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE;QAC/F,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE;KAC5F,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type AgentAuditEntry, type AgentAuditInput, type AuditQueryOptions } from "../metadata.js";
2
+ import type { DuckdbClient } from "./client.js";
3
+ /** Append one audit row. */
4
+ export declare function recordAudit(client: DuckdbClient, entry: AgentAuditInput): Promise<void>;
5
+ /** Read a project's audit rows, newest first, within an optional time range. */
6
+ export declare function listAudit(client: DuckdbClient, projectId: string, opts?: AuditQueryOptions): Promise<AgentAuditEntry[]>;
7
+ /**
8
+ * Delete audit rows older than `cutoffMs` (epoch ms). Idempotent — deleting an
9
+ * already-empty range is a no-op — so the collector can run it on a timer.
10
+ * Returns nothing; the caller only needs to know it did not throw.
11
+ */
12
+ export declare function pruneAudit(client: DuckdbClient, cutoffMs: number): Promise<void>;
13
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/duckdb/audit.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAEvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA6ChD,4BAA4B;AAC5B,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB7F;AAED,gFAAgF;AAChF,wBAAsB,SAAS,CAC7B,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,eAAe,EAAE,CAAC,CAqB5B;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAItF"}
@@ -0,0 +1,67 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { clampAuditTool, } from "../metadata.js";
3
+ const AUDIT_COLS = `id, project_id, key_id, epoch_ms("at") AS at_ms, surface, tool_or_path,
4
+ params, row_count, duration_ms, status`;
5
+ function toEntry(row) {
6
+ return {
7
+ id: row.id,
8
+ projectId: row.project_id,
9
+ keyId: row.key_id,
10
+ at: new Date(Number(row.at_ms)),
11
+ surface: row.surface,
12
+ toolOrPath: row.tool_or_path,
13
+ params: row.params,
14
+ rowCount: row.row_count == null ? null : Number(row.row_count),
15
+ durationMs: Number(row.duration_ms),
16
+ status: Number(row.status),
17
+ };
18
+ }
19
+ /** Append one audit row. */
20
+ export async function recordAudit(client, entry) {
21
+ await client.run(`INSERT INTO agent_audit (id, project_id, key_id, "at", surface, tool_or_path, params,
22
+ row_count, duration_ms, status)
23
+ VALUES ($id, $projectId, $keyId, make_timestamp($atUs), $surface, $toolOrPath, $params,
24
+ CAST($rowCount AS BIGINT), $durationMs, $status)`, {
25
+ id: randomUUID(),
26
+ projectId: entry.projectId,
27
+ keyId: entry.keyId,
28
+ atUs: (entry.at?.getTime() ?? Date.now()) * 1000,
29
+ surface: entry.surface,
30
+ toolOrPath: clampAuditTool(entry.toolOrPath),
31
+ params: entry.params,
32
+ rowCount: entry.rowCount ?? null,
33
+ durationMs: Math.trunc(entry.durationMs),
34
+ status: Math.trunc(entry.status),
35
+ });
36
+ }
37
+ /** Read a project's audit rows, newest first, within an optional time range. */
38
+ export async function listAudit(client, projectId, opts = {}) {
39
+ const limit = Math.min(Math.max(Math.trunc(opts.limit ?? 100), 1), 1000);
40
+ const params = { projectId };
41
+ const where = ["project_id = $projectId"];
42
+ if (opts.since != null) {
43
+ where.push(`"at" >= make_timestamp($since)`);
44
+ params.since = Math.trunc(opts.since) * 1000;
45
+ }
46
+ if (opts.until != null) {
47
+ where.push(`"at" < make_timestamp($until)`);
48
+ params.until = Math.trunc(opts.until) * 1000;
49
+ }
50
+ const rows = await client.all(`SELECT ${AUDIT_COLS}
51
+ FROM agent_audit
52
+ WHERE ${where.join(" AND ")}
53
+ ORDER BY "at" DESC
54
+ LIMIT ${limit}`, params);
55
+ return rows.map(toEntry);
56
+ }
57
+ /**
58
+ * Delete audit rows older than `cutoffMs` (epoch ms). Idempotent — deleting an
59
+ * already-empty range is a no-op — so the collector can run it on a timer.
60
+ * Returns nothing; the caller only needs to know it did not throw.
61
+ */
62
+ export async function pruneAudit(client, cutoffMs) {
63
+ await client.run(`DELETE FROM agent_audit WHERE "at" < make_timestamp($cutoff)`, {
64
+ cutoff: Math.trunc(cutoffMs) * 1000,
65
+ });
66
+ }
67
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/duckdb/audit.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/duckdb/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAmUxE,CAAC;AAEF;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAQvE"}
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/duckdb/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAoaxE,CAAC;AAEF;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAQvE"}
@@ -331,6 +331,103 @@ export const DUCKDB_MIGRATIONS = [
331
331
  ALTER TABLE events ADD COLUMN IF NOT EXISTS near DOUBLE;
332
332
  `,
333
333
  },
334
+ // --- Agent-scoped keys (#309, ADR 0051 §7) --------------------------------
335
+ // The singular `capability` column becomes a capability *set*, stored as a
336
+ // canonical comma-separated token list in a plain text column (every engine
337
+ // stores and compares text natively — no JSON type needed). Forward-only and
338
+ // additive: `0027_api_keys_capability` stays untouched and keeps feeding the
339
+ // read path as the fallback for any row this backfill has not reached.
340
+ {
341
+ id: "0031_api_keys_capabilities",
342
+ sql: /* sql */ `
343
+ ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS capabilities VARCHAR;
344
+ `,
345
+ },
346
+ // Idempotent backfill: promote each legacy single capability to a one-element
347
+ // set, exactly once. Guarded on NULL/'' so re-running the migration on every
348
+ // boot is a no-op after the first (and never clobbers a key minted with a set).
349
+ {
350
+ id: "0032_api_keys_capabilities_backfill",
351
+ sql: /* sql */ `
352
+ UPDATE api_keys
353
+ SET capabilities = coalesce(nullif(capability, ''), 'query')
354
+ WHERE capabilities IS NULL OR capabilities = '';
355
+ `,
356
+ },
357
+ // Operator-supplied key name (`uptimizr new-key --label "weekly-report-agent"`).
358
+ {
359
+ id: "0033_api_keys_label",
360
+ sql: /* sql */ `
361
+ ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS label VARCHAR;
362
+ `,
363
+ },
364
+ // Optional per-key request budget. NULL on either half falls back to the
365
+ // collector's global COLLECTOR_RATE_LIMIT_* defaults.
366
+ {
367
+ id: "0034_api_keys_rate_limit_max",
368
+ sql: /* sql */ `
369
+ ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS rate_limit_max BIGINT;
370
+ `,
371
+ },
372
+ {
373
+ id: "0035_api_keys_rate_limit_window_ms",
374
+ sql: /* sql */ `
375
+ ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS rate_limit_window_ms BIGINT;
376
+ `,
377
+ },
378
+ // Agent audit log: one row per authenticated request made with a non-dashboard
379
+ // key. `params` is bounded and redacted before it is written (never the key);
380
+ // rows expire after AUDIT_RETENTION_DAYS. Metadata, not events — no event type
381
+ // is added (`@uptimizr/schema` untouched).
382
+ //
383
+ // `at` is a DuckDB keyword, so it is double-quoted here and in every accessor
384
+ // (`duckdb/audit.ts`). The column name matches the other three engines, where
385
+ // it needs no quoting.
386
+ {
387
+ id: "0036_agent_audit",
388
+ sql: /* sql */ `
389
+ CREATE TABLE IF NOT EXISTS agent_audit (
390
+ id VARCHAR PRIMARY KEY,
391
+ project_id VARCHAR NOT NULL,
392
+ key_id VARCHAR NOT NULL,
393
+ "at" TIMESTAMP NOT NULL DEFAULT now(),
394
+ surface VARCHAR NOT NULL DEFAULT 'http',
395
+ tool_or_path VARCHAR NOT NULL,
396
+ params VARCHAR NOT NULL DEFAULT '',
397
+ row_count BIGINT,
398
+ duration_ms BIGINT NOT NULL DEFAULT 0,
399
+ status INTEGER NOT NULL DEFAULT 200
400
+ );
401
+ `,
402
+ },
403
+ {
404
+ id: "0037_agent_audit_idx",
405
+ sql: /* sql */ `
406
+ CREATE INDEX IF NOT EXISTS agent_audit_project_at_idx
407
+ ON agent_audit (project_id, "at");
408
+ `,
409
+ },
410
+ // Scene regions (ADR 0051 §2 / sketch §B.2): developer-named, labelled boxes
411
+ // that extend the scene registry (ADR 0014) with a vocabulary for *where* —
412
+ // "the entrance", "the checkout counter". One row per region, keyed by
413
+ // (project, scene, region); regions may overlap. `bounds` is JSON text (the
414
+ // `[minX,…,maxZ]` tuple) parsed by the row mapper, exactly as
415
+ // `scene_representations.bounds` is.
416
+ {
417
+ id: "0038_scene_regions",
418
+ sql: /* sql */ `
419
+ CREATE TABLE IF NOT EXISTS scene_regions (
420
+ project_id VARCHAR NOT NULL,
421
+ scene_id VARCHAR NOT NULL,
422
+ region_id VARCHAR NOT NULL,
423
+ label VARCHAR NOT NULL,
424
+ description VARCHAR,
425
+ bounds VARCHAR NOT NULL,
426
+ updated_at TIMESTAMP NOT NULL DEFAULT now(),
427
+ PRIMARY KEY (project_id, scene_id, region_id)
428
+ );
429
+ `,
430
+ },
334
431
  ];
335
432
  /**
336
433
  * Apply all DuckDB migrations in order. Idempotent — safe to run on every boot.
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/duckdb/migrations.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA+C;IAC3E,6EAA6E;IAC7E,0EAA0E;IAC1E,6EAA6E;IAC7E,6EAA6E;IAC7E,2DAA2D;IAC3D;QACE,EAAE,EAAE,aAAa;QACjB,GAAG,EAAE,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;KAyBd;KACF;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,GAAG,EAAE,SAAS,CAAC;;;KAGd;KACF;IACD,8EAA8E;IAC9E,4EAA4E;IAC5E,gEAAgE;IAChE;QACE,EAAE,EAAE,eAAe;QACnB,GAAG,EAAE,SAAS,CAAC;;;;;;KAMd;KACF;IACD;QACE,EAAE,EAAE,eAAe;QACnB,GAAG,EAAE,SAAS,CAAC;;;;;;;;;KASd;KACF;IACD,8EAA8E;IAC9E,8EAA8E;IAC9E,2CAA2C;IAC3C;QACE,EAAE,EAAE,4BAA4B;QAChC,GAAG,EAAE,SAAS,CAAC;;;;;;;;;;;;;;;;;KAiBd;KACF;IACD,6EAA6E;IAC7E,6EAA6E;IAC7E,wEAAwE;IACxE,6EAA6E;IAC7E,+EAA+E;IAC/E,8EAA8E;IAC9E;QACE,EAAE,EAAE,sBAAsB;QAC1B,GAAG,EAAE,SAAS,CAAC;;;;;;;;;;;;KAYd;KACF;IACD;QACE,EAAE,EAAE,wBAAwB;QAC5B,GAAG,EAAE,SAAS,CAAC;;;;;;;;;KASd;KACF;IACD,6EAA6E;IAC7E,mEAAmE;IACnE,+EAA+E;IAC/E,yEAAyE;IACzE,8EAA8E;IAC9E,4EAA4E;IAC5E,4EAA4E;IAC5E;QACE,EAAE,EAAE,wBAAwB;QAC5B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,yBAAyB;QAC7B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,6BAA6B;QACjC,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD,uEAAuE;IACvE,yEAAyE;IACzE;QACE,EAAE,EAAE,2BAA2B;QAC/B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,4BAA4B;QAChC,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,uBAAuB;QAC3B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,sBAAsB;QAC1B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,2BAA2B;QAC/B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD,0EAA0E;IAC1E,sEAAsE;IACtE,8EAA8E;IAC9E,wEAAwE;IACxE;QACE,EAAE,EAAE,sBAAsB;QAC1B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD,6EAA6E;IAC7E,6EAA6E;IAC7E,6EAA6E;IAC7E,+EAA+E;IAC/E,gFAAgF;IAChF,+EAA+E;IAC/E,iFAAiF;IACjF,0EAA0E;IAC1E,gEAAgE;IAChE;QACE,EAAE,EAAE,mBAAmB;QACvB,GAAG,EAAE,SAAS,CAAC;;;;;;;;;;;;;;KAcd;KACF;IACD;QACE,EAAE,EAAE,uBAAuB;QAC3B,GAAG,EAAE,SAAS,CAAC;;;KAGd;KACF;IACD,6EAA6E;IAC7E,8EAA8E;IAC9E,uEAAuE;IACvE,+EAA+E;IAC/E,gFAAgF;IAChF;QACE,EAAE,EAAE,2BAA2B;QAC/B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,+BAA+B;QACnC,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,yBAAyB;QAC7B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,0BAA0B;QAC9B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD,6EAA6E;IAC7E,0EAA0E;IAC1E,+EAA+E;IAC/E,8EAA8E;IAC9E,6EAA6E;IAC7E,6EAA6E;IAC7E,8EAA8E;IAC9E;QACE,EAAE,EAAE,8BAA8B;QAClC,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,6BAA6B;QACjC,GAAG,EAAE,SAAS,CAAC;;;KAGd;KACF;IACD,8EAA8E;IAC9E,4EAA4E;IAC5E,qEAAqE;IACrE,iCAAiC;IACjC;QACE,EAAE,EAAE,0BAA0B;QAC9B,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD,gFAAgF;IAChF,gFAAgF;IAChF,wEAAwE;IACxE,iFAAiF;IACjF,gFAAgF;IAChF,iEAAiE;IACjE;QACE,EAAE,EAAE,iBAAiB;QACrB,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;IACD;QACE,EAAE,EAAE,kBAAkB;QACtB,GAAG,EAAE,SAAS,CAAC;;KAEd;KACF;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAoB;IACtD,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE,CAAC;QAC1C,MAAM,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IACD,+EAA+E;IAC/E,sEAAsE;IACtE,4EAA4E;IAC5E,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/duckdb/migrations.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { apiKeyPrefix, generateApiKey, hashApiKey, type ApiKeyCapability, type ApiKeyRecord, type Project, type ResolvedApiKey } from "../metadata.js";
1
+ import { apiKeyPrefix, generateApiKey, hashApiKey, type ApiKeyRecord, type CreateApiKeyOptions, type Project, type ResolvedApiKey } from "../metadata.js";
2
2
  import type { DuckdbClient } from "./client.js";
3
3
  export type { Project, ApiKeyRecord };
4
4
  export { hashApiKey, apiKeyPrefix, generateApiKey };
@@ -9,15 +9,19 @@ export declare function getProject(client: DuckdbClient, id: string): Promise<Pr
9
9
  /**
10
10
  * Issue a new API key for a project. Returns both the record and the plaintext
11
11
  * key — the plaintext is shown to the caller exactly once and never stored.
12
+ *
13
+ * The legacy singular `capability` column is written alongside the set (its
14
+ * first token) so a collector still running older code keeps resolving the key.
12
15
  */
13
- export declare function createApiKey(client: DuckdbClient, projectId: string, capability?: ApiKeyCapability): Promise<{
16
+ export declare function createApiKey(client: DuckdbClient, projectId: string, options?: CreateApiKeyOptions): Promise<{
14
17
  key: string;
15
18
  record: ApiKeyRecord;
16
19
  }>;
17
20
  /**
18
- * Resolve a plaintext API key to its (non-revoked) project id and capability, or
19
- * `null` when the key is unknown or revoked. The collector uses this to
20
- * authenticate and scope read requests at the boundary.
21
+ * Resolve a plaintext API key to its (non-revoked) project id, key id,
22
+ * capability set and per-key rate limit, or `null` when the key is unknown or
23
+ * revoked. The collector uses this to authenticate and scope requests at the
24
+ * boundary, and to attribute audit rows to a key without ever logging the key.
21
25
  */
22
26
  export declare function resolveApiKey(client: DuckdbClient, plaintext: string): Promise<ResolvedApiKey | null>;
23
27
  //# sourceMappingURL=projects.d.ts.map