Skip to content

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 #21285

Description

@objectstack-fleet

Filing-gate class: ③ maintainer-directed task.
Body last written 2026-10-02T01:43Z: the spec TSDoc sentence was split out to the spec-lane card #21286; this card does not touch packages/spec.
Routing: the maintainer direct-dispatch channel (session_018gA1pE6eJtwHhqx72G8U9X) routes this card to domain:cli and area:devpath; triage grades the priority.
Acting reader: the maintainer direct-dispatch session (Seat: domain:devx#3), which dispatches one os-dev.
Dedup: I listed 558 objectstack issues and PRs over REST (open, plus the most recently updated closed) and grepped titles and bodies for oclif.plugins, os plugins install, plugin-plugins and plugin-help. The only hits are today's version bump (#21125 / PR #21212) and the Dependabot PRs it replaced (#21031, #21035). None removes the entries.

Maintainer ruling (verbatim)

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

Given in session session_018gA1pE6eJtwHhqx72G8U9X on 2026-10-02, in reply to the seat's recommendation after #21212 landed.

Measured (at origin/main c7396f1a9)

  • packages/cli/package.json → oclif.plugins lists @oclif/plugin-help and @oclif/plugin-plugins. Both packages appear only in devDependencies (^7.0.2, ^7.0.3).
  • oclif's core-plugin loader matches oclif.plugins names only against dependencies, so neither plugin ever loads:
  • Text that names this configuration or the commands it was meant to supply:
    • content/docs/plugins/index.mdx:400-408;
    • packages/cli/README.md ### os plugins (oclif) (about line 206) and ## oclif Plugin System (about lines 216-277);
    • packages/cli/bin/run.js:84-94;
    • packages/cli/src/commands/doctor.ts:2377-2380 and doctor-deprecation-hint-commands.test.ts:15;
    • packages/cli/test/plugin-commands.test.ts:22-23;
    • docs/qa/platform-checklist/areas/cli.json:658;
    • packages/spec/src/kernel/cli-extension.zod.ts:17-18, plus its generated page content/docs/references/kernel/cli-extension.mdx:21 (carried by spec(kernel): the cli-extension.zod.ts TSDoc tells plugin authors to os plugins install, a command os has never registered #21286, not this card).

What to do

  1. Remove the plugins array from oclif in packages/cli/package.json. Change no other oclif key.
  2. The two devDependencies exist only to back that array.
  3. Behaviour acceptance: nothing an operator sees changes, because the plugins never loaded.
    • Show os --help and the full command list byte-identical before and after.
    • Take a positive control first: show that the reading would catch a real difference.
  4. Fix the published text this change makes false or touches. Each site gets a conclusion in the PR body: changed; already true (with evidence); or out of scope (with the reason). No site is skipped silently.
    • content/docs/plugins/index.mdx callout. Its stated reason ("lists @oclif/plugin-plugins under oclif.plugins, but the package sits in devDependencies") becomes false. Restate the fact as it will be: @objectstack/cli ships no plugin manager, os plugins … and os help are not commands, and os --help is the help entry. Keep the build-your-own-distribution route only if it is still true.
    • packages/cli/README.md: ### os plugins (oclif) and ## oclif Plugin System describe os plugins install/uninstall/update as available, which is false. Correct them.
    • packages/cli/bin/run.js:84-94: its reasoning names the devDependencies placement. Restate it to the new fact.
    • doctor.ts:2377-2380 and doctor-deprecation-hint-commands.test.ts:15 say "neither bundled plugin … supplies one". After this change there is no bundled plugin. Restate.
    • test/plugin-commands.test.ts:22-23 asserts both entries are present. Rewrite it to pin the new truth (no oclif.plugins, no plugin manager). ⛔ Do not just delete the guard.
    • docs/qa/platform-checklist/areas/cli.json:658: the evidence text names the array's contents.
    • ⛔ Not this card: packages/spec/src/kernel/cli-extension.zod.ts:17-18 and its generated page content/docs/references/kernel/cli-extension.mdx:21 ("or users install it via os plugins install <pkg>"). That sentence sits on the spec contract surface, which is spec-lane work. It is carried by spec(kernel): the cli-extension.zod.ts TSDoc tells plugin authors to os plugins install, a command os has never registered #21286. Leave both files untouched.
  5. Changeset: a patch for @objectstack/cli (its published manifest's oclif field and its README). Not skip-changeset.

Out of scope (a separate maintainer question)

With no plugin manager and no listed plugins, the CLI-extension protocol in cli-extension.zod.ts (OclifPluginConfig) describes a capability no os user can reach today, short of building their own os distribution. Whether to deliver it (a plugin manager as a real dependency) or retire the protocol (ADR-0049 enforce-or-remove) goes to the maintainer separately. ⛔ This card corrects false sentences only. It changes no schema or export.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    dependenciesPull requests that update a dependency file
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    and removed on Oct 2, 2026
  2. objectstack-fleet commented on Oct 2, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 4
    Session: session_018gA1pE6eJtwHhqx72G8U9X
    Account: os-bill (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-21285-drop-dead-oclif-plugins
    Worktree: objectstack-issue-21285
    Domain: domain:cli
    Seat: domain:devx#3 (the maintainer's direct-dispatch session; it holds no seat post, so #3 collides with no post: objectstack devx seats 1 and 2 are #6023 and #20163)
    Provenance:


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 2, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 21285,
    "status": "done",
    "branch": "claude/issue-21285-drop-dead-oclif-plugins",
    "pr": "#21306",
    "session": "session_018gA1pE6eJtwHhqx72G8U9X",
    "premise_still_valid": true,
    "summary": "Removed the oclif.plugins array from packages/cli/package.json. It named @oclif/plugin-help and @oclif/plugin-plugins, which were only devDependencies, so oclif's loadCorePlugins never matched them. No other oclif key changed. H1 held: there is no consumer, so both devDependencies were removed and the lockfile was regenerated with pnpm install --lockfile-only. Every text site now states the new fact: no plugin manager; os plugins and os help are not commands; os --help is the help entry; an extension loads through an os distribution that lists it in both oclif.plugins and dependencies (H4 measured true). test/plugin-commands.test.ts was rewritten to pin that state, and a patch changeset was added. The claim was verified first: the newest Claim (comment 5944050007) names this branch. packages/spec was left untouched (#21286).",
    "pr_subscribed": "Subscribed to activity on #21306. Comments, CI status changes, reviews, and other PR events will now be delivered into this conversation as wake reason=external-event envelopes.",
    "h1_verdict": "Holds; both devDependencies were removed. Searched at base 748b240: git grep for plugin-help and plugin-plugins over imports, require, scripts and fixtures. The names appear only in the oclif.plugins array and devDependencies, in comments (bin/run.js:89, doctor.ts:2379, doctor-deprecation-hint-commands.test.ts:15), in docs text, and in one test assertion (plugin-commands.test.ts:22-23). In pnpm-lock.yaml, only the packages/cli importer referenced them. No script reads oclif.plugins: grep over the oclif.X readers finds bin, commands and topicSeparator readers only.",
    "help_reading": "Script: node packages/cli/bin/run.js with NODE_ENV unset and OCLIF_COLUMNS=120, run from an empty cwd. Runs: --help; help; plugins; plugins install @acme/plugin-marketplace; frobnicate; TOPIC --help for each of the 32 root topics; and an oclif Config.load dump (plugins, 65 command ids, 75 topics). That is 114 files of stdout, stderr and exit codes. BEFORE (base 748b240): root help 12 topics + 22 commands; help, plugins and plugins install exit 2 with 'command ... not found'; loaded plugins: @objectstack/cli only. POSITIVE CONTROL (base with both plugins added to dependencies via ablation-replace, restore proven blob==HEAD and git diff HEAD empty): differs in 9 files plus 6 new ones; help exits 0; plugins exits 0; the command table goes 65 to 76 (help plus 10 plugins:* ids); root help gains the plugins topic. AFTER (cc13e25, and a593c8c rebuilt): diff -r empty over all 114 files; sha256 of the concatenation 338e1f0f...5c6f38 on both. FINAL HEADS 3c8442f and a1e7291: identical except the two VERSION strings 17.5.0 to 17.6.0, which come from main's Version Packages merge.",
    "h2": "Holds. In @oclif/core 5.1.2, lib/config/plugin-loader.js loadCorePlugins = findMatchingDependencies(rootPlugin.pjson.dependencies, oclif.plugins). Also measured on a standalone fixture root: listed in dependencies, marketplace:search loads and runs; listed in devDependencies, nothing loads.",
    "h3": "Holds; no site was missing. The PM grep was re-run, then widened to plugins install/uninstall/update/link/inspect/reset (space and colon forms), @oclif/plugin-, and os or objectstack plugins/help. The widened forms add only three hits: bin/run.js:87 (the plugins link sentence, covered by the run.js site), case-insensitive 'ObjectStack plugins' prose (6 files, not a command), and root CHANGELOG.md:1367 'Affected plugins updated' (unrelated). Release-owned: packages/cli/CHANGELOG.md:1362 restates the devDependencies placement. It was true of the version it shipped with and is not edited in a code PR.",
    "h4": "Holds, decided from the loader. A fixture root listing @acme/plugin-marketplace in both oclif.plugins and dependencies loads marketplace:search and runs it. A root listing @objectstack/cli plus the extension the same way loads 66 commands (this CLI's 65 plus marketplace:search). A devDependencies-only listing loads nothing. The distribution route was therefore kept in both the docs and the README.",
    "sites": [
    "packages/cli/package.json oclif.plugins + 2 devDependencies: changed (removed)",
    "pnpm-lock.yaml: changed (tooling regeneration)",
    "content/docs/plugins/index.mdx:400-408 callout: changed (no plugin manager; os plugins/os help not commands; os --help is the entry; distribution route kept per H4; dependencies-only loader rule)",
    "content/docs/plugins/index.mdx '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; exit 2; use os --help)",
    "packages/cli/README.md ## oclif Plugin System (intro, step 3, Install and use, comparison row): changed (load through an os distribution listing the plugin in oclif.plugins + dependencies)",
    "packages/cli/bin/run.js:84-97: changed (reason is now no plugin manager / no oclif.plugins; 34 entries re-measured as 12 topics + 22 commands)",
    "packages/cli/src/commands/doctor.ts:2377-2380: changed (comment)",
    "packages/cli/src/commands/doctor-deprecation-hint-commands.test.ts:15: changed (comment)",
    "packages/cli/test/plugin-commands.test.ts: rewritten (pins oclif.plugins undefined and no @oclif/plugin-
    in any dependency field; discovery and bin pins kept)",
    "docs/qa/platform-checklist/areas/cli.json:658: changed (source line; item revision 1 to 2 with history entry; check:platform-checklist green)",
    "packages/spec/src/kernel/cli-extension.zod.ts:18 and content/docs/references/kernel/cli-extension.mdx:21: out of scope (spec lane, #21286; untouched)",
    "packages/cli/CHANGELOG.md:1362: out of scope (release-owned; true when released)"
    ],
    "lockfile": "Measured against both merge bases (748b240 and 5a9292e). 14 package entries and 14 snapshots removed, 0 added. All 14 are in the two plugins' transitive 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 and yarn@1.22.22. All 1379 kept snapshots and packages are byte-identical, and only the packages/cli importer changed. DOWN count 0: isexe, lru-cache, path-key and which each lose only a second, plugin-only version. pnpm install --frozen-lockfile exits 0 after each merge of main.",
    "tests": "@objectstack/cli unit tier (vitest run --project unit --maxWorkers=2, under os-verify-lock): 243 files and 3440 tests passed at 3c8442f and again at a593c8c. The two edited test files were re-run at a1e7291: 2 files, 16 tests passed. Typecheck (pnpm --filter @objectstack/cli typecheck) at a593c8c: 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). Integration tier (--project integration, run because bin/ is touched) at a593c8c: 69/70 files and 601/603 tests passed. The 1 failure, published-entry-node-env-source-reroute.test.ts 'CONTROL: neutralising the declaration in the child reproduces the card verbatim', also fails on base 748b240, built 59/59 cached in a separate worktree, with the same result (1 failed, 4 passed). Cause: tsx 4.23.15's ESM API registers ./esm/index.mjs relative to dist/esm/api/index.cjs, and that path does not exist ('Could not find tsx' in oclif:config:ts-path debug). It is unrelated to this diff. Reverse verification, done with the fix committed and each mutation made through ablation-replace with its restore proven (blob==HEAD, git diff HEAD empty): re-adding the oclif.plugins array turned 'declares no oclif.plugins' red; adding @oclif/plugin-plugins to devDependencies turned 'depends on no @oclif/plugin-* package' red. The direction was the expected red both times. Lint, narrowed: eslint --no-inline-config --format json on the 4 touched JS/TS files reports 4 files, 0 errors, 0 warnings. The other 6 touched files are outside eslint.config.mjs's files globs (line 971). The config enables no parserOptions.project (its only mention is the comment at line 328), so this diff cannot move an untouched file's verdict.",
    "gates": "dispatch-gates --repo objectstack-ai/objectstack --commands at a1e7291 (merge base 4e53056): 106 commands, all run, exit codes captured before any pipe, all 106 exit 0. --ran: '106 derived famil(ies) accounted for, 106 run, 0 NOT-MEASURED'. The same 106 were also all green at 3c8442f (merge base 5a9292e). At a593c8c, 4 needed re-runs and were then green: three refused with exit 3 (PREREQUISITE NOT MET) before builds (spec check:skill-examples, check:dual-build-cjs-loads, check:i18n-coverage), and check:slot-lookup hit an ENOENT on a temp fixture a concurrent CLI test deleted. CI state: in_progress (PR just opened).",
    "line_budget": "n/a: no skills/** or governed ledger touched; the diff is 10 files, +101/-244 vs main",
    "files_changed": [
    ".changeset/21285-drop-dead-oclif-plugins.md",
    "content/docs/plugins/index.mdx",
    "docs/qa/platform-checklist/areas/cli.json",
    "packages/cli/README.md",
    "packages/cli/bin/run.js",
    "packages/cli/package.json",
    "packages/cli/src/commands/doctor-deprecation-hint-commands.test.ts",
    "packages/cli/src/commands/doctor.ts",
    "packages/cli/test/plugin-commands.test.ts",
    "pnpm-lock.yaml"
    ],
    "deviations": [
    "Commit trailers use the model-free pair (Claude-Session + Co-authored-by: Claude) that AGENTS.md prescribes, not the harness reminder's model-named Co-Authored-By. The PR footer uses the AGENTS.md session-URL form.",
    "The integration tier ran at a593c8c, not at the final head. The two later merges of main touched no packages/cli file, so it is declared to CI.",
    "The full unit tier ran at 3c8442f. At a1e7291 only the two edited test files were re-run; the 4 incoming main commits touch no packages/cli path.",
    "main moved twice while verifying, so the branch merged it twice (a593c8c, 3c8442f, a1e7291), each a clean merge with no regen pending. Gates were re-derived and re-run at each final head. Any later main movement is not merged.",
    "A wait for a build step used a shell loop that busy-polled for about 3.5 minutes instead of tail --pid. It was a CPU-only cost and was not repeated.",
    "Labels: zero label writes. The dispatch named none, and skip-changeset does not apply because a patch changeset is present. The PR carries labeler-bot labels: documentation, dependencies, size/m, tests, tooling."
    ],
    "mcp_calls": "1: mcp__claude-code-remote__subscribe_pr_activity (session subscription, not a GitHub write). 0 GitHub MCP calls.",
    "api_writes": "3, each one relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]): (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls, giving #21306, read-back 12709 bytes sent and 12709 stored, identical; (2) assign os-bill, POST /repos//issues/21306/assignees, read-back matches; (3) this os-dev-report comment, POST /repos//issues/21285/comments. Plus git pushes (not REST).",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: a · reach: public door, os -h and os -v on the built entry exit 2 with 'command -h not found' / 'command -v not found', while packages/cli/README.md ### Global documents '-v, --version' and '-h, --help' (only --help and --version work; @oclif/core 5.1.2 adds no short help/version flag without additionalHelpFlags/additionalVersionFlags) · evidence: measured at a593c8c from an empty cwd · dedupe words: os -h, -h --help README Global, additionalHelpFlags, additionalVersionFlags, short help flag",
    "class: a · reach: named failing probe, packages/cli/test/published-entry-node-env-source-reroute.test.ts CONTROL leg fails on base 748b240 (built, 1 failed / 4 passed), so the pin's absence legs pass over a trap that never arms · evidence: tsx 4.23.15 dist/esm/api/index.cjs registers './esm/index.mjs' with parentURL = its own file, which resolves to the nonexistent dist/esm/api/esm/index.mjs; oclif:config:ts-path logs 'Could not find tsx. Skipping tsx registration'; tsx@4.23.15 entered with f3b16fc · dedupe words: published-entry-node-env-source-reroute, tsx 4.23.15 esm api register, Could not find tsx, neutralising the declaration CONTROL",
    "carrier: the PR for #21167 (it edits packages/cli/README.md) · noted, not filed · README ### Plugin Management says 'There is no os plugin command group in v1', but os plugin build|sign|publish is registered (the plugin topic shows in os --help). Pre-existing drift, left untouched because another claim holds the file. It is also in the PR's Acceptance notes."
    ]
    }


    Generated by Claude Code

  4. added a commit that references this issue on Oct 7, 2026
    dabd1c5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdependenciesPull requests that update a dependency filedomain:cli

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions