import { type CapabilityState } from "./capability-catalog.js"; import { ProviderStore } from "./provider-store.js"; import { FeatureStore } from "./feature-store.js"; import type { SessionOwnerInfo, SessionSummaryState } from "./types.js"; /** A persisted session event (non-ephemeral). */ export interface SessionEvent { seq: number; sessionId: string; eventType: string; data: unknown; createdAt: Date; workerNodeId?: string; } /** One row from cms_get_top_event_emitters. */ export interface TopEventEmitterRow { workerNodeId: string; eventType: string; eventCount: number; sessionCount: number; firstSeenAt: Date | null; lastSeenAt: Date | null; } export interface InsertTurnMetricInput { sessionId: string; agentId: string | null; model: string | null; reasoningEffort: string | null; turnIndex: number; startedAt: Date; endedAt: Date; durationMs: number; tokensInput: number; tokensOutput: number; tokensCacheRead: number; tokensCacheWrite: number; toolCalls: number; toolErrors: number; resultType: string | null; errorMessage: string | null; workerNodeId: string | null; } export interface CompleteTurnWritebackInput extends InsertTurnMetricInput { toolNames?: string[]; state: string; lastActiveAt: Date; lastError: string | null; waitReason: string | null; currentIteration: number; } export interface TurnMetricRow { id: number; sessionId: string; agentId: string | null; model: string | null; reasoningEffort: string | null; turnIndex: number; startedAt: Date; endedAt: Date; durationMs: number; tokensInput: number; tokensOutput: number; tokensCacheRead: number; tokensCacheWrite: number; toolCalls: number; toolErrors: number; resultType: string | null; errorMessage: string | null; workerNodeId: string | null; createdAt: Date; } export interface TokensByModelRow { /** Combined model:effort label (or provider/model when no effort). */ model: string; turnCount: number; totalTokensInput: number; totalTokensOutput: number; totalTokensCacheRead: number; totalTokensCacheWrite: number; } export interface HourlyTokenBucketRow { hourBucket: Date; turnCount: number; totalTokensInput: number; totalTokensOutput: number; totalTokensCacheRead: number; totalTokensCacheWrite: number; } /** A row in the sessions table. */ export interface SessionRow { sessionId: string; orchestrationId: string | null; title: string | null; titleLocked: boolean; state: string; /** Session regeneration: which SDK-transcript incarnation is live. 0 = original. */ transcriptEpoch: number; /** Epoch-ms of the last completed flip; null before any regeneration. */ lastRegeneratedAt: number | null; model: string | null; reasoningEffort: string | null; contextTier: string | null; modelResolutionSource: string | null; createdAt: Date; updatedAt: Date; lastActiveAt: Date | null; deletedAt: Date | null; currentIteration: number; lastError: string | null; /** Live wait reason (e.g. "waiting for build"). Synced from runTurn activity. */ waitReason: string | null; /** * In-flight turn index while a turn is running, else null. Written by the * runTurn activity's pre-turn writeback; cleared by the post-turn * writeback and by any state transition away from "running". Used by * stopSessionTurn() to address the turn-scoped stop queue. */ activeTurnIndex: number | null; /** If this session is a sub-agent, the parent session's ID. */ parentSessionId: string | null; /** Whether this is a system session (e.g. Sweeper Agent). */ isSystem: boolean; /** * Service sessions (tree-scoped system sessions): machinery that serves * ONE session tree, e.g. "regen-distiller". Read-only to users, distinct * icon, parented under the served tree's root. null = ordinary session. */ serviceKind: string | null; /** The session this service session serves (regen: the regenerating session). */ serviceOf: string | null; /** Agent definition ID (e.g. "sweeper"). Links session to its agent config. */ agentId: string | null; /** Splash banner (terminal markup) from the agent definition. */ splash: string | null; /** Narrow-viewport splash variant, used when the main splash art is wider than the pane. */ splashMobile: string | null; /** * The placement viewer's private group for this ROOT session, when the * read supplied a placement viewer. NULL on child rows and whenever no * placement viewer was passed. Surfaced to DTOs as `viewerGroupId`. */ groupId: string | null; /** Short live summary for discovery/session lists. */ shortSummary: string | null; /** Structured live summary state, application domain payload included. */ summaryState: SessionSummaryState | null; /** Last time summaryState/shortSummary was updated. */ summaryUpdatedAt: Date | null; /** Authenticated user associated with this session, if any. */ owner: SessionOwnerInfo | null; /** * Sharing level of this row. Meaningful on ROOT sessions only — access * for a child always resolves through its root's visibility/shares. */ visibility: SessionVisibility; /** Denormalized session-tree root (self for top-level sessions). */ rootSessionId: string | null; } /** Sharing level of a session tree, set on the root row. */ export type SessionVisibility = "private" | "shared_read" | "shared_write"; /** A targeted per-user grant on a session tree. */ export interface SessionShareInfo { provider: string; subject: string; email: string | null; displayName: string | null; access: "read" | "write"; grantedAt: Date; grantedByDisplay: string | null; } /** * One round-trip access snapshot for the enforcement predicate: the root's * system flag, visibility, owner, and the viewer's targeted share. Facts * only — combining them with the caller's role is the caller's concern. */ export interface SessionAccessSnapshot { rootSessionId: string; isSystem: boolean; visibility: SessionVisibility; owner: SessionOwnerInfo | null; viewerIsOwner: boolean; viewerShareAccess: "read" | "write" | null; } /** A directory entry for share autocomplete. */ export interface KnownUserInfo { provider: string; subject: string; email: string | null; displayName: string | null; } /** One authz audit record (denial, break-glass read, share change). */ export interface AuthzAuditEntry { auditId: number; occurredAt: Date; actorProvider: string | null; actorSubject: string | null; actorDisplay: string | null; action: string; sessionId: string | null; target: string | null; decision: string; reason: string | null; details: Record; } /** Fields that can be updated on a session row. */ export interface SessionRowUpdates { orchestrationId?: string | null; title?: string | null; titleLocked?: boolean; state?: string; model?: string | null; reasoningEffort?: string | null; contextTier?: string | null; modelResolutionSource?: string | null; lastActiveAt?: Date; currentIteration?: number; lastError?: string | null; waitReason?: string | null; isSystem?: boolean; agentId?: string | null; splash?: string | null; splashMobile?: string | null; } /** Identity used to scope group placements (a user's private organization). */ export interface PlacementViewer { provider: string; subject: string; /** Treat every live session as readable (the runtime passes admin OR NOT enforce). */ isAdmin?: boolean; } /** Per-root outcome of a placement request. */ export interface SessionPlacementResult { rootSessionId: string; placed: boolean; /** 'not_found' (unknown or unreadable — same shape) or 'system'. Null on success. */ reason: string | null; } export interface SessionGroupRow { groupId: string; title: string; description: string | null; owner: SessionOwnerInfo | null; metadata: Record; memberCount: number; runningCount: number; waitingCount: number; completedCount: number; failedCount: number; cancelledCount: number; latestActivityAt: Date | null; latestSummaryUpdatedAt: Date | null; createdAt: Date; updatedAt: Date; } export interface ChildOutcomeRow { childSessionId: string; parentSessionId: string; contractJson: Record | null; resultJson: Record | null; verdict: string | null; summary: string | null; completedAt: Date | null; createdAt: Date; updatedAt: Date; } /** Per-session metric summary — one row per session, updated in place. */ export interface SessionMetricSummary { sessionId: string; agentId: string | null; model: string | null; reasoningEffort: string | null; parentSessionId: string | null; /** Compressed (stored) snapshot size in bytes. */ snapshotSizeBytes: number; /** Uncompressed snapshot size in bytes; ratio = raw / snapshot. */ rawSizeBytes: number; dehydrationCount: number; hydrationCount: number; lossyHandoffCount: number; lastDehydratedAt: number | null; lastHydratedAt: number | null; lastCheckpointAt: number | null; tokensInput: number; tokensOutput: number; tokensCacheRead: number; tokensCacheWrite: number; /** Cached-prompt hit ratio (0..1), null when tokensInput is 0. Derived. */ cacheHitRatio: number | null; /** Session regeneration: completed flips (rollbacks included). */ regenCount: number; /** Stats of the last completed regeneration (kind, stage timings, sizes). */ lastRegenStats: Record | null; deletedAt: number | null; createdAt: number; updatedAt: number; } /** Fields for atomic upsert — increments are additive, absolutes are set. */ export interface SessionMetricSummaryUpsert { snapshotSizeBytes?: number; rawSizeBytes?: number; dehydrationCountIncrement?: number; hydrationCountIncrement?: number; lossyHandoffCountIncrement?: number; lastDehydratedAt?: boolean; lastHydratedAt?: boolean; lastCheckpointAt?: boolean; tokensInputIncrement?: number; tokensOutputIncrement?: number; tokensCacheReadIncrement?: number; tokensCacheWriteIncrement?: number; } /** Per-session event-log aggregate (footprint events axis). */ export interface SessionEventStats { eventCount: number; dataBytes: number; maxSeq: number; } /** Per-session compaction counters derived from persisted SDK events. */ export interface SessionCompactionStats { starts: number; completes: number; failed: number; tokensRemoved: number; /** Epoch-ms of the newest start/complete — feeds the stuck-compaction timeout. */ lastStartAtMs: number | null; lastCompleteAtMs: number | null; } /** Fleet-wide aggregate stats. */ export interface FleetStats { windowStart: number | null; earliestSessionCreatedAt: number | null; byAgent: Array<{ agentId: string | null; model: string | null; sessionCount: number; turnCount: number; totalSnapshotSizeBytes: number; totalDehydrationCount: number; totalHydrationCount: number; totalLossyHandoffCount: number; totalTokensInput: number; totalTokensOutput: number; totalTokensCacheRead: number; totalTokensCacheWrite: number; /** Derived: cache_read / input. Null when input is 0. */ cacheHitRatio: number | null; }>; totals: { sessionCount: number; totalSnapshotSizeBytes: number; totalRawSizeBytes: number; totalTokensInput: number; totalTokensOutput: number; totalTokensCacheRead: number; totalTokensCacheWrite: number; cacheHitRatio: number | null; }; } export type UserStatsOwnerKind = "user" | "system" | "unowned"; export interface UserStatsModelBucket { model: string | null; sessionIds: string[]; sessionCount: number; turnCount: number; totalSnapshotSizeBytes: number; totalOrchestrationHistorySizeBytes: number; totalDehydrationCount: number; totalHydrationCount: number; totalLossyHandoffCount: number; totalTokensInput: number; totalTokensOutput: number; totalTokensCacheRead: number; totalTokensCacheWrite: number; cacheHitRatio: number | null; } export interface UserStatsBucket { ownerKind: UserStatsOwnerKind; owner: SessionOwnerInfo | null; sessionIds: string[]; sessionCount: number; totalSnapshotSizeBytes: number; totalOrchestrationHistorySizeBytes: number; totalTokensInput: number; totalTokensOutput: number; totalTokensCacheRead: number; totalTokensCacheWrite: number; cacheHitRatio: number | null; byModel: UserStatsModelBucket[]; } export interface UserStats { windowStart: number | null; earliestSessionCreatedAt: number | null; users: UserStatsBucket[]; totals: { sessionCount: number; totalSnapshotSizeBytes: number; totalOrchestrationHistorySizeBytes: number; totalTokensInput: number; totalTokensOutput: number; totalTokensCacheRead: number; totalTokensCacheWrite: number; cacheHitRatio: number | null; }; } /** * Public user profile shape exposed through the management surface and * consumed by the Admin Console UI. * * `profileSettings` is an opaque application-owned JSON document (the * Admin Console + future client-state migrations decide its schema). * * `githubCopilotKeySet` is a presence flag; the raw key text is only * available through the worker-side resolver in `SessionCatalog` * to prevent accidental leakage through this management-facing type. */ export interface UserProfile { userId: number; provider: string; subject: string; email: string | null; displayName: string | null; profileSettings: Record; githubCopilotKeySet: boolean; createdAt: Date | null; updatedAt: Date | null; } export interface UserPrincipal { provider: string; subject: string; email?: string | null; displayName?: string | null; } /** * The authorization role last OBSERVED for a principal, and when it was last * confirmed. * * `role` is a point-in-time observation, not a fact: the authority is the * identity provider, and this is the most recent thing it told the portal. * `seenAt` is therefore load-bearing — a reader that grants privilege on this * value must decide how stale an observation it will still believe. * * `null` role means "no privilege", and covers three distinct situations that * callers must not try to distinguish: never seen, seen with no role, and * seen with a role outside the known vocabulary. */ export type UserRoleValue = "admin" | "user" | "anonymous"; export interface UserRoleInfo { role: UserRoleValue | null; seenAt: Date | null; } /** Narrow unknown role text to the stored vocabulary. Anything else is no privilege. */ export declare function normalizeUserRole(value: unknown): UserRoleValue | null; /** * The first-class "system" user. Platform-managed sessions carry * `owner: null` in the catalog; for credential resolution they act as this * principal, so an admin-stored GitHub Copilot key on the system user (Admin * Console → "Store as System key") is picked up by ownerless system sessions * through the exact same per-user key path as everyone else. The user row is * created lazily on first key set (`cms_set_user_github_copilot_key` * upserts via `cms_register_user`). */ export declare const SYSTEM_USER_PRINCIPAL: UserPrincipal; /** * Resolve the owner a spawned sub-agent should inherit, by walking up the * session lineage from `startSessionId` (normally the spawning parent): * * - The nearest ancestor with an owner wins — a user-owned parent's children * stay attributed to that user. * - A SYSTEM ancestor (ownerless by design) maps to the concrete SYSTEM user * principal. The child is then a normal, deletable session whose owner is * the System user — so it resolves the admin-stored System GitHub Copilot * key through the ordinary per-owner credential path, WITHOUT being marked * `is_system` itself (which would make it undeletable/unmanageable). * - An unresolvable lineage (missing rows, no owner, no system ancestor, * depth exhausted) yields null: the child is created ownerless, exactly as * before. * * Pure lineage logic — callers supply the row lookup so worker activities and * unit tests share one implementation. */ export declare function resolveEffectiveSpawnOwner(getSession: (sessionId: string) => Promise<{ owner?: SessionOwnerInfo | null; isSystem?: boolean; parentSessionId?: string | null; } | null | undefined>, startSessionId: string | null | undefined, maxDepth?: number): Promise; /** Aggregate of a session and all its descendants. */ export interface SessionTreeStats { rootSessionId: string; self: SessionMetricSummary; tree: { sessionCount: number; totalTokensInput: number; totalTokensOutput: number; totalTokensCacheRead: number; totalTokensCacheWrite: number; /** Derived: cache_read / input across the tree. Null when input is 0. */ cacheHitRatio: number | null; totalDehydrationCount: number; totalHydrationCount: number; totalLossyHandoffCount: number; totalSnapshotSizeBytes: number; totalRawSizeBytes: number; }; /** Per-model breakdown across the tree, sorted by total input tokens. */ byModel: Array<{ model: string; sessionCount: number; turnCount: number; totalTokensInput: number; totalTokensOutput: number; totalTokensCacheRead: number; totalTokensCacheWrite: number; totalSnapshotSizeBytes: number; /** Derived per model. Null when input is 0. */ cacheHitRatio: number | null; }>; } /** * Compute prompt-cache hit ratio with the inclusive token convention. * Returns a value in [0, 1] or null when tokensInput is 0 / negative / missing. * Defined once so per-session, tree, and fleet surfaces report identical values. */ export declare function computeCacheHitRatio(tokensInput: number | null | undefined, tokensCacheRead: number | null | undefined): number | null; /** Discriminator: 'static' = SDK skill.invoked, 'learned' = read_facts on skills/. */ export type SkillKind = "static" | "learned"; /** One row of skill-usage aggregation for a single session. */ export interface SkillUsageRow { kind: SkillKind; /** Static: skill name. Learned: requested key or keyPattern (e.g. "skills/foo/%"). */ name: string; pluginName: string | null; pluginVersion: string | null; invocations: number; firstUsedAt: Date; lastUsedAt: Date; } /** Skill usage rolled up across the spawn tree rooted at a session. */ export interface SessionTreeSkillUsage { rootSessionId: string; perSession: Array<{ sessionId: string; agentId: string | null; skills: SkillUsageRow[]; }>; rolledUp: SkillUsageRow[]; totalInvocations: number; } /** One row of skill-usage aggregation across the fleet, by agent. */ export interface FleetSkillUsageRow extends SkillUsageRow { agentId: string | null; sessionCount: number; } /** Fleet-wide skill usage. */ export interface FleetSkillUsage { windowStart: number | null; rows: FleetSkillUsageRow[]; } export type RetrievalSurface = "facts" | "skills" | "graph"; export type RetrievalOperation = "facts_search" | "facts_similar" | "search_skills" | "graph_search_nodes" | "graph_search_edges" | "graph_neighbourhood"; export interface RetrievalUsageRow { surface: RetrievalSurface; operation: RetrievalOperation; namespace: string | null; calls: number; totalResults: number; avgResults: number; totalDurationMs: number | null; avgDurationMs: number | null; firstUsedAt: Date; lastUsedAt: Date; } export interface SessionTreeRetrievalUsage { rootSessionId: string; perSession: Array<{ sessionId: string; agentId: string | null; rows: RetrievalUsageRow[]; }>; rolledUp: RetrievalUsageRow[]; totalCalls: number; } export interface FleetRetrievalUsageRow extends RetrievalUsageRow { agentId: string | null; sessionCount: number; } export interface FleetRetrievalUsage { windowStart: number | null; rows: FleetRetrievalUsageRow[]; } export type GraphNodeUsageKind = "searched" | "loaded"; export interface GraphNodeUsageRow { nodeKey: string; namespace: string | null; operation: RetrievalOperation; kind: GraphNodeUsageKind; count: number; firstSeenAt: Date; lastSeenAt: Date; } export interface FleetGraphNodeUsageRow extends GraphNodeUsageRow { agentId: string | null; sessionCount: number; } export interface FleetGraphNodeUsage { windowStart: number | null; rows: FleetGraphNodeUsageRow[]; } export interface GraphEdgeSearchUsageRow { predicateKey: string | null; fromKey: string | null; toKey: string | null; namespace: string | null; calls: number; totalResults: number; firstSearchedAt: Date; lastSearchedAt: Date; } /** * SessionCatalog — abstraction over the CMS backing store. * * Initial implementation: PostgreSQL. * Future: CosmosDB, etc. */ export type AgentPackageScope = "shared" | "user"; /** * WHICH copy of a package name an operation means. * * Package identity is `(scope, owner, name)` (migration 0043), so a bare name * is ambiguous the moment a user takes a personal copy of a shared package. * * `null` / omitted is not "any" — it is **resolve**: the actor's own copy if * they have one, otherwise the shared copy. That is the same rule agent * binding uses, so "show me X", "edit X" and "run X" always mean the same * package. * * A selector says which copy is MEANT. It never says which copy may be SEEN — * visibility is re-applied against the resolved row, so naming someone else's * owner triple cannot be used to read their private package. */ export interface AgentPackageSelector { scope?: AgentPackageScope | null; owner?: AgentPrincipal | null; } /** Principal pair — the same identity primitive session procs use. */ export interface AgentPrincipal { provider: string; subject: string; /** Populated on READ via the users join (migration 0041); optional on write. */ email?: string | null; /** Populated on READ via the users join (migration 0041); optional on write. */ displayName?: string | null; } export interface AgentSourceRow { sourceId: string; kind: "github" | "ado" | "url" | "upload"; scope: AgentPackageScope; repoUrl: string | null; ref: string | null; path: string | null; url: string | null; authTokenSet: boolean; autoSync: boolean; lastSyncAt: Date | null; lastSyncStatus: string | null; lastSyncError: string | null; lastCommitSha: string | null; owner: AgentPrincipal | null; createdBy: string | null; createdAt: Date; } export interface AgentPackageVersionRow { versionId: string; semver: string; sha256: string; sizeBytes: number; artifactFilename: string; commitSha: string | null; manifest: Record; createdAt: Date; createdBy: string | null; } export interface AgentPackageSummary { packageId: string; sourceId: string | null; name: string; scope: AgentPackageScope; owner: AgentPrincipal | null; enabled: boolean; createdBy: string | null; createdAt: Date; /** * This SHARED package is currently overridden for the viewer by their own * enabled copy of the same name. The distinction between "you have two * packages" and "you have one package with a fallback" is worth showing. */ shadowed: boolean; /** * The viewer may change this package's contents and rollout: admin, * owner, or a granted editor. Scope changes, delete and the editor list * stay with the owner/admin — see `owner` for that. */ canEdit: boolean; /** Active version join; null only for a package with no versions (shouldn't happen). */ active: AgentPackageVersionRow | null; } export interface AgentPackageEditorInfo { provider: string; subject: string; email: string | null; displayName: string | null; grantedAt: Date; grantedByDisplay: string | null; } export interface AgentPackageDetail extends Omit { activeVersionId: string | null; /** Full version history, newest first. */ versions: AgentPackageVersionRow[]; /** Granted editors. Always empty for a user-scope copy. */ editors: AgentPackageEditorInfo[]; } export interface AgentPackageInstallEntry { /** * Stable per-row identity. With per-user namespaces two packages can share * a `name`, so the installer keys its cache directories off this rather * than off the name — otherwise Alice's `triager` and Bob's `triager` * would fight over the same directory. */ packageId: string; name: string; scope: AgentPackageScope; owner: AgentPrincipal | null; semver: string; sha256: string; sizeBytes: number; artifactFilename: string; manifest: Record; } export interface AgentWorkerStateRow { workerNodeId: string; epoch: number; installed: Record; updatedAt: Date; } export interface PublishAgentPackageInput { name: string; scope: AgentPackageScope; owner: AgentPrincipal | null; sourceId: string | null; semver: string; sha256: string; sizeBytes: number; artifactFilename: string; commitSha: string | null; manifest: Record; createdBy: string | null; isAdmin: boolean; } export interface PublishAgentPackageResult { status: "published" | "noop"; packageId: string; versionId: string; } export type WorkerPhase = "starting" | "ready" | "draining"; export interface WorkerRow { workerNodeId: string; pool: string; phase: WorkerPhase; owner: AgentPrincipal | null; registeredAt: Date; updatedAt: Date; info: Record; health: Record; state: Record; } export interface WorkerHeartbeatInput { workerNodeId: string; pool?: string | null; phase?: WorkerPhase; owner?: AgentPrincipal | null; info?: Record; health?: Record; state?: Record; } /** Effective (merged) directive returned to a worker by the heartbeat. */ export interface EffectiveDirective { domain: string; /** SUM of contributing rows' epochs — changes on any contributing bump. */ epoch: number; actuation: "worker" | "external"; desired: Record; } export interface FleetDirectiveRow { domain: string; pool: string; workerNodeId: string; epoch: number; actuation: "worker" | "external"; desired: Record; updatedAt: Date; updatedBy: string | null; } export interface SessionCatalog { getSessionCapabilities?(sessionId: string): Promise; saveSessionCapabilities?(sessionId: string, expectedRevision: number, state: CapabilityState): Promise; /** * Provider budgets (migrations 0049-0051). Optional, like every other * late feature here, so a duck-typed test double need not implement it. * See provider-store.ts. */ readonly providers?: ProviderStore; readonly features?: FeatureStore; /** Per-slot canvas cache (migration 0045); optional so test doubles need not implement it. */ upsertSessionCanvas?(sessionId: string, slot: number, name: string | null, latestRev: number, sizeBytes: number | null): Promise; getSessionCanvases?(sessionId: string): Promise>; listSessionCanvasesFor?(sessionIds: string[]): Promise>>; /** * The canvas data plane (migration 0047): one UNLOGGED last-value row per * (session, slot), written on every tick and draw, NOTIFY on write. All * optional — absent on catalogs that predate the plane, and the bridge * degrades to the durable-event path when the probe says so. */ canvasLiveAvailable?(): Promise; /** Atomic next-rev mint on the 0045 cache row; seedRev floors legacy sessions. Multi-writer safe. */ mintCanvasRev?(sessionId: string, slot: number, seedRev: number): Promise; /** * A data tick. Exactly one of input.data (replace wholesale) or * input.patch (RFC 7386 merge into the LOCKED current row — concurrent * patches compose). Refused, nothing written, when the resulting payload * would exceed maxBytes. Returns the DB's seq and the MERGED payload — * the dual-write legacy event carries that merged state so old readers * stay whole. */ upsertCanvasLiveTick?(sessionId: string, slot: number, input: { data?: Record; patch?: Record; }, updatedBy: string, maxBytes?: number): Promise<{ seq: number; sizeBytes: number; payload: Record; } | { refused: true; currentSizeBytes: number | null; }>; /** A document pointer after a draw. RESETS payload to {} — the new page starts from its own initial state. */ upsertCanvasLiveDoc?(sessionId: string, slot: number, doc: { rev: number; sha: string; }, updatedBy: string): Promise<{ seq: number; } | null>; getCanvasLive?(sessionId: string): Promise; updatedBy: string; updatedAt: string; }>>; /** Generic ephemeral last-value plane (migration 0073). */ liveAvailable?(): Promise; publishLive?(sessionId: string, topic: string, input: { patch: Record; } | { snapshot: Record; } | { signal: true; }, updatedBy: string, maxBytes?: number): Promise<{ seq: number; sizeBytes: number; payload: Record; } | { signal: true; } | { refused: true; currentSizeBytes: number | null; } | null>; getLive?(sessionId: string, topics?: string[]): Promise; updatedBy: string; updatedAt: string; }>>; /** * Canvas share links (migration 0048): one live view token per * (session, slot), stored as a HASH. The raw token never touches the * database. All optional; absent on older catalogs. */ getCanvasShareLinkInfo?(sessionId: string, slot: number): Promise<{ exists: boolean; createdAt?: string; createdBy?: string; }>; /** Create-or-rotate: the previous token (if any) stops validating the moment this row lands. */ setCanvasShareLink?(sessionId: string, slot: number, tokenHash: string, createdBy: string): Promise; removeCanvasShareLink?(sessionId: string, slot: number): Promise; /** The token door: hash lookup → which canvas this token views, or null. */ resolveCanvasShareToken?(tokenHash: string): Promise<{ sessionId: string; slot: number; } | null>; /** * The canvas KV store (migration 0064): per-key shared state for canvas * apps, plus the per-canvas write policy. All optional; absent on older * catalogs, and the doors answer "unavailable" when so. The rules live in * canvas-kv.ts — these are the raw rows. */ getCanvasKvSettings?(sessionId: string, slot: number): Promise<{ kvAccess: "owner" | "readers" | "link"; kvManifest: unknown; latestRev: number; } | null>; setCanvasKvAccess?(sessionId: string, slot: number, access: "owner" | "readers" | "link"): Promise; setCanvasKvManifest?(sessionId: string, slot: number, manifest: unknown | null): Promise; canvasKvGet?(sessionId: string, slot: number, key: string): Promise<{ key: string; value: any; rev: number; updatedAt: string; } | null>; canvasKvList?(sessionId: string, slot: number, prefix: string | null, limit: number, afterKey: string | null): Promise>; canvasKvWrite?(sessionId: string, slot: number, key: string, value: unknown | null, ifMatch: number | null, limits: { maxKeys: number; maxBytes: number; maxValueBytes: number; }): Promise<{ status: string; rev: number; sizeBytes: number | null; }>; canvasKvStats?(sessionId: string, slot: number): Promise<{ keys: number; bytes: number; }>; /** Create schema and tables if they don't exist. */ initialize(): Promise; /** * The one round-trip: upsert this worker's row (info/owner insert-only; * pool/phase/health/state every beat), prune hour-silent rows, and * return the effective directive set (fleet/pool/worker shallow-merge, * epoch = SUM of contributing rows). */ workerHeartbeat(input: WorkerHeartbeatInput): Promise; listWorkers(): Promise; /** * Upsert-and-bump a directive row. pool/workerNodeId default '*'; * worker-scoped rows must use pool '*' (canonical form); desired null * keeps the existing payload (doorbell bump). Returns the row's epoch. */ fleetDirectiveBump(domain: string, opts?: { pool?: string | null; workerNodeId?: string | null; desired?: Record | null; actuation?: "worker" | "external"; updatedBy?: string | null; }): Promise; getFleetDirectives(): Promise; /** Current registry epoch — workers poll this single-row read. */ agentRegistryEpoch(): Promise; registerAgentSource(source: { sourceId: string; kind: "github" | "ado" | "url" | "upload"; scope: AgentPackageScope; repoUrl?: string | null; ref?: string | null; path?: string | null; url?: string | null; authToken?: string | null; autoSync?: boolean; owner: AgentPrincipal | null; createdBy?: string | null; }): Promise; listAgentSources(viewer: AgentPrincipal | null, isAdmin: boolean): Promise; getAgentSource(sourceId: string): Promise; /** Internal-only raw token read for sync fetchers. Never expose via management APIs. */ getAgentSourceToken(sourceId: string): Promise; updateAgentSourceSync(sourceId: string, status: string, error: string | null, commitSha: string | null): Promise; deleteAgentSource(sourceId: string, actor: AgentPrincipal | null, isAdmin: boolean): Promise; /** Atomic publish — see cms_publish_agent_package. Throws AGENT_PACKAGE_* errors. */ publishAgentPackage(input: PublishAgentPackageInput): Promise; listAgentPackages(viewer: AgentPrincipal | null, isAdmin: boolean): Promise; /** * One package. `selector` picks WHICH copy of the name (own / shared / * a named owner's); omitted means resolve own-then-shared, the same rule * agent binding follows. See {@link AgentPackageSelector}. */ getAgentPackage(name: string, viewer: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; /** Worker-facing install manifest: every enabled package's active version. */ getAgentPackagesInstallManifest(): Promise; /** * Which copy of a package name this viewer gets, as a package id. * `requireEnabled` defaults to true: a disabled personal copy falls * through to shared, which is the recovery path. */ resolveAgentPackageId(name: string, viewer: AgentPrincipal | null, selector?: AgentPackageSelector | null, opts?: { requireEnabled?: boolean; }): Promise; setAgentPackageScope(name: string, scope: AgentPackageScope, actor: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; setAgentPackageEnabled(name: string, enabled: boolean, actor: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; pinAgentPackageVersion(name: string, semver: string, actor: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; /** Returns artifact filenames of deleted versions for post-commit artifact cleanup. */ deleteAgentPackage(name: string, actor: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; /** * Editors: write access on a SHARED package for named users (publish, * republish into it, pin, enable/disable — never scope, delete, or the * editor list). Grant/revoke are owner-or-admin. Demoting the package to * user scope deletes every grant. */ isAgentPackageEditor(packageId: string, principal: AgentPrincipal | null): Promise; grantAgentPackageEditor(name: string, grantee: AgentPrincipal, actor: AgentPrincipal | null, isAdmin: boolean): Promise; revokeAgentPackageEditor(name: string, grantee: AgentPrincipal, actor: AgentPrincipal | null, isAdmin: boolean): Promise; /** Editors of the shared copy of `name`. Visible to anyone who can see the package. */ listAgentPackageEditors(name: string): Promise; /** How many published versions reference this content-addressed blob (>0 ⇒ never delete it). */ countAgentPackageArtifactRefs(artifactFilename: string): Promise; upsertAgentWorkerState(workerNodeId: string, epoch: number, installed: Record): Promise; listAgentWorkerState(): Promise; /** Insert a new session. No-op if session already exists. */ createSession(sessionId: string, opts?: { model?: string; reasoningEffort?: string; contextTier?: string | null; modelResolutionSource?: string; parentSessionId?: string; isSystem?: boolean; agentId?: string; splash?: string; splashMobile?: string; groupId?: string | null; owner?: SessionOwnerInfo | null; /** Sharing level for a new ROOT session; children resolve through their root. */ visibility?: SessionVisibility | null; /** Service sessions (tree-scoped machinery, migration 0037). */ serviceKind?: string | null; serviceOf?: string | null; /** Durable creation config (migration 0072); see getSessionCreationConfig. */ creationConfig?: Record | null; }): Promise; /** * The session's durable creation config (migration 0072), or null. * Optional: stores that predate it simply leave the start path on the * in-memory map plus the worker-side bound-agent backfill. */ getSessionCreationConfig?(sessionId: string): Promise | null>; /** Stamp a session as a service session post-create (migration 0037). */ markSessionService(sessionId: string, serviceKind: string, serviceOf: string | null): Promise; /** Update one or more fields on an existing session. */ updateSession(sessionId: string, updates: SessionRowUpdates): Promise; /** Publish the in-flight turn index (stop-turn targeting). */ setActiveTurnIndex(sessionId: string, turnIndex: number): Promise; /** Soft-delete a session (set deleted_at). */ softDeleteSession(sessionId: string): Promise; /** Privileged archive/reset for deterministic system-session restart. */ archiveSystemSessionForRestart(sessionId: string, state: "completed" | "cancelled" | "failed", lastError?: string | null): Promise; /** List all non-deleted sessions, newest first. */ listSessions(placement?: { provider: string; subject: string; } | null): Promise; /** List one bounded page of sessions, newest first. */ listSessionsPage(opts?: { limit?: number; cursorUpdatedAt?: Date | null; cursorSessionId?: string | null; includeDeleted?: boolean; systemFilter?: "all" | "only" | "exclude"; /** When set, restrict rows to what this principal can read (viewer-scoped listing). */ viewer?: { provider: string; subject: string; systemVisible?: boolean; } | null; /** When set, root rows carry this principal's private group placement as groupId. */ placement?: { provider: string; subject: string; } | null; }): Promise; /** List sessions visible to a principal (non-paged viewer-scoped listing). */ listSessionsVisible(viewer: { provider: string; subject: string; systemVisible?: boolean; }, placement?: { provider: string; subject: string; } | null): Promise; /** Member directory (for share autocomplete); excludes synthetic principals. */ listKnownUsers(opts?: { limit?: number; }): Promise; /** Get a single session by ID (null if not found or deleted). */ getSession(sessionId: string, placement?: { provider: string; subject: string; } | null): Promise; /** Set the sharing level on the ROOT of the given session's tree. */ setSessionVisibility(sessionId: string, visibility: SessionVisibility): Promise; /** Grant (or update) a targeted share on the session's tree root. */ grantSessionShare(sessionId: string, grantee: SessionOwnerInfo, access: "read" | "write", grantedBy?: SessionOwnerInfo | null): Promise; /** Revoke a targeted share on the session's tree root. */ revokeSessionShare(sessionId: string, grantee: { provider: string; subject: string; }): Promise; /** List targeted shares on the session's tree root. */ listSessionShares(sessionId: string): Promise; /** Access snapshot for the enforcement predicate (null = missing/deleted session). */ getSessionAccess(sessionId: string, viewer: { provider: string; subject: string; }): Promise; filterVisibleSessionIds(sessionIds: string[], viewer: { provider: string; subject: string; }, systemVisible: boolean): Promise; /** Append one authz audit record. */ recordAuthzAudit(entry: { actor?: { provider?: string | null; subject?: string | null; display?: string | null; } | null; action: string; sessionId?: string | null; target?: string | null; decision: string; reason?: string | null; details?: Record | null; }): Promise; /** Read authz audit records, newest first (optionally scoped to one session). */ listAuthzAudit(opts?: { limit?: number; sessionId?: string | null; }): Promise; /** Get all descendant session IDs (children, grandchildren, etc.) of a given session. */ getDescendantSessionIds(sessionId: string): Promise; /** Get the most recently active session ID. */ getLastSessionId(): Promise; /** Persist a structured live session summary. */ updateSessionSummary(sessionId: string, summaryState: SessionSummaryState, shortSummary?: string | null): Promise; /** Create a visual session group. */ createSessionGroup(input: { groupId: string; title: string; description?: string | null; owner?: SessionOwnerInfo | null; metadata?: Record; }): Promise; /** Update title/description/owner/metadata for a session group. */ updateSessionGroup(groupId: string, patch: { title?: string; description?: string | null; owner?: SessionOwnerInfo | null; metadataPatch?: Record; }): Promise; /** * List session groups with aggregate member status. With a viewer, only * that viewer's OWN groups with placement-scoped counts; without one, * the unscoped legacy listing (audit path, counts frozen at 0034). */ listSessionGroups(viewer?: PlacementViewer | null): Promise; /** List non-deleted sessions whose root the placement viewer placed in the group. */ listGroupSessions(groupId: string, placement?: { provider: string; subject: string; } | null): Promise; /** Delete a session group (placements cascade; sessions untouched). Returns false when missing. */ deleteSessionGroup(groupId: string): Promise; /** * Upsert (or delete, when groupId is null) the viewer's private placement * for each distinct resolved live root. The target group must be owned by * the viewer (throws otherwise). Never touches shared session data. */ placeSessionsInGroup(viewer: PlacementViewer, sessionIds: string[], groupId: string | null): Promise; /** Upsert current child contract/result outcome state. */ upsertChildOutcome(input: { childSessionId: string; parentSessionId: string; contractJson?: Record | null; resultJson?: Record | null; verdict?: string | null; summary?: string | null; completedAt?: Date | null; }): Promise; /** Get a child outcome record by child session id. */ getChildOutcome(childSessionId: string): Promise; /** List child outcome records for a parent session. */ listChildOutcomes(parentSessionId: string): Promise; /** Record a batch of events for a session. */ recordEvents(sessionId: string, events: { eventType: string; data: unknown; }[], workerNodeId?: string): Promise; /** * Get a provider-capped page of events for a session, ordered ascending by seq. * Without afterSeq this returns the latest page; with afterSeq it returns the next forward page. * Use getSessionEventsBefore() paging to drain complete history. */ getSessionEvents(sessionId: string, afterSeq?: number, limit?: number, eventTypes?: string[]): Promise; /** * Get a provider-capped older page before a sequence number, ordered ascending by seq. * Call repeatedly with the oldest returned seq to drain complete history. */ getSessionEventsBefore(sessionId: string, beforeSeq: number, limit?: number, eventTypes?: string[]): Promise; /** Get the highest-volume event emitters since a point in time. */ getTopEventEmitters(since: Date, limit?: number): Promise; /** Insert one per-turn metrics row. */ insertTurnMetric(input: InsertTurnMetricInput): Promise; /** Complete one turn's CMS writeback atomically. */ completeTurnWriteback(input: CompleteTurnWritebackInput): Promise; /** Get bounded per-session turn metrics, newest-first. */ getSessionTurnMetrics(sessionId: string, opts?: { since?: Date; limit?: number; }): Promise; /** Get per-session token totals grouped by model:effort, with per-bucket turn count. */ getSessionTokensByModel(sessionId: string): Promise; /** Aggregate hourly token buckets from session turn metrics. */ getHourlyTokenBuckets(since: Date, opts?: { agentId?: string; model?: string; }): Promise; /** Delete turn metrics older than a cutoff and return deleted row count. */ pruneTurnMetrics(olderThan: Date): Promise; /** Get the metric summary for a single session. */ getSessionMetricSummary(sessionId: string): Promise; /** Per-session event count/bytes/max-seq aggregate (footprint). Always session-scoped. */ getSessionEventStats(sessionId: string, afterSeq?: number): Promise; /** Per-session compaction counters from persisted SDK events (footprint). */ getSessionCompactionStats(sessionId: string, afterSeq?: number): Promise; /** * Session regeneration boundary transaction: session.epoch_committed * event + sessions.transcript_epoch + regen_count, atomically and * idempotently (attempt-keyed). Returns the boundary event's seq. */ recordEpochCommitted(sessionId: string, payload: Record): Promise; /** Proven rebirth: session.regenerated event + last_regen_stats (attempt-idempotent). */ recordRegenerated(sessionId: string, payload: Record): Promise; /** Get a session's own stats plus rolled-up totals of all descendants. */ getSessionTreeStats(sessionId: string): Promise; /** Get fleet-wide aggregate stats, optionally filtered. */ getFleetStats(opts?: { includeDeleted?: boolean; since?: Date; }): Promise; /** Get user/session-owner aggregate stats, optionally filtered. */ getUserStats(opts?: { includeDeleted?: boolean; since?: Date; }): Promise; /** * Read the public user profile (settings + key-set flag). Returns * `null` when the principal has not been registered yet. * * Never returns the raw key text; callers wanting the key must use * `getUserGitHubCopilotKey` so leakage stays auditable. */ getUserProfile(principal: UserPrincipal): Promise; /** * Internal: fetch the raw GitHub Copilot key for a user. Used by the * worker's per-user token resolver. Returns `null` when no override * is set or the user is unknown. */ getUserGitHubCopilotKey(principal: UserPrincipal): Promise; /** * Replace the user's `profile_settings` JSON document. Creates the * user row lazily if needed so settings can be saved before the * principal owns any sessions. * Saved multi-dashboard MoA settings are retained when a legacy client * omits them or submits an older schema; clear them with a v3 layout. */ setUserProfileSettings(principal: UserPrincipal, settings: Record): Promise; /** * Set or clear the per-user GitHub Copilot key. Pass `null` to * remove the override (which reverts the user to the worker's * env-supplied default). */ setUserGitHubCopilotKey(principal: UserPrincipal, key: string | null): Promise; /** * Read the last-observed authorization role for a principal. * * Returns `{ role: null }` for an unknown principal, which callers must * treat exactly like a stored `null` — no privilege. */ getUserRole(principal: UserPrincipal): Promise; /** * Record the authorization role observed for a principal, replacing any * previous value and refreshing `seenAt`. * * Called by the portal on authenticated requests. It is NOT reachable * through the Web API: a caller able to write its own role would hold a * privilege-escalation primitive. */ setUserRole(principal: UserPrincipal, role: string | null): Promise; /** Get skill usage (skill.invoked event aggregation) for a single session. */ getSessionSkillUsage(sessionId: string, opts?: { since?: Date; }): Promise; /** Get skill usage rolled across the spawn tree rooted at the given session. */ getSessionTreeSkillUsage(sessionId: string, opts?: { since?: Date; }): Promise; /** Get fleet-wide skill usage broken down by agent. Tuner / management surface. */ getFleetSkillUsage(opts?: { since?: Date; includeDeleted?: boolean; }): Promise; /** Get per-session retrieval usage counts from durable retrieval events. */ getSessionRetrievalUsage(sessionId: string, opts?: { since?: Date; }): Promise; /** Get retrieval usage rolled up across the spawn tree rooted at the given session. */ getSessionTreeRetrievalUsage(sessionId: string, opts?: { since?: Date; }): Promise; /** Get fleet-wide retrieval usage broken down by agent. */ getFleetRetrievalUsage(opts?: { since?: Date; includeDeleted?: boolean; }): Promise; /** Get exact graph node-key search/load usage for one session. */ getSessionGraphNodeUsage(sessionId: string, opts?: { since?: Date; limit?: number; nodeKeyLike?: string; kind?: GraphNodeUsageKind; }): Promise; /** Get exact graph node-key search/load usage across the fleet. */ getFleetGraphNodeUsage(opts?: { since?: Date; includeDeleted?: boolean; limit?: number; nodeKeyLike?: string; kind?: GraphNodeUsageKind; }): Promise; /** Get requested graph edge-search shapes for one session. */ getSessionGraphEdgeSearchUsage(sessionId: string, opts?: { since?: Date; limit?: number; }): Promise; /** Upsert a session metric summary with atomic increments. */ upsertSessionMetricSummary(sessionId: string, updates: SessionMetricSummaryUpsert): Promise; /** Hard-delete summary rows for sessions deleted before the cutoff. Returns count removed. */ pruneDeletedSummaries(olderThan: Date): Promise; /** Cleanup / close connections. */ close(): Promise; } /** * PgSessionCatalog — PostgreSQL implementation of SessionCatalog. * * Uses the `pg` package (node-postgres) directly. * Must be created via the async `PgSessionCatalog.create()` factory. */ export declare class PgSessionCatalog implements SessionCatalog { private pool; private initialized; private sql; private _providers; readonly features: FeatureStore; private constructor(); /** * Provider budgets — see provider-store.ts. Kept behind one accessor * rather than spread across this class: the whole feature talks to the * `cms_provider_*` procs and nothing else, so it reads better as its own * surface than as thirty more methods here. */ get providers(): ProviderStore; static readonly DEFAULT_POOL_MAX = 3; /** Factory: create and connect a PgSessionCatalog. */ static create(connectionString: string, schema?: string, opts?: { useManagedIdentity?: boolean; aadUser?: string; }): Promise; initialize(): Promise; createSession(sessionId: string, opts?: { model?: string; reasoningEffort?: string; contextTier?: string | null; modelResolutionSource?: string; parentSessionId?: string; isSystem?: boolean; agentId?: string; splash?: string; splashMobile?: string; groupId?: string | null; owner?: SessionOwnerInfo | null; visibility?: SessionVisibility | null; /** Service sessions (tree-scoped machinery, e.g. the regen distiller). */ serviceKind?: string | null; serviceOf?: string | null; /** * The session's full serializable creation config (migration 0072). * Durable so the orchestration start — which can run on a DIFFERENT * process than the create — rebuilds the exact config instead of an * empty one. Read back only via getSessionCreationConfig, never * through the shared getSession row (viewers must not see it). */ creationConfig?: Record | null; }): Promise; /** * Stamp a session as a service session (tree-scoped machinery, migration * 0037) after creation — for callers that go through client.createSession * and cannot thread opts into the create transaction. */ markSessionService(sessionId: string, serviceKind: string, serviceOf: string | null): Promise; private _splashMobileCreateSupported; /** Whether the DB has migration 0026's 9-arg cms_create_session overload. Cached per catalog instance. */ private supportsSplashMobileCreate; private _visibilityCreateSupported; private _providerSessionModelValidationSupported; private supportsProviderSessionModelValidation; /** Whether the DB has migration 0029's 10-arg cms_create_session overload. Cached per catalog instance. */ private _creationConfigColumnSupported; /** Whether the DB has migration 0072's creation_config column. Cached per catalog instance. */ private supportsCreationConfig; private supportsVisibilityCreate; updateSession(sessionId: string, updates: SessionRowUpdates): Promise; setActiveTurnIndex(sessionId: string, turnIndex: number): Promise; softDeleteSession(sessionId: string): Promise; archiveSystemSessionForRestart(sessionId: string, state: "completed" | "cancelled" | "failed", lastError?: string | null): Promise; listSessions(placement?: { provider: string; subject: string; } | null): Promise; listSessionsPage(opts?: { limit?: number; cursorUpdatedAt?: Date | null; cursorSessionId?: string | null; includeDeleted?: boolean; systemFilter?: "all" | "only" | "exclude"; viewer?: { provider: string; subject: string; systemVisible?: boolean; } | null; placement?: { provider: string; subject: string; } | null; }): Promise; listSessionsVisible(viewer: { provider: string; subject: string; systemVisible?: boolean; }, placement?: { provider: string; subject: string; } | null): Promise; listKnownUsers(opts?: { limit?: number; }): Promise; getSession(sessionId: string, placement?: { provider: string; subject: string; } | null): Promise; /** * The session's durable creation config (migration 0072), or null. * * Deliberately its own narrow query: the shared getSession row is handed * to any viewer with read access by the web getSession op, and a stored * systemMessage is the owner's business. Called only on the * orchestration-start path when the in-memory config map misses, so it * adds nothing to the per-turn hot path. Fails soft on a pre-0072 * database (probe short-circuits before querying the column). */ getSessionCapabilities(sessionId: string): Promise; saveSessionCapabilities(sessionId: string, expectedRevision: number, state: CapabilityState): Promise; getSessionCreationConfig(sessionId: string): Promise | null>; setSessionVisibility(sessionId: string, visibility: SessionVisibility): Promise; grantSessionShare(sessionId: string, grantee: SessionOwnerInfo, access: "read" | "write", grantedBy?: SessionOwnerInfo | null): Promise; revokeSessionShare(sessionId: string, grantee: { provider: string; subject: string; }): Promise; listSessionShares(sessionId: string): Promise; filterVisibleSessionIds(sessionIds: string[], viewer: { provider: string; subject: string; }, systemVisible: boolean): Promise; getSessionAccess(sessionId: string, viewer: { provider: string; subject: string; }): Promise; recordAuthzAudit(entry: { actor?: { provider?: string | null; subject?: string | null; display?: string | null; } | null; action: string; sessionId?: string | null; target?: string | null; decision: string; reason?: string | null; details?: Record | null; }): Promise; listAuthzAudit(opts?: { limit?: number; sessionId?: string | null; }): Promise; getDescendantSessionIds(sessionId: string): Promise; getLastSessionId(): Promise; updateSessionSummary(sessionId: string, summaryState: SessionSummaryState, shortSummary?: string | null): Promise; createSessionGroup(input: { groupId: string; title: string; description?: string | null; owner?: SessionOwnerInfo | null; metadata?: Record; }): Promise; updateSessionGroup(groupId: string, patch: { title?: string; description?: string | null; owner?: SessionOwnerInfo | null; metadataPatch?: Record; }): Promise; listSessionGroups(viewer?: PlacementViewer | null): Promise; listGroupSessions(groupId: string, placement?: { provider: string; subject: string; } | null): Promise; deleteSessionGroup(groupId: string): Promise; placeSessionsInGroup(viewer: PlacementViewer, sessionIds: string[], groupId: string | null): Promise; upsertChildOutcome(input: { childSessionId: string; parentSessionId: string; contractJson?: Record | null; resultJson?: Record | null; verdict?: string | null; summary?: string | null; completedAt?: Date | null; }): Promise; getChildOutcome(childSessionId: string): Promise; listChildOutcomes(parentSessionId: string): Promise; recordEvents(sessionId: string, events: { eventType: string; data: unknown; }[], workerNodeId?: string): Promise; /** * Per-slot canvas cache — see migration 0045. The event log stays the * durable source; this is what makes per-slot revs O(1) and lets the * sessions list say "has canvases" without replaying events. A missed * write self-heals on the next draw (the bridge falls back to an event * scan when the row is absent), so callers treat failures as non-fatal. */ upsertSessionCanvas(sessionId: string, slot: number, name: string | null, latestRev: number, sizeBytes: number | null): Promise; /** * Drawn canvases for MANY sessions in one query — the sessions-list * attachment. Only rows with a real rev; empty ids short-circuit. */ listSessionCanvasesFor(sessionIds: string[]): Promise>>; /** All drawn canvases for one session, ordered by slot. */ getSessionCanvases(sessionId: string): Promise>; /** * Atomically mint the next canvas revision for (session, slot) — the * multi-writer-safe replacement for read-latest-then-plus-one, which * only the single-writer promise chain kept safe. seedRev is the * caller's best knowledge from the event scan: it floors the counter so * a session whose 0045 row was never written (legacy, missed upsert) * cannot mint rev 1 over a live rev-12 canvas. */ mintCanvasRev(sessionId: string, slot: number, seedRev: number): Promise; private canvasLiveProbe; canvasLiveAvailable(): Promise; upsertCanvasLiveTick(sessionId: string, slot: number, input: { data?: Record; patch?: Record; }, updatedBy: string, maxBytes?: number): Promise<{ seq: number; sizeBytes: number; payload: Record; } | { refused: true; currentSizeBytes: number | null; }>; upsertCanvasLiveDoc(sessionId: string, slot: number, doc: { rev: number; sha: string; }, updatedBy: string): Promise<{ seq: number; } | null>; getCanvasLive(sessionId: string): Promise; updatedBy: string; updatedAt: string; }>>; private liveProbe; liveAvailable(): Promise; publishLive(sessionId: string, topic: string, input: { patch: Record; } | { snapshot: Record; } | { signal: true; }, updatedBy: string, maxBytes?: number): Promise<{ seq: number; sizeBytes: number; payload: Record; } | { signal: true; } | { refused: true; currentSizeBytes: number | null; } | null>; getLive(sessionId: string, topics?: string[]): Promise; updatedBy: string; updatedAt: string; }>>; getCanvasKvSettings(sessionId: string, slot: number): Promise<{ kvAccess: "owner" | "readers" | "link"; kvManifest: unknown; latestRev: number; } | null>; setCanvasKvAccess(sessionId: string, slot: number, access: "owner" | "readers" | "link"): Promise; setCanvasKvManifest(sessionId: string, slot: number, manifest: unknown | null): Promise; canvasKvGet(sessionId: string, slot: number, key: string): Promise<{ key: string; value: any; rev: number; updatedAt: string; } | null>; canvasKvList(sessionId: string, slot: number, prefix: string | null, limit: number, afterKey: string | null): Promise>; canvasKvWrite(sessionId: string, slot: number, key: string, value: unknown | null, ifMatch: number | null, limits: { maxKeys: number; maxBytes: number; maxValueBytes: number; }): Promise<{ status: string; rev: number; sizeBytes: number | null; }>; canvasKvStats(sessionId: string, slot: number): Promise<{ keys: number; bytes: number; }>; getCanvasShareLinkInfo(sessionId: string, slot: number): Promise<{ exists: boolean; createdAt?: string; createdBy?: string; }>; setCanvasShareLink(sessionId: string, slot: number, tokenHash: string, createdBy: string): Promise; removeCanvasShareLink(sessionId: string, slot: number): Promise; resolveCanvasShareToken(tokenHash: string): Promise<{ sessionId: string; slot: number; } | null>; getSessionEvents(sessionId: string, afterSeq?: number, limit?: number, eventTypes?: string[]): Promise; getSessionEventsBefore(sessionId: string, beforeSeq: number, limit?: number, eventTypes?: string[]): Promise; getTopEventEmitters(since: Date, limit?: number): Promise; insertTurnMetric(input: InsertTurnMetricInput): Promise; completeTurnWriteback(input: CompleteTurnWritebackInput): Promise; getSessionTurnMetrics(sessionId: string, opts?: { since?: Date; limit?: number; }): Promise; getSessionTokensByModel(sessionId: string): Promise; getHourlyTokenBuckets(since: Date, opts?: { agentId?: string; model?: string; }): Promise; pruneTurnMetrics(olderThan: Date): Promise; getSessionMetricSummary(sessionId: string): Promise; getSessionEventStats(sessionId: string, afterSeq?: number): Promise; getSessionCompactionStats(sessionId: string, afterSeq?: number): Promise; recordEpochCommitted(sessionId: string, payload: Record): Promise; recordRegenerated(sessionId: string, payload: Record): Promise; getSessionTreeStats(sessionId: string): Promise; getFleetStats(opts?: { includeDeleted?: boolean; since?: Date; }): Promise; getUserStats(opts?: { includeDeleted?: boolean; since?: Date; }): Promise; upsertSessionMetricSummary(sessionId: string, updates: SessionMetricSummaryUpsert): Promise; getUserProfile(principal: UserPrincipal): Promise; getUserGitHubCopilotKey(principal: UserPrincipal): Promise; setUserProfileSettings(principal: UserPrincipal, settings: Record): Promise; setUserGitHubCopilotKey(principal: UserPrincipal, key: string | null): Promise; getUserRole(principal: UserPrincipal): Promise; setUserRole(principal: UserPrincipal, role: string | null): Promise; pruneDeletedSummaries(olderThan: Date): Promise; getSessionSkillUsage(sessionId: string, opts?: { since?: Date; }): Promise; getSessionTreeSkillUsage(sessionId: string, opts?: { since?: Date; }): Promise; getFleetSkillUsage(opts?: { since?: Date; includeDeleted?: boolean; }): Promise; getSessionRetrievalUsage(sessionId: string, opts?: { since?: Date; }): Promise; getSessionTreeRetrievalUsage(sessionId: string, opts?: { since?: Date; }): Promise; getFleetRetrievalUsage(opts?: { since?: Date; includeDeleted?: boolean; }): Promise; getSessionGraphNodeUsage(sessionId: string, opts?: { since?: Date; limit?: number; nodeKeyLike?: string; kind?: GraphNodeUsageKind; }): Promise; getFleetGraphNodeUsage(opts?: { since?: Date; includeDeleted?: boolean; limit?: number; nodeKeyLike?: string; kind?: GraphNodeUsageKind; }): Promise; getSessionGraphEdgeSearchUsage(sessionId: string, opts?: { since?: Date; limit?: number; }): Promise; workerHeartbeat(input: WorkerHeartbeatInput): Promise; listWorkers(): Promise; fleetDirectiveBump(domain: string, opts?: { pool?: string | null; workerNodeId?: string | null; desired?: Record | null; actuation?: "worker" | "external"; updatedBy?: string | null; }): Promise; getFleetDirectives(): Promise; agentRegistryEpoch(): Promise; registerAgentSource(source: { sourceId: string; kind: "github" | "ado" | "url" | "upload"; scope: AgentPackageScope; repoUrl?: string | null; ref?: string | null; path?: string | null; url?: string | null; authToken?: string | null; autoSync?: boolean; owner: AgentPrincipal | null; createdBy?: string | null; }): Promise; listAgentSources(viewer: AgentPrincipal | null, isAdmin: boolean): Promise; getAgentSource(sourceId: string): Promise; getAgentSourceToken(sourceId: string): Promise; updateAgentSourceSync(sourceId: string, status: string, error: string | null, commitSha: string | null): Promise; deleteAgentSource(sourceId: string, actor: AgentPrincipal | null, isAdmin: boolean): Promise; publishAgentPackage(input: PublishAgentPackageInput): Promise; listAgentPackages(viewer: AgentPrincipal | null, isAdmin: boolean): Promise; getAgentPackage(name: string, viewer: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; /** * Which package a name means for this viewer, as a package id. * * Exposed because the WORKER needs the same answer the API gives: agent * binding, package reads and package writes must never disagree about * which copy of a name they are talking about. */ resolveAgentPackageId(name: string, viewer: AgentPrincipal | null, selector?: AgentPackageSelector | null, opts?: { requireEnabled?: boolean; }): Promise; getAgentPackagesInstallManifest(): Promise; setAgentPackageScope(name: string, scope: AgentPackageScope, actor: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; setAgentPackageEnabled(name: string, enabled: boolean, actor: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; pinAgentPackageVersion(name: string, semver: string, actor: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; deleteAgentPackage(name: string, actor: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; isAgentPackageEditor(packageId: string, principal: AgentPrincipal | null): Promise; grantAgentPackageEditor(name: string, grantee: AgentPrincipal, actor: AgentPrincipal | null, isAdmin: boolean): Promise; revokeAgentPackageEditor(name: string, grantee: AgentPrincipal, actor: AgentPrincipal | null, isAdmin: boolean): Promise; listAgentPackageEditors(name: string): Promise; /** * How many published version rows reference this artifact blob filename. * Blob files are content-addressed (name@semver.sha), so identical bytes * published under the same name+semver in two scopes share ONE file. A * cleanup path must never delete a blob this reports > 0 for. */ countAgentPackageArtifactRefs(artifactFilename: string): Promise; upsertAgentWorkerState(workerNodeId: string, epoch: number, installed: Record): Promise; listAgentWorkerState(): Promise; close(): Promise; } /** @deprecated Use `SessionCatalog` instead. */ export type SessionCatalogProvider = SessionCatalog; /** @deprecated Use `PgSessionCatalog` instead. */ export declare const PgSessionCatalogProvider: typeof PgSessionCatalog; //# sourceMappingURL=cms.d.ts.map