@useatlas/types
Advanced tools
| /** | ||
| * Wire format for the datasource-profiling REST endpoint | ||
| * (`POST /api/v1/datasources/{id}/profile`, #4052 / ADR-0027) — the `atlas | ||
| * datasource profile <id>` CLI surface and the REST sibling of the MCP | ||
| * `profile_datasource` tool. | ||
| * | ||
| * The endpoint is long-running and streams newline-delimited JSON | ||
| * (`application/x-ndjson`): a `start` event, one `table` event per profiled | ||
| * table, then a terminal `result` (or `error`) event. Before #4111 the only | ||
| * machine-checkable contract for this stream was a prose description on the | ||
| * route's `ProfileResponseSchema = z.object({})` plus a hand-declared CLI | ||
| * interface — nothing shared. These types are the SSOT for both the route's | ||
| * emit-side ({@link DatasourceProfileStreamEvent}, so a malformed event fails | ||
| * to compile) and the CLI's `.safeParse()` consumer (via `@useatlas/schemas`). | ||
| */ | ||
| /** | ||
| * Terminal `error`-event codes the profile route emits AFTER the stream has | ||
| * committed its 200 (so they ride as NDJSON, never an HTTP 5xx): | ||
| * | ||
| * - `reconnect_required` — an OAuth token was revoked mid-profile. | ||
| * - `profiling_failed` — an actionable validation outcome (no profilable | ||
| * tables, too many introspection failures, a persist failure). | ||
| * - `internal_error` — an unexpected throw from the profiler. | ||
| * | ||
| * Every terminal `error` event carries a `requestId` for log correlation | ||
| * (the route stamps it on all three). | ||
| */ | ||
| export declare const DATASOURCE_PROFILE_ERROR_CODES: readonly ["reconnect_required", "profiling_failed", "internal_error"]; | ||
| export type DatasourceProfileErrorCode = (typeof DATASOURCE_PROFILE_ERROR_CODES)[number]; | ||
| /** Type guard — checks whether a string is a known {@link DatasourceProfileErrorCode}. */ | ||
| export declare function isDatasourceProfileErrorCode(value: string): value is DatasourceProfileErrorCode; | ||
| /** | ||
| * The terminal `result` event's payload — the generated (draft) semantic-layer | ||
| * summary. This is the value the `atlas datasource profile` command resolves | ||
| * with, so it is also the CLI's public return shape. | ||
| */ | ||
| export interface DatasourceProfileResult { | ||
| readonly id: string; | ||
| readonly queryable: boolean; | ||
| readonly persisted: boolean; | ||
| /** Lifecycle of the persisted layer — `"draft"` today (never auto-published). */ | ||
| readonly persistedStatus?: string; | ||
| readonly entitiesGenerated: number; | ||
| readonly metricsGenerated: number; | ||
| readonly tables: readonly string[]; | ||
| readonly profilingErrors: number; | ||
| /** | ||
| * Honest partial-success signal: some tables failed introspection but stayed | ||
| * under the fatal threshold, so the layer persisted with those tables ABSENT. | ||
| */ | ||
| readonly incomplete: boolean; | ||
| /** Names of the tables that failed introspection (present only when `incomplete`). */ | ||
| readonly incompleteTables?: readonly string[]; | ||
| readonly elapsedMs: number; | ||
| } | ||
| /** `start` — emitted once, before any table is profiled. */ | ||
| export interface DatasourceProfileStartEvent { | ||
| readonly type: "start"; | ||
| readonly total: number; | ||
| } | ||
| /** `table` — one per profiled table, carrying its done/error status. */ | ||
| export interface DatasourceProfileTableEvent { | ||
| readonly type: "table"; | ||
| readonly name: string; | ||
| readonly index: number; | ||
| readonly total: number; | ||
| readonly status: "done" | "error"; | ||
| /** Scrubbed introspection error message, present only on `status: "error"`. */ | ||
| readonly error?: string; | ||
| } | ||
| /** `result` — the terminal success event wrapping {@link DatasourceProfileResult}. */ | ||
| export interface DatasourceProfileResultEvent extends DatasourceProfileResult { | ||
| readonly type: "result"; | ||
| } | ||
| /** `error` — the terminal failure event (rides as NDJSON; the 200 is already sent). */ | ||
| export interface DatasourceProfileErrorEvent { | ||
| readonly type: "error"; | ||
| readonly error: DatasourceProfileErrorCode; | ||
| readonly message: string; | ||
| /** Log-correlation id — the route stamps it on every terminal error event. */ | ||
| readonly requestId?: string; | ||
| } | ||
| /** | ||
| * The discriminated union of every line the profile NDJSON stream can emit, | ||
| * keyed on `type`. The route's per-line `write(...)` is typed against this so a | ||
| * malformed event fails to compile; the CLI `.safeParse()`s each parsed line | ||
| * against the matching member. | ||
| */ | ||
| export type DatasourceProfileStreamEvent = DatasourceProfileStartEvent | DatasourceProfileTableEvent | DatasourceProfileResultEvent | DatasourceProfileErrorEvent; |
| /** | ||
| * Durable agent-run status wire types (#3749, ADR-0020). | ||
| * | ||
| * The web chat reads a conversation's latest run status on load/reconnect to | ||
| * decide which durability affordance to render: an "interrupted — resume" banner | ||
| * (`running`), a "waiting on approval" state (`parked`), or nothing for a | ||
| * terminal run (`done`/`failed`) or a conversation with no run to surface | ||
| * (`none`). The runtime values mirror the `agent_runs.status` lifecycle plus the | ||
| * client-only `none` sentinel for "no run / not available". | ||
| */ | ||
| /** The four `agent_runs.status` lifecycle values (mirrors `AGENT_RUN_STATUS`). */ | ||
| export type AgentRunLifecycleStatus = "running" | "parked" | "done" | "failed"; | ||
| /** | ||
| * The latest run's status for a conversation, as surfaced to the chat client. | ||
| * `running` is interrupted-and-resumable; `parked` is suspended awaiting a human | ||
| * approval decision; `done`/`failed` are terminal (no affordance); `none` means | ||
| * there is no run to surface (no internal DB, durability off, no row, or a | ||
| * fail-soft read blip — all collapse to "render nothing"). | ||
| */ | ||
| export type RunStatusValue = AgentRunLifecycleStatus | "none"; | ||
| /** | ||
| * Response of the latest-run-status probe | ||
| * (`GET /api/v1/chat/{conversationId}/run-status`). When `status` is `none` the | ||
| * run identifiers are absent. For a real run, `runId` is the durable run's id | ||
| * (the same id the resume endpoint surfaces as `x-run-id`), and `parkedReason` | ||
| * carries the approval-queue reference for a `parked` run (null otherwise). | ||
| */ | ||
| export interface RunStatusResponse { | ||
| status: RunStatusValue; | ||
| /** The latest run's id — absent when `status` is `none`. */ | ||
| runId?: string; | ||
| /** The approval-queue ref a `parked` run is waiting on; null for non-parked runs, absent when `none`. */ | ||
| parkedReason?: string | null; | ||
| } |
| /** | ||
| * Wire format for the semantic-layer exploration REST endpoint | ||
| * (`POST /api/v1/explore`, #4049 / ADR-0027) — the REST sibling of the agent | ||
| * loop's / MCP `explore` tool. | ||
| * | ||
| * SSOT for the route's local hono-`z` `ExploreResponseSchema` | ||
| * (`satisfies z.ZodType<ExploreRestResponse>`). A command-level failure | ||
| * (a `grep` that matched nothing, a missing file) rides inside `output` as the | ||
| * facade's `Error (exit N):` string — a normal 200 result, not an HTTP error. | ||
| */ | ||
| export interface ExploreRestResponse { | ||
| /** The command's combined output (including non-zero-exit results). */ | ||
| readonly output: string; | ||
| } |
| /** | ||
| * Wire format for the canonical metric-run REST endpoint | ||
| * (`POST /api/v1/metrics/{id}/run`, #4048 / ADR-0027) — the `atlas metric run | ||
| * <id>` CLI surface and the REST sibling of the MCP `runMetric` tool. | ||
| * | ||
| * SSOT for the route's local hono-`z` `RunMetricResponseSchema` | ||
| * (`satisfies z.ZodType<RunMetricRestResponse>`) and the CLI's `.safeParse()` | ||
| * (via `@useatlas/schemas` `RunMetricRestResponseSchema`). The route maps every | ||
| * non-`ok` execution outcome to an HTTP error envelope, so this models only the | ||
| * 200 body. | ||
| */ | ||
| export interface RunMetricRestResponse { | ||
| /** The metric id (from `semantic/metrics/*.yml`). */ | ||
| readonly id: string; | ||
| /** Human-readable label, or `null` when the metric defines none. */ | ||
| readonly label: string | null; | ||
| /** | ||
| * Scalar value for a single-column/single-row metric, else the full row set. | ||
| * Mirrors the MCP `runMetric` tool's `value` projection — `unknown` because | ||
| * the cell type is metric-defined. | ||
| */ | ||
| readonly value: unknown; | ||
| readonly columns: string[]; | ||
| readonly rows: Record<string, unknown>[]; | ||
| readonly rowCount: number; | ||
| /** True when the result hit the auto-LIMIT row cap (more rows exist upstream). */ | ||
| readonly truncated: boolean; | ||
| /** The authoritative SQL that was executed (used exactly as defined). */ | ||
| readonly sql: string; | ||
| /** ISO-8601 timestamp stamped when the route shaped the response. */ | ||
| readonly executedAt: string; | ||
| } |
| /** | ||
| * Durable session-memory wire types (#3758, ADR-0020). | ||
| * | ||
| * The read/reset affordance over a session's accumulated durable working memory | ||
| * (`agent_session_memory`, migration 0145). One slot is a named JSONB value the | ||
| * agent stashed in a prior turn ("the user means EU revenue"); a session view | ||
| * bundles a conversation with the slots it has accumulated. Shared across the API | ||
| * responses, the admin Session Memory page, and the in-conversation reset | ||
| * control. | ||
| */ | ||
| /** One persisted durable-working-memory slot for a session. */ | ||
| export interface SessionMemorySlot { | ||
| /** Slot name, e.g. `"analyst.lastTable"`. */ | ||
| namespace: string; | ||
| /** The remembered value — any JSON-serializable payload (round-trips through JSONB). */ | ||
| value: unknown; | ||
| /** ISO-8601 timestamp of the slot's last write. */ | ||
| updatedAt: string; | ||
| } | ||
| /** A session (conversation) and the durable working-memory slots it has accumulated. */ | ||
| export interface SessionMemoryView { | ||
| /** The conversation (session) the slots belong to. */ | ||
| conversationId: string; | ||
| /** The conversation's title, or `null` if untitled. */ | ||
| title: string | null; | ||
| /** ISO-8601 timestamp of the most recently written slot in the session. */ | ||
| updatedAt: string; | ||
| /** Every named slot the session has accumulated, ordered by name. */ | ||
| slots: SessionMemorySlot[]; | ||
| } |
+18
-2
@@ -15,3 +15,3 @@ /** | ||
| */ | ||
| export declare const APPROVAL_RULE_TYPES: readonly ["table", "column", "cost"]; | ||
| export declare const APPROVAL_RULE_TYPES: readonly ["table", "column", "cost", "datasource"]; | ||
| export type ApprovalRuleType = (typeof APPROVAL_RULE_TYPES)[number]; | ||
@@ -39,3 +39,3 @@ export declare const APPROVAL_STATUSES: readonly ["pending", "approved", "denied", "expired"]; | ||
| */ | ||
| export declare const APPROVAL_RULE_ORIGINS: readonly ["any", "chat", "mcp", "scheduler", "slack", "teams", "telegram", "discord", "whatsapp", "gchat", "webhook"]; | ||
| export declare const APPROVAL_RULE_ORIGINS: readonly ["any", "chat", "mcp", "scheduler", "slack", "teams", "telegram", "discord", "whatsapp", "gchat", "webhook", "cli"]; | ||
| export type ApprovalRuleOrigin = (typeof APPROVAL_RULE_ORIGINS)[number]; | ||
@@ -65,2 +65,7 @@ export type ApprovalRequestOrigin = Exclude<ApprovalRuleOrigin, "any">; | ||
| * `pattern`; threshold is unused and stored as null. | ||
| * - `datasource` rules (#3573) match when a destructive MCP datasource action | ||
| * targets a `datasource:<id>` resource matching `pattern` (or `*` / | ||
| * `datasource:*` for all); threshold is unused and stored as null. This is | ||
| * the first-class rule type behind ADR-0016 gate 4's approval-by-default for | ||
| * destructive datasource mutations over MCP. | ||
| * | ||
@@ -82,2 +87,6 @@ * The union encodes the "threshold XOR pattern" invariant at the type level | ||
| threshold: null; | ||
| } | { | ||
| ruleType: "datasource"; | ||
| pattern: string; | ||
| threshold: null; | ||
| }); | ||
@@ -176,2 +185,9 @@ /** | ||
| origin?: ApprovalRuleOrigin; | ||
| } | { | ||
| ruleType: "datasource"; | ||
| pattern: string; | ||
| name: string; | ||
| threshold?: null; | ||
| enabled?: boolean; | ||
| origin?: ApprovalRuleOrigin; | ||
| }; | ||
@@ -178,0 +194,0 @@ export interface UpdateApprovalRuleRequest { |
+30
-9
@@ -1,17 +0,38 @@ | ||
| /** Overage status levels for a workspace's usage against its plan limits. */ | ||
| export type OverageStatus = "ok" | "warning" | "soft_limit" | "hard_limit"; | ||
| /** | ||
| * Usage status for a single metered dimension (queries or tokens). | ||
| * Overage status levels for a workspace's usage against its plan limits. | ||
| * | ||
| * Included in billing API responses and enforcement headers so clients | ||
| * Metered soft-cap progression, denominated in dollars (#3990, #4038): | ||
| * - `ok` (0–79%): within the included usage credit, no signal. | ||
| * - `warning` (80–99%): approaching the included credit. | ||
| * - `metered` (100% → ceiling): over the included credit but still served — | ||
| * every dollar past the credit accrues at provider cost (zero markup). The | ||
| * billing page surfaces the accrued "in overage, $X.XX so far" figure. A | ||
| * paying workspace is metered, not cut off, for ordinary overage. | ||
| * - `hard_limit` (≥ ceiling): the cutoff. Under the `continue` spend policy the | ||
| * ceiling is the abuse ceiling (a conservative multiple of the credit) that | ||
| * bounds runaway spend; under `cutoff` it clamps to the credit (100%). The | ||
| * request is cut off with a 429 here and only here. | ||
| * | ||
| * `soft_limit` is retained in the union for wire/back-compat (older API or web | ||
| * bundles may still emit or parse it) but the current classifier never returns | ||
| * it — the 100%+ band is `metered`. | ||
| */ | ||
| export type OverageStatus = "ok" | "warning" | "soft_limit" | "metered" | "hard_limit"; | ||
| /** | ||
| * Usage status for the metered usage dimension, denominated in dollars (#4038). | ||
| * | ||
| * Included in billing API responses and enforcement warnings so clients | ||
| * can display usage bars, warnings, and upgrade CTAs. | ||
| */ | ||
| export interface PlanLimitStatus { | ||
| /** Which metric this status applies to. */ | ||
| metric: "tokens"; | ||
| /** Current usage count for the billing period. */ | ||
| /** | ||
| * Which metric this status applies to. `usd` — the at-cost usage spend | ||
| * measured against the included dollar credit (Structure B, #4038). | ||
| */ | ||
| metric: "usd"; | ||
| /** Current usage for the billing period, in USD (summed at-cost provider spend). */ | ||
| currentUsage: number; | ||
| /** Plan limit for the billing period. -1 = unlimited. */ | ||
| /** Included usage credit for the billing period, in USD (`$/seat × seats`). */ | ||
| limit: number; | ||
| /** Usage as a percentage of the limit. 0 = no usage, 100 = at limit. No upper bound. */ | ||
| /** Usage as a percentage of the credit. 0 = no usage, 100 = at the credit. No upper bound. */ | ||
| usagePercent: number; | ||
@@ -18,0 +39,0 @@ /** Overage status level. */ |
@@ -84,2 +84,22 @@ /** Conversation persistence types — wire format for conversations and messages. */ | ||
| restFocusDatasourceId?: string | null; | ||
| /** | ||
| * Per-conversation Group reach (#3895, ADR-0022). The cross-group axis ABOVE | ||
| * member routing (`routingMode`): | ||
| * | ||
| * - `null` / absent — **All sources** (the default): every visible | ||
| * Connection group is reachable and the agent routes per question via the | ||
| * Source catalog. | ||
| * - a `connectionGroupId` value — **Focus → that group**: a hard, exclusive | ||
| * narrowing where only that group is reachable for the conversation. | ||
| * `executeSQL` rejects any other group target — never a silent re-route to | ||
| * a different source. | ||
| * | ||
| * Authoritative per-conversation; the web sticky preference only seeds NEW | ||
| * chats (mirrors `restFocusDatasourceId`). Independent of `routingMode` | ||
| * (intra-group) and the REST scope fields (a separate axis). Genuinely | ||
| * nullable: the column is plain nullable `text` and `null` is the meaningful | ||
| * "All sources" state. Optional so pre-#3895 fixtures / SDK consumers can omit | ||
| * it; the runtime treats missing the same as `null`. | ||
| */ | ||
| groupReach?: string | null; | ||
| starred: boolean; | ||
@@ -86,0 +106,0 @@ createdAt: string; |
+28
-0
@@ -7,2 +7,30 @@ import type { AuthMode } from "./auth"; | ||
| export declare function isChatErrorCode(value: string): value is ChatErrorCode; | ||
| /** | ||
| * The `error`-field discriminators the REST-backed CLI suite (raw SQL, | ||
| * metric-run, datasource lifecycle/profile) emits in its JSON error envelope | ||
| * and that the `atlas` CLI clients branch on. A PARTIAL registry on purpose — | ||
| * only the codes a CLI switch actually discriminates on (the HTTP status | ||
| * carries the rest); it deliberately does not duplicate the chat catalog in | ||
| * {@link CHAT_ERROR_CODES} or the admin route-response codes documented in | ||
| * `apps/docs/content/docs/reference/error-codes.mdx`. | ||
| * | ||
| * Before #4111 these were bare string literals on both the emitting routes and | ||
| * the CLI switches, with nothing shared — several emitted codes | ||
| * (`connection_failed`, `mfa_enrollment_required`, `reconnect_required`) were | ||
| * absent from any registry. Sharing the union lets the CLI's `ERR` maps pin to | ||
| * it (`satisfies Record<…, CliRestErrorCode>`) so the CLI's branch literals and | ||
| * this shared vocabulary can't drift — renaming a code here breaks the `ERR` | ||
| * maps at compile time. Note this couples CLI↔registry only: the HTTP-envelope | ||
| * routes still emit bare literals (and deliberately emit codes outside this | ||
| * partial registry, e.g. `invalid_sql`/`rls_blocked`), so a server-side *emit* | ||
| * rename is not caught here. The datasource-profile NDJSON path is the one that | ||
| * gets full emit-side pinning — its `write()` is typed against the shared | ||
| * `DatasourceProfileStreamEvent`, so an unregistered terminal code fails to | ||
| * compile at the route. | ||
| */ | ||
| export declare const CLI_REST_ERROR_CODES: readonly ["bad_request", "forbidden_role", "mfa_enrollment_required", "connection_failed", "not_available", "plan_limit_exceeded", "reconnect_required"]; | ||
| /** Union of the {@link CLI_REST_ERROR_CODES} the CLI clients discriminate on. */ | ||
| export type CliRestErrorCode = (typeof CLI_REST_ERROR_CODES)[number]; | ||
| /** Type guard — checks whether a string is a known {@link CliRestErrorCode}. */ | ||
| export declare function isCliRestErrorCode(value: string): value is CliRestErrorCode; | ||
| /** Returns `true` if the given error code represents a transient, retryable failure. */ | ||
@@ -9,0 +37,0 @@ export declare function isRetryableError(code: ChatErrorCode): boolean; |
+14
-0
@@ -34,2 +34,14 @@ // src/errors.ts | ||
| } | ||
| var CLI_REST_ERROR_CODES = [ | ||
| "bad_request", | ||
| "forbidden_role", | ||
| "mfa_enrollment_required", | ||
| "connection_failed", | ||
| "not_available", | ||
| "plan_limit_exceeded", | ||
| "reconnect_required" | ||
| ]; | ||
| function isCliRestErrorCode(value) { | ||
| return CLI_REST_ERROR_CODES.includes(value); | ||
| } | ||
| var RETRYABLE_MAP = { | ||
@@ -350,2 +362,3 @@ rate_limited: true, | ||
| isRetryableError, | ||
| isCliRestErrorCode, | ||
| isChatErrorCode, | ||
@@ -355,2 +368,3 @@ isChatContextWarningCode, | ||
| authErrorMessage, | ||
| CLI_REST_ERROR_CODES, | ||
| CLIENT_ERROR_CODES, | ||
@@ -357,0 +371,0 @@ CHAT_ERROR_CODES, |
@@ -85,1 +85,27 @@ /** | ||
| export type ExecuteSqlResult = ExecuteSqlSuccessResult | ExecuteSqlFailureResult; | ||
| /** | ||
| * Wire format for the raw-SQL REST endpoint's success body | ||
| * (`POST /api/v1/execute-sql`, #4047 / ADR-0027) — the `atlas sql "SELECT …"` | ||
| * CLI surface. This is the REST sibling of the agent loop's | ||
| * {@link ExecuteSqlResult}, named distinctly to avoid colliding with that | ||
| * tool-call shape (which carries `success`/`row_count`/`envContributions`). | ||
| * Here the route has already mapped every non-`ok` outcome to an HTTP error | ||
| * envelope, so this models only the 200 body: a flat `{columns, rows}` plus | ||
| * row-count / truncation / timing metadata (no pagination — `truncated` is the | ||
| * auto-LIMIT cap signal, not a paging cursor). | ||
| * | ||
| * SSOT for the route's local hono-`z` `ExecuteSqlResponseSchema` | ||
| * (`satisfies z.ZodType<ExecuteSqlRestResponse>`) and the CLI's | ||
| * `.safeParse()` (via `@useatlas/schemas` `ExecuteSqlRestResponseSchema`). | ||
| */ | ||
| export interface ExecuteSqlRestResponse { | ||
| readonly columns: string[]; | ||
| readonly rows: Record<string, unknown>[]; | ||
| readonly rowCount: number; | ||
| /** True when the result hit the auto-LIMIT row cap (more rows exist upstream). */ | ||
| readonly truncated: boolean; | ||
| /** Wall-clock execution time in milliseconds. */ | ||
| readonly executionMs: number; | ||
| /** ISO-8601 timestamp stamped when the route shaped the response. */ | ||
| readonly executedAt: string; | ||
| } |
+5
-0
@@ -41,3 +41,8 @@ export * from "./auth"; | ||
| export * from "./execute-sql"; | ||
| export * from "./metric-run"; | ||
| export * from "./datasource-profile"; | ||
| export * from "./explore"; | ||
| export * from "./proactive"; | ||
| export * from "./catalog"; | ||
| export * from "./session-memory"; | ||
| export * from "./durable-run"; |
+32
-2
@@ -156,2 +156,14 @@ // src/auth.ts | ||
| } | ||
| var CLI_REST_ERROR_CODES = [ | ||
| "bad_request", | ||
| "forbidden_role", | ||
| "mfa_enrollment_required", | ||
| "connection_failed", | ||
| "not_available", | ||
| "plan_limit_exceeded", | ||
| "reconnect_required" | ||
| ]; | ||
| function isCliRestErrorCode(value) { | ||
| return CLI_REST_ERROR_CODES.includes(value); | ||
| } | ||
| var RETRYABLE_MAP = { | ||
@@ -603,2 +615,4 @@ rate_limited: true, | ||
| var PARTITION_STRATEGIES = ["range", "list", "hash"]; | ||
| var INDEX_TYPES = ["btree", "gin", "gist", "brin", "hash", "other"]; | ||
| var INDEX_POSITIONS = ["leading", "trailing"]; | ||
| var SEMANTIC_TYPES = [ | ||
@@ -665,3 +679,3 @@ "currency", | ||
| // src/approval.ts | ||
| var APPROVAL_RULE_TYPES = ["table", "column", "cost"]; | ||
| var APPROVAL_RULE_TYPES = ["table", "column", "cost", "datasource"]; | ||
| var APPROVAL_STATUSES = ["pending", "approved", "denied", "expired"]; | ||
@@ -679,3 +693,4 @@ var APPROVAL_RULE_ORIGINS = [ | ||
| "gchat", | ||
| "webhook" | ||
| "webhook", | ||
| "cli" | ||
| ]; | ||
@@ -804,2 +819,11 @@ var APPROVAL_REQUEST_ORIGINS = APPROVAL_RULE_ORIGINS.filter((s) => s !== "any"); | ||
| ]; | ||
| // src/datasource-profile.ts | ||
| var DATASOURCE_PROFILE_ERROR_CODES = [ | ||
| "reconnect_required", | ||
| "profiling_failed", | ||
| "internal_error" | ||
| ]; | ||
| function isDatasourceProfileErrorCode(value) { | ||
| return DATASOURCE_PROFILE_ERROR_CODES.includes(value); | ||
| } | ||
| export { | ||
@@ -821,2 +845,4 @@ transformMessages, | ||
| isDefaultLanding, | ||
| isDatasourceProfileErrorCode, | ||
| isCliRestErrorCode, | ||
| isChatErrorCode, | ||
@@ -869,2 +895,4 @@ isChatContextWarningCode, | ||
| INTEGRATION_PLATFORMS, | ||
| INDEX_TYPES, | ||
| INDEX_POSITIONS, | ||
| IMPLEMENTATION_STATUSES, | ||
@@ -882,5 +910,7 @@ HEALTH_STATUSES, | ||
| DB_TYPES, | ||
| DATASOURCE_PROFILE_ERROR_CODES, | ||
| CONNECTION_STATUSES, | ||
| COMPLIANCE_REPORT_TYPES, | ||
| COMPLIANCE_EXPORT_FORMATS, | ||
| CLI_REST_ERROR_CODES, | ||
| CLIENT_ERROR_CODES, | ||
@@ -887,0 +917,0 @@ CLEANUP_GRACE_PERIOD_DAYS, |
@@ -61,2 +61,14 @@ /** Learned query pattern types — wire format for the learned_patterns table. */ | ||
| amendmentPayload: AmendmentPayload | null; | ||
| /** | ||
| * True when the nightly auto-promote/decay job promoted this row from | ||
| * pending → approved without human review (PRD #3617 B-2). Lets the admin UI | ||
| * mark machine-approved patterns distinct from human-approved ones. | ||
| */ | ||
| autoPromoted: boolean; | ||
| /** | ||
| * Rolling-mean wall-clock execution time (ms) of the pattern's runs, or null | ||
| * until first observed (PRD #3617 B-0/B-2). Drives perf-weighted retrieval | ||
| * down-weighting and is surfaced to the agent in injected context. | ||
| */ | ||
| avgDurationMs: number | null; | ||
| } |
+47
-0
@@ -133,1 +133,48 @@ /** | ||
| export type CanonicalToggle = "auto" | "always" | "never"; | ||
| /** | ||
| * Closed set of MCP action *categories* a customer admin can allow/deny for | ||
| * their workspace. Gate 1 of the dispatch order (ADR-0016) consults the | ||
| * per-workspace policy and short-circuits a blocked category *before* scope / | ||
| * RBAC / approval — distinct from the non-configurable **origin ceiling**. | ||
| * | ||
| * Categories map to the MCP admin tool tiers in PRD #3483: | ||
| * - `datasource` — datasource create / test / profile / delete (Tier-2 flagship) | ||
| * - `integration` — BYOT integration connections (Slack/GitHub/Linear/Email, Phase 4) | ||
| * - `policy` — governance-*raising* tools (approval rules, PII classes, Phase 4) | ||
| * | ||
| * Type-only here (no value tuple) so `@atlas/web` shares the union without | ||
| * reaching into `@atlas/api`; the runtime tuple + per-category labels live in | ||
| * `packages/api/src/lib/mcp/action-policy.ts`, and the dashboard renders the | ||
| * categories straight off the policy API response — same no-value-export | ||
| * discipline as `CanonicalToggle` above. | ||
| */ | ||
| export type McpActionCategory = "datasource" | "integration" | "policy"; | ||
| /** | ||
| * Stored state of one category for a workspace. The default posture is | ||
| * `allowed` (no stored row); a customer admin opts a category into `blocked`. | ||
| */ | ||
| export type McpActionPolicyStatus = "allowed" | "blocked"; | ||
| /** | ||
| * One category's policy state, as surfaced to the customer-admin dashboard | ||
| * (`GET /api/v1/admin/mcp/action-policy`). `label`/`description` are | ||
| * server-authoritative so the web UI never hardcodes the category set. | ||
| */ | ||
| export interface McpActionPolicyEntry { | ||
| readonly category: McpActionCategory; | ||
| readonly label: string; | ||
| readonly description: string; | ||
| readonly status: McpActionPolicyStatus; | ||
| /** ISO timestamp of the last explicit toggle; null when never set (default). */ | ||
| readonly updatedAt: string | null; | ||
| /** Actor id that last toggled this category; null for the default state. */ | ||
| readonly updatedBy: string | null; | ||
| } | ||
| /** `GET /api/v1/admin/mcp/action-policy` response — every category + status. */ | ||
| export interface McpActionPolicyResponse { | ||
| readonly entries: readonly McpActionPolicyEntry[]; | ||
| } | ||
| /** `PUT /api/v1/admin/mcp/action-policy` request — set one category's status. */ | ||
| export interface McpActionPolicyUpdateRequest { | ||
| readonly category: McpActionCategory; | ||
| readonly status: McpActionPolicyStatus; | ||
| } |
@@ -1,2 +0,2 @@ | ||
| /** Migration bundle types — wire format for atlas export/import. */ | ||
| /** Migration bundle types — wire format for `atlas-operator export` / `atlas import`. */ | ||
| import type { MessageRole, Surface } from "./conversation"; | ||
@@ -3,0 +3,0 @@ import type { LearnedPattern } from "./learned-pattern"; |
@@ -11,4 +11,28 @@ /** | ||
| export type OnboardingMilestone = (typeof ONBOARDING_MILESTONES)[number]; | ||
| /** Trigger source for an onboarding email — either a milestone or a time-based fallback. */ | ||
| export type OnboardingEmailTrigger = OnboardingMilestone | "time_based"; | ||
| /** | ||
| * Trigger source for an onboarding email record. Splits into two classes — | ||
| * triggers under which an email was *dispatched*, and *satisfaction markers* | ||
| * under which the step is recorded complete but no message was sent: | ||
| * | ||
| * Dispatched: | ||
| * - `"signup_completed"` — the welcome email (sent immediately on signup). The | ||
| * only milestone that mails proactively. | ||
| * - `"time_based"` — a fallback nudge sent because the step's milestone wasn't | ||
| * hit within its `fallbackHours` window. | ||
| * | ||
| * Satisfaction markers (NO email — see api/lib/email/engine.ts `getSuppressedSteps`): | ||
| * - an *action* {@link OnboardingMilestone} (`database_connected`, | ||
| * `first_query_executed`, `team_member_invited`, `feature_explored`) — recorded | ||
| * when the user does the thing the step nudges toward. Mailing the nudge in the | ||
| * same breath is backwards (a demo-only signup got "ask your first question" the | ||
| * instant they asked — #3962), so reaching the milestone *suppresses* the nudge | ||
| * instead: it marks the step done (the time-based fallback then skips it) without | ||
| * sending. Recorded via `onMilestoneReached`. | ||
| * - `"demo_activated"` — the demo-only analogue for `connect_database`: a demo | ||
| * signup activates the bundled demo, satisfying the step without the misleading | ||
| * "connect your *own* database" copy (#3949). Never a key in the milestone→step | ||
| * map (`MILESTONE_TO_STEP`, api/lib/email/sequence.ts) — it only ever appears in | ||
| * a persisted record's `triggeredBy`. | ||
| */ | ||
| export type OnboardingEmailTrigger = OnboardingMilestone | "time_based" | "demo_activated"; | ||
| export interface OnboardingEmailRecord { | ||
@@ -27,5 +51,16 @@ id: string; | ||
| orgId: string; | ||
| /** Steps that have been sent. Together with pendingSteps, partitions all OnboardingEmailStep values. */ | ||
| /** | ||
| * Steps whose email was actually dispatched. Excludes steps satisfied without | ||
| * a send (see `suppressedSteps`). `sentSteps ∪ suppressedSteps` are the | ||
| * completed steps, and together with `pendingSteps` they partition the full | ||
| * sequence. | ||
| */ | ||
| sentSteps: OnboardingEmailStep[]; | ||
| /** Steps remaining. Complement of sentSteps against the full sequence. */ | ||
| /** | ||
| * Steps marked complete WITHOUT an email being sent — e.g. `connect_database` | ||
| * satisfied by activating the demo (#3949). Completed for drip-progression | ||
| * purposes (so they are not in `pendingSteps`) but no message went out. | ||
| */ | ||
| suppressedSteps: OnboardingEmailStep[]; | ||
| /** Steps remaining. Complement of the completed steps (sent + suppressed) against the full sequence. */ | ||
| pendingSteps: OnboardingEmailStep[]; | ||
@@ -32,0 +67,0 @@ /** Whether the user has unsubscribed from onboarding emails. */ |
+63
-0
@@ -16,2 +16,24 @@ /** | ||
| export type PartitionStrategy = (typeof PARTITION_STRATEGIES)[number]; | ||
| /** | ||
| * Index access methods we surface to the agent. PostgreSQL exposes these via | ||
| * `pg_am.amname`; MySQL effectively only has `btree` (and `fulltext`/`spatial`, | ||
| * mapped to `gin`/`gist` respectively for a uniform vocabulary). `other` is the | ||
| * catch-all so an unrecognized access method never drops the index entirely. | ||
| */ | ||
| export declare const INDEX_TYPES: readonly ["btree", "gin", "gist", "brin", "hash", "other"]; | ||
| export type IndexType = (typeof INDEX_TYPES)[number]; | ||
| /** | ||
| * Marks how a column participates in indexes, for sargability hints (#3634). | ||
| * | ||
| * - `leading` — the column is independently sargable: it is the first column | ||
| * of at least one index, OR a member of a non-btree index (GIN/BRIN/etc. do | ||
| * not depend on column position). The agent can filter on it cheaply. | ||
| * - `trailing` — the column appears in indexes ONLY as a non-first member of a | ||
| * composite btree. A trailing btree column is NOT independently sargable: an | ||
| * index on `(a, b)` does not accelerate `WHERE b = ?` without `a`. | ||
| * | ||
| * Derived during profile analysis (`analyzeTableProfiles`), never harvested. | ||
| */ | ||
| export declare const INDEX_POSITIONS: readonly ["leading", "trailing"]; | ||
| export type IndexPosition = (typeof INDEX_POSITIONS)[number]; | ||
| /** Semantic types inferred from column names, sample values, and SQL types. */ | ||
@@ -47,4 +69,38 @@ export declare const SEMANTIC_TYPES: readonly ["currency", "percentage", "email", "url", "phone", "timestamp"]; | ||
| semantic_type?: SemanticType; | ||
| /** | ||
| * Whether the column participates in any index. Derived during profile | ||
| * analysis from {@link TableProfile.indexes} (#3634), not harvested per-column. | ||
| * Absent on profiles produced before index harvesting (treat as unknown). | ||
| */ | ||
| indexed?: boolean; | ||
| /** | ||
| * Sargability marker derived alongside {@link indexed}. Present only when | ||
| * `indexed` is true; see {@link IndexPosition}. A `trailing` column is indexed | ||
| * but not independently sargable. | ||
| */ | ||
| index_position?: IndexPosition; | ||
| profiler_notes: string[]; | ||
| } | ||
| /** | ||
| * A single index harvested from the database catalog (#3634). | ||
| * | ||
| * `columns` is the ORDERED list of index members — for a composite btree the | ||
| * order is load-bearing (only the leading prefix is independently sargable). | ||
| * Expression-index members are rendered as their definition text (e.g. | ||
| * `lower(email)`) rather than a bare column name, so they survive into the YAML | ||
| * even though they don't map to a single `ColumnProfile`. | ||
| * | ||
| * `predicate` is the partial-index WHERE text (PostgreSQL only; null when the | ||
| * index is not partial). MySQL has no partial indexes, so MySQL-harvested | ||
| * indexes always carry `is_partial: false` and `predicate: null`. | ||
| */ | ||
| export interface IndexProfile { | ||
| name: string; | ||
| columns: string[]; | ||
| index_type: IndexType; | ||
| is_unique: boolean; | ||
| is_primary: boolean; | ||
| is_partial: boolean; | ||
| predicate: string | null; | ||
| } | ||
| /** Heuristic flags set by `analyzeTableProfiles`. */ | ||
@@ -75,2 +131,9 @@ export interface TableFlags { | ||
| inferred_foreign_keys: ForeignKey[]; | ||
| /** | ||
| * Indexes harvested from the catalog (#3634). Empty when the table has no | ||
| * (non-implicit) indexes, when the object is a view/matview, or when the | ||
| * harvest query failed soft (a warning is logged, profiling continues). | ||
| * Optional so profiles produced before index harvesting still type-check. | ||
| */ | ||
| indexes?: IndexProfile[]; | ||
| profiler_notes: string[]; | ||
@@ -77,0 +140,0 @@ table_flags: TableFlags; |
+40
-0
@@ -44,3 +44,43 @@ /** | ||
| isDefault: boolean; | ||
| /** | ||
| * Public API base for this region (e.g. "https://api-eu.useatlas.dev"). | ||
| * | ||
| * Carries the region→apiUrl map to the browser so the signup region step can | ||
| * point the API base at the chosen region *before* the first identity write | ||
| * (ADR-0024 §4 — `applyRegionSignal` in `@/lib/api-url`). Omitted when the | ||
| * region config declares no `apiUrl` (single-region / local dev), where the | ||
| * browser stays on its same-origin base and no repoint is possible. | ||
| */ | ||
| apiUrl?: string; | ||
| } | ||
| /** | ||
| * One region the returning-user login front-door can route to — a selectable | ||
| * region projected with the API base the browser is repointed at. Unlike | ||
| * {@link RegionPickerItem} (signup picker), this carries the `apiUrl` the | ||
| * front-door fans its hashed-email existence probe out to. | ||
| */ | ||
| export interface RegionRoutingMapEntry { | ||
| /** Region identifier (e.g. "eu"). */ | ||
| id: string; | ||
| /** Human-readable label (e.g. "Europe"). */ | ||
| label: string; | ||
| /** Regional API base the front-door probes and the browser targets. */ | ||
| apiUrl: string; | ||
| /** Whether this is the deployment's default region. */ | ||
| isDefault: boolean; | ||
| } | ||
| /** | ||
| * Response of `GET /api/v1/auth/region-map` — the region→apiUrl map served | ||
| * identically by every regional API, consumed by the login front-door. SSOT | ||
| * for the wire shape shared by `@atlas/api` (producer) and `@atlas/web` | ||
| * (consumer); the Zod mirror lives in `@useatlas/schemas`. | ||
| */ | ||
| export interface RegionRoutingMap { | ||
| /** False when residency is not configured (self-hosted / single region). */ | ||
| configured: boolean; | ||
| /** Default region id, or "none" when not configured. */ | ||
| defaultRegion: string; | ||
| /** Selectable regions with a configured apiUrl. */ | ||
| regions: RegionRoutingMapEntry[]; | ||
| } | ||
| /** Valid migration status values — single source of truth for Zod schemas and type. */ | ||
@@ -47,0 +87,0 @@ export declare const MIGRATION_STATUSES: readonly ["pending", "in_progress", "completed", "failed", "cancelled"]; |
+1
-1
| { | ||
| "name": "@useatlas/types", | ||
| "version": "0.3.0", | ||
| "version": "0.4.0", | ||
| "description": "Shared types for the Atlas text-to-SQL agent", | ||
@@ -5,0 +5,0 @@ "type": "module", |
269022
11.1%71
7.58%6496
9.36%