Repository navigation
fix(cli): retire objectui add and analyze's two flags, no-ops that exited 0; one enumeration pin over the built CLI's commands (objectui#11496) - #11499
Conversation
…t exited 0; one enumeration pin over the built CLI's commands (objectui#11496) `add` printed "Feature not implemented yet." and wrote nothing, exit 0. The family close-out over every command and flag found one more no-op: `analyze --render-performance` printed fixed text in any directory. `--bundle-size` goes with it, having nothing left to choose between. The bin refuses all three; the docs and README drop them. Claude-Session: https://claude.ai/code/session_01YLg8XqWGJ785fwQ5v4pH37 Co-authored-by: Claude <noreply@anthropic.com>
…e docs from this test needs a markdown-test-inputs ledger row outside this card's file surface (objectui#11496) Claude-Session: https://claude.ai/code/session_01YLg8XqWGJ785fwQ5v4pH37 Co-authored-by: Claude <noreply@anthropic.com>
…lib has no Array.at (objectui#11496) Claude-Session: https://claude.ai/code/session_01YLg8XqWGJ785fwQ5v4pH37 Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: PR objectui#11499 (card objectui#11496), judged against triage's ruling ① Derived judgments
② Semver level
③ Boundary flagsDev report Open questions
Deviations
Out-of-scope findings
Reviewer's finding, escalated to the seat (not a dev flag; found in ①.6).
Check-runs on the head43 check-runs on Implemented-by: VERDICT: PASS Generated by Claude Code |
Fixes #11496
Clause-②: yes
What
objectui add COMPONENTwas declared ("Add a new component renderer to your project") and documented with an example. Its action printed "Feature not implemented yet.", wrote nothing and exited 0. Triage ruled it retired, with no placeholder (ruling comment5958245941, on the precedents5955124315and5957399263). The ruling also asked for a family close-out over every command and flag, plus one enumeration pin over the built CLI's commands. This PR:addcommand frompackages/cli/src/cli.tsand deletespackages/cli/src/commands/add.ts;analyze --render-performance, the one further no-op the close-out found, andanalyze --bundle-sizewith it (see Contract notes). Their option lines go fromcli.ts, and the placeholder function and the option plumbing go fromcommands/analyze.ts;addsection and theanalyzeflag table fromcontent/docs/utilities/cli.mdx, replaces its stored command count with a pointer toobjectui --help, and drops theaddsection frompackages/cli/README.md;packages/cli/src/__tests__/cli-bin.test.ts, all run through the builtdist/cli.js;.changeset/11496-retire-cli-add.md(@object-ui/climinor, BREAKING banner, one FROM to TO line per retired surface, a Clause-② line).No refusal code was needed. Measured on the BASE build before any edit: the program declares no default command,
allowUnknownOption,passThroughOptionsorallowExcessArguments.objectui bogusexits 1 witherror: unknown command 'bogus', andobjectui --bogusexits 1 witherror: unknown option '--bogus'. So commander's default refusal applies once a command or option is undeclared.Serial: PR objectui#11495 (
generate --from) landed as1fe05ff37before the first edit here. This branch was fast-forwarded onto it, so1fe05ff37is the base.origin/mainhas not moved since.Contract notes
The accept set narrows (Clause-② yes). The published
objectuibin refuses three surfaces it used to accept:objectui add COMPONENT(exit 0, nothing written) TO a non-zero exit witherror: unknown command 'add', nothing written.objectui analyze --render-performance(exit 0, fixed text) TO a non-zero exit witherror: unknown option '--render-performance'.objectui analyze --bundle-sizeTO a non-zero exit witherror: unknown option '--bundle-size'. The replacement isobjectui analyze, which prints the same bundle report.There is no alias, no deprecation window and no silent accept.
Why
--bundle-sizegoes too. It only chose between the bundle report and the render section. With the render section retired, the flag would be declared, documented and read by nothing, which is whygenerate --outputwas retired. Keeping it would leave that defect in place, so it goes. This is a judgement on top of triage's ruling; it is raised as an open question in the dev report so the contract review can overturn it.Unchanged.
objectui analyzewith no flag prints the bundle-size report ofdist/byte for byte as before, minus the fixed render section. Its help description is untouched. No exported symbol of@object-ui/climoves:cli.tsis the bin entry, andanalyzeis not in the package'sexports(src/index.tsexportsserveandinitonly).validateandcheckare not edited. Draft PR objectui#11069 owns them. Both measured as working (table below). That PR also edits the README'svalidatesection and the docs'validate/checksections. Those regions do not touch the ones edited here: four untouched README lines separate the nearest hunks.Family close-out: every command and flag
cli.tsdeclaresOne run per row in a fresh temp directory, on the built CLI (exit code, files written). The rows were measured on the build of
4abc0aafa, which differs from base1fe05ff37only bygenerate --from, plus the post-fix build for the rows marked "after". The help texts are commander's. Placeholders are spelled in capitals, because GitHub strips angle-bracket shapes from a saved body.--helpsayscli.mdxsays-V, --version17.6.0, exit 0-h, --helpnpx @object-ui/cli --helpserve [schema]dev, "same positional argument and-p/-hflags asdev(no--no-open)"app.json, deps installed): HTTP 200 from the dev serverserve -p, -hdevserve --no-openservehas no such flagdev [schema],-p,-h,--no-open--help--no-openhonouredbuild [schema],-o, --out-dir,--clean--helpout/index.htmlandout/assets/, exit 0;--cleanremoved a sentinel filestart,-p,-h,-d, --dir--helpout/: HTTP 200 on/and on a deep route (SPA fallback)init [name],-t, --template--help-t formhonoured;-t nopeexits 1-t nopeleaves an empty directory, Acceptance notes)lint,--fixdevgeneratestest,-w,-c,--uidevgeneratesgenerate/g TYPE NAME--helppage,object,resourceandplugineach write their file, exit 0; an unknown type exits 1doctoradd COMPONENTerror: unknown command 'add'studio@object-ui/plugin-designer) against the local projectapps/console's Vite dev server (MSW mode) on its fixed port, not the local project. In a simulated published install: exit 1, "Console app not found in workspace"check--helpvalidate [schema]--helpapp.json: exit 0; missing file: exit 1create TYPE NAME@object-ui/create-plugincreate plugin my-widget: exit 1,Cannot find moduleon acreate-plugin/dist/index.jspath, in the checkout and in a simulated published install; another type exits 1analyzedist/: totals and the ten largest files; without: a warning, then "Analysis complete", exit 0dist/, Acceptance notes)analyze --bundle-sizeanalyze, alone. After: exit 1, unknown optionanalyze --render-performancedist/(same md5); exit 0. After: exit 1, unknown optionhelp [command]Pins
All of them are in
cli-bin.test.tsand run through the builtdist/cli.js:--help>lists exactly the declared commands, no more and no fewer. This is the enumeration pin. It parses the Commands section of the root--helpand asserts that the names equalSUBCOMMANDS, in both directions and without duplicates. Its lit control: commander's ownhelpentry is read as the last entry, which proves the parse reached the end of the section. It replaces a containment check that a retired command coming back would have passed.the retired add command is refused (objectui#11496):add Inputin an empty temp directory exits non-zero, stderr namesunknown command 'add', and the directory stays empty. Its control:g page Probein the same directory then exits 0 and writespages/probe.json.analyze refuses its retired flags (objectui#11496): each flag exits non-zero naming itself as an unknown option, and writes nothing. The control:analyzewith no flag over a planteddist/exits 0, prints the bundle report and the planted file, and prints no render section.analyze --helplists neither flag, with a lit control on its own usage line.SUBCOMMANDSdropsadd, and theanalyzerow leaves the "exposes the documented flags" table.Reverse verification
Predictions were written down before each run. Every leg ran on final head
5e7b89431, with the fix committed.cli.ts,commands/analyze.tsandcommands/add.tswere checked out at base1fe05ff37, with the pins at HEAD. Each blob equalled its base blob:ab22eb7e6fa6,7d9e7e3af440,b2fd2fcae3e9. The CLI was rebuilt: dist markersadd=1,render-performance=1. Predicted 6 red. ObservedTests 6 failed | 41 passed (47): pin 1, pin 2, both flag refusals, the no-flag control (it printed the render section), and theanalyze --helppin.cli.tsandanalyze.tsblobs equal HEAD (004165f17300,63659c0b30c9),add.tsis absent,git diff HEADis empty andgit status --porcelainis empty.scripts/ablation-replace.mjsran in wrap mode on the committed fix, with its restore trap. It planted back intocli.tsanaddcommand that prints one line and exits 0, plus bothanalyzeoption lines;analyze.tsstayed fixed. Anchorx1 -> x0, blob004165f17300 -> cdd4d9455089. Source markersadd=1 render-perf=1 bundle=1; the CLI was rebuilt; dist markersadd=1 render-perf=1 bundle=1. Predicted 5 red, with the no-flag control staying green becauseanalyze.tswas not mutated. ObservedTests 5 failed | 42 passed (47), on exactly those five names.git checkout HEAD --on the absolute path. Blob after = HEAD blob004165f17300,git diff HEADis empty andgit status --porcelainis empty. CLI rebuilt; dist markers all 0;Tests 47 passed (47).d9294d27b, with identical counts. The only change since is reading the last--helpentry by index rather than withArray.at.Tests and gates
All of these ran on final head
5e7b89431.pnpm --filter @object-ui/cli build: exit 0.dist/carries 0 hits each ofcommand("add"),render-performanceandbundle-size.pnpm --filter @object-ui/cli type-check(tsc --noEmit): exit 0.--listFilescoverscli.ts,commands/analyze.tsandcli-bin.test.ts. An earlier run caughtArray.at, which is not in this package's ES2020 lib; that is fixed.pnpm exec vitest run packages/cli/, plus the cross-package readers ofcli.ts,cli.mdx, the generator or the CLI bin:toc-anchor-parity,nested-page-children-11223,page-node-headings-drawn-11436,body-dialect-census,filter-builder-mirror-6939,check-node-esm-load,one-authority-per-exported-name-6273,markdown-test-inputs,check-pending-changeset-literals. Result:Test Files 34 passed (34),Tests 665 passed (665).node packages/cli/dist/cli.js add Inputexits 1 witherror: unknown command 'add', and the directory stays empty.pnpm docs:check-links:Links are valid across 17 scan roots.pnpm check:doc-fences: ✅node scripts/markdown-test-inputs.mjs --audit:115 candidate test files, all adjudicated; 82 declared entries, all present.pnpm check:control-bytes: ✅ OKpnpm check:new-line-citations:VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0node scripts/check-changeset-presence.mjs: exit 0.check-changeset-no-major.mjs: ✅.check-changeset-overwrite.mjs: ✅pnpm check:changeset-claims(report-only) names two pending changesets that mention a file this change touches.7658-toc-code-span-anchor-paritynamescli.mdxand the README for theaddheading its slug fix repaired; it is a past-tense account of that fix and is still true.7694-chart-series-chart-type-alias-refusalnamescli.tsas the home ofobjectui validate, which is still true.pnpm check:pending-changeset-literals,check:test-path-roots,check:unreferenced-sources,check:doc-typesandcheck:doc-example-ids: exit 0.turbo run lint, which runs the package'seslint srcagainst the rooteslint.config.js(the package has no config of its own). I ran that sameeslint src.--format jsoncounts 51 files linted, equal to the 51 tracked ts/js files underpackages/cli/src. It reports 0 errors and 5no-explicit-anywarnings, all in untouched files. The three edited source files read 0/0.parserOptionsorprojectService) and no import plugin, and no rule undereslint-rules/reads the filesystem. So this diff cannot move a verdict on a file it does not touch.cli.mdx, the README and the changeset are outside every eslintfilesglob. The repo-widepnpm lintis left to CI.check:doc-snippetsandcheck:doc-examples. Reason: PRECONDITION NOT MET (exit 2), because their scoped 34-package build was not run. The docs edit touches no ts or json fence; it removes one bash fence and one table.check:readme-exportsis NOT MEASURED for the same reason (unbuilt packages); none of its unjudged lines is inpackages/cli/README.md. The fullpnpm testis CI's.Acceptance notes
Named here and not changed, per the close-out ruling (partials are named, never implemented).
create pluginnever succeeds. The script path is resolved one directory too high from the CLI'sdist/:../../../create-plugin/dist/index.jslands on the repo root, or on a top-levelnode_modules/create-pluginin an install.@object-ui/create-pluginis not a dependency of@object-ui/clieither. Reported to the seat as a defect finding.lintandtestcannot succeed on the appdevgenerates. The temp app declares neither ESLint nor Vitest and carries no config and no tests. The tool's own error is relabelled ("Linting found issues", "Some tests failed"). Measured past the precondition with a hand-built.objectui-tmp, not one a realdevrun produced; said so in the report. Reported as a finding.studioruns the objectui console's dev server on its fixed port in a checkout, and refuses in a published install. The docs say it launches the designer against the local project. Reported as a finding.doctor: its help promises "fix", and nothing is written; its docs promise a Node version check, and none is printed; it exits 0 with an error-level finding.serve --no-openis declared and honoured, but the docs sayservehas no such flag.analyzewithoutdist/prints a warning and then "Analysis complete", exit 0.init -t noperefuses with exit 1 but leaves the empty project directory behind.devwithout--no-open, where no browser opener exists, prints Vite's rawspawn xdg-open ENOENT;serveprints a readable line for the same case.toc-anchor-parity.test.tsx(packages/plugin-markdown) keeps anaddheading row inLIVE_SHAPESwhosewherenamescli.mdxand the README. That attribution is now stale; the row still exercises the slugger on its literal. It is outside this card's file surface.### objectui NAMEheadings to the same list fromcli-bin.test.tsredsmarkdown-test-inputs --auditunless the test gains a row in that script'sADJUDICATEDledger. That file is outside this card's file surface, so the docs half is left to the seat (one ledger row plus about ten test lines). TheSUBCOMMANDScomment says the docs headings are kept in step by hand.Implemented by the os-dev agent dispatched by the
domain:uiseat 1 PM, sessionhttps://claude.ai/code/session_01YLg8XqWGJ785fwQ5v4pH37.Generated by Claude Code