This document freezes the command-line interface planned for ProfileDock 1.0. The executable contract is version 1 and is maintained in tests/fixtures/cli/contract-v1.json. Tagged pre-1.0 releases may add capabilities, but they must follow the compatibility and deprecation rules below.
The top-level commands are create, list, show, rename, set-engine, tags, proxy-test, coherence, status, launch, tabs, open-tab, close-tab, read, shot, pdf, eval, cookies, top, close, delete, doctor, migrate, backup, restore, verify, logs, config, and mcp.
mcp serve uses MCP JSON-RPC over stdio, independently of the CLI JSON envelope.
Its lifecycle and tool results follow MCP version 2024-11-05.
The cookies --clear operation returns deletion counts through the existing
CLI JSON envelope; its filters and limitations are described in the command reference.
The config commands are show, set, add-url, remove-url, and reset. config set accepts the setting names default-tabs, engine, browser, and window-size.
The root options are --data-root, --verbose/-v, --log-level, --non-interactive, and --version/-V. The complete argument requirements and option aliases are recorded in the golden contract fixture and checked against the generated Typer application in every test run.
Human output is terminal-aware: color and Unicode status symbols appear only on interactive terminals that support them, never in piped or redirected output, and are disabled by NO_COLOR. Machine JSON output is unaffected.
The only engine values are direct and playwright.
create --engineandlaunch --enginesupport the-ealias.set-engine <profile> <engine>updates profile metadata.config set <profile> engine <engine>updates the launch preset.- Launch resolution is: explicit
launch --engine, launch-config engine, profile engine,PROFILEDOCK_DEFAULT_ENGINE, thendirect. Playwright launches open a visible Chromium window unless--headlessis supplied. tags <profile> [tag ...]replaces fleet tags. At least one tag or--clearis required;--clearcannot be combined with tags.launchaccepts exactly one target selector: a profile argument,--tag, or--all.launch --jsonis valid only with--tagor--alland emits a version-1 batch outcome envelope.- Profile JSON returned by
list,show, andstatusexposes the effective engine, not merely the nullable metadata value. - Launch-config JSON exposes its independently stored engine value.
Commands accepting a profile selector resolve it in this order:
- Exact, case-sensitive profile ID.
- Unique, case-sensitive profile-ID prefix.
- Exact, case-sensitive profile name.
Multiple prefix or name matches return the ambiguous_profile error category. Empty and unmatched selectors return not_found. No fuzzy or case-insensitive matching is performed.
Every command uses the same precedence:
--data-root <path>.PROFILEDOCK_DATA_ROOT.- The platform application-data default.
Relative overrides resolve from the process working directory. Unsafe filesystem roots, home directories, links, junctions, and invalid existing targets are rejected.
0: successful command or completed no-op.1: user, operational, validation, confirmation, storage, security, profile-resolution, or browser error.2: command-line syntax or usage error generated before command execution.
doctor exits 0 when no check reports failed (warnings are tolerated). With --strict, doctor exits 1 when any check reports warning as well; its --json document reports this separately in strict_healthy while healthy keeps the failure-only meaning.
Human success output, prompts, and JSON success documents use standard output. Operational errors use standard error and leave standard output empty. A machine-readable migration failure report uses the normal versioned JSON envelope on standard error and also leaves standard output empty. Usage diagnostics use Typer's usage-error stream behavior.
Operational errors begin with Error [<category>]:. Version 1 categories are:
ambiguous_profilebrowser_launch_failedconfirmation_requiredcorrupted_datainvalid_inputnot_foundprofile_activesecurity_violationstorage_error
Error wording may become clearer, but the category and exit-code class are the stable automation interface.
Commands supporting --json emit JSON output version 1 with exactly this envelope:
{
"output_version": 1,
"command": "list",
"data": []
}The JSON commands are list, show, status, config show, doctor, migrate, backup, restore, verify, logs, tabs, open-tab, close-tab, read, eval, cookies, and coherence. Consumers must reject unsupported output_version values. Golden output fixtures cover profile listing and profile detail, including effective-engine behavior.
Human rendering and JSON serialization use separate paths. Tests replace the human renderer with a failing implementation while asserting byte-equivalent JSON data, preventing human-output improvements from changing the JSON contract accidentally.
Profile deletion, source removal during migration, and destructive doctor repairs require confirmation unless --yes/-y is supported and supplied. Declining a Typer confirmation aborts with exit code 1 and does not mutate data.
--non-interactive and truthy PROFILEDOCK_NON_INTERACTIVE values (1, true, yes, or on) prohibit prompts. A missing confirmation fails with confirmation_required. Launching without an explicit or configured tab count fails with invalid_input and instructs the caller to use --tabs. JSON migration with source removal also requires --yes and never prompts.
Automation should always provide --tabs, --yes when required, and --json when machine-readable output is needed.
Until 1.0, additive commands and options may be introduced in minor releases. Existing command names, argument order, option meanings, aliases, exit-code classes, stream assignments, JSON version-1 fields, engine values, resolution order, precedence rules, and non-interactive semantics will not be removed or changed without deprecation.
A deprecation must:
- Be documented in the README and this contract.
- Preserve the old behavior for at least one minor release and at least 90 days.
- Emit a warning only on standard error and never corrupt JSON on standard output.
- Offer the replacement in the same release that begins deprecation.
- Remove or alter the contract only in a major release, except for a security correction that cannot safely retain prior behavior.
Additive JSON fields require a new JSON output version because version 1 envelopes and payload fixtures are strict. A new version may be offered alongside the old version during migration; ProfileDock never silently changes the requested machine format.