/**
 * Request and response types for the `projects` namespace.
 *
 * These types map to the shapes of the run402 API endpoints exposed by
 * the gateway. They are intentionally not re-used from the gateway source
 * (private repo) — the SDK version is the canonical client-side contract.
 */
import type { ProjectKeys } from "../credentials.js";
import type { ExposeManifest, EffectiveAccessPreview } from "./deploy.types.js";
import type { OperationActorSnapshot } from "./identity-links.types.js";
export type ProjectTier = "prototype" | "hobby" | "team";
export interface ProvisionOptions {
    /** Tier determines price, lease length, storage, and API-call limits. Default: "prototype". */
    tier?: ProjectTier;
    /** Optional display name. Auto-generated when omitted. */
    name?: string;
    /**
     * Provision into an EXISTING org by id (v1.82). The caller must hold a
     * `developer`+ membership on that org (a project-scoped grant cannot authorize
     * creating a new project). Omit for the cold-start path — the wallet's billing
     * account is used or auto-created exactly as before. Note: tier is governed by
     * the org/organization, not the project — the gateway ignores a client tier.
     */
    orgId?: string;
    /**
     * Idempotency key for safe retries (durable-side-effects doctrine). When set,
     * the SDK sends it as the `Idempotency-Key` header so a re-run with the same
     * key + payload returns the existing project instead of creating a duplicate.
     * Supply a stable key derived from the logical project identity (e.g. the app
     * name) so an agent's natural re-run after a crash cannot double-bill. The CLI
     * auto-derives one from `--name` when `--idempotency-key` is omitted.
     */
    idempotencyKey?: string;
}
export interface ProvisionResult {
    project_id: string;
    anon_key: string;
    service_key: string;
    schema_slot: string;
    endpoints?: {
        rest_url?: string;
        static_base_url?: string;
        storage_base_url?: string;
    };
    active_release_id?: string | null;
    capabilities?: unknown;
}
/**
 * Lifecycle state of the owning organization (gateway v1.57+). The state
 * machine moved from `internal.projects` to `internal.organizations`; every
 * project on the account inherits the same value. `purging` is an internal
 * transition state and is not exposed on the wire.
 */
export type OrganizationLifecycleState = "active" | "past_due" | "frozen" | "dormant" | "purged";
/**
 * Effective project status, derived from `(organization_lifecycle_state,
 * deleted_at, archived_at)`:
 *   - `deleted_at` set → `"deleted"`
 *   - `archived_at` set → `"archived"`
 *   - otherwise → the organization's `lifecycle_state`
 *
 * Use this for serving / UX decisions instead of trying to combine the
 * underlying fields yourself.
 */
export type EffectiveProjectStatus = "active" | "past_due" | "frozen" | "dormant" | "archived" | "deleted";
/**
 * One project row from the named, domain-aware inventory (gateway
 * `project-findability`). Returned by `GET /projects/v1` (membership-scoped)
 * and `GET /agent/v1/me/projects` (every organization, `--all`) — both
 * share this shape.
 *
 * Tier and lifecycle live on the owning organization, not the project; the
 * row mirrors them for convenience but read `r.tier.status()` for the
 * authoritative account view.
 */
export interface ProjectSummary {
    id: string;
    name: string;
    /** Account-derived tier (mirror; authoritative source is `r.tier.status()`). */
    tier?: string;
    /**
     * Primary public URL: the first claimed run402.com subdomain, else the first
     * custom domain, else null. Surfaced by the named inventory (`GET /projects/v1`
     * and the `--all` read).
     */
    site_url?: string | null;
    /**
     * Every custom hostname mapped to this project (empty when none). The
     * run402.com subdomain is reflected in `site_url`, not here.
     */
    custom_domains?: string[];
    /** Derived effective status — see {@link EffectiveProjectStatus}. */
    status?: EffectiveProjectStatus;
    /** Alias of `status` (gateway v1.57 canonical field). */
    effective_status?: EffectiveProjectStatus;
    /** Owning organization's lifecycle state. */
    organization_lifecycle_state?: OrganizationLifecycleState;
    /** Account-level lease-perpetual escape hatch (mirror). */
    lease_perpetual?: boolean;
    /**
     * Owning org (organization) id — v1.77 org-owned control plane. A wallet
     * authenticates; the org owns the project. Surfaced as `org_id` in CLI/MCP
     * output. `null` for legacy rows; optional because the legacy wallet-scoped
     * list (`GET /wallets/v1/:address/projects`) omits it.
     */
    org_id?: string | null;
    /**
     * Provisioning principal id — provenance for who created the project (v1.77).
     * Optional for the same reason as {@link ProjectSummary.org_id}.
     */
    created_by?: string | null;
    /** Immutable creation-time public provenance; null on legacy projects. */
    creator?: OperationActorSnapshot | null;
    created_at: string;
    deleted_at?: string | null;
    archived_at?: string | null;
    /**
     * Legacy wallet-scoped list (`GET /wallets/v1/:address/projects`) only — the
     * named inventory does not include per-project usage counters. Read
     * `r.projects.getUsage(id)` for live usage.
     */
    api_calls?: number;
    /** See {@link ProjectSummary.api_calls}. */
    storage_bytes?: number;
}
/**
 * Options for {@link Projects.list}.
 *
 * Membership-scoped by default (`GET /projects/v1` — every project owned by an
 * org the caller's principal is an active member of). The cold-start lone-agent
 * path is `list()` with no options.
 */
