import { type ResolvedConfig } from "../shared/config.js"; export interface ProjectCommandDeps { /** Print a transcript line. */ print: (line: string) => void; /** The directory the command acts in. */ cwd: string; /** Resolve the API host + PAT (the apiUrl gate lives here). */ config: () => Promise; } export interface CreateCommandDeps extends ProjectCommandDeps { /** * The org to create in, resolved LAZILY: every local guard (already linked, * unusable name) runs before this is called, so a refused create makes no * server request at all. */ org: () => Promise<{ ok: true; org: { slug: string; name: string; }; } | { ok: false; message: string; }>; } export interface CreateCommandOptions { name?: string; slug?: string; /** Replace a binding this folder already has. */ force?: boolean; } /** * `vincentt create` — register a project and link this folder to it. * * It does NOT scaffold. An unscaffolded folder gets a `!` advisory and the command * PROCEEDS: the server accepts a create from any folder or none, and blocking here * would put the open template behind the auth gate, which is the one thing the * init/create split exists to prevent. */ export declare function createCommand(deps: CreateCommandDeps, opts?: CreateCommandOptions): Promise; /** * `vincentt link ` — one verb for four situations (console-first * birth, a fresh clone, a folder that lost its binding, a re-link after * `login --force`). It is a READ plus a local write: the server has no notion of * "which folder", so linking is entirely client-side, gated only by the server's * willingness to return the project at all. */ export declare function linkCommand(deps: ProjectCommandDeps, projectId: string | undefined): Promise; /** * The API's error messages are lowercase and unpunctuated by convention * (`that handle is taken`, `this project is not available to you`), while both * client surfaces present them as sentences. Casing is the ONLY thing either * surface may change — the words are the server's, so a creator moving between * the CLI and the console reads one sentence and support can match a screenshot * to a log line without a translation table. */ export declare function asSentence(message: string): string; /** * Flow L10. Line 1 is the API's message; the body names both candidate causes and * resolves neither (that is the maximum the anti-oracle contract permits, and it * is accurate for all four real causes). `whoami` is offered first because it is * the one diagnosis that discloses nothing about the project. */ export declare function printUnreachable(print: (line: string) => void, message: string): void; /** * `vincentt unlink` — deletes the local binding. NO server call: the binding is a * local pointer and the project is untouched, so there is nothing to tell the * server about. */ export declare function unlinkCommand(deps: ProjectCommandDeps): Promise; /** * The advisory's trigger: a package.json that depends on @vincentt-xr/sdk. It is a * HINT only — create proceeds either way — so a false negative costs one extra * line of output, never a refused command. */ export declare function looksLikeVincenttApp(cwd: string): Promise; /** Resolve the bound project for a project-scoped verb, or explain why not. */ export declare function requireBinding(deps: ProjectCommandDeps): Promise<{ projectId: string; slug: string; } | undefined>;