/** * `org` namespace — the org-owned control plane (gateway v1.77+, first-class in * v1.82). Mirrors the `r.projects` / `r.project(id)` idiom: * * - `r.orgs` — collection + identity: `create`, `list`, `whoami`. * - `r.org(id)` — a resource-scoped sub-client (id pre-bound): `get`, * `rename`, `members.*`, `invites.*`, `audit`. * * All routes use the existing SIWX (or control-plane-session) auth; authorization * is a membership lookup, never `wallet == signer`. Mutations (`create`, * `rename`, member/invite changes) are step-up gated server-side and may return * `STEP_UP_REQUIRED` when driven by a stale control-plane session. */ import type { Client } from "../kernel.js"; import type { AddMemberInput, AuditOptions, AuditResult, SetOrgSlugResult, CreateInviteInput, CreateOrgInput, MemberMutationResult, MemberRevokeResult, MemberRevokeEncryptionKeyResult, OrgDetail, OrgInvite, OrgInviteRevokeResult, OrgMember, OrgMembership, OrgSummary, SetPayoutWalletInput, SetPayoutWalletResult, SetMemberRoleOptions, WhoAmIResult } from "./org.types.js"; /** Member management — `r.org(id).members.*`. The org id is bound at construction. */ export declare class OrgMembers { private readonly client; private readonly orgId; constructor(client: Client, orgId: string); /** List members of the org (`GET /orgs/v1/:org_id/members`). Any active member. */ list(): Promise; /** * Add a member by wallet (`POST /orgs/v1/:org_id/members`). Requires an active * `owner` membership. A brand-new wallet is provisioned as a `human` principal; * `role` defaults to `"developer"` server-side. */ add(input: AddMemberInput): Promise; /** * Change a member's role (`PATCH …/members/:principal_id`). Requires `owner`; * demoting the org's only active owner fails with `409 LAST_OWNER`. */ setRole(principalId: string, opts: SetMemberRoleOptions): Promise; /** * Revoke a member (`DELETE …/members/:principal_id`) — one row, status * `revoked`, no key rotation. Requires `owner`; revoking the org's only active * owner fails with `409 LAST_OWNER`. */ revoke(principalId: string): Promise; /** * vault-agent-envelopes D3 — an OWNER revokes a member's current vault * encryption key (`DELETE /orgs/v1/:org_id/members/:principal_id/encryption-key`, * owner + step-up). The independent-credential rotation path: a member whose * keystore was lost or rebuilt cannot self-rotate (the asking credential is * the one a thief would hold); after this, the member's next vault * operation enrolls its current keystore key afresh and a key-holder's next * operation wraps each vault to it. Audited, org-feed row + mandatory * security notification (`gitvault_encryption_key_revoked`). */ revokeEncryptionKey(principalId: string, input?: { reason?: string; }): Promise; } /** Email-invite management — `r.org(id).invites.*`. The org id is bound at construction. */ export declare class OrgInvites { private readonly client; private readonly orgId; constructor(client: Client, orgId: string); /** List pending email invites (`GET /orgs/v1/:org_id/invites`). Any active member. */ list(): Promise; /** * Invite a person by email (`POST …/invites`); claimed at their first login. * Requires `owner` (plus step-up when driven by a control-plane session). */ create(input: CreateInviteInput): Promise; /** Revoke a pending invite by its pending principal id (`DELETE …/invites/:principal_id`). Requires `owner`. */ revoke(principalId: string): Promise; } /** * A resource-scoped org sub-client returned by `r.org(id)`. The org id is bound * at construction; instance operations take no repeated id argument. Mirrors the * project-scoped `r.project(id)` shape (narrower scope). */ export declare class ScopedOrg { private readonly client; /** Member management (`r.org(id).members.*`). */ readonly members: OrgMembers; /** Email-invite management (`r.org(id).invites.*`). */ readonly invites: OrgInvites; /** The org id this sub-client is bound to. Read-only. */ readonly orgId: string; constructor(client: Client, orgId: string); /** * Read this org (`GET /orgs/v1/:org_id`) — `{ org_id, display_name, tier, * lease_started_at, lease_expires_at, role }`. * Any active member may view; a non-member (including a guessed id) gets the * same non-revealing `403`. */ get(): Promise; /** * Rename this org (`PATCH /orgs/v1/:org_id`). Owner-only + step-up gated. Pass * `null` or `""` to clear the label. Returns the updated `{ org_id, * display_name, tier, lease_started_at, lease_expires_at }`. */ rename(displayName: string | null): Promise; /** * Claim or rename this org's address-form slug * (`POST /orgs/v1/:org_id/slug`, repo-first-onramp design D6). Owner-only. * A genesis claim (this org had no prior slug) debits `~$1` (the payable * claim fee, ruins bulk-squatting economics) and is a paid, side-effecting * mutation — REQUIRES `Idempotency-Key`, which this method generates * client-side (a fresh one per call) unless `opts.idempotencyKey` is * supplied, so a retried call after a dropped response cannot double-bill. * A rename releases the OLD slug into its ~90-day cooldown (typed * `SLUG_RELEASED` refusal on the old slug thereafter, naming this org's * new one as successor — never a redirect). `created` is `true` for a * genesis claim, `false` for a rename or an idempotent no-op replay of the * SAME target slug. */ setSlug(slug: string, opts?: { idempotencyKey?: string; }): Promise; /** * Set or clear the default payout wallet for tenant priced routes * (`PATCH /orgs/v1/:org_id/payout-wallet`). Requires org admin/owner plus * server-side step-up or fresh SIWX. The wallet must already be active and * linked to this org; pass `null` to clear the explicit default. */ setPayoutWallet(input: SetPayoutWalletInput): Promise; /** * Control-plane audit trail for this org (`GET /orgs/v1/:org_id/audit`). * admin+. Newest-first; page forward with the `after` keyset cursor * (`next_cursor` from a prior page) — the legacy `before` cursor is still * accepted. Returns `{ events, has_more, next_cursor }`. */ audit(opts?: AuditOptions): Promise; } /** * Org collection + identity — `r.orgs.*`. Operations that are not bound to a * single org: create a new org, list the caller's orgs, resolve the principal. */ /** * An adopt challenge (`POST /orgs/v1/adopt/challenge`). The wallet must sign a * fresh SIWX message carrying {@link AdoptChallenge.nonce}; that signed message * becomes the `SIGN-IN-WITH-X` header on {@link OrgAdopt.submit}. Reveals * nothing about the wallet's orgs — control is proven only at adopt time. */ export interface AdoptChallenge { challenge_id: string; nonce: string; expires_at: string; sign_instructions?: { scheme?: string; nonce?: string; note?: string; [key: string]: unknown; }; [key: string]: unknown; } /** Input to {@link OrgAdopt.challenge}. */ export interface AdoptChallengeInput { /** The wallet (0x EVM address) whose agent-owned org is being adopted. */ wallet: string; /** * The human's write-capable control-plane session bearer. Falls back to the * client's default auth when omitted — pass it explicitly unless the client was * constructed with control-plane-session credentials. */ token?: string; } /** Input to {@link OrgAdopt.submit}. */ export interface AdoptSubmitInput { /** * The fresh SIWX proof over the challenge nonce — the value of the * `SIGN-IN-WITH-X` header (the wallet proof). In Node, build it with * `signOrgAdopt` from `@run402/sdk/node`. */ siwx: string; /** The human's control-plane session bearer (see {@link AdoptChallengeInput.token}). */ token?: string; /** * Target org id. Omit on the first submit; supply it on the second round when * the first returned `select_org` (the wallet's agent owns more than one org). * The same `token` + `siwx` are reused — no re-challenge, no re-sign. */ orgId?: string; /** Optional label to set on the adopted org at the same time. `null`/`""` clears. */ displayName?: string | null; } /** One org offered for selection when a wallet's agent owns more than one (`select_org`). */ export interface SelectableOrg { org_id: string; display_name: string | null; tier: string; [key: string]: unknown; } /** * Result of {@link OrgAdopt.submit}. A discriminated union: `"adopted"` on * success, or `"select_org"` when the wallet's agent owns more than one org and * the caller must re-submit with a chosen `orgId`. `select_org` is a normal * (non-error) result — it is returned, never thrown. */ export type AdoptResult = { status: "adopted"; org_id: string; display_name: string | null; role: string; /** True when the human already owned the org (idempotent re-adopt). */ already_owned?: boolean; [key: string]: unknown; } | { status: "select_org"; selectable_orgs: SelectableOrg[]; [key: string]: unknown; }; /** * Adopt the org your wallet's agent owns — `r.orgs.adopt.*`. The isomorphic * (raw-proof) seam: `challenge` issues a nonce; `submit` posts the dual proof * (control-plane session bearer + a fresh `SIGN-IN-WITH-X` wallet signature). The * Node convenience `signOrgAdopt` / `adoptOrg` in `@run402/sdk/node` * runs the whole dance (read session → challenge → sign → submit). */ export declare class OrgAdopt { private readonly client; constructor(client: Client); /** Request a single-use challenge nonce the wallet must sign (`POST /orgs/v1/adopt/challenge`). */ challenge(input: AdoptChallengeInput): Promise; /** * Execute the adopt (`POST /orgs/v1/adopt`) carrying both proofs: the * control-plane session bearer (the human) and the `SIGN-IN-WITH-X` wallet * signature. Returns a discriminated {@link AdoptResult}; a `select_org` result * is returned (not thrown). Throws {@link StepUpRequiredError} when the session * is not passkey-fresh, and `ApiError` (`WALLET_PROOF_INVALID`) on a bad proof. */ submit(input: AdoptSubmitInput): Promise; } export declare class Orgs { private readonly client; /** * Adopt the org your wallet's agent owns: `r.orgs.adopt.challenge()` + * `.submit()`. The raw dual-proof seam; the Node convenience `adoptOrg` in * `@run402/sdk/node` runs the full dance. */ readonly adopt: OrgAdopt; constructor(client: Client); /** * Create an empty org on the `prototype` tier (`POST /orgs/v1`); the caller * becomes `owner`. Accepts only an optional `displayName` — there is no tier * input at create. The response reports the created org's tier/lease state. * Step-up gated; the soft per-owner free-org cap answers 403 * `FREE_ORG_OWNER_LIMIT_EXCEEDED` with `next_actions` (a policy refusal, * never a 429 — raised as {@link Unauthorized} carrying that `code`). */ create(input?: CreateOrgInput): Promise; /** List the orgs the caller is an active member of (`GET /orgs/v1`), as memberships. */ list(): Promise; /** * Resolve the caller's control-plane principal and its org memberships * (`GET /agent/v1/whoami`). This is the REMOTE identity; for the local, * network-free wallet/profile identity use `r.whoami()`. */ whoami(): Promise; /** * Set the caller's own display name (`PATCH /agent/v1/me`) — the name * promotion credit (`hand_to_member.credited_as`), `up`'s room presence, * and audit surfaces show for this principal. 1–64 characters after * trimming, no control characters. Self-only: a grant key names the * principal it acts for. Returns the same body `whoami()` returns. */ setDisplayName(displayName: string): Promise; } //# sourceMappingURL=org.d.ts.map