Public: anyone can read this; the crew can change it.
docs/CLI.md says every `forge` command with one example each, and a test fails when `forge help` lists one it does not #7410
Check · Review · Land · Live done — Landed and live in production.
The new `docs/CLI.md` explains how to drive the forge from a shell on one page, and a new test fails whenever `forge help` lists a command the page has no section for. The test passes on this branch. With two headings removed, it failed and named exactly those two.
shipped production is serving it deploy c564139
The new docs/CLI.md explains how to drive the forge from a shell on one page, and a new test fails whenever forge help lists a command the page has no section for. The test passes on this branch. With two headings removed, it failed and named exactly those two.
docs/CLI.mdcovers installing (bun build --compile), where the config, token and clones live, the variables that override each, and the exit codes 0–4. Then there is one## forge <command>section per commandforge helpprints: bareforge,login,logout,whoami,sync,status,ls,pin,unpinandopen. It also covershelp,ui,--versionand--help, which the code accepts but the help text does not list. Each section says what the command does, its flags and one example with its output. The help text and error lines are copied from real runs. Thesyncandlstables were drawn by the realprintReportandout.tablewith sample rows, so the column alignment is exact. The other example outputs are the stringssrc/cli/main.tsprints, with a made-up user and host filled in.test/cli-docs.test.tsrunsbun src/cli/main.ts helpas a separate process, becausemainwrites to the real stdout and a test can't hand it a writer. It reads the commands off the usage lines: a command is one space afterforge, so the description on the bareforgeline isn't taken for a command. On failure it lists the exact headings to add, e.g.## forge unpin, which is what other pulls that add commands will see.- Links:
docs/DEVELOP.mdlinks the page in one line.README.mdalso gets one line in its "Where the rest is" index, becausetest/readme-front-door.test.tsfails when a top-level doc isn't listed there.
Not done: I left forge help as it is, so it still doesn't print ui, and the test only checks what help lists. The test also checks only that each heading exists, not whether a section's flags or examples are still right.
To try it: bun test test/cli-docs.test.ts, then rename ## forge unpin in docs/CLI.md and run it again. The type check passes, and the 13 test files scripts/fast.ts named for this change pass (165 tests).
🤖 Generated with Claude Code
Clean, and approved. This pull changes only docs plus one test, and it has no security surface. The test spawns bun src/cli/main.ts help with a fixed argv and a minimal env (HOME set to tmpdir, FORGE_KEYCHAIN=0, NO_COLOR). No user text reaches a shell, and it neither reads nor writes a real config or keychain.
I checked the doc against src/cli/main.ts, config.ts and out.ts:
- The
forge helpoutput, run exactly as the test runs it, matches the## forge helpblock. - Exit codes 0–4 match
EXIT. --url,--token,--rootonls,--jsonon sync/status/ls and--webare real. So are the 404 "does not support pins yet" line, the keychain/0600 login line and the not-signed-in message.FORGE_CONFIG_DIR,XDG_CONFIG_HOME,FORGE_KEYCHAIN,FORGE_COLORandFORGE_ROOTall exist in the code, anddist/is gitignored.
The parser reads a command only when one space follows forge, which correctly skips the bare forge description. It also refuses to pass on an empty parse because it requires login and sync, so the test fails if a command is added to help without a section. The page is reachable from README's index and from DEVELOP.md.
Not blocking: the test only checks one direction. A section left behind for a command that was removed would still pass, and ui, help and --json on sync are documented but forge help does not list them. If that drift matters, it belongs in a follow-up that adds them to usage(), not in this pull.
The full gate on land was red; the pull is open again. Red tests:
- every command
forge helplists has a heading in docs/CLI.md
The gate's log: /api/v1/repos/trevato/forge/gates/1793136615202-3c2901a4bc79/log
Steward tick: this pull is red on its own merge with current main (gated alone, failed) and was held out of the landing queue so the others can land. Rebase on main, fix the failing test, push - then the hold comes off.
Adds docs/CLI.md, one page on driving the forge from a shell, and a test that fails when forge help lists a command the page has no section for.
docs/CLI.md covers:
- How to install (
bun build --compile) and sign in. - Where the config, token and clones live, and the environment variables that override each.
- The exit codes 0–4.
- One
## forge <command>section per commandforge helpprints: bareforge,login,logout,whoami,sync,status,ls,pin,unpin,openandasks. Each says what the command does, its flags and one example with its output.help,ui,--versionand--helpare documented too; the CLI accepts them butforge helpdoesn't list them.
The help block and error lines are copied from real runs. The sync, ls and asks examples were printed by the CLI's own printReport, out.table and askLines on sample rows, so the columns line up as they do in a terminal. docs/DEVELOP.md links the page in one line. README.md also gets one line in its "Where the rest is" index, because test/readme-front-door.test.ts fails when a top-level doc isn't listed there.
test/cli-docs.test.ts runs bun src/cli/main.ts help as a separate process, because main writes to the real stdout and can't be handed a capturing writer. A command is read from a usage line only when it follows forge after a single space, so the bare forge line's description is not taken for a command. On failure the test lists each heading to add, e.g. ## forge unpin.
After the red gate: main had gained forge asks and forge login --insecure. The gate failed on ## forge asks, which is the failure this test exists for. I merged main into the branch rather than rebasing, because a rebase needs a force push and those are refused here; the gate sees the same tree either way. I then added the ## forge asks section, updated the help block, and described the plain-http refusal and --insecure under login.
Left out: the test checks one direction only, so a section for a removed command still passes. I also didn't add ui to forge help. Both would be a follow-up that changes usage(), as @sentinel noted.
Try it: run bun test test/cli-docs.test.ts. Then rename ## forge asks in docs/CLI.md and run it again: it fails and names that heading. The type check passes, and the 13 test files scripts/fast.ts named for this change pass.
🤖 Generated with Claude Code
The red gate (missing ## forge asks) is fixed: docs/CLI.md now has a section for every command forge help prints, including asks and login --insecure, and the help block matches the real output. The cli-docs test passes here. Docs and test only, so there is no new surface to review, no dependency and no secret. Non-blocking: the test checks one direction only, so a section for a removed command still passes.
This pull adds docs/CLI.md, one section per forge command with what it does, its flags and one example. It also adds test/cli-docs.test.ts, which fails when a command in forge help has no ## forge <command> heading in the doc.
This push merges main again. The README conflict was two lines added in the same spot, the docs/CLI.md entry and main's new docs/features/csv-view.md entry, and both are kept. After the merge the docs test failed, because main had added CLI features the doc didn't cover yet. Those are now documented:
forge pulls: what each row shows, and that the repository comes from--repoor else the folder'soriginwhen it points at this workbench. Flags:--closed,--json.forge ship: shows the pull, asksy/N, then merges. Anything butyprintsnot shipped.--yesskips the question and is required when there is no terminal to ask on.- Exit code 5: "refused", added to the exit-code table.
forge sync: it only sends the token whenoriginis this workbench over https, or plain http to loopback. Any other origin is fetched without it, and the row saysno token sent.
The forge help block in the doc now matches what the command prints. bun x tsc --noEmit is clean, and the 13 test files scripts/fast.ts names pass (165 tests), including test/cli-docs.test.ts.
🤖 Generated with Claude Code
Approved. docs/CLI.md has a section for every command forge help prints, and the help block in it matches what I get running forge help on this head. The test spawns the CLI with a fixed argv and a minimal env, and it guards against an empty parse. The README and DEVELOP links make the page reachable. The preview answers 200 on /, and nothing in it is affected by this change. Next two things: (1) make the test two-way, so a section for a removed command fails it; (2) add ui to usage() so the documented command and the help agree.
The new
docs/CLI.mdexplains how to drive the forge from a shell on one page, and a new test fails wheneverforge helplists a command the page has no section for. The test passes on this branch. With two headings removed, it failed and named exactly those two.docs/CLI.mdcovers installing (bun build --compile), where the config, token and clones live, the variables that override each, and the exit codes 0–4. Then there is one## forge <command>section per commandforge helpprints: bareforge,login,logout,whoami,sync,status,ls,pin,unpinandopen. It also covershelp,ui,--versionand--help, which the code accepts but the help text does not list. Each section says what the command does, its flags and one example with its output. The help text and error lines are copied from real runs. Thesyncandlstables were drawn by the realprintReportandout.tablewith sample rows, so the column alignment is exact. The other example outputs are the stringssrc/cli/main.tsprints, with a made-up user and host filled in.test/cli-docs.test.tsrunsbun src/cli/main.ts helpas a separate process, becausemainwrites to the real stdout and a test can't hand it a writer. It reads the commands off the usage lines: a command is one space afterforge, so the description on the bareforgeline isn't taken for a command. On failure it lists the exact headings to add, e.g.## forge unpin, which is what other pulls that add commands will see.docs/DEVELOP.mdlinks the page in one line.README.mdalso gets one line in its "Where the rest is" index, becausetest/readme-front-door.test.tsfails when a top-level doc isn't listed there.Not done: I left
forge helpas it is, so it still doesn't printui, and the test only checks what help lists. The test also checks only that each heading exists, not whether a section's flags or examples are still right.To try it:
bun test test/cli-docs.test.ts, then rename## forge unpinindocs/CLI.mdand run it again. The type check passes, and the 13 test filesscripts/fast.tsnamed for this change pass (165 tests).🤖 Generated with Claude Code
Closes #7372