export interface ListProjectsOptions {
    /**
     * Narrow to projects owned by one org (organization) id. Authorize-before-
     * reveal: a non-member or guessed id returns the same 403 as a real-but-
     * unauthorized org; a non-UUID id is a clean 400.
     */
    org?: string;
    /**
     * Read every project the caller can reach across all its organizations
     * (`GET /agent/v1/me/projects`) instead of the single membership-scoped page.
     * Supply `token` (a sign-in session) for the person's account; without it,
     * `all` uses the credential provider and a SIWX wallet reads its own slice.
     * Mutually exclusive with `org`.
     */
    all?: boolean;
    /**
     * Sign-in session bearer token for the `all` read. When omitted, `all` uses
     * the credential provider. Ignored when `all` is not set.
     */
    token?: string;
    /** Page size. Server default 50, max 200. Ignored for `all` (union, unpaged). */
    limit?: number;
    /** Opaque pagination cursor from a previous response's `next_cursor`. */
    cursor?: string;
}
export interface ListProjectsResult {
    projects: ProjectSummary[];
    /** True when more pages remain (membership-scoped reads). */
    has_more?: boolean;
    /** Cursor to fetch the next page, or null at the end. */
    next_cursor?: string | null;
    /** `all` reads echo the resolved scope: `"principal"` (a sign-in session) or `"wallet"` (a wallet slice). */
    scope?: string;
}
/** Result of {@link Projects.rename}. */
export interface RenameProjectResult {
    project_id: string;
    name: string;
}
/** Result of {@link Projects.setRepoName} (`POST /projects/v1/:id/repo-name`). */
export interface SetRepoNameResult {
    project_id: string;
    repo_name: string;
    /** The project's PRIOR address-form name, or `null` if it had none. */
    previous_repo_name: string | null;
}
export type TenantPaymentStatus = "settling" | "settled" | "settle_failed" | "ambiguous";
export interface ListTenantPaymentsOptions {
    /** Page size. Server default 50, max 200. */
    limit?: number;
    /** Opaque keyset cursor from a previous response's `next_cursor`. */
    after?: string;
    /** Optional status filter. */
    status?: TenantPaymentStatus;
}
/**
 * Redacted project-scoped tenant x402 payment record. Raw x402 authorization
 * headers, canonical authorization hashes, and internal metadata are never
 * returned by the gateway.
 */
export interface TenantPaymentRecord {
    payment_id: string;
    status: TenantPaymentStatus;
    org_id: string;
    project_id: string;
    release_id: string | null;
    route_pattern: string;
    route_method: string;
    route_target_function: string | null;
    amount_usd_micros: number;
    settled_amount_usd_micros: number | null;
    network: string;
    asset: string | null;
    asset_address: string | null;
    payer: string | null;
    pay_to: string;
    scheme: "x402" | string;
    scheme_version: string | null;
    facilitator: string | null;
    settlement_reference: string | null;
    settlement_tx_hash: string | null;
    request_id: string | null;
    host: string | null;
    path: string | null;
    operation_id: string | null;
    attempts: number;
    last_error_code: string | null;
    last_error_message: string | null;
    next_reconcile_at: string | null;
    last_reconciled_at: string | null;
    reconciliation_attempts: number;
    reuse_expires_at: string | null;
    last_seen_at: string | null;
    created_at: string;
    updated_at: string;
    settled_at: string | null;
    [key: string]: unknown;
}
export interface TenantPaymentListResult {
    project_id: string;
    payments: TenantPaymentRecord[];
    has_more: boolean;
    next_cursor: string | null;
}
/** Active-release pointer on {@link ProjectDetail}. `null` when nothing is live. */
export interface ProjectLastDeploy {
    release_id: string;
    activated_at: string;
}
/** Usage counters paired with the owning account's tier limits. */
export interface ProjectUsageWithLimits {
    api_calls: number;
    storage_bytes: number;
    api_calls_limit: number;
    storage_bytes_limit: number;
    /** `storage_bytes_limit` as a human string ("250 MB"), derived from the tier constant. */
    storage_limit: string;
}
/**
 * Authoritative server-side view of one project, from `GET /projects/v1/:project_id`
 * (gateway `project.read`). A superset of {@link ProjectSummary} that adds the
 * public id, the active-release pointer, active mailbox addresses, and usage vs.
 * tier limits. Carries NO key material — the endpoint never returns secrets; read
 * `r.projects.keys(id)` (local) for the anon/service keys.
 *
 * Authorize-before-reveal: a caller without `project.read` authority sees the same
 * `Unauthorized` for a real-but-forbidden project as for an absent one — never a
 * 404 that would confirm existence.
 */
