Skip to content

fix(cli): drop the never-loaded oclif.plugins entries and correct the text that says os plugins works - #21306

Merged
objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-21285-drop-dead-oclif-plugins
Oct 2, 2026
Merged

objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-21285-drop-dead-oclif-plugins

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #21285
Clause-②: no

What this does

packages/cli/package.json listed @oclif/plugin-help and @oclif/plugin-plugins under oclif.plugins, but both were only devDependencies. oclif loads an oclif.plugins entry only when the same name is in dependencies, so neither ever loaded. This PR:

  • removes the oclif.plugins array (no other oclif key changes);
  • removes the two devDependencies (no consumer remains, see H1) and regenerates pnpm-lock.yaml with pnpm install --lockfile-only;
  • corrects every published text that described the array or said os plugins works (per-site table below);
  • rewrites test/plugin-commands.test.ts so it pins the new state instead of the dead array;
  • adds .changeset/21285-drop-dead-oclif-plugins.md (patch, @objectstack/cli).

Maintainer ruling (verbatim):

同意:oclif.plugins: 里面那两个插件只装在 devDependencies,所以从来没加载过,os help 和 os plugins 都不是可用命令。我建议删掉这两条配置。

packages/spec/** is untouched. That includes cli-extension.zod.ts and its generated page content/docs/references/kernel/cli-extension.mdx, which still say os 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.js with NODE_ENV unset and OCLIF_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-marketplace and frobnicate;
  • TOPIC --help for each of the 32 root-level topics;
  • an @oclif/core Config.load dump: loaded plugins, all 65 command ids and all 75 topics.

That is 114 files per reading.

Reading Tree Result
before base 748b24072, unmodified os --help: 12 topics + 22 commands. help, plugins and plugins install exit 2 with command ... not found. Plugins loaded: @objectstack/cli only.
positive control base, with the two plugins added to dependencies (mutation through scripts/ablation-replace.mjs, restore proven: blob == HEAD, git diff HEAD empty) differs in 9 files, plus 6 new ones. os help exits 0. os plugins exits 0 ("No plugins installed."). The command table gains help and 10 plugins:* ids (65 to 76). The root help gains the plugins topic and the help and plugins commands. So the reading catches a real difference.
after cc13e2532 (array and devDependencies removed, lockfile regenerated) and a593c8c62 (CLI rebuilt) diff -r against before: empty, all 114 files, same sha256 over the concatenation (338e1f0f...5c6f38)
final heads 3c8442fc0 and a1e72918c (after merging main) identical, except the two version strings 17.5.0 to 17.6.0. Those come from main's Version Packages merge, not from this diff.

Hypotheses

  • H1 (no consumer): holds. Both devDependencies are removed. git grep finds plugin-help and plugin-plugins only in these places:
    • the array and the devDependencies block;
    • comments in bin/run.js, doctor.ts and doctor-deprecation-hint-commands.test.ts;
    • docs text;
    • the one test assertion.
      No import, require, script, fixture or other importer names them. In the lockfile, only the packages/cli importer referenced them.
  • Lockfile comparison, measured against both merge bases (748b24072 and 5a9292e6f), with the same result:
    • 14 package entries and 14 snapshots are removed and 0 added. Every removed entry is in the transitive closure of the two plugins: @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.0 and yarn@1.22.22.
    • All 1379 kept snapshots and packages are byte-identical.
    • DOWN count: 0. Four names lose only a second, plugin-only version: isexe 3.1.5, lru-cache 10.4.3, path-key 4.0.0 and which 4.0.0. The versions every other consumer resolves are unchanged.
  • H2 (only dependencies count): holds. @oclif/core 5.1.2 lib/config/plugin-loader.js loadCorePlugins calls findMatchingDependencies(rootPlugin.pjson.dependencies ?? {}, corePlugins). Measured three ways:
    • the before/after identity above;
    • the positive control above;
    • a standalone fixture root on 5.1.2: with @acme/plugin-marketplace listed in oclif.plugins plus dependencies, marketplace:search loads and runs. Moved to devDependencies, nothing loads.
  • H3 (the site list is complete): holds, with no new site. The PM's grep was re-run, then widened to plugins install/uninstall/update/link/... in space and colon forms, every @oclif/plugin-*, and os|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 (the plugins link sentence, covered with the run.js site), the phrase "ObjectStack plugins" (prose, not a command), and one CHANGELOG.md line.
  • H4 (the build-your-own-distribution route stays true): holds. Decided from the loader, not the old text. Fixture distribution roots on @oclif/core 5.1.2 Config.load:
    • a root listing @acme/plugin-marketplace in both oclif.plugins and dependencies loads marketplace:search and runs it;
    • a root listing both @objectstack/cli and the extension that way loads 66 commands (this CLI's 65 plus marketplace:search);
    • devDependencies-only loads nothing.

Per-site conclusions

Site Conclusion
packages/cli/package.json oclif.plugins + 2 devDependencies Changed: removed.
pnpm-lock.yaml Changed: regenerated by the tooling, comparison above.
content/docs/plugins/index.mdx Step 3 callout (lines 400-408) Changed. Its reason ("plugin-plugins sits in devDependencies") became false. It now says: no plugin manager; os plugins ... and os help are not commands; os --help is the help entry; the distribution route, kept because H4 holds; and the loader's dependencies-only rule.
same page, "Once loaded, the new commands appear in os --help" Already true: true of the distribution's own os --help (H4 fixture).
packages/cli/README.md ### os plugins (oclif) Changed. Now ### os plugins and os help (not commands): no plugin manager; each exits 2; use os --help; link to the plugin-system section.
packages/cli/README.md ## oclif Plugin System (intro, step 3, "Install and use", comparison row) Changed. os plugins install is gone. Step 3 and the example load through an os distribution listing the plugin in oclif.plugins + dependencies.
packages/cli/bin/run.js:84-97 Changed. The reasoning now names "no plugin manager, no oclif.plugins, no @oclif/plugin-plugins dependency" instead of the devDependencies placement. The 34-entry count is re-measured (12 topics + 22 commands).
packages/cli/src/commands/doctor.ts:2377-2380 Changed (comment): "no plugin supplies one (the package declares no oclif.plugins)".
packages/cli/src/commands/doctor-deprecation-hint-commands.test.ts:15 Changed (comment), same restatement.
packages/cli/test/plugin-commands.test.ts Rewritten to pin the new state. oclif.plugins is 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) Changed. The source line now reads "no oclif.plugins at all, no plugin manager, no help command and no not-found plugin, so unknown commands hard-error". Revision 1 to 2, with a history entry. pnpm check:platform-checklist is green.
packages/spec/src/kernel/cli-extension.zod.ts:18 and content/docs/references/kernel/cli-extension.mdx:21 Out of scope. Spec-lane, carried by #21286, untouched as the card directs.
packages/cli/CHANGELOG.md:1362 (the "plugins linked TypeScript plugin ... @oclif/plugin-plugins sits in devDependencies" entry) Out of scope. Release-owned, and true of the version it shipped with. Not edited in a code PR.
"ObjectStack plugins" hits (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), root CHANGELOG.md:1367 Not a site: a case-insensitive match on prose, not an os plugins command.

Tests and gates (final head a1e72918c unless noted)

  • Gates: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands at a1e72918c derives 106 commands. All 106 were run with each exit code captured before any pipe, and all 106 exit 0. --ran reconciles them: 106 derived famil(ies) accounted for, 106 run, 0 NOT-MEASURED.

    • The same 106 were also all green at 3c8442fc0.
    • At 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-loads and check:i18n-coverage. check:slot-lookup hit an ENOENT on a temp fixture that a concurrent CLI test deleted. All 4 were green on re-run.
  • @objectstack/cli unit tier (vitest run --project unit --maxWorkers=2): 243 files and 3440 tests passed at 3c8442fc0, and again at a593c8c62. The two edited test files were re-run at a1e72918c: 2 files and 16 tests passed. The last merge (3c8442fc0 to a1e72918c) brought 4 main commits, none of which touch packages/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 HEAD empty):

    • re-adding the oclif.plugins array: declares no oclif.plugins goes red (expected [ '@oclif/plugin-help', ... ] to be undefined);
    • adding @oclif/plugin-plugins to devDependencies: depends on no @oclif/plugin-* package goes red.
  • pnpm --filter @objectstack/cli typecheck (at a593c8c62): exit 0. plugin-commands.test.ts is in tsconfig.test.json's program and doctor-deprecation-hint-commands.test.ts in tsconfig.json's (--listFilesOnly).

  • --project integration (at a593c8c62, run because the diff touches bin/): 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 base 748b24072, built (59/59 turbo cache), in a separate worktree. Cause: tsx 4.23.15's ESM API registers ./esm/index.mjs relative to dist/esm/api/index.cjs. That resolves to the nonexistent dist/esm/api/esm/index.mjs (oclif:config:ts-path debug: "Could not find tsx. Skipping tsx registration"), so the control's trap never arms. It is unrelated to oclif.plugins. The integration tier was not re-run at the final head: the incoming main commits touch no packages/cli/bin or src file. It is declared to CI.

  • Lint, narrowed and measured: eslint --no-inline-config --format json over the 4 touched JS/TS files reports 4 files, 0 errors and 0 warnings. The other 6 touched files (.md, .mdx, .json, .yaml) are outside eslint.config.mjs's files globs. The config enables no type-aware linting (no parserOptions.project), so this diff cannot move an untouched file's verdict. The full pnpm lint is CI's.

Acceptance notes (not filed here; for the seat)

  • packages/cli/README.md ### Global says -v, --version and -h, --help. Measured on the built entry: os -h and os -v exit 2 with command -h not found and command -v not found. Only --help and --version work. This is pre-existing and unrelated to this diff, so it is reported, not fixed.
  • packages/cli/README.md ### Plugin Management says "There is no os plugin command group in v1". os plugin build|sign|publish is registered: the plugin topic is in os --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.
  • The tsx 4.23.15 ESM-API defect above. It reds that integration control leg on base too, so it will red packages/cli's integration tier wherever that file runs.

Generated by Claude Code

claude added 5 commits October 2, 2026 02:03
…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>
@github-actions github-actions Bot added size/m dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation tests tooling labels Oct 2, 2026
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/cli, touching 1 documentable anchor(s). ⚠️ 3 changed file(s) yielded no anchor (packages/cli/README.md, packages/cli/bin/run.js, packages/cli/package.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

9 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/automation/flows.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))
  • content/docs/automation/jobs.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))
  • content/docs/data-modeling/indexing.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))
  • content/docs/deployment/cli.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))
  • content/docs/deployment/environment-variables.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))
  • content/docs/deployment/production-readiness.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))
  • content/docs/protocol/backward-compatibility.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))
  • content/docs/protocol/kernel/config-resolution.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))
  • content/docs/protocol/kernel/http-protocol.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))

⛔ 2 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v16.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))
  • content/docs/releases/v17/17-5.mdx (via os doctor (command, read off packages/cli/src/commands/doctor.ts))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/cli/README.md, packages/cli/bin/run.js, packages/cli/package.json) — pages documenting those are invisible to this run
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 26 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 393ae878d3d52fe843c56b4621c004b934dcf853 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 41bc43f7c37ebe067058dfd357bf604f9731b5be — the merge of head a1e72918c3e9cf7764709af152072dcda2d250f6 into base 393ae878d3d52fe843c56b4621c004b934dcf853, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# 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

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 393ae878d3d52fe843c56b4621c004b934dcf853 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Review: ACCEPT, PR #21306 (head a1e72918c3), card #21285

Reviewed 2026-10-02T03:43Z by the PM seat (session_018gA1pE6eJtwHhqx72G8U9X) against GitHub and the branch.

Verified at the head:

  • Shape. The PR is a draft against main. Its body opens Fixes #21285, with no other closing keyword. The assignee is os-bill, and the PR is subscribed to the dispatching session. The history is two commits (cc13e2532 removal, 4a532ac75 text) plus three clean merges of main; nothing was rebased, amended or force-pushed.
  • Scope. 10 files, +101/−244. check-governed-merges reads NOT governed, 345 changed lines. Nothing under packages/spec/**: the cli-extension TSDoc sentence stays with spec(kernel): the cli-extension.zod.ts TSDoc tells plugin authors to os plugins install, a command os has never registered #21286, as the card rules.
  • Manifest. packages/cli/package.json drops exactly the oclif.plugins array and the two devDependencies lines. No other oclif key changes.
  • Lockfile against the merge base 4e530568a.
    • 14 names change, and every change is a removal. Nothing is added and no version moves.
    • All 14 are in the two plugins' transitive closure. isexe, path-key and which each lose only their newer, plugin-only copy (3.1.5, 4.0.0, 4.0.0); the older copy every remaining consumer resolves to stays. No consumer resolves to a lower version.
  • Text. Every step-4 site now states the shipped fact: no plugin manager; os plugins … and os help are not commands; os --help is the help entry. The build-your-own-distribution route is kept, because the os-dev's H4 fixture shows oclif loads a plugin listed in both oclif.plugins and dependencies, and nothing when it is listed in devDependencies only. The doctor.ts edit is comment-only (0 non-comment lines), so the nine pages the drift check lists for os doctor are unaffected. The only os plugins text left in content/docs is the corrected callout and the generated spec page that spec(kernel): the cli-extension.zod.ts TSDoc tells plugin authors to os plugins install, a command os has never registered #21286 carries.
  • The guard is rewritten, not deleted. test/plugin-commands.test.ts now pins oclif.plugins undefined and no @oclif/plugin-* in any dependency field. Each failure message names the texts that must change with it. The os-dev's reverse verification turned both pins red by re-adding the array and the dependency.
  • Behaviour. The os-dev's before/after reading covers 114 files of stdout, stderr and exit codes: root help, help, plugins, plugins install …, an unknown command, every root topic's --help, and the Config.load plugin/command/topic dump. Before and after are byte-identical. The positive control (both plugins added to dependencies) differs in 9 files and adds 6, so the reading would have caught a change.
  • Changeset. .changeset/21285-drop-dead-oclif-plugins.md is a patch for @objectstack/cli. It says nothing changes for an operator, and corrects the README's old claim.

Still owed: the diff touches content/docs/** and .changeset prose, both contract-review surfaces. The maintainer's 2026-10-01 waiver covered #21212 only. The PR carries needs:contract-review until a CONTRACT_REVIEW_TIER record for this head reads PASS. Then, with every check green or an expected skip, it is flipped to ready and queued.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: a1e72918c3e9cf7764709af152072dcda2d250f6
Local-runs: none

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 main at merge base 4e530568a), and the check-runs on the head. The remote tip of claude/issue-21285-drop-dead-oclif-plugins is this head; head repo equals base repo, so this is a delivery, not a fork proposal.

① Derived judgments

Every accept-set and public-surface change the diff implies, each named right or wrong:

  1. packages/cli/package.json drops the oclif.plugins array and nothing else in oclif. The block at the head keeps bin, dirname, commands (pattern, ./dist/commands), hooks.preparse and topicSeparator. RIGHT. Not a public-surface change: both names sat only in devDependencies, and oclif's core-plugin loader matches oclif.plugins names against dependencies alone, so nothing loaded before and nothing loads after; the same rule governs a distribution that loads @objectstack/cli as a child plugin, so no transitive surface moves either. The dev's reading covers 114 files (root help, help, plugins, plugins install …, an unknown command, every root topic's --help, the Config.load plugin/command/topic dump) and is byte-identical before and after; its positive control (both plugins ablated into dependencies, restore proven) differs in 9 files and adds 6, so the instrument sees the change it reports absent. RIGHT.
  2. The two devDependencies go with the array (card step 2, H1). Re-checked at the head: git grep for plugin-help, plugin-plugins and oclif.plugins over the whole tree finds only the changeset, the corrected texts, the rewritten test's own prose, the two spec-lane sites spec(kernel): the cli-extension.zod.ts TSDoc tells plugin authors to os plugins install, a command os has never registered #21286 carries, and release-owned CHANGELOG lines. No import, require, script or fixture. RIGHT.
  3. pnpm-lock.yaml acceptance met. The net diff has zero added lines; every removed line is a whole block: the packages/cli importer's two entries, 14 packages: resolution blocks and 14 snapshots: blocks, all inside the two plugins' closure (@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.0, yarn@1.22.22). No kept snapshot's dependency line changes, so no consumer's resolution moves and no version goes down: isexe@2.0.0, lru-cache@11.5.3, path-key@3.1.1 and the older which stay as the versions every remaining consumer resolves. A pure subtree removal is the shape a tooling regeneration leaves, not a hand edit; Validate Package Dependencies is green. RIGHT.
  4. test/plugin-commands.test.ts is rewritten, not deleted (card step 4). It pins pkg.oclif.plugins undefined and no @oclif/plugin-* name across dependencies, optionalDependencies, peerDependencies and devDependencies; keeps the pattern-discovery and bin pins; and each failure message names the texts that must change with it. The dev's reverse verification turned both pins red through ablation with the restore proven. RIGHT.
  5. Every step-4 text site is handled and none is skipped silently. content/docs/plugins/index.mdx callout restated (no plugin manager; os plugins … and os help exit 2; os --help is the entry; the distribution route kept because H4 was decided from the loader, with the dependencies-only rule stated). packages/cli/README.md: the ### os plugins section and the four ## oclif Plugin System spots (intro, step 3, the "Install and use" example, the comparison row) no longer advertise os plugins install. bin/run.js:84-97 reasoning restated. doctor.ts and doctor-deprecation-hint-commands.test.ts are comment-only. docs/qa/platform-checklist/areas/cli.json source line restated, revision 1 to 2 with a history row. The residual grep at the head leaves os plugins install only in packages/spec/src/kernel/cli-extension.zod.ts:18 and its generated page content/docs/references/kernel/cli-extension.mdx:21 (spec(kernel): the cli-extension.zod.ts TSDoc tells plugin authors to os plugins install, a command os has never registered #21286, untouched as the card directs; the generated page is an os-regen path and correctly stays out of this diff) and in release-owned CHANGELOG entries. "Once loaded, the new commands appear in os --help" (index.mdx) reads true of the distribution's own binary. The PR body carries a conclusion per site, out-of-scope ones with the reason. RIGHT.
  6. The bin/run.js count "34 entries, 12 topics and 22 commands" checked against the command tree at the head: 12 topic directories; 20 root command files plus migrate/index.ts plus the root alias g on generate (oclif lists an alias as its own root entry) = 22. RIGHT.
  7. doctor.ts is comment-only, so the nine os doctor pages the docs-drift check lists are unaffected; no content/docs/references/** or content/docs/releases/** is touched. RIGHT.
  8. Governed surfaces: none. No docs/adr/**, docs/NORTH-STAR.md, .claude/**, skills/**, AGENTS.md or CLAUDE.md in the file list; Governed Surface Queue Guard green; 345 changed lines, far under the 5,000 ceiling. The review obligation comes from content/docs/** and .changeset prose, and this record discharges it. RIGHT.
  9. packages/spec untouched, so no generated artifact is owed. Console Pin Gate skipped on its path filter, and nothing removed here is importable by the pinned sibling (a devDependency and a manifest field, not an export). RIGHT.

Check-runs on the head (latest run per name, all concluded; ci-failure.mjs --sha reads GREEN, exit 0): 32 success, 0 failed, 0 cancelled. All seven required contexts are green: Lint & Repo Gates, TypeScript Type Check, Test Core (and its six shards), Dogfood Regression Gate (and its three shards), Build Core, Temporal Conformance (live PG + MySQL), Governed Surface Queue Guard. Also green: Build Docs, Check Changeset, Check Documentation Links, Dogfood Verify CLI, Flag docs affected by code changes, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, Spec property liveness, The card this PR closes must claim this branch, the four Type Check · legs, Validate Package Dependencies, filter. Four skipped, each expected and not a failure: Auto Label and Check PR Size (the labeled-event re-run skipped; the push run of each had concluded success), Console Pin Gate (path filter: no console or objectui path in the diff), Packed-tarball smoke (opt-in) (not opted in).

② Semver level

.changeset/21285-drop-dead-oclif-plugins.md declares '@objectstack/cli': patch. What publishes: the tarball's package.json (minus oclif.plugins) and its README. Operator behaviour is unchanged (item 1), and nothing an author can write is removed or renamed (not a spec key, an export or a config field), so no migration text, no tombstone and no ADR-0087 marker is owed; the body states the operator-facing fact and the README correction. patch, not skip-changeset: a released package's manifest and README change, which is exactly the card's step 5. RIGHT.

The PR body's declaration line reads Clause-②: no, repeated in the changeset body, with no arm. The diff widens no accept set and no public surface, and narrows none either (identical command table, topics and help before and after), so a bare no is the correct reading. Check Changeset green. RIGHT.

③ Boundary flags

open_questions: none declared. The dev's six declared deviations, each answered:

  1. Commit trailers use the repo's model-free pair (Claude-Session plus Co-authored-by: Claude) rather than the harness reminder's model-named form. Verified on cc13e2532 and 4a532ac75; AGENTS.md is this repo's source of truth and its pre-push hook refuses a model id in that pair. Accepted, no action.
  2. and 3. The integration tier ran at a593c8c62 and the full unit tier at 3c8442fc0, with only the two edited files re-run at the head. The dev's flag says the later merges of main touched no packages/cli file; precisely, one did, the Version Packages merge 617f25f8a (the package.json version 17.5.0 to 17.6.0 and CHANGELOG.md), which the dev's own help reading already accounts for, and no source, bin or test file. Test Core 1/6 to 6/6 on this head are the authority and are green. Accepted.
  3. Three merges of main with no regen pending: pnpm-lock.yaml is not an os-regen path and no os-regen path is in the diff; Validate Package Dependencies green. Accepted.
  4. A busy-poll wait during a build: process cost only, no effect on the diff. Noted.
  5. Zero label writes by the dev; needs:contract-review was set by the seat's ACCEPT act. Noted.

out_of_scope_findings, three, each escalated to the seat (none in the card's scope, none blocks this PR):

Implemented-by: claude/issue-21285-drop-dead-oclif-plugins
Reviewed-by: session_018gA1pE6eJtwHhqx72G8U9X

VERDICT: PASS

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 2, 2026 04:13
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 2, 2026
Merged via the queue into main with commit dabd1c5 Oct 2, 2026
45 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-21285-drop-dead-oclif-plugins branch October 2, 2026 04:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cli: drop the never-loaded @oclif/plugin-help and @oclif/plugin-plugins from oclif.plugins, and correct every published text that says os plugins works

2 participants