/** * Organization context, owned by the Node SDK: the ONE resolver every * org-scoped command consumes, and the verbs that select, report, and bind * the current organization. * * The org is the ownership root — it owns projects, holds memberships, and is * the scope for rooms, escalations, members, grants, and audit. Precedence is * four INTENT CLASSES, highest first, and inside each class an organization * named directly outranks one derived from a project named in that same class: * * 1. flag `org` (--org) else `project` (--project) -> its org * 2. environment RUN402_ORG, else the org half else RUN402_PROJECT_ID -> its org * of RUN402_ROOM * 3. binding the `org` key of the nearest .run402(.local).json * 3.5 vault pin `r402.orgId` in this checkout's local git config * 4. profile state the profile's selected org else its active project -> org * * Naming a project IS naming its organization, so a stale profile selection * never outranks it; classes 3 and 4 are what let an org that owns no project * be addressed at all. * * Two things this deliberately does NOT do: * - Infer the org from the caller's memberships, at any count: membership is * server state that changes without the caller acting. * - Validate membership locally: a well-formed id goes to the server and the * server's answer is surfaced as returned, never retried against a lower * class and never rewritten into a local not-found. */ import { LocalError, type NextAction } from "../errors.js"; import type { Client } from "../kernel.js"; import { Orgs } from "../namespaces/org.js"; import { Rooms } from "../namespaces/rooms.js"; import { Projects } from "../namespaces/projects.js"; export declare const ORG_ENV = "RUN402_ORG"; export declare const ROOM_ENV = "RUN402_ROOM"; export declare const PROJECT_ENV = "RUN402_PROJECT_ID"; /** `org_id` is a UUID at every API boundary. */ export declare const ORG_ID_RE: RegExp; export type OrgSource = "flag" | "env" | "binding" | "vault_pin" | "profile"; export interface ResolvedOrg { orgId: string; source: OrgSource; sourceDetail: string; } export interface ResolveOrgInput { /** The org named directly (the `--org` flag). */ org?: string | null; /** A project named directly (the `--project` flag); its owning org decides. */ project?: string | null; } export interface ResolveOrgOptions { env?: Record; /** Directory the binding walk starts from. Default `process.cwd()`. */ cwd?: string; /** Return null instead of throwing `ORG_REQUIRED` when nothing supplies an org. */ optional?: boolean; /** Skip the env-vs-binding `AMBIGUOUS_ORG` error (surfaces that must stay usable while ambiguous). */ allowConflict?: boolean; } export interface OrgProvenance { org_id: string | null; org_source: OrgSource | null; org_source_detail: string | null; } export interface CurrentOrgResult extends OrgProvenance { selected_org_id: string | null; } export interface OrgBindResult { org_id: string; room_key: string | null; org_source: "flag" | "sole_membership"; file: ".run402.json"; path: string; bound: true; safe_to_commit: true; note: string; binding: Record | null; } export interface OrgUnbindResult { file: ".run402.json"; unbound: boolean; removed: boolean; binding: Record | null; } export declare function listOrgsAction(): NextAction; /** The recovery actions an `ORG_REQUIRED` refusal carries: every way to supply an org. */ export declare function orgRequiredActions(): NextAction[]; /** * Shape-validate an organization id from a local source. Never checks * membership. A rejected value may be a pasted secret, so it is redacted. */ export declare function assertOrgIdShape(orgId: string, origin: string): string; /** The `ORG_REQUIRED` refusal, optionally naming a rejected positional. */ export declare function orgRequiredError(opts?: { rejectedPositional?: string; positionalHint?: boolean; }): LocalError; /** Provenance triple for command output: bounded, never a resolution trace. */ export declare function orgProvenance(resolved: ResolvedOrg | null): OrgProvenance; /** * `r.orgs` on the Node entry: the isomorphic org collection and identity * verbs plus the local organization context. */ export declare class NodeOrgs extends Orgs { #private; /** * @param namespaces the reads the resolver makes (a project's org, the * project listing); default to fresh namespaces on `client`. */ constructor(client: Client, namespaces?: { rooms?: Pick; projects?: Pick; }); /** * The one resolver. Returns the org with its provenance, or null when * `optional` and nothing supplies one; throws `BAD_ORG_ID`, `AMBIGUOUS_ORG`, * or `ORG_REQUIRED` (each with its recovery actions) otherwise. */ resolve(input?: ResolveOrgInput, opts?: ResolveOrgOptions): Promise; /** Select the current organization for the active wallet profile (`orgs use`). */ use(orgId: string): Promise<{ org_id: string; selected: true; scope: "wallet_profile"; }>; /** * The organization this directory and profile resolve to, with provenance, * beside the profile's own selection. An empty selection is an explicit * null state. Never fails on ambiguity: the command that reports the * selection stays usable while it is ambiguous. */ current(opts?: Pick): Promise; /** The profile's selected organization, without running the chain. */ selected(): string | null; /** Clear the profile's selected organization. */ clear(): Promise<{ org_id: null; selected: false; previous_org_id: string | null; }>; /** * Write this checkout's org (and room) into `.run402.json`. With no org, the * caller's sole membership is used and written down: an explicit, recorded * act, unlike the chain, which never infers. Two or more memberships refuse. */ bind(orgId?: string | null, opts?: { room?: string | null; cwd?: string; }): Promise; /** Remove the `org` and `room` keys from `./.run402.json`; the file goes when nothing else is left. */ unbind(opts?: { cwd?: string; }): Promise; /** * Stamp a project's owning organization as the profile's selection * (`projects use` does this: a project determines its org unambiguously). * Best-effort: returns the org, or null, and never throws. */ selectFromProject(projectId: string): Promise; /** * The organization that OWNS a specific project, or null. Distinct from * {@link resolve} (which org a command is addressed at): an `--org` override * here would be a mis-binding. Remembered in the local project entry after * the first lookup, so the vault scaffold adds no network read on a * returning machine; an exact id match is required. */ owningOrgOf(projectId: string): Promise; } //# sourceMappingURL=org-context.d.ts.map