/** * Reader/writer for the workspace's `quonfig.json` file. * * The `workspace` pin is stored as `/` (Guard 1 in * `project/plans/cli-git-sync.md`, multi-org form in * `project/plans/multi-org-cli-auth.md`). `qfg push` uses it to confirm that * the local dir belongs to the cloud workspace the user thinks it does. * * The reader returns `{orgSlug, workspaceSlug}` when the field is present. * Missing file or missing field returns `undefined`. A bare slug (no `/`) * throws with a migration message — bare slugs are no longer accepted. * * The writer always emits the `/` form. It preserves all unknown * fields and, when the file already exists, does a format-stable in-place * edit so the diff is just the pin line. Missing or unparseable files fall * back to canonical 2-space JSON with a trailing newline. */ export interface WorkspacePin { orgSlug: string; workspaceSlug: string; } /** * Shape of `quonfig.json`. Everything is optional from the reader's * perspective so a partially-written or in-flight file doesn't blow up * downstream consumers — `qfg verify` is the source of strict validation. */ export interface QuonfigJson { [key: string]: unknown; environments?: string[]; /** `/` pin string. */ workspace?: string; } /** * Non-throwing variant of `parsePinString`. Returns `undefined` when `raw` * isn't in `/` form (e.g. a bare slug from a transitional backend * response). Callers that want the migration error should use * `readWorkspaceSlug` instead. */ export declare function tryParseWorkspacePin(raw: string): WorkspacePin | undefined; /** * Read the workspace pin from `/quonfig.json`. * * Returns `undefined` when the file is missing OR when the `workspace` * field is absent OR when the field is present but not a string. Throws * when the file is malformed JSON, OR when the workspace value is a bare * slug (no `/`) — bare slugs are rejected with a migration message. */ export declare function readWorkspaceSlug(dir: string): Promise; /** * Write the workspace pin into `/quonfig.json`, always in the * `/` form. * * If the file exists and is parseable, the existing bytes are preserved * verbatim except for the `workspace` key — either its value is replaced * in place, or the new key is inserted just before the closing brace * using the file's existing indentation. This keeps the git diff to the * single pin line on first backfill (no reflow of `environments` or * unrelated formatting). * * If the file is missing or cannot be parsed, fall back to a canonical * 2-space JSON write with a trailing newline. * * Throws when either component is empty or contains a `/` — bare slugs * are not accepted on the write path. */ export declare function writeWorkspaceSlug(dir: string, pin: WorkspacePin): Promise; /** * Format-stable in-place edit of `quonfig.json`. * * Returns the new file bytes, or `undefined` if the input isn't a shape we * can safely edit (malformed JSON, non-object root, or no closing brace * found). Caller should fall back to a canonical write in that case. * * Two cases: * 1. `workspace` key already present (with a string value) → replace just * the value bytes via regex. Diff is one token. * 2. `workspace` key absent → splice a new key before the closing brace, * using indentation detected from the first existing key (or 2-space * default for an empty object). Other keys are untouched. */ export declare function upsertWorkspaceKey(raw: string, slug: string): string | undefined;