import { type ResolvedOrg } from "./org.js"; import { type RelayClient } from "./diagnostics.js"; import { type ResolvedConfig } from "../shared/config.js"; import { type RunningPreview, type StartPreviewOptions } from "../preview/index.js"; import type { DiagEventKind, RelayResult } from "@vincentt-xr/harness/events"; export interface CreateOptions { name?: string; slug?: string; /** Replace a binding this folder already has. */ force?: boolean; /** --org ; else VINCENTT_ORG; else the machine config's active org. */ org?: string; /** Honor a binding's apiUrl override (--allow-custom-api). */ allowCustomApi?: boolean; /** * Stream the transcript as it happens. The CLI passes console.log so a slow * create shows progress and the apiUrl advisory lands before the request; MCP * omits it and reads the buffered `message`. */ onLine?: (line: string) => void; } export interface CreateResult { /** The full transcript, exactly as the CLI prints it. */ message: string; /** Non-zero when nothing was created (already linked, address taken, no org). */ exitCode: number; } /** * The shared `create` orchestration behind both `vincentt create` and the MCP * `project_create` tool, so the two surfaces can never diverge in behavior OR in * what they tell the caller. * * It does NOT scaffold — that is `vincentt init`, which needs no account. See * `initCommand`. */ export declare function projectCreate(projectCwd: string, opts?: CreateOptions): Promise; /** * Resolve which org a create acts in: the named one if it is an ACTIVE membership, * else the personal org when nothing is named. A named org the caller is not an * active member of resolves to nothing rather than silently falling back — acting * in an org the creator did not ask for is the retargeting the binding rules forbid. */ export declare function resolveOrgForCommand(cfg: ResolvedConfig, input: { flag?: string; }): Promise<{ ok: true; org: ResolvedOrg; } | { ok: false; message: string; }>; export interface PublishOptions { distDir?: string; note?: string; allowCustomApi?: boolean; /** * Where the apiUrl advisory goes. It must reach the creator BEFORE the request, * so it cannot ride the returned message — that is only rendered after the call * has already happened (or thrown). */ warn?: (line: string) => void; /** Skip the confirmation. REFUSED on a first publish; see publishCommand. */ yes?: boolean; } export interface PublishOutcome { /** The full transcript, exactly as the CLI prints it. */ message: string; exitCode: number; } /** * The shared `publish` orchestration behind both `vincentt publish` and the MCP * `project_publish` tool, so the two surfaces can never diverge. * * MCP has no terminal, so it is a non-TTY caller: the command refuses without * `--yes` rather than assuming consent, and refuses `--yes` outright on a first * publish. An agent cannot make an address permanent. */ export declare function projectPublish(projectCwd: string, opts?: PublishOptions): Promise; export declare function getActivePreview(): RunningPreview | null; export interface PreviewStartResult { preview: RunningPreview; /** false when a preview was already running (the existing one is returned). */ started: boolean; } /** Everything the runner needs that this process does not already know. */ export type PreviewStartOptions = Omit; /** * Resolve the binding and the config, then start. The binding is a HINT and * never an authority (B12): the projectId it carries is presented to the API, * which resolves the org itself and answers 404 for every unreachable cause. */ export declare function previewStart(projectCwd: string, onLog: (msg: string) => void, extra?: PreviewStartOptions): Promise; export declare function previewStop(): Promise; export interface PreviewStopOutcome { stopped: boolean; message: string; } /** * Stop a preview started by a *different* process (the common case: `vincentt * preview` runs in the background and the agent later wants it down). Reads the * pidfile and signals the recorded pid rather than the in-process * `activePreview`. * * There is NO orphaned-tunnel case any more, and that is the point of the edge * repoint: the tunnel is a socket this process owns rather than a child process * that could be reparented to init. When the preview process dies the socket * closes, the edge sees the tunnel go, and the session drains on its own — so * SIGTERM plus clearing the stale relay info is the whole of the cleanup. */ export declare function previewStopSignal(projectCwd: string): Promise; export interface DiagQueryOptions { since?: number; limit?: number; errorsOnly?: boolean; /** * One tester — one browser tab, across its refreshes. The filter that answers * "it breaks on their phone but not mine". Absent = every tester. */ tester?: string; /** * One CONNECTION (2.8), the sub-coordinate below the tester. Absent = every * viewer, which is the default read. */ viewer?: string; } /** Raw diagnostics query against the running relay (used by CLI --json). */ export declare function diagQuery(projectCwd: string, kind: DiagEventKind, opts?: DiagQueryOptions, relay?: RelayClient): Promise; /** Rendered diagnostics text (used by CLI default + MCP tools). */ export declare function diagRead(projectCwd: string, kind: DiagEventKind, opts?: DiagQueryOptions, relay?: RelayClient, now?: () => number): Promise;