From d28f47cc32f963c587d26930a1db99d3848aa79a Mon Sep 17 00:00:00 2001 From: Raghu Betina Date: Fri, 28 Aug 2026 09:31:04 -0500 Subject: [PATCH] Rewrite CLI repository guide --- README.md | 148 +++++++++++++++++++++---------------- docs/README.md | 23 +++--- test/documentation.test.js | 5 +- test/package.test.js | 4 - 4 files changed, 97 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index 990d9a9..7410ba9 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,106 @@ # First Draft CLI -`firstdraft` is the command-line client for First Draft. It helps agents author and review -Foundation Plans with their users, then submit a valid Plan for the current bounded compilation and private GitHub -publication journey. +firstdraft is the command-line client shared by First Draft agents and automation. It manages local Foundation Plan +files, calls the versioned Service API, exposes reviewed analysis and GapSets, and coordinates Compilation plus +private GitHub publication. -The current `0.2.x` source line includes local Plan initialization, application-key and UUID generation, conditional -whole-document push, whole-graph analysis polling, compile-and-publish orchestration, and read-only retained -Compilation download. Analysis status exposes the complete reviewed GapSet before Compile. Remote commands require -a compatible First Draft service and are intended for coordinated trials; publishing this CLI does not make the -wider service generally available. +Trying First Draft as a tester? Start with the +[Drawing Board guide](https://github.com/firstdraft/drawing-board#build-an-app-with-first-draft), which installs a +compatible CLI and Skill together. -## Install +## What this repository owns -Running the CLI requires Node.js 22.0.0 or newer. Install the stable release selected by npm's `latest` dist-tag: +- local Plan initialization, UUIDs, application keys, and source hashing; +- conditional whole-document push and conflict reporting; +- analysis polling and complete GapSet output; +- Compile-and-publish orchestration; +- retained Compilation inspection and artifact download; +- terminal output, exit status, and recovery contracts; +- the dependency-free npm package; and +- package provenance and release promotion. -```sh -npm install --global @firstdraft.com/cli -firstdraft --version -``` +The Service owns Foundation Plan meaning and server-side lifecycle. Skills own the agent conversation. This +repository owns the exact command and transport behavior between them. + +## Start with the right document + +| Task | Read first | +| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | +| Change the CLI | [Agent instructions](https://github.com/firstdraft/cli/blob/main/AGENTS.md), then [documentation map](docs/README.md) | +| Find a command or output contract | [Command reference](docs/commands.md) | +| Interpret an error or recover safely | [Errors and recovery](docs/errors.md) | +| Prepare or promote a package | [Release runbook](RELEASING.md) | +| Inspect dated package observations | [Release history](docs/release-history.md) | +| Report a vulnerability | [Security policy](SECURITY.md) | -The package installs the `firstdraft` executable. Pin an exact compatible version, such as -`@firstdraft.com/cli@0.1.0`, when a repeatable installation matters. Candidate publication under `next` is not stable -release completion and does not displace the supported `latest` release before promotion; see the -[release policy](RELEASING.md) and [dated release history](docs/release-history.md). +Run firstdraft --help or a command group's --help for concise terminal syntax. -## Shortest current journey +## Repository layout -From the project that the Foundation Plan describes: +| Path | Responsibility | +| -------- | ------------------------------------------------------------- | +| bin/ | Published executable entrypoint | +| src/ | Commands, API client, local Plan state, and output contracts | +| test/ | Command, protocol, recovery, and package tests | +| scripts/ | Test runner and package allowlist/smoke checks | +| docs/ | Command, error, release-history, and maintainer documentation | + +## Development + +Development uses the Node.js and npm versions pinned in `.tool-versions`. Follow +[Work on the repository](docs/README.md#work-on-the-repository) for the complete install, audit, and check sequence. ```sh -firstdraft plan init --name "Oscar Party" +npm run check ``` -Edit `.firstdraft/foundation-plan.json`, preserving each authored subject's UUID across renames and moves that do not -replace the concept. Generate new subject identities locally as needed: +The complete check runs type checking, ESLint, Prettier verification, tests, package allowlist validation, and a +smoke installation of the packed tarball. Use the narrower scripts while iterating: ```sh -firstdraft generate uuid +npm run typecheck +npm run lint +npm test +npm run pack:check +npm run pack:smoke ``` -Provide an API token only through the environment, then submit, analyze, compile, and publish the exact current Plan: +To exercise the checkout directly: ```sh -export FIRSTDRAFT_API_TOKEN="your-token" -firstdraft plan compile +node bin/firstdraft.js --help ``` -Invoking `plan compile` authorizes the internal GitHub Publication lifecycle. It proceeds only after the accepted -Plan's analysis is valid, writes allowlisted progress to standard error, and on success writes only the validated -private GitHub repository URL to standard output. The current Publication is a Project singleton and cannot be -repointed to a later accepted Head. Read the [complete command contract](docs/commands.md#compile-and-publish-the-current-plan) -before using it and follow [phase-specific recovery](docs/errors.md#ambiguous-mutations) after an ambiguous mutation. - -To review analysis before that terminal action, use `firstdraft plan push` followed by -`firstdraft plan status --wait`. See [Command reference](docs/commands.md) for all supported commands, flags, output -contracts, and retained-Compilation operations. - -## Trust model - -- The published CLI runs the reviewed JavaScript source directly, without generated or bundled code. -- It has no runtime dependencies, install scripts, telemetry, update checks, or network activity except an explicitly - invoked API command. -- API tokens are read from `FIRSTDRAFT_API_TOKEN`, sent as Bearer credentials, and never saved in `.firstdraft` or - printed. Revoke an exposed token in First Draft. -- Package contents are allowlisted and checked before release. The public documentation graph is packaged with the - exact CLI version; agent instructions and source-only release metadata remain repository-only. -- CI exercises the exact minimum Node.js version separately from current development tooling. -- Public packages carry npm provenance linking registry bytes to the reviewed GitHub workflow and commit. - -## Find the right documentation - -| Task | Read | -| ------------------------------------------------------- | ------------------------------------------ | -| Install and complete the shortest current journey | This README | -| Choose a command or inspect its exact behavior | [Command reference](docs/commands.md) | -| Interpret an error or recover safely | [Errors and recovery](docs/errors.md) | -| Contribute to this repository | [Documentation map](docs/README.md) | -| Prepare, publish, verify, recover, or promote a release | [Release policy and runbook](RELEASING.md) | -| Check dated package, tag, or channel observations | [Release history](docs/release-history.md) | -| Report a vulnerability | [Security policy](SECURITY.md) | - -Run `firstdraft --help` or a command group's `--help` for concise terminal syntax. The documentation map explains -which source owns each longer-lived contract. +Remote commands read FIRSTDRAFT_API_TOKEN from the environment. See +[Push a Foundation Plan](docs/commands.md#push-a-foundation-plan) for FIRSTDRAFT_API_URL and origin pinning. Keep +tokens out of arguments, shell history, fixtures, snapshots, and logs. + +## Package contract + +The published CLI supports Node.js 22 or newer. Direct automation callers can install the stable package with: + +```sh +npm install --global @firstdraft.com/cli +``` + +Pin an exact compatible version when a repeatable installation matters; [RELEASING.md](RELEASING.md) owns channel +and promotion meaning. + +The published package: + +- installs the firstdraft executable; +- runs reviewed JavaScript source directly; +- has no runtime dependencies or install scripts; +- performs no telemetry, update check, or network request unless the caller invokes an API command; +- reads Bearer credentials only from the environment; and +- carries npm provenance linking registry bytes to its GitHub workflow and commit. + +Inspect the packed file list whenever a source or documentation path moves. The public documentation graph, +including the release runbook and dated release history, ships with the package. `AGENTS.md` and the source-only +`release/compatibility.json` do not. + +## Release boundary + +Merging source is not package publication. Publishing a candidate, moving npm dist-tags, coordinating the Skills +package, and promoting a stable release are distinct steps in [RELEASING.md](RELEASING.md). Verify the exact packed +digest and Service compatibility before any promotion. diff --git a/docs/README.md b/docs/README.md index d285c5f..14f1eeb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,18 +3,19 @@ Use this page to find the narrowest authoritative document for a task. Runtime source and tests remain the final evidence for implemented behavior; if they contradict a document, surface the contradiction instead of guessing. -| If the task concerns... | Read first | -| -------------------------------------------------------------------------------------- | --------------------------------------------- | -| Public installation, trust, or the shortest current journey | [Root README](../README.md) | -| Commands, options, environment variables, API behavior, output, or materialization | [Command reference](commands.md) | -| Stable errors, exit codes, retry safety, ambiguous outcomes, or local recovery | [Errors and recovery](errors.md) | -| Version policy, release preparation, publication, verification, rollback, or promotion | [Release policy and runbook](../RELEASING.md) | -| What was observed for an earlier tag, package, or dist-tag | [Release history](release-history.md) | -| Vulnerability reporting | [Security policy](../SECURITY.md) | +| If the task concerns... | Read first | +| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| Beginner tester journey | [Drawing Board guide](https://github.com/firstdraft/drawing-board#build-an-app-with-first-draft) | +| Direct CLI installation, repository orientation, or package contract | [Root README](../README.md) | +| Commands, options, environment variables, API behavior, output, or materialization | [Command reference](commands.md) | +| Stable errors, exit codes, retry safety, ambiguous outcomes, or local recovery | [Errors and recovery](errors.md) | +| Version policy, release preparation, publication, verification, rollback, or promotion | [Release policy and runbook](../RELEASING.md) | +| What was observed for an earlier tag, package, or dist-tag | [Release history](release-history.md) | +| Vulnerability reporting | [Security policy](../SECURITY.md) | ## Authority boundaries -- [README.md](../README.md) owns public onboarding, the shortest supported journey, current trust claims, and routes. +- [README.md](../README.md) owns repository orientation, direct installation, package boundaries, and routes. - [commands.md](commands.md) owns detailed command semantics. Built-in `--help`, runtime source, and tests own exact executable syntax and behavior. - [errors.md](errors.md) owns handled-error interpretation and recovery guidance. @@ -26,9 +27,7 @@ evidence for implemented behavior; if they contradict a document, surface the co ## Retrieval quality Start here, then load the one owning document for the task. Follow a cross-link only when the task crosses an -authority boundary, such as moving from successful command behavior to failure recovery. Prefer descriptive -headings, short paragraphs, command maps, and checklists; create another page only when it has a distinct audience, -task, or authority. +authority boundary. Create another page only for a distinct audience, task, or authority. The documentation tests keep `AGENTS.md` at or below 2 KiB, the root README at or below 6 KiB, and this map at or below 4 KiB. They also require every public topic to remain reachable from this map or the root README and verify diff --git a/test/documentation.test.js b/test/documentation.test.js index 6adf1b2..b18897b 100644 --- a/test/documentation.test.js +++ b/test/documentation.test.js @@ -35,10 +35,6 @@ test("documentation routes commands, recovery, and release knowledge", () => { assert(releasing); assert(history); - assert.match( - readme, - /`firstdraft` is the command-line client for First Draft\./, - ); assert.doesNotMatch( readme, /\[First Draft\]\(https:\/\/firstdraft\.com\)/, @@ -47,6 +43,7 @@ test("documentation routes commands, recovery, and release knowledge", () => { assert.match(readme, /\[Command reference\]\(docs\/commands\.md\)/); assert.match(readme, /\[Errors and recovery\]\(docs\/errors\.md\)/); assert.match(readme, /\[Release history\]\(docs\/release-history\.md\)/); + assert.match(readme, /\[Release runbook\]\(RELEASING\.md\)/); assert.match(index, /\[Command reference\]\(commands\.md\)/); assert.match(index, /\[Errors and recovery\]\(errors\.md\)/); assert.match(index, /\[Release policy and runbook\]\(\.\.\/RELEASING\.md\)/); diff --git a/test/package.test.js b/test/package.test.js index 127bdf2..39c6ecd 100644 --- a/test/package.test.js +++ b/test/package.test.js @@ -118,10 +118,6 @@ test("stable release completion requires qualified latest promotion", () => { releaseHistory, /Later on August 7, 2026,[\s\S]*?`next`, while `latest`[\s\S]*?continued to identify `0\.1\.0-alpha\.2`[\s\S]*?On August 12, 2026,[\s\S]*?selected bounded CLI `0\.1\.0` user-journey smoke passed[\s\S]*?separate promotion approval[\s\S]*?both `next` and `latest` then identified ordinary version `0\.1\.0`[\s\S]*?Full\s+v14 service qualification remained separate and incomplete/, ); - assert.match( - readme, - /stable release selected by npm's `latest` dist-tag[\s\S]*?Candidate publication under `next` is not stable\s+release completion and does not displace the supported `latest` release before promotion[\s\S]*?\[dated release history\]\(docs\/release-history\.md\)/, - ); assert.match( releasingGuide, /Until promotion, `latest` remains the supported stable release; a distinct `next` candidate\s+is supported only for its named qualification\. When both tags identify one version, that version fills both roles\./,