export interface ProjectDetail {
    project_id: string;
    /** Short public identifier (distinct from the `prj_…` id). */
    public_id: string;
    name: string;
    /** Owning org (organization) id — v1.77 org-owned control plane. */
    org_id: string;
    /** Account-derived tier (authoritative source is `r.tier.status()`). */
    tier: string;
    /** Derived effective status — see {@link EffectiveProjectStatus}. */
    effective_status: EffectiveProjectStatus;
    /** Owning organization's lifecycle state. */
    organization_lifecycle_state: OrganizationLifecycleState;
    /** Primary public URL, or `null` when none is claimed. */
    site_url: string | null;
    /** Every custom hostname mapped to this project (empty when none). */
    custom_domains: string[];
    /** Active-release pointer, or `null` when nothing is deployed. */
    last_deploy: ProjectLastDeploy | null;
    /** Active mailbox addresses (formatted, e.g. `hello@p-abc123.mail.run402.com`). */
    mailbox: string[];
    /** Usage counters paired with the owning account's tier limits. */
    usage: ProjectUsageWithLimits;
    created_at: string;
    /** Legacy creating-principal field retained for compatibility. */
    created_by: string | null;
    /** Immutable creation-time public provenance; null on legacy projects. */
    creator: OperationActorSnapshot | null;
    /** Forward-compat: unknown future fields a newer gateway may add. */
    [key: string]: unknown;
}
export interface UsageReport {
    project_id: string;
    tier: string;
    /** Owning organization id, or `null` for a project with no organization. */
    org_id: string | null;
    api_calls: number;
    api_calls_limit: number;
    storage_bytes: number;
    storage_limit_bytes: number;
    /** `storage_limit_bytes` as a human string ("250 MB"), derived from the tier constant. */
    storage_limit: string;
    /** Derived effective status — see {@link EffectiveProjectStatus}. */
    status: EffectiveProjectStatus;
    /**
     * ISO-8601 expiry of the owning organization's tier lease. `null` when the
     * lease is perpetual (`lease_perpetual: true`) or the project has no
     * organization.
     */
    lease_expires_at: string | null;
    /**
     * `true` when the owning organization's lease never expires
     * (`lease_expires_at` is then `null`); `false` otherwise, including a
     * project with no organization. Matches `tier.status()`.
     */
    lease_perpetual: boolean;
}
export interface ColumnSchema {
    name: string;
    type: string;
    nullable: boolean;
    default_value: string | null;
}
export interface ConstraintSchema {
    name: string;
    type: string;
    definition: string;
}
export interface RlsPolicy {
    name: string;
    command: string;
    using_expression: string | null;
    check_expression: string | null;
}
export interface TableSchema {
    name: string;
    columns: ColumnSchema[];
    constraints: ConstraintSchema[];
    rls_enabled: boolean;
    /**
     * Planner row estimate (`reltuples`), refreshed by ANALYZE/VACUUM. Always an
     * estimate, never an exact count. `null` when the table was never analyzed
     * (so "unknown" stays distinguishable from a real zero); may be absent from
     * gateways predating the field.
     */
    row_estimate?: number | null;
    policies: RlsPolicy[];
}
export interface SchemaReport {
    schema: string;
    tables: TableSchema[];
}
/** A warning on a SQL result. A warning never changes the result. */
export interface SqlWarning {
    /** `ROUTE_RETIRING` (a retiring route was called), `SCHEMA_CHANGE_OUTSIDE_MIGRATION`
     *  (DDL on a project with a live release, which the release no longer
     *  describes), or `MULTI_STATEMENT_TEXT_BODY` (several statements in one text
     *  body; use {@link Projects.sqlBatch}). Future codes remain valid strings. */
    code: "ROUTE_RETIRING" | "SCHEMA_CHANGE_OUTSIDE_MIGRATION" | "MULTI_STATEMENT_TEXT_BODY" | (string & {});
    severity?: string;
    message: string;
    next_actions: Array<Record<string, unknown>>;
    [key: string]: unknown;
}
/** One result column: its name and Postgres type. */
export interface SqlField {
    name: string;
    type: string;
}
/** Options for {@link Projects.sql}. */
export interface SqlOptions {
    /** Run read-only, enforced by PostgreSQL (one statement; a write answers
     *  DATABASE_READ_ONLY). Honored for every caller, service key included. */
    readOnly?: boolean;
}
/** The result of {@link Projects.sql}, in the wire shape. */
export interface SqlResult {
    status: string;
    schema: string;
    /** The last statement's rows. */
    rows: Array<Record<string, unknown>>;
    /** The last statement's row count (returned or affected). */
    row_count: number;
    /** The last statement's columns. */
    fields: SqlField[];
    /** One entry per statement, in order; their sum is a batch's total. */
    statements: Array<{
        command: string | null;
        row_count: number;
    }>;
    warnings: SqlWarning[];
}
/** One statement in a {@link Projects.sqlBatch} call: exactly one SQL statement. */
export interface SqlBatchStatement {
    sql: string;
    params?: unknown[];
}
export interface SqlBatchOptions {
    /** `all` (default): one transaction; the first failure rolls back every
     *  statement and throws `SQL_BATCH_STATEMENT_FAILED` naming its index.
     *  `each`: every statement in its own transaction; failures are reported
     *  per statement and later statements still run. */
    transaction?: "all" | "each";
}
export type SqlBatchStatementResult = {
    index: number;
    status: "ok";
    command: string | null;
    rows: Array<Record<string, unknown>>;
    row_count: number;
    fields: SqlField[];
} | {
    index: number;
    status: "error";
    message: string;
};
/** The result of {@link Projects.sqlBatch}. `status` is `partial` when a
 *  statement failed under `transaction: "each"`. */
