Repository navigation
fix(cli): drop the never-loaded oclif.plugins entries and correct the text that says os plugins works - #21306
Conversation
…pendencies `oclif.plugins` named @oclif/plugin-help and @oclif/plugin-plugins, but both sat in devDependencies and oclif's core-plugin loader matches those names only against `dependencies`, so neither ever loaded. Remove the array and the two devDependencies; the lockfile regeneration drops exactly their two subtrees (14 entries, 0 added, no surviving resolution changed). Claude-Session: https://claude.ai/code/session_018gA1pE6eJtwHhqx72G8U9X Co-authored-by: Claude <noreply@anthropic.com>
The README, the plugins docs callout, the bin entry's auto-transpile note, the doctor comment, the platform checklist and the plugin-surface test all described `oclif.plugins` or an `os plugins` command group. Restate each to the new fact: no `oclif.plugins`, no plugin manager, `os --help` is the help entry, and a CLI extension loads through an `os` distribution that lists it in both `oclif.plugins` and `dependencies`. The test now pins that state instead of the dead array. Adds the patch changeset. Claude-Session: https://claude.ai/code/session_018gA1pE6eJtwHhqx72G8U9X Co-authored-by: Claude <noreply@anthropic.com>
…op-dead-oclif-plugins
…op-dead-oclif-plugins
…op-dead-oclif-plugins
📓 Docs Drift CheckThis PR changes 1 package(s): 9 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 26 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 41bc43f7c37ebe067058dfd357bf604f9731b5be && git checkout 41bc43f7c37ebe067058dfd357bf604f9731b5be
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 393ae878d3d52fe843c56b4621c004b934dcf853 a1e72918c3e9cf7764709af152072dcda2d250f6 && git checkout -B drift-repro 393ae878d3d52fe843c56b4621c004b934dcf853 && git merge --no-ff a1e72918c3e9cf7764709af152072dcda2d250f6
node scripts/docs-audit/affected-docs.mjs --json 393ae878d3d52fe843c56b4621c004b934dcf853
|
Review: ACCEPT, PR #21306 (head
|
Contract reviewServed-tier: Read at 2026-10-02T04:12Z from the inputs alone: card #21285 (body, the Claim comment, the os-dev report), PR #21306 (body, 10-file list, the two PR comments, and the three-dot net diff against ① Derived judgmentsEvery accept-set and public-surface change the diff implies, each named right or wrong:
Check-runs on the head (latest run per name, all concluded; ② Semver level
The PR body's declaration line reads ③ Boundary flags
Implemented-by: VERDICT: PASS |
… that the built os registers (objectstack-ai#21354) Fixes objectstack-ai#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 objectstack-ai#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 objectstack-ai#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 objectstack-ai#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 objectstack-ai#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 objectstack-ai#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>
Fixes #21285
Clause-②: no
What this does
packages/cli/package.jsonlisted@oclif/plugin-helpand@oclif/plugin-pluginsunderoclif.plugins, but both were onlydevDependencies. oclif loads anoclif.pluginsentry only when the same name is independencies, so neither ever loaded. This PR:oclif.pluginsarray (no otheroclifkey changes);devDependencies(no consumer remains, see H1) and regeneratespnpm-lock.yamlwithpnpm install --lockfile-only;os pluginsworks (per-site table below);test/plugin-commands.test.tsso it pins the new state instead of the dead array;.changeset/21285-drop-dead-oclif-plugins.md(patch,@objectstack/cli).Maintainer ruling (verbatim):
packages/spec/**is untouched. That includescli-extension.zod.tsand its generated pagecontent/docs/references/kernel/cli-extension.mdx, which still sayos plugins install. The spec-lane card #21286 carries them, and it remains open.Behaviour: nothing an operator sees changes
Reading script:
node packages/cli/bin/run.jswithNODE_ENVunset andOCLIF_COLUMNS=120, run from an empty directory. Each run's stdout, stderr and exit code were captured. The runs:--help,help,plugins,plugins install @acme/plugin-marketplaceandfrobnicate;TOPIC --helpfor each of the 32 root-level topics;@oclif/coreConfig.loaddump: loaded plugins, all 65 command ids and all 75 topics.That is 114 files per reading.
748b24072, unmodifiedos --help: 12 topics + 22 commands.help,pluginsandplugins installexit 2 withcommand ... not found. Plugins loaded:@objectstack/clionly.dependencies(mutation throughscripts/ablation-replace.mjs, restore proven: blob == HEAD,git diff HEADempty)os helpexits 0.os pluginsexits 0 ("No plugins installed."). The command table gainshelpand 10plugins:*ids (65 to 76). The root help gains thepluginstopic and thehelpandpluginscommands. So the reading catches a real difference.cc13e2532(array and devDependencies removed, lockfile regenerated) anda593c8c62(CLI rebuilt)diff -ragainst before: empty, all 114 files, same sha256 over the concatenation (338e1f0f...5c6f38)3c8442fc0anda1e72918c(after merging main)17.5.0to17.6.0. Those come from main's Version Packages merge, not from this diff.Hypotheses
git grepfindsplugin-helpandplugin-pluginsonly in these places:devDependenciesblock;bin/run.js,doctor.tsanddoctor-deprecation-hint-commands.test.ts;No import,
require, script, fixture or other importer names them. In the lockfile, only thepackages/cliimporter referenced them.748b24072and5a9292e6f), with the same result:@oclif/plugin-help@7.0.2,@oclif/plugin-plugins@7.0.3,hosted-git-info@7.0.2,isexe@3.1.5,lru-cache@10.4.3,npm@11.21.0,npm-package-arg@11.0.3,npm-run-path@5.3.0,object-treeify@4.0.1,path-key@4.0.0,proc-log@4.2.0,validate-npm-package-name@5.0.1,which@4.0.0andyarn@1.22.22.isexe3.1.5,lru-cache10.4.3,path-key4.0.0 andwhich4.0.0. The versions every other consumer resolves are unchanged.dependenciescount): holds.@oclif/core5.1.2lib/config/plugin-loader.jsloadCorePluginscallsfindMatchingDependencies(rootPlugin.pjson.dependencies ?? {}, corePlugins). Measured three ways:@acme/plugin-marketplacelisted inoclif.pluginsplusdependencies,marketplace:searchloads and runs. Moved todevDependencies, nothing loads.plugins install/uninstall/update/link/...in space and colon forms, every@oclif/plugin-*, andos|objectstack plugins|help. Every hit is accounted for in the table below. The widened spellings found only three things beyond the card's sites:bin/run.js:87(theplugins linksentence, covered with the run.js site), the phrase "ObjectStack plugins" (prose, not a command), and oneCHANGELOG.mdline.@oclif/core5.1.2Config.load:@acme/plugin-marketplacein bothoclif.pluginsanddependenciesloadsmarketplace:searchand runs it;@objectstack/cliand the extension that way loads 66 commands (this CLI's 65 plusmarketplace:search);Per-site conclusions
packages/cli/package.jsonoclif.plugins+ 2devDependenciespnpm-lock.yamlcontent/docs/plugins/index.mdxStep 3 callout (lines 400-408)plugin-pluginssits in devDependencies") became false. It now says: no plugin manager;os plugins ...andos helpare not commands;os --helpis the help entry; the distribution route, kept because H4 holds; and the loader'sdependencies-only rule.os --help"os --help(H4 fixture).packages/cli/README.md### os plugins (oclif)### os plugins and os help (not commands): no plugin manager; each exits 2; useos --help; link to the plugin-system section.packages/cli/README.md## oclif Plugin System(intro, step 3, "Install and use", comparison row)os plugins installis gone. Step 3 and the example load through anosdistribution listing the plugin inoclif.plugins+dependencies.packages/cli/bin/run.js:84-97oclif.plugins, no@oclif/plugin-pluginsdependency" instead of the devDependencies placement. The 34-entry count is re-measured (12 topics + 22 commands).packages/cli/src/commands/doctor.ts:2377-2380oclif.plugins)".packages/cli/src/commands/doctor-deprecation-hint-commands.test.ts:15packages/cli/test/plugin-commands.test.tsoclif.pluginsis undefined, and no@oclif/plugin-*package appears in any dependency field. The command-discovery and bin pins are kept. The guard is not deleted (reverse verification below).docs/qa/platform-checklist/areas/cli.json:658(cli.flag-command-error-ux)pnpm check:platform-checklistis green.packages/spec/src/kernel/cli-extension.zod.ts:18andcontent/docs/references/kernel/cli-extension.mdx:21packages/cli/CHANGELOG.md:1362(the "plugins linked TypeScript plugin ...@oclif/plugin-pluginssits indevDependencies" entry)content/docs/ai/skills.mdx,api/error-handling-server.mdx,plugins/development.mdx,packages/core/src/types.ts,packages/types/README.md,skills/objectstack-platform/references/plugin-hooks.md), rootCHANGELOG.md:1367os pluginscommand.Tests and gates (final head
a1e72918cunless noted)Gates:
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commandsata1e72918cderives 106 commands. All 106 were run with each exit code captured before any pipe, and all 106 exit 0.--ranreconciles them:106 derived famil(ies) accounted for, 106 run, 0 NOT-MEASURED.3c8442fc0.a593c8c62, 4 needed a re-run. Three refused with exit 3 (PREREQUISITE NOT MET) before the packages they read were built:check:skill-examples,check:dual-build-cjs-loadsandcheck:i18n-coverage.check:slot-lookuphit an ENOENT on a temp fixture that a concurrent CLI test deleted. All 4 were green on re-run.@objectstack/cliunit tier (vitest run --project unit --maxWorkers=2): 243 files and 3440 tests passed at3c8442fc0, and again ata593c8c62. The two edited test files were re-run ata1e72918c: 2 files and 16 tests passed. The last merge (3c8442fc0toa1e72918c) brought 4 main commits, none of which touchpackages/cli.Reverse verification on the rewritten test, with the fix committed. Each mutation went through
scripts/ablation-replace.mjs(anchor hit, blob changed) with its restore proven (blob == HEAD,git diff HEADempty):oclif.pluginsarray:declares no oclif.pluginsgoes red (expected [ '@oclif/plugin-help', ... ] to be undefined);@oclif/plugin-pluginstodevDependencies:depends on no @oclif/plugin-* packagegoes red.pnpm --filter @objectstack/cli typecheck(ata593c8c62): exit 0.plugin-commands.test.tsis intsconfig.test.json's program anddoctor-deprecation-hint-commands.test.tsintsconfig.json's (--listFilesOnly).--project integration(ata593c8c62, run because the diff touchesbin/): 69/70 files and 601/603 tests pass. The 1 failure is pre-existing:test/published-entry-node-env-source-reroute.test.ts,CONTROL: neutralising the declaration in the child reproduces the card verbatim. It fails identically on base748b24072, built (59/59 turbo cache), in a separate worktree. Cause: tsx 4.23.15's ESM API registers./esm/index.mjsrelative todist/esm/api/index.cjs. That resolves to the nonexistentdist/esm/api/esm/index.mjs(oclif:config:ts-pathdebug: "Could not find tsx. Skipping tsx registration"), so the control's trap never arms. It is unrelated tooclif.plugins. The integration tier was not re-run at the final head: the incoming main commits touch nopackages/cli/binorsrcfile. It is declared to CI.Lint, narrowed and measured:
eslint --no-inline-config --format jsonover the 4 touched JS/TS files reports 4 files, 0 errors and 0 warnings. The other 6 touched files (.md,.mdx,.json,.yaml) are outsideeslint.config.mjs'sfilesglobs. The config enables no type-aware linting (noparserOptions.project), so this diff cannot move an untouched file's verdict. The fullpnpm lintis CI's.Acceptance notes (not filed here; for the seat)
packages/cli/README.md### Globalsays-v, --versionand-h, --help. Measured on the built entry:os -handos -vexit 2 withcommand -h not foundandcommand -v not found. Only--helpand--versionwork. This is pre-existing and unrelated to this diff, so it is reported, not fixed.packages/cli/README.md### Plugin Managementsays "There is noos plugincommand group in v1".os plugin build|sign|publishis registered: theplugintopic is inos --help. This is pre-existing, and feat(cli,create-objectstack): os generate picklist, the src/picklists starter barrel, and a Picklists count in the metadata summary #21167 also holds this file, so it is left untouched.packages/cli's integration tier wherever that file runs.Generated by Claude Code