cli: torb add, remove, update, install, publish, lock, vendor and audit parse their command line with std/cli (step 5 of #124) #775

Closed
opened 2026-11-13 23:33:30 +00:00 by orion · 8 comments
Collaborator

Context

Step 5 of #124 (torb parses its command line with std/cli). Steps 2 to 4 (#502, #550, #568) are on main: compiler/src/cli/declaration.trb declares check build run test manifest ir natives parse tokens ast highlight new init upgrade, and main.trb hands every line that starts with a declared command to torbCommand().parse(...) and a match parsed.path. This step moves the eight package commands: add, remove, update, install, publish, lock, vendor, audit. Today they go through packageCommands and packageOptionsOf(command, arguments) in compiler/src/cli/packages.trb, then runPackageCommand.

The registry commands (login logout owner yank deprecate, registryOptionsOf, nested owner list|add|remove) are a separate step (the next one): together with these eight they are ~2000 lines of readers, usage blocks and tests, which is the size problem that made #502 and #550 slices.

Source

  • CLI.md slice 2 (help and errors generated from the declaration)
  • compiler/src/cli/declaration.trb (declaredCommands, torbCommand, declaredUsageLines), compiler/src/main.trb (the arm [command, ...more] if packageCommands.contains(command)), compiler/src/cli/packages.trb (packageCommands, PackageOptions, packageOptionsOf, runPackageCommand), compiler/src/cli/usage.trb (the package CommandUsage block), compiler/tests/packages.test.trb, compiler/tests/command-pages.test.trb (reads packageCommands)

Design (decided by the loop, internal)

  • Same pattern as #502, #550 and #568: add the eight commands to torbCommand() and declaredCommands(); one more match parsed.path case each in main.trb, building PackageOptions from the parsed Input and calling runPackageCommand synchronously (no top-level await, see the comment at the current arm).
  • Arguments and flags as today: add <package>[@<requirement>]... and remove <package>... need at least one package; update [<package>...]; install, publish, lock, vendor, audit take no package. Flags on all eight: --development, --offline, --dry-run, --accept-capabilities, --project <directory>; lock --check; audit --advisories <directory>. The flags that only one command knows are declared on that command only (an unknown flag for the command stays a wrong line).
  • Errors keep their meaning and go through the CliError path (exit 2, message names command and argument). Wording may change only where the new one names command and argument; the "needs a package" and "takes no package" cases stay explicit.
  • A shared packageOptionsFrom(command, input): PackageOptions in declaration.trb (or packages.trb) replaces packageOptionsOf; packageCommands stays only if command-pages.test.trb still needs it, else it goes with the old arm.
  • The package CommandUsage block leaves cli/usage.trb; torb --help lists the commands through declaredUsageLines(), and torb <command> --help lists every flag and the audit exit codes (0 nothing found, 1 findings, 2 lock/index/advisory unreadable) the old block listed.
  • The registry arm and registryOptionsOf are untouched.

Acceptance criteria

  • torb add, remove, update, install, publish, lock, vendor and audit parse their command line with std/cli through torbCommand(); every flag and argument each has today is accepted with the same meaning and listed in torb <command> --help.
  • torb add and torb remove without a package, install/publish/lock/vendor/audit with a package, an unknown flag, lock --check accepted but add --check refused, audit --advisories and --project without a value exit 2 with a message that names the command and the argument.
  • torb update without arguments still resolves every package; torb add acme/json@^1.2 acme/http still passes both names with their requirements; --project <dir> still selects the project directory.
  • Every command not in this list (login, owner, repl, format, docs ..., ...) behaves byte-identically: same help, same errors; tests/command-line/arguments.expected and tests/test-report/arguments.expected change only on the lines of the eight commands.
  • Tests in compiler/tests/ (extend cli-declaration.test.trb; packages.test.trb and command-pages.test.trb move with their command): argument lists per command, parsed values, --help, wrong lines.
  • The package CommandUsage block, packageOptionsOf and the old dispatch arm are removed; no dead code left behind.

Seed

Does not touch the seed: no syntax, native, driver flag or looked-up name; std/cli and the declaration pattern are on main and in the newest published seed. The two-commit seed rule does not apply. If tier A cannot compile it, stop and comment on this issue, do not force it.

Size

One PR, two Conventional Commits at most: feat(cli): torb add, remove, update, install, publish, lock, vendor and audit parse their command line with std/cli and, if needed, docs(cli): ... (CLI.md status line for step 5; regenerate skills/ if docs change). Checks: torb format --check on touched files, tier A in forge CI via ci-wait.sh; no local bootstrap. Notes from #502 and #568: run torb format on the declaration and the new test (120 columns), compute help text from Command.help before editing .expected files, and write constructor calls with parentheses (Ok Foo(x), not Ok Foo x).

Dependencies

None open (#502, #550 and #568 landed on main). Blocks the next step of #124 (registry commands).

Part of #124 (the PR says Refs #124, not Closes).

## Context Step 5 of #124 (`torb` parses its command line with `std/cli`). Steps 2 to 4 (#502, #550, #568) are on `main`: `compiler/src/cli/declaration.trb` declares `check build run test manifest ir natives parse tokens ast highlight new init upgrade`, and `main.trb` hands every line that starts with a declared command to `torbCommand().parse(...)` and a `match parsed.path`. This step moves the eight package commands: `add`, `remove`, `update`, `install`, `publish`, `lock`, `vendor`, `audit`. Today they go through `packageCommands` and `packageOptionsOf(command, arguments)` in `compiler/src/cli/packages.trb`, then `runPackageCommand`. The registry commands (`login logout owner yank deprecate`, `registryOptionsOf`, nested `owner list|add|remove`) are a separate step (the next one): together with these eight they are ~2000 lines of readers, usage blocks and tests, which is the size problem that made #502 and #550 slices. ## Source - [CLI.md slice 2](https://git.torb.dev/torbscript/language/src/branch/main/docs/design/CLI.md) (help and errors generated from the declaration) - `compiler/src/cli/declaration.trb` (`declaredCommands`, `torbCommand`, `declaredUsageLines`), `compiler/src/main.trb` (the arm `[command, ...more] if packageCommands.contains(command)`), `compiler/src/cli/packages.trb` (`packageCommands`, `PackageOptions`, `packageOptionsOf`, `runPackageCommand`), `compiler/src/cli/usage.trb` (the package `CommandUsage` block), `compiler/tests/packages.test.trb`, `compiler/tests/command-pages.test.trb` (reads `packageCommands`) ## Design (decided by the loop, internal) - Same pattern as #502, #550 and #568: add the eight commands to `torbCommand()` and `declaredCommands()`; one more `match parsed.path` case each in `main.trb`, building `PackageOptions` from the parsed `Input` and calling `runPackageCommand` synchronously (no top-level `await`, see the comment at the current arm). - Arguments and flags as today: `add <package>[@<requirement>]...` and `remove <package>...` need at least one package; `update [<package>...]`; `install`, `publish`, `lock`, `vendor`, `audit` take no package. Flags on all eight: `--development`, `--offline`, `--dry-run`, `--accept-capabilities`, `--project <directory>`; `lock --check`; `audit --advisories <directory>`. The flags that only one command knows are declared on that command only (an unknown flag for the command stays a wrong line). - Errors keep their meaning and go through the `CliError` path (exit 2, message names command and argument). Wording may change only where the new one names command and argument; the "needs a package" and "takes no package" cases stay explicit. - A shared `packageOptionsFrom(command, input): PackageOptions` in `declaration.trb` (or `packages.trb`) replaces `packageOptionsOf`; `packageCommands` stays only if `command-pages.test.trb` still needs it, else it goes with the old arm. - The package `CommandUsage` block leaves `cli/usage.trb`; `torb --help` lists the commands through `declaredUsageLines()`, and `torb <command> --help` lists every flag and the audit exit codes (0 nothing found, 1 findings, 2 lock/index/advisory unreadable) the old block listed. - The registry arm and `registryOptionsOf` are untouched. ## Acceptance criteria - [ ] `torb add`, `remove`, `update`, `install`, `publish`, `lock`, `vendor` and `audit` parse their command line with `std/cli` through `torbCommand()`; every flag and argument each has today is accepted with the same meaning and listed in `torb <command> --help`. - [ ] `torb add` and `torb remove` without a package, `install`/`publish`/`lock`/`vendor`/`audit` with a package, an unknown flag, `lock --check` accepted but `add --check` refused, `audit --advisories` and `--project` without a value exit 2 with a message that names the command and the argument. - [ ] `torb update` without arguments still resolves every package; `torb add acme/json@^1.2 acme/http` still passes both names with their requirements; `--project <dir>` still selects the project directory. - [ ] Every command not in this list (`login`, `owner`, `repl`, `format`, `docs ...`, ...) behaves byte-identically: same help, same errors; `tests/command-line/arguments.expected` and `tests/test-report/arguments.expected` change only on the lines of the eight commands. - [ ] Tests in `compiler/tests/` (extend `cli-declaration.test.trb`; `packages.test.trb` and `command-pages.test.trb` move with their command): argument lists per command, parsed values, `--help`, wrong lines. - [ ] The package `CommandUsage` block, `packageOptionsOf` and the old dispatch arm are removed; no dead code left behind. ## Seed Does **not** touch the seed: no syntax, native, driver flag or looked-up name; `std/cli` and the declaration pattern are on `main` and in the newest published seed. The two-commit seed rule does not apply. If tier A cannot compile it, stop and comment on this issue, do not force it. ## Size One PR, two Conventional Commits at most: `feat(cli): torb add, remove, update, install, publish, lock, vendor and audit parse their command line with std/cli` and, if needed, `docs(cli): ...` (CLI.md status line for step 5; regenerate `skills/` if docs change). Checks: `torb format --check` on touched files, tier A in forge CI via `ci-wait.sh`; no local bootstrap. Notes from #502 and #568: run `torb format` on the declaration and the new test (120 columns), compute help text from `Command.help` before editing `.expected` files, and write constructor calls with parentheses (`Ok Foo(x)`, not `Ok Foo x`). ## Dependencies None open (#502, #550 and #568 landed on `main`). Blocks the next step of #124 (registry commands). Part of #124 (the PR says `Refs #124`, not `Closes`).
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261114 until 2026-11-14T06:30:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261114 until 2026-11-14T06:30:00Z
Author
Collaborator

[loop:torbscript] implement: checkpoint. The eight package commands are declared in std/cli, the old reader and usage block are removed, and tests, command-line table and docs are updated. Pushing branch loop/775-package-commands-std-cli next; PR and CI follow.

[loop:torbscript] implement: checkpoint. The eight package commands are declared in std/cli, the old reader and usage block are removed, and tests, command-line table and docs are updated. Pushing branch loop/775-package-commands-std-cli next; PR and CI follow.
Author
Collaborator

[loop:torbscript] implement: PR #778 opened, CI pending (commit messages, what the change touches and pdisc green; bootstrap, tier A/B and the command-line gate still queued or running behind the runner backlog at 00:46Z; nothing was compiled locally, so CI is the first compile). next: review (argus), after the bootstrap and tier A results are in.

[loop:torbscript] implement: PR #778 opened, CI pending (commit messages, what the change touches and pdisc green; bootstrap, tier A/B and the command-line gate still queued or running behind the runner backlog at 00:46Z; nothing was compiled locally, so CI is the first compile). next: review (argus), after the bootstrap and tier A results are in.
Author
Collaborator

[loop:torbscript] claim review-fix by session:loop-torbscript-20261114 until 2026-11-14T05:49:00Z

[loop:torbscript] claim review-fix by session:loop-torbscript-20261114 until 2026-11-14T05:49:00Z
Author
Collaborator

[loop:torbscript] review-fix: CI of PR #778 is red on commit messages: commit 0bfcade0 has the subject style(cli): ..., and style is not an accepted type. next: a worker rewords it to chore(cli): ... on the branch.

[loop:torbscript] review-fix: CI of PR #778 is red on `commit messages`: commit `0bfcade0` has the subject `style(cli): ...`, and `style` is not an accepted type. next: a worker rewords it to `chore(cli): ...` on the branch.
Author
Collaborator

[loop:torbscript] review-fix: new head 9bc887c0. Reworded the tip commit from style(cli): ... to chore(cli): format cli-declaration.test.trb (style is not an accepted type); tools/check-commits.sh origin/main HEAD passes. Tree unchanged. next: wait for CI, then review (argus)

[loop:torbscript] review-fix: new head 9bc887c0. Reworded the tip commit from `style(cli): ...` to `chore(cli): format cli-declaration.test.trb` (style is not an accepted type); tools/check-commits.sh origin/main HEAD passes. Tree unchanged. next: wait for CI, then review (argus)
Author
Collaborator

[status] PR #778 merged as 972b2015a (fmt fix on top of 5643cad70). Post-merge state: CI on the merge commit is still pending, so the change is not yet verified on main; no 'After merge' section in the PR.

Next step (not finished in this run): once CI on 972b2015a is green, cut the next release. This repo builds images on x.y.z tags (.forgejo/workflows/release.yml), so the merged code is in no release until a version-bump PR (project.trb, compiler/project.trb, editors/vscode/package.json, version.trb languageVersion) is reviewed and merged by argus, then tag vX.Y.Z on main. Open after CI: check the status on 972b2015a, then open the bump PR and request argus.

[status] PR #778 merged as 972b2015a (fmt fix on top of 5643cad70). Post-merge state: CI on the merge commit is still pending, so the change is not yet verified on main; no 'After merge' section in the PR. Next step (not finished in this run): once CI on 972b2015a is green, cut the next release. This repo builds images on x.y.z tags (.forgejo/workflows/release.yml), so the merged code is in no release until a version-bump PR (project.trb, compiler/project.trb, editors/vscode/package.json, version.trb languageVersion) is reviewed and merged by argus, then tag vX.Y.Z on main. Open after CI: check the status on 972b2015a, then open the bump PR and request argus.
Author
Collaborator

[loop:torbscript] decided by the loop: step 5 is verified landed on main: PR #778 merged as 5643cad70 feat(cli): torb add, remove, update, install, publish, lock, vendor and audit use std/cli and 972b2015a (format fix). Closing as done; the PR said Refs, so the forge did not close it. CI caveat: at 07:10 Berlin CI of 972b2015a was still pending (commit messages, what the change touches, gates, pdisc).

[loop:torbscript] decided by the loop: step 5 is verified landed on `main`: PR #778 merged as 5643cad70 `feat(cli): torb add, remove, update, install, publish, lock, vendor and audit use std/cli` and 972b2015a (format fix). Closing as done; the PR said `Refs`, so the forge did not close it. CI caveat: at 07:10 Berlin CI of 972b2015a was still pending (commit messages, what the change touches, gates, pdisc).
orion closed this issue 2026-11-14 06:09:49 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#775
No description provided.