Commit 37a0148
docs(cli): the README states the global flags and the os plugin group that the built os registers (#21354)
Fixes #21310
Clause-②: no
## What changes
`packages/cli/README.md` now says what the built `os` does. Every claim
below was read off the built entry (`packages/cli/bin/run.js`,
`@oclif/core` 5.1.2), run from an empty cwd: `os --help`, `os plugin
--help`, every topic's `--help` and each documented command's `--help`.
The credential sources were also measured against a local echo server.
- **`### Global`** lists `--version` and `--help` only. It says there is
no short form: `os -h` and `os -v` exit 2. It also names the commands
where `-v` is the command's own flag.
- **`### Plugin Management`** drops "There is no `os plugin` command
group in v1". It lists the registered group instead: `os plugin build`,
`os plugin sign` and `os plugin publish`. It notes that the group has no
`install` (per ADR-0025's status line), and that `os plugin` is
unrelated to `os plugins`.
- **Two command-table rows were wrong:** `os init [name]` and `os dev
[package]`. Both are rewritten.
- **Cloud credentials and flags (patch round 1).** The Cloud section
said every cloud command reads `os cloud login`'s session, or `--token`
/ `OS_CLOUD_API_KEY` and `--server` / `OS_CLOUD_URL`. A new `####
Credentials and server URL` table states, per command, the server-URL
flag, the token flag and the stored session it uses. The typical publish
flow now says that its `os environments create` step does not read the
`os cloud login` session.
- **`os serve --ui` (patch round 1)** now uses the `--help` wording:
"Enable the bundled Console portal", in place of "Enable Studio UI".
- **`.changeset/21310-cli-readme-flags.md`** is a `patch` for
`@objectstack/cli`, because `README.md` is in the package's `files`. It
now counts five false claims.
No code, flag, environment variable, exit code or help page changes.
`packages/cli/package.json` is untouched.
## Short flags: the README route (docs follow the implementation)
Readings on the built entry from an empty cwd. "Before" is at
`1caa60373`, the branch point after #21167 landed. "After" is at
`9bdb092ca`, this head.
| argv | before | after |
|---|---|---|
| `os -h` | exit 2, `command -h not found` | exit 2, `command -h not
found` (unchanged by design) |
| `os -v` | exit 2, `command -v not found` | exit 2, `command -v not
found` (unchanged by design) |
| `os --help` | exit 0, 3712 bytes, md5
`1855676fe5a2bb87aa5871fc1bed196f` | byte-identical, same md5 |
| `os --version` | exit 0, `@objectstack/cli/17.6.0 linux-x64
node-v22.22.0` | same |
**The ruling's check.** The ruling: "show that no command already uses
`-h` / `-v` as its own flag. If one does, choose the README route and
say why."
Six commands already own `-v`. Found by `git grep` for `char: 'v'` in
`packages/cli/src`, then read back in each command's `--help`:
- `-v` is `--verbose` on `os dev` (`dev.ts:212`), `os serve`
(`serve.ts:1209`), `os start` (`start.ts:93`) and `os doctor`
(`doctor.ts:1905`).
- `-v` is `--version VALUE` on `os package publish`
(`package/publish.ts:315`) and `os package install`
(`package/install.ts:57`).
No command owns `-h`. So the ruling sends `-v` down the README route.
`-h` was eligible on its own, and it is dropped too, for the reasons in
the four axes below.
**What the alternative would have done.** These rows come from oclif's
own predicates, `versionAddition` and `helpAddition` in `@oclif/core`
5.1.2 `lib/main.js`. They were evaluated in memory on this package's
loaded `Config`, with `additionalVersionFlags: ["-v"]` and
`additionalHelpFlags: ["-h"]` set on it. No file was written.
| argv | today | with the two keys |
|---|---|---|
| `-v serve` | exit 2, `command -v not found` | version check true:
prints the version, exits 0, **and serve never runs** |
| `serve -v` | `--verbose` | `--verbose` (oclif checks only argv[0] for
a version flag) |
| `serve -h` | exit 2, `Nonexistent flag: -h` | help check true: prints
help |
**The four axes.**
- **实际业务需求.** There is no measured pull. `git grep` for `os -h`, `os -v`
and `objectstack -h|-v` over the whole tree (content/docs, skills,
examples, packages, scripts) finds no occurrence. This README's `###
Global` was the only text that named the short forms.
- **项目长远合理性.** `-v` already has two meanings inside this CLI: verbose on
four commands and a package version on two. Adding a third that applies
only at argv[0] (print the CLI version) makes the flag's meaning depend
on where it appears. Making the docs follow the implementation removes
the false claim with no runtime change.
- **防 AI 写代码犯错.** Today a mistaken `os -v serve` fails loudly with exit
2. With the key set, it would print a version line, exit 0 and start
nothing, so a loud failure would become a silent one. The README now
says the short forms do not exist, so an agent reading it uses `--help`
and `--version`, which work in every position.
- **创业阶段不扩散需求.** New flags would be a new capability with no measured
pull, and the default is to keep scope tight. Making only `-h` work
would also leave `### Global` asymmetric, with no measured user who
needs it.
## `os plugin` — the commands, verbatim
`os plugin --help` at `9bdb092ca`, exit 0. The output is byte-identical
at `1caa60373`.
```text
Compile a plugin into a signed-ready `.osplugin` artifact (ADR-0025 §3.4)
USAGE
$ os plugin COMMAND
COMMANDS
plugin build Compile a plugin into a signed-ready `.osplugin` artifact
(ADR-0025 §3.4)
plugin publish Publish a signed .osplugin to ObjectStack Cloud (ADR-0025
§3.4)
plugin sign Sign a built .osplugin with a publisher Ed25519 key (ADR-0025
§3.4)
```
Usage lines: `os plugin build [DIR] [-e VALUE] [-o VALUE] [--minify]`,
`os plugin sign ARTIFACT -k VALUE [--key-id VALUE] [-o VALUE]` and `os
plugin publish [ARTIFACT] …`. There is no `install`, and that matches
ADR-0025's status line, which says the code-plugin install half is
unimplemented.
## Every README command-table row against `--help`
Placeholders are spelled in capitals here (TYPE, NAME, ID).
| Section | Row | Conclusion |
|---|---|---|
| Development | `os init [name]` | **Changed.** It said "in the current
directory". `os init --help` says: "When provided, a new directory with
this name is created; otherwise the current directory is used." The
Quick Start's own `os init my-app` was a counterexample. |
| Development | `os dev [package]` | **Changed.** It said "with hot
reload". `os dev --help` says: "watch sources, rebuild the artifact, and
restart the server on change". `dev.ts` records that the old "server
will auto-reload" line "advertised a hot reload the runtime only
partially performs". |
| Development | `os serve [config]` | **Already true.** For "plugin
auto-detection": `serve.ts:11` imports `isHostConfig` /
`shouldBootWithLibrary` from `utils/plugin-detection.ts`, which detect a
host config that carries instantiated plugins. The row leaves out the
artifact fallback that `--help` leads with, but that is an omission, not
a false claim. |
| Build & Validate | `os compile [config]` | **Already true.** `-o`
defaults to `dist/objectstack.json`. |
| Build & Validate | `os validate [config]` | **Already true.** `--help`
also mentions CEL expressions and widget bindings, which the row leaves
out. |
| Build & Validate | `os info [config]` | **Already true.**
`info.ts:117` prints agents. |
| Scaffolding | `os generate TYPE NAME` | **Left alone, per the ruling**
(these rows are #21167's, which landed as `bcd68a29f` before this
branch's base). It is also already true: `--help` marks NAME optional,
but `generate.ts` refuses a metadata type without a name ("Missing
required argument"). NAME is optional only for the `types`, `client` and
`migration` routes. |
| Scaffolding | `os create TYPE [name]` | **Already true.** `--help`
says "Create a new standalone kernel code plugin from a built-in
template", with TYPE = plugin. |
| Cloud | `os cloud login` | **Already true.** `-e/--email` and
`-p/--password` skip the browser flow, and credentials go to
`~/.objectstack/cloud.json`. |
| Cloud | `os cloud whoami` / `os cloud logout` | **Already true.** Both
are listed in `os cloud --help`. |
| Cloud | `os environments create --org ID --name N` | **Already true.**
Both flags are required in the usage line. There is no `projects` topic
in `os --help`. |
| Cloud | `os environments list` / `show ID` | **Already true.** |
| Cloud | `os package publish [artifact]` | **Already true.** ARTIFACT
defaults to `dist/objectstack.json`. |
| Plugin Management | (prose) | **Changed** (see above). |
| Quality | `os test [files]`, `os doctor`, `os lint [config]`, `os diff
[before] [after]` | **Already true.** The usage lines match. |
| Reference | `os explain [schema]` | **Already true.** |
| CLI Options | `### Global` | **Changed** (see above). |
| CLI Options | `os plugins` and `os help` (not commands) | **Already
true since #21306; not re-edited.** `os plugins` exits 2 with `command
plugins not found`, and `os help` exits 2 with `command help not found`.
`package.json` has no `oclif.plugins` and no `@oclif/plugin-*`
dependency. |
| Cloud | lead sentence: credentials from `os cloud login`, or `--token`
/ `OS_CLOUD_API_KEY` and `--server` / `OS_CLOUD_URL` | **Changed (patch
round 1).** This holds only for `os package publish` and `os plugin
publish`. The new per-command table is below. |
| Cloud | typical flow: `os cloud login`, then `os environments create`
| **Changed (patch round 1).** With only the `os cloud login` session
present, `os environments create` exits 1 with `Authentication required.
Please run os login or set OS_TOKEN environment variable.` The flow now
says so at that step and names what the step reads instead. |
| Cloud | "Set `OS_CLOUD_URL` (or `--server`)" | **Changed (patch round
1).** `os cloud login`, `os package publish` and `os environments` read
`OS_CLOUD_URL`. The flag is `--server` on `os package publish` and
`--url` on the other two. `os cloud whoami` / `logout` read neither. |
| CLI Options | `### os serve` `--ui` | **Changed (patch round 1).** It
said "Enable Studio UI". It now uses the `--help` wording: "Enable the
bundled Console portal at /_console/ when @object-ui/console is
installed (default: true)". |
## Cloud commands: flags, env vars and stored session, per command
Read off each command's `--help` at `9bdb092ca`. The "stored session"
column was measured, not taken from the help: `HOME` pointed at a temp
dir holding only a `cloud.json`, or only a `credentials.json`, whose URL
was a local echo server that logged each request's path and bearer.
| Command | Server URL flag (env) | Token flag (env) | Stored session it
authenticates with |
|---|---|---|---|
| `os cloud login` | `-u, --url` (`OS_CLOUD_URL`, default
`https://cloud.objectos.ai`) | none: `-e, --email` / `-p, --password`,
or the browser device flow | writes `~/.objectstack/cloud.json` |
| `os cloud whoami`, `os cloud logout` | none (`--json` only) | none |
read / delete `cloud.json` (`cloud/whoami.ts:26`,
`cloud/logout.ts:29,39`) |
| `os package publish` | `-s, --server` (`OS_CLOUD_URL`, default
`https://cloud.objectos.ai`; with neither set, the URL in `cloud.json`)
| `-t, --token` (`OS_CLOUD_API_KEY`, then `OS_TOKEN`) | `cloud.json`.
With only `credentials.json`: exit 1, "Not logged in to ObjectStack
Cloud. Run os cloud login first", and 0 requests. With only
`cloud.json`: the request goes to its URL with its bearer. With
`OS_CLOUD_API_KEY` or `OS_TOKEN`: the request carries that bearer. |
| `os plugin publish` | `-s, --server` (`OS_CLOUD_URL`) | `-t, --token`
(`OS_CLOUD_API_KEY`) | `cloud.json`, by the same precedence code as
package publish (`plugin/publish.ts:170-178`). Code-read only; not run,
because it needs a built `.osplugin`. |
| `os environments list` / `show` / `create` / `bind` / `switch` | `-u,
--url` (`OS_CLOUD_URL`); else the URL in `credentials.json`; else
`http://localhost:3000` | `-t, --token` (`OS_TOKEN`) |
`credentials.json`, the `os login` session. With only `cloud.json`, all
five exit 1 with `Authentication required`, before any request. With
only `credentials.json`, `list` sends `GET /api/v1/cloud/environments`
with its bearer. `OS_TOKEN` works, and `OS_CLOUD_API_KEY` alone does
not. |
| `os package install` (a runtime command, not a cloud one) | `-r,
--runtime` (`OS_RUNTIME_URL`, default `http://localhost:3000`) | none:
`--email` / `--password` (`OS_RUNTIME_EMAIL` / `OS_RUNTIME_PASSWORD`) |
none |
| Also read, not in the README's Cloud section: `os whoami`, `os data
*`, `os meta list/get/register/delete` | `-u, --url` (`OS_CLOUD_URL`) |
`-t, --token` (`OS_TOKEN`) | `credentials.json`, through the same
`createApiClient` (code-read) |
| Also read: `os datasource introspect/list-tables/validate` | `-u,
--url` (`OS_CLOUD_URL`, else `http://localhost:3000`) | `-t, --token`
(`OS_TOKEN`) | none. These use flags and env only
(`datasource/introspect.ts:10-13`, code-read). |
| Also measured: `os login` / `os register` | `-u, --url`
(`OS_RUNTIME_URL` for login, `OS_CLOUD_URL` for register; default
`http://localhost:3000`) | none (email/password, or the device flow for
login) | writes `credentials.json` |
## Acceptance notes
These are out of scope. The last one is filed as #21360; the others are
not filed.
- **Registered commands with no README row.** `build`, `start`,
`verify`, `login`, `logout`, `register`, `whoami`, `migrate`, `data`,
`datasource`, `db`, `i18n`, `meta`, `secret`, `storage`, `package
install` and `environments bind/switch` have no row. These are
omissions, not mismatches: the README does not claim to be complete, and
`content/docs/deployment/cli.mdx` is the full reference.
- **"Runtime plugins are bundled into the build artifact" is kept as
written.** I did not re-measure it. Only the false clause in front of it
was removed.
- **For the seat — the README is now true, but the flow it documents has
a gap.** After only `os cloud login`, `os environments create` refuses
and says to run `os login`. `os login --help` says "For the hosted
package registry, use `os cloud login` instead." This round changes no
code, so the README states the gap rather than closing it. The seat
filed it as #21360.
## Verification
- **Build.** `pnpm turbo run build --filter=!@objectstack/docs
--concurrency=2` at `9bdb092ca`: 72/72 tasks, verify-lock `VERDICT
command-exit 0`.
- **Derived gates.** `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands` at `9bdb092ca` gives 52 commands;
the merged `main` added `check-dts-emitted.mjs --self-test`. All 52
exited 0 at `9bdb092ca`, each exit code captured before any pipe. The
`--ran` reconciliation reads "52 derived, 52 run, 0 NOT-MEASURED, 0
UNRUN", and that zero is derived from recorded exit codes.
- **`main` moved again after the last merge.** That happened while the
gates ran: `96b12b589` (a pm-roster step in `lint.yml`) and `23365eaed`
(spec). Neither touches `packages/cli` or this changeset. The merge
queue rebuilds the PR on current `main`.
- **Runtime unchanged.** `os --help` is byte-identical at `9bdb092ca`
and at `1caa60373`: exit 0, 3712 bytes, md5
`1855676fe5a2bb87aa5871fc1bed196f`. `os -h` and `os -v` still exit 2.
- **CLI unit tier.** `pnpm --filter @objectstack/cli exec vitest run
--project unit --maxWorkers=2`: 244 files and 3461 tests passed,
`VERDICT command-exit 0`, at `4e7e91fd2`. Since then, `git diff
4e7e91f 9bdb092 -- packages/cli` touches only
`packages/cli/README.md`, and no CLI test reads that file. The tests
that mention a README read the README that `os create` emits. The
integration tier is left to CI.
- **CLI typecheck.** `pnpm --filter @objectstack/cli typecheck`: exit 0
at `4e7e91fd2`.
---
_Generated by [Claude
Code](https://claude.ai/code/session_018gA1pE6eJtwHhqx72G8U9X)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 13a24ec commit 37a0148
2 files changed
Lines changed: 64 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
43 | | - | |
| 42 | + | |
| 43 | + | |
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| |||
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
84 | | - | |
85 | | - | |
86 | | - | |
| 84 | + | |
| 85 | + | |
87 | 86 | | |
88 | 87 | | |
89 | 88 | | |
| |||
97 | 96 | | |
98 | 97 | | |
99 | 98 | | |
100 | | - | |
101 | | - | |
| 99 | + | |
| 100 | + | |
102 | 101 | | |
103 | 102 | | |
104 | 103 | | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
105 | 108 | | |
106 | 109 | | |
107 | 110 | | |
108 | 111 | | |
109 | 112 | | |
110 | | - | |
111 | | - | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
112 | 133 | | |
113 | 134 | | |
114 | 135 | | |
115 | | - | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
116 | 147 | | |
117 | 148 | | |
118 | 149 | | |
| |||
176 | 207 | | |
177 | 208 | | |
178 | 209 | | |
179 | | - | |
180 | | - | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
181 | 217 | | |
182 | 218 | | |
183 | 219 | | |
| |||
200 | 236 | | |
201 | 237 | | |
202 | 238 | | |
203 | | - | |
| 239 | + | |
204 | 240 | | |
205 | 241 | | |
206 | 242 | | |
| |||
0 commit comments