This repository was archived by the owner on Oct 26, 2026. It is now read-only.
Repository navigation
Commit 37268aa
fix(cli): retire
Fixes #11500
Clause-②: yes
## What
Triage ruled (comment `5960445419`) that four commands of the published
`objectui` bin retire, and that four noted residues ride in the same PR
as one-line corrections, each to what the command does. This PR:
- removes `create`, `lint`, `test` and `studio` from
`packages/cli/src/cli.ts`, and deletes `commands/create-plugin.ts`,
`commands/lint.ts`, `commands/test.ts` and `commands/studio.ts`.
`plugin` was the only type `create` accepted, so `create` goes whole.
Nothing else imported the four modules, and they read nothing under
`utils/`, so no other code goes. `SCAFFOLD_DEV_DEPENDENCIES` names
neither ESLint nor Vitest, so it is untouched;
- corrects the four residues (`doctor`, `serve` in the docs, `analyze`
without `dist/`, `init` with an unknown template);
- drops the four commands' sections from
`content/docs/utilities/cli.mdx` and `packages/cli/README.md`, and names
the plugin initializer in `cli.mdx`;
- adds the pins in `packages/cli/src/__tests__/cli-bin.test.ts`, all run
through the built `dist/cli.js`;
- adds `.changeset/11500-retire-cli-create-lint-test-studio.md`
(`@object-ui/cli` `minor`, BREAKING banner, one FROM to TO line per
retired command, one line per residue, a Clause-② line).
No refusal code was needed. On the BASE build, commander already refuses
any command the program does not declare: `objectui bogus` exits 1 with
`error: unknown command 'bogus'`.
## Measured: BASE `fcdc8ec91` build against the HEAD build
One run per row, each in a fresh temp directory, on the built bin.
Placeholders are spelled in capitals, because GitHub strips
angle-bracket shapes from a saved body.
| Run | BASE | HEAD |
|---|---|---|
| `create plugin x` | exit 1, `Cannot find module` on
`create-plugin/dist/index.js` at the worktree ROOT (one directory too
high); nothing written | exit 1, `error: unknown command 'create'`;
nothing written |
| `lint` | exit 1, "No Object UI application found" | exit 1, `error:
unknown command 'lint'` |
| `test` | exit 1, the same precondition error | exit 1, `error: unknown
command 'test'` |
| `studio` | run from a temp dir, it found this checkout's
`apps/console` through its own `dist` path and started that app's Vite
dev server; `timeout` stopped it and nothing was left running | exit 1,
`error: unknown command 'studio'` |
| `analyze`, no `dist/` | a warning, then "Analysis complete", exit 0 |
`Error: No dist/ directory to analyze. Run objectui build first.` on
stderr, exit 1 |
| `init app -t nope` | exit 1, `Unknown template: nope`, and an empty
`app/` left behind | exit 1, the same error, nothing written |
| `doctor --help` | "Diagnose and fix common issues". `doctor` writes
nothing and prints no Node line | "Diagnose common project setup issues
(reports only, changes nothing)" |
## The plugin initializer, measured before it was written
`packages/create-plugin/package.json` names `@object-ui/create-plugin`
with one bin, `create-plugin`. It is not `private`, it is in the
release's `fixed` group, and npm answers `17.6.0` for it. The bin takes
`[plugin-name]`, `-d, --description` and `-a, --author`. In a temp
directory, `npm create @object-ui/plugin probe-widget` installed
`@object-ui/create-plugin@17.6.0` and ran `create-plugin probe-widget`.
Under a pseudo-terminal, taking each prompt's default, it wrote
`packages/plugin-probe-widget/` (8 files) and exited 0. So `cli.mdx` now
carries a short "Scaffolding a plugin" section with `npm create
@object-ui/plugin my-awesome-widget` and a link to the Create Plugin
page, which says where to run it. No dependency was added.
## Contract notes
- **The accept set narrows (Clause-② yes).** The published `objectui`
bin refuses what it used to accept:
- FROM `objectui create plugin NAME` (exit 1, generator not found) TO
exit 1 with `error: unknown command 'create'`, nothing written. The
replacement is `npm create @object-ui/plugin NAME`.
- FROM `objectui lint` and `objectui test` (exit 1 on every run, a setup
error reported as findings) TO the unknown-command error. The
replacement is the project's own ESLint and Vitest.
- FROM `objectui studio` TO the unknown-command error. There is no
published replacement; contributors run `pnpm --filter console dev` in
the monorepo.
- FROM `objectui analyze` with no `dist/` exiting 0 TO exiting 1.
There is no alias, no deprecation window and no silent accept.
- **Unchanged.** `init` with a known template writes the same file map
(pinned byte for byte by "writes exactly the file map buildInitFiles
returns, byte for byte"). `analyze` over a `dist/` prints the same
report. `doctor`'s checks and output are untouched; only its help line
moves. No exported symbol of `@object-ui/cli` moves: `src/index.ts`
exports `serve` and `init`, and `init`'s signature is unchanged.
- **`validate` and `check` are not edited.** Draft PR objectui#11069
owns them. In the README, only `studio` and `create plugin NAME` leave
the heading that also names `check`, `doctor` and `analyze`. Four
untouched lines separate that hunk from objectui#11069's `validate`
hunk. In `cli.mdx`, no hunk touches the `validate` or `check` sections.
- **Two edits beyond the sections**, both naming retired commands: the
README tagline and the `cli.mdx` intro sentence each listed lint and
test. Both now say scaffold, develop, build and validate, as the
package's own `description` already does.
## Pins
All in `cli-bin.test.ts`, run through the built `dist/cli.js`:
1. The objectui#11496 enumeration pin, "lists exactly the declared
commands, no more and no fewer": `SUBCOMMANDS` loses `create`, `lint`,
`test` and `studio`.
2. "the retired create, lint, test and studio commands are refused
(objectui#11500)": four rows. Each one exits non-zero, its stderr
contains `unknown command 'NAME'`, and the temp directory stays empty.
The control is `g page Probe` in the same directory, which writes
`pages/probe.json`. These runs empty `PATH`. Run from inside a checkout,
the BASE `studio` started the console dev server. With no `PATH`, a
retired command that came back fails at its first external tool (at
BASE, `/bin/sh: 1: pnpm: not found`), and the stderr assertion still
turns red.
3. "doctor --help does not claim to fix anything (objectui#11500)": it
asserts the kind of claim, not the wording, as the existing `check
--help` pin does.
4. "exits non-zero without dist/, and claims no analysis
(objectui#11500)".
5. "refuses an unknown template before creating the directory
(objectui#11500)". The control is `init probe-app -t simple` in the same
directory, which writes `probe-app/app.json`.
6. The `serve` row of the flag-contract table gains `--no-open`, a
docs-alignment pin that is green at BASE by design. The `lint` and
`test` rows go.
## Reverse verification
Predictions were written down before each leg. In each leg, the mutation
is a `git checkout COMMIT -- PATH`, proven on disk by blob hash. The CLI
is then rebuilt, a marker is read from `dist/`, and `cli-bin.test.ts`
runs. An EXIT/INT/TERM trap restores from HEAD and proves the restore by
blob hash, an empty `git diff HEAD` and an empty porcelain.
- **BASE leg.** `cli.ts`, `analyze.ts`, `init.ts` and the four deleted
modules at `fcdc8ec91`, with the pins at HEAD `a20223743`. Blobs on disk
equalled BASE: `004165f17300`, `63659c0b30c9`, `ad7bde24bfcc`,
`e8438188bbc5`, `613605f90d07`, `48db26298d9a`, `5039e918e38e`. `dist/`
carried the studio marker and the old doctor text, twice each. Predicted
8 red. Observed `Tests 8 failed | 40 passed (48)`: the enumeration pin,
the four refusals, doctor, analyze and init. The `serve` row stayed
green, as predicted.
- **Restore-one leg.** HEAD plus `studio` alone: its module from BASE,
and its import and command block re-inserted into `cli.ts`, each counted
once on disk. Predicted 2 red. Observed `Tests 2 failed | 46 passed
(48)`: the enumeration pin and the `studio` refusal. The six other new
pins read green here, which also shows `dist/` was rebuilt from this
leg's sources.
- **Restore.** The tree equals HEAD `a20223743` (blobs `ec9d879fdc20`,
`fb81635c05cb`, `ab62a52b5efd`; the four modules absent), and the CLI
was rebuilt. The four BASE markers count 0 in `dist/`, and HEAD's doctor
text counts 2, as a positive control.
## Local gates, at HEAD `a20223743`
- `pnpm exec vitest run` over `packages/cli/src/__tests__/` in full,
plus every test that names a retired command, `create-plugin`, `cli.mdx`
or the CLI README, plus the `scripts/__tests__` readers of the CLI tree:
`Test Files 39 passed (39)`, `Tests 658 passed (658)`. The 14 files
beyond the CLI suite: `toc-anchor-parity.test.tsx`,
`nested-page-children-11223.test.ts`, both `create-plugin` suites, and
`spawned-build-vitest-env-8598`, `check-doc-snippet-emitted-census`,
`doc-version-claims`, `package-files-exist`,
`one-authority-per-exported-name-6273`,
`check-published-tsconfig-tooling-exclude`, `body-dialect-census`,
`body-dialect-producer-scan` and `check-test-path-roots`. Four other
`scripts/__tests__` hits on the names `lint` and `test` are file stems
and workflow job names, not the CLI.
- `pnpm --filter @object-ui/cli type-check` exit 0 (its `tsconfig`
includes `src/**/*`, and `--listFiles` lists `cli-bin.test.ts`); `pnpm
--filter @object-ui/cli build` exit 0.
- `docs:check-links` "Links are valid across 17 scan roots." ·
`check:doc-fences` OK · `check:readme-exports` OK ·
`markdown-test-inputs.mjs --audit` "115 candidate test files, all
adjudicated" · `check:control-bytes` OK · `check:new-line-citations` "0
new citation(s)" · `check-changeset-presence.mjs` "8 source file(s) of 1
released package(s) changed, and this change declares 1 changeset(s)" ·
`changeset:check` "No changeset declares a `major` bump." ·
`check:changeset-claims` report-only, see Acceptance notes ·
`check:pending-changeset-literals` "No test source names a pending
changeset." · `check:test-path-roots`, `check:unused-deps`,
`check:phantom-deps`, `check:doc-types`, `check:doc-example-ids`,
`check:shell-escape-residue`, `check:unreferenced-sources` and
`check:vi-mock-specifiers` OK · `check:doc-snippets` "Every covered
documentation snippet compiles against the built types." ·
`check:doc-examples` OK · `pnpm check` "287 validated … 0 did not
validate". The README and snippet gates ran after a scoped build of
their package closure; before it they answered PRECONDITION NOT MET,
which is not a verdict.
- ESLint over all of `packages/cli/src`, the population CI's `eslint
src` lints for this package: 47 files in the JSON output, equal to the
47 tracked `.ts` files there. 0 errors. 5 warnings, all in three files
this diff does not touch. Type-aware linting is off
(`tseslint.configs.recommended`, no `projectService`), and no rule in
`eslint-rules/` reads the disk, so the verdicts of untouched files
cannot move.
- `scripts/check-governed-queue-guard.mjs --test` over the 11 paths: NOT
GOVERNED.
The full `pnpm test` and the repo-wide lint are left to CI.
## Acceptance notes
- **Governed rows this PR leaves to the `skills` lane.**
`skills/objectui/guides/project-setup.md`'s CLI table still lists the
retired commands. These rows are cited by content, because a line
address in a body is the banned cross-file form:
- the row reading `objectui studio` / "Visual UI editor"; carrier: seat
→ objectui#11503
- the row reading `objectui lint` / "Lint generated app code (ESLint)";
carrier: seat → objectui#11503
- the row reading `objectui test` / "Run app tests (Vitest)"; carrier:
seat → objectui#11503
- the row reading `objectui create plugin` / "Scaffold a new plugin";
carrier: seat → objectui#11503
- **Residue sizes.** `analyze`: two lines become one `throw`. `doctor`:
one help line in `cli.ts` and one sentence in `cli.mdx`. `serve`: one
docs line. `init`: one statement hoisted, which is one line added
(`const files = buildInitFiles(…)` above the `mkdirSync`) and the loop
header collapsed from three lines to one, plus a corrected comment. The
old comment's "Unknown templates still throw here, before the first
write" was false, because the directory was created first.
- **What `analyze` prints without `dist/`.** Its two header lines still
print on stdout before the error. The error is on stderr, and "Analysis
complete" no longer prints.
- **`check:changeset-claims`** flagged two pending changesets naming
files this PR touches. Both were re-read, and both stay true.
`7658-toc-code-span-anchor-parity.md` describes, in the past tense,
headings its own change fixed.
`7694-chart-series-chart-type-alias-refusal.md` names `objectui
validate` in `cli.ts`, which this PR does not touch.
- **Observed, not filed** (no declared contract is violated; carrier:
none):
- `doctor` exits 0 even with an error-level finding. At BASE, in an
empty directory, it printed `x package.json not found` and `Found 2
issue(s).`, and exited 0. Nothing documents its exit code.
- The published `@object-ui/create-plugin@17.6.0`, run with a non-TTY
stdin, prints its second prompt and exits 0 with nothing written.
objectui#8786's fix is on `main` but unreleased: the published bin
contains no `isTTY` check. It ships with the next release.
- `packages/plugin-markdown/src/toc-anchor-parity.test.tsx`'s
`LIVE_SHAPES` still names the `objectui add COMPONENT` heading as live,
with `where` naming `cli.mdx` and the README. Since objectui#11496 that
heading exists in neither file, and after this PR neither does `objectui
create plugin NAME`. The test hard-codes the heading strings and reads
no file, so it stays green; only its `where` is stale.
Implemented by the dispatched `domain:ui` seat 1 dev agent; PM session
`https://claude.ai/code/session_01YLg8XqWGJ785fwQ5v4pH37`.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01YLg8XqWGJ785fwQ5v4pH37)_
---------
Co-authored-by: Claude <noreply@anthropic.com>create, lint, test and studio, commands that could only fail; correct four residues to what the commands do (objectui#11500) (#11508)1 parent 58b480e commit 37268aa
11 files changed
Lines changed: 140 additions & 406 deletions
File tree
- .changeset
- content/docs/utilities
- packages/cli
- src
- __tests__
- commands
| 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 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
10 | | - | |
| 9 | + | |
11 | 10 | | |
12 | 11 | | |
13 | 12 | | |
| |||
73 | 72 | | |
74 | 73 | | |
75 | 74 | | |
76 | | - | |
| 75 | + | |
77 | 76 | | |
78 | 77 | | |
79 | 78 | | |
| |||
105 | 104 | | |
106 | 105 | | |
107 | 106 | | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | 107 | | |
137 | 108 | | |
138 | 109 | | |
| |||
278 | 249 | | |
279 | 250 | | |
280 | 251 | | |
281 | | - | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
282 | 255 | | |
283 | | - | |
| 256 | + | |
284 | 257 | | |
285 | | - | |
286 | | - | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
287 | 262 | | |
288 | | - | |
| 263 | + | |
289 | 264 | | |
290 | | - | |
| 265 | + | |
| 266 | + | |
291 | 267 | | |
292 | 268 | | |
293 | | - | |
| 269 | + | |
294 | 270 | | |
295 | 271 | | |
296 | | - | |
297 | | - | |
298 | | - | |
299 | | - | |
300 | | - | |
| 272 | + | |
| 273 | + | |
301 | 274 | | |
302 | 275 | | |
303 | 276 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
87 | 87 | | |
88 | 88 | | |
89 | 89 | | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | 90 | | |
109 | 91 | | |
110 | 92 | | |
| |||
120 | 102 | | |
121 | 103 | | |
122 | 104 | | |
123 | | - | |
| 105 | + | |
124 | 106 | | |
125 | 107 | | |
126 | 108 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
30 | 32 | | |
31 | 33 | | |
32 | 34 | | |
33 | 35 | | |
34 | 36 | | |
35 | 37 | | |
36 | 38 | | |
37 | | - | |
38 | | - | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
42 | 41 | | |
43 | 42 | | |
44 | | - | |
45 | 43 | | |
46 | 44 | | |
47 | 45 | | |
| |||
237 | 235 | | |
238 | 236 | | |
239 | 237 | | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
240 | 251 | | |
241 | 252 | | |
242 | 253 | | |
243 | | - | |
| 254 | + | |
244 | 255 | | |
245 | 256 | | |
246 | 257 | | |
247 | | - | |
248 | | - | |
249 | 258 | | |
250 | 259 | | |
251 | 260 | | |
| |||
319 | 328 | | |
320 | 329 | | |
321 | 330 | | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
322 | 375 | | |
323 | 376 | | |
324 | 377 | | |
| |||
350 | 403 | | |
351 | 404 | | |
352 | 405 | | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
353 | 418 | | |
354 | 419 | | |
355 | 420 | | |
| |||
406 | 471 | | |
407 | 472 | | |
408 | 473 | | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
409 | 489 | | |
410 | 490 | | |
411 | 491 | | |
| |||
0 commit comments