export interface SqlBatchResult {
    status: "ok" | "partial";
    schema: string;
    transaction: "all" | "each";
    results: SqlBatchStatementResult[];
    warnings: SqlWarning[];
}
export type ProjectRestMethod = "GET" | "POST" | "PATCH" | "DELETE";
export type ProjectRestKeyType = "anon" | "service";
export interface ProjectRestOptions {
    /** HTTP method. Default: "GET". */
    method?: ProjectRestMethod;
    /** Query string without leading "?", or key/value query parameters. */
    query?: string | Record<string, string>;
    /** JSON body for POST/PATCH/DELETE requests. */
    body?: unknown;
    /** Key used for apikey + bearer auth. Default: "anon", or, when this
     *  machine has no cached key for the project, your own authority on the
     *  project REST route (database authority, like "service"). */
    keyType?: ProjectRestKeyType;
}
export interface ProjectRestResponse<T = unknown> {
    status: number;
    body: T;
}
export type ExposeManifestValidationInput = ExposeManifest | string;
export interface ValidateExposeOptions {
    /** Project id used for live-schema validation. Omit for projectless validation. */
    project?: string;
    /** Alias for `project`, accepted for callers that already use gateway/MCP naming. */
    project_id?: string;
    /** Migration SQL used as validation context only; it is not executed. */
    migrationSql?: string;
}
export type ExposeManifestValidationIssueType = "missing-table" | "missing-column" | "missing-view-base" | "missing-rpc" | "ambiguous-rpc" | "unrestricted-ack-required" | "sensitive-column-public-write" | "grant-to-role-unknown" | "force-owner-without-owner-column" | "validation-inconclusive" | "schema-shape";
export type ExposeManifestValidationSeverity = "error" | "warning";
export interface ExposeManifestValidationIssue {
    type: ExposeManifestValidationIssueType;
    severity: ExposeManifestValidationSeverity;
    detail: string;
    fix?: string;
}
export interface ExposeManifestValidationResult {
    effective_access?: EffectiveAccessPreview[];
    hasErrors: boolean;
    errors: ExposeManifestValidationIssue[];
    warnings: ExposeManifestValidationIssue[];
}
/**
 * One tier's pricing row from `GET /tiers/v1`. Byte quotas are decimal
 * (250 MB is 250,000,000 bytes); each byte count carries its human string
 * beside it under the same name with `_bytes` removed.
 */
export interface TierQuote {
    price: string;
    lease_days: number | null;
    /** App/project storage quota in bytes, pooled per organization. */
    storage_bytes: number;
    /** `storage_bytes` as a human string ("250 MB"). */
    storage: string;
    /** Vault (repos) quota in bytes — a separate pooled limit from `storage_bytes`. */
    source_bytes: number;
    /** `source_bytes` as a human string ("1 GB"). */
    source: string;
    api_calls: number;
    max_functions: number;
    description: string;
}
export interface QuoteResult {
    tiers: Record<string, TierQuote>;
    auth?: Record<string, unknown>;
}
export interface ProjectInfo extends ProjectKeys {
    project_id: string;
}
//# sourceMappingURL=projects.types.d.ts.map