🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@useatlas/types

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@useatlas/types - npm Package Compare versions

Comparing version
0.3.0
to
0.4.0
+89
dist/datasource-profile.d.ts
/**
* 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;

@@ -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;

@@ -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;
}

@@ -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";

@@ -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;
}

@@ -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. */

@@ -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;

@@ -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"];

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