Skip to content

cli: move to the @oclif/core 5 line, with plugin-help 7 and plugin-plugins 7 in the same commit (replaces Dependabot #21034, #21031, #21035) #21125

Description

@objectstack-fleet

Filing-gate class: ③ maintainer-directed task.
Body last written 2026-10-01T13:28Z: unblocked. #21094 closed completed when PR #21162 merged as f3b16fc2f3. The area rule was re-derived with no new blocker, and the card was dispatched in the same act.
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). The maintainer directed it 「相关卡片你使用项目经理技能派发处理」, and it dispatches one os-dev.
Dedup: a semantic issue search ("upgrade @oclif/core to version 5 for the cli") returned 0. I also listed 789 objectstack issues over REST (open, plus the most recently updated closed) and grepped them for oclif/core 5, plugin-help 7, plugin-plugins 7, #21034, #21031 and #21035. The only hit was #21094, which names those PRs only in its serial-constraints note. No card covers this upgrade.

Maintainer ruling (verbatim)

三组大版本升级:同意

  • oclif:关三个 PR,立卡(推荐)。

Given in session session_018gA1pE6eJtwHhqx72G8U9X on 2026-10-01, in reply to the seat's risk read of the open Dependabot major bumps.

Why one card instead of the three Dependabot PRs

All three Dependabot PRs are closed in favour of this card.

  • They are coupled. @oclif/plugin-help@7.0.2 and @oclif/plugin-plugins@7.0.3 both depend on @oclif/core ^5.0.0 (measured with npm view). Landing any one of the three alone leaves two copies of @oclif/core in the lockfile. The pairs also conflict with each other in pnpm-lock.yaml.
  • Each Dependabot lockfile carries unrelated movement, including nodemailer going DOWN from 10.0.12 to 10.0.11. That downgrade is in every npm Dependabot PR opened on 2026-10-01.
  • chore(deps)(deps): bump @oclif/core from 4.13.3 to 5.1.2 #21034 has no changeset, yet @oclif/core is a production dependency of the published @objectstack/cli.
  • Code risk measured on chore(deps)(deps): bump @oclif/core from 4.13.3 to 5.1.2 #21034's CI is low. The only breaking change upstream states is "require Node >=22", which matches packages/cli engines (>=22.0.0). The CLI's Test Core shards were green on core 5.1.2.

What to do

  1. One commit bumps all three: @oclif/core ^5.1.2 in dependencies, and @oclif/plugin-help ^7.0.2 and @oclif/plugin-plugins ^7.0.3 in devDependencies, all in packages/cli/package.json.
  2. Regenerate pnpm-lock.yaml with the repo's tooling, starting from origin/main. Never edit it by hand.
    • Acceptance: exactly one @oclif/core copy at 5.x.
    • Acceptance: no resolved version goes DOWN against the merge base (nodemailer stays at 10.0.12 or later).
    • Acceptance: only the oclif subtree moves.
  3. Re-measure what the code says was measured on 4.13.3 — a ruling gated on a premise.
    • Premise (falsifiable; verify it FIRST): every behaviour the tree records as measured against @oclif/core@4.13.3 holds on 5.1.2.
    • Re-check command: git grep -n "4\.13\.3" -- packages/cli scripts ':!**/CHANGELOG.md'
    • It gives 17 lines at origin/main 5e470f8c1c.
    • The ones that state a measurement are in packages/cli/bin/run.js and bin/run-dev.js (inlined execute()), packages/cli/src/utils/port-contract.ts (the parser's integer handling, and the [finding] os dev --port is unvalidated and os start --port is unbounded — both forward to the serve child on a channel that renames the operator's input #12673 re-measure), and scripts/check-cli-test-child-env.mjs (isProd() and the ts-path skip).
    • Also in the set: the literal 'module: @oclif/core@4.13.3' in packages/cli/test/unbuilt-workspace-lead.test.ts, and the comment in scripts/check-cli-command-ids.mjs.
    • If the premise holds, update each site to the version actually measured.
    • ⛔ If any of them no longer holds, do not force it. Stop and report the fork with the differing measurement.
  4. Changeset: add a patch changeset for @objectstack/cli, which is in the fixed group. It should say that the exported Command classes now build on @oclif/core 5 and that Node 22 or later is required.
  5. Apply needs:pack-smoke to the PR, so the packed tarball's install and run is tested. That job is opt-in and was skipped on all three Dependabot PRs.

Out of scope (a separate maintainer question)

packages/cli/package.json lists both plugins in oclif.plugins, but only as devDependencies. oclif loads oclif.plugins only from dependencies, so neither plugin ever loads, and os help and os plugins are not registered commands. Whether to remove those entries or make the plugins real dependencies is put to the maintainer separately. ⛔ This card does not change it.


Generated by Claude Code

Activity

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

    @objectstack-fleet
    ContributorAuthor

    pm:queue → pm:blocked: serial wait on #21102

    Read 2026-10-01T08:13Z · PM session session_018gA1pE6eJtwHhqx72G8U9X (the maintainer's direct-dispatch session: 「相关卡片你使用项目经理技能派发处理」).


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Serial wait re-derived: Blocked-by: #21102 → Blocked-by: #21094

    Read 2026-10-01T09:07Z · PM session session_018gA1pE6eJtwHhqx72G8U9X.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3
    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-21125-oclif-core-5
    Worktree: objectstack-issue-21125
    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

  5. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 21125,
    "status": "done",
    "branch": "claude/issue-21125-oclif-core-5",
    "pr": "#21212",
    "session": "session_018gA1pE6eJtwHhqx72G8U9X",
    "premise_still_valid": true,
    "summary": "Commit 7649ab4 moves @oclif/core to ^5.1.2 (dependencies) and @oclif/plugin-help to ^7.0.2 and @oclif/plugin-plugins to ^7.0.3 (devDependencies), all in packages/cli/package.json. pnpm-lock.yaml was regenerated with pnpm install --lockfile-only and installed with --frozen-lockfile: 11 names changed, all in the oclif subtree, 0 went DOWN, and one @oclif/core copy remains (5.1.2). Item 3 is LIFTED. Every behaviour recorded as measured on 4.13.3 was re-measured on 5.1.2 before any site was touched, and every one held. The present-tense sites are restamped to 5.1.2 (commit 20b92f5). The two unbuilt-workspace-lead transcript literals stay verbatim, and a docblock sentence now says why. The patch changeset .changeset/21125-oclif-core-5.md is added. The draft PR is #21212, assigned to os-bill, with the needs:pack-smoke label already applied by the seat.",
    "item3_verdict": {
    "verdict": "LIFTED: the premise held at every site",
    "upstream": "The changelog from 4.13.3 to 5.1.2 has one BREAKING entry, in 5.0.0: 'require Node >=22, drop EOL Node versions'. Every 5.x release declares engines.node >=22.0.0. A tarball diff found 33 lib/.js files changed. The behavioural deltas besides Node: ejs 3->6; is-wsl replaced by a dynamic import of wsl-utils (getPlatform/getShell become async, neither is exported); readStdin resolves undefined instead of null; loadHelpClass gains a compiled-path fallback (this CLI sets no helpClass); a Plugin #private field now carries the module label; OCLIF_STDIN_TIMEOUT_MS (5.1.0, default still 10 ms). None of them reaches this tree.",
    "sites": [
    "bin/run.js:8, bin/run-dev.js:8, inlined execute(): HELD. lib/execute.js is byte-identical in 4.13.3, 5.0.0 and 5.1.2 (sha256 5ef58b0a01aa...). Restamped.",
    "bin/run.js:34; published-entry-node-env-source-reroute.test.ts:9; serve-mcp-capability-collision.e2e:66, serve-mcp-stdio-answers.e2e:65, serve-stdio-stdout-purity.e2e:62; check-cli-test-child-env.mjs:187,1093,1600,1608, the ts-path / isProd() claim and the four-row table: HELD. A Config.load() probe gives unset -> dist/commands, production -> dist/commands, development -> src/commands, test -> src/commands, identical on both versions. The isProd body is identical and its pinned line moves from util.js:66 to :65. In ts-path.js only split('.', 1) changed, and enableAutoTranspile is still read ahead of isProd. Restamped, including 66 -> 65.",
    "port-contract.ts:38,98,104, the seven-row parse/min-max-over-default table: HELD. A Parser.parse probe reproduces all 7 rows identically (string argv/env: parse runs; default and default fn: parse does not run; integer {min:0,max:65535} argv/env 99999 refused, default 99999 accepted). parse.js:420-426 is unchanged. Restamped.",
    "port-contract.ts:375, the integer parser /^-?\d+$/: HELD. lib/flags.js and lib/args.js are byte-identical. 18 Flags.integer readings and 7 Parser.parse legs are identical (03000 -> 3000). Restamped.",
    "check-cli-command-ids.mjs:385, the non-command-module warning block: HELD. It has the same lines (Warning: Error / module / task / plugin / root / message) and now reads module: @oclif/core@5.1.2. Restamped.",
    "unbuilt-workspace-lead.test.ts:62,160 (now 68,166), the module line of two transcripts: HELD. 5.1.2 addErrorScope differs only in _base -> #base, and the classifier reads message: only. Kept verbatim as 4.13.3 transcripts; a docblock sentence says why.",
    "bin/run-dev.js:470-476 (no version stamp), displayWarnings() before Config.load()'s first await: HELD. run-dev-unbuilt-workspace.e2e is green.",
    "bin/run.js:89-92 (no version stamp), oclif.plugins loads from dependencies only: HELD. loadCorePlugins is identical, and the root help lists no plugins and no help topic."
    ],
    "help_and_entry": "All 139 rendered help pages (the root, 64 commands and 74 topics) are byte-identical between 4.13.3 and 5.1.2. Through bin/run.js, these six invocations give the same exit code, stdout sha256 and stderr sha256 on both versions: --version (0), --help (0), unknown command (2), dev --no-ui (2), serve --port abc (1) and serve --port 3e3 (1)."
    },
    "lockfile": {
    "merge_base": "0d421041d (pnpm-lock.yaml there is byte-equal to fbcc05f, the base where the regeneration ran)",
    "changed_names": 11,
    "changes": "@oclif/core 4.13.3->5.1.2; @oclif/plugin-help 6.2.58->7.0.2; @oclif/plugin-plugins 5.4.87->7.0.3; ejs 3.1.10->6.0.1; jake 10.9.4 and filelist 1.0.6 removed; is-wsl 2.2.0 and is-docker 2.2.1 removed (3.x kept); wsl-utils +0.4.0 (0.1.0 kept); powershell-utils +0.1.0; npm 11.19.0->11.21.0 (plugin-plugins 7 asks for ^11.19.1)",
    "down_count": 0,
    "oclif_core_copies": "1 (5.1.2)",
    "importers_moved": "the three packages/cli entries only",
    "nodemailer": "unchanged at 10.0.13"
    },
    "tests": "At 7649ab4 (bump only, base fbcc05f): pnpm --filter @objectstack/cli typecheck exited 0, with the test-typecheck ledger held at 3 files / 28 errors / 6 signatures. vitest --project unit --maxWorkers=2: 'Test Files 242 passed (242) / Tests 3435 passed (3435)'. --project integration: 'Test Files 1 failed | 68 passed (69) / Tests 1 failed | 598 passed | 1 skipped'. The 1 red is published-entry-node-env-source-reroute > 'CONTROL: neutralising the declaration in the child reproduces the card verbatim'. It reds identically on base fbcc05f with 4.13.3 in a second worktree ('Tests 1 failed | 4 passed (5)', same AssertionError), so it is environmental, not the bump. OS_TEST_TIERS=nightly (the e2e tier, 76 files in 7 chunks): 76 files / 775 tests passed. At merged head cdfd7fd: typecheck exited 0; unit 'Test Files 242 passed / Tests 3436 passed'; integration 70 files, 69 passed plus the same 1 environmental red (validate-lint-mapping-connector-source.test.ts from #21176 is included and green); an e2e subset of 6 files / 25 tests passed (the 3 edited serve-
    e2e, build-json-undeclared-key-parity, run-dev-unbuilt-workspace, serve-node-env-production-default). Final head ee3dbc6: its merge brought no packages/cli, lockfile or pnpm-workspace.yaml change. A packed-tarball smoke ran: pnpm pack produced a manifest with ^5.1.2/^7.0.2/^7.0.3; from the extracted package, bin/run.js --version exited 0 (48 B) and --help exited 0 (3712 B, no plugins topic). No ablation: there is no new guard or test.",
    "gates": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands at ee3dbc6 derived 95 commands from 13 paths vs merge base 0d42104. All 95 ran with the exit code captured before any pipe, and all exited 0. The --ran reconcile reads 'Run reconciliation - 95 derived, 95 run, 0 NOT-MEASURED, 0 UNRUN' (a DERIVED zero). The same 95 were all green at cdfd7fd. At 20b92f5, check:dual-build-cjs-loads and check:i18n-coverage first exited 3 (PREREQUISITE NOT MET, no dist), then exited 0 after a full build. The edited gate scripts' own self-tests ran inside check:cli-command-ids and check:cli-test-child-env (exit 0, 152 self-test cases), and serve-node-env-production-default.e2e, which reads check-cli-test-child-env, is green.",
    "line_budget": "n/a: no skills/** file or ledger file touched",
    "files_changed": [
    ".changeset/21125-oclif-core-5.md",
    "packages/cli/bin/run-dev.js",
    "packages/cli/bin/run.js",
    "packages/cli/package.json",
    "packages/cli/src/utils/port-contract.ts",
    "packages/cli/test/published-entry-node-env-source-reroute.test.ts",
    "packages/cli/test/serve-mcp-capability-collision.e2e.test.ts",
    "packages/cli/test/serve-mcp-stdio-answers.e2e.test.ts",
    "packages/cli/test/serve-stdio-stdout-purity.e2e.test.ts",
    "packages/cli/test/unbuilt-workspace-lead.test.ts",
    "pnpm-lock.yaml",
    "scripts/check-cli-command-ids.mjs",
    "scripts/check-cli-test-child-env.mjs"
    ],
    "deviations": [
    "The two unbuilt-workspace-lead.test.ts module: literals were NOT restamped. They are transcripts of a 4.13.3 run, the version actually measured. Restamping one line would make them transcripts of no run, which matches the precedent of check-i18n-bundles.mjs keeping its 4.13.2 transcript across the 4.13.3 bump. A docblock sentence records that the line is historical. The census now gives 3 lines, all in that file.",
    "The e2e tier ran in full only at 7649ab4. After the main merges, only a 6-file subset ran. The merged main commits touched CLI help, warning and refusal text and one new integration test, none of them oclif code.",
    "Because of the roughly 10-minute foreground cap, the integration and e2e populations ran as file-list chunks. Every file was covered, and the totals are the sums.",
    "On the final head ee3dbc6, only the 95 gates ran: that merge brought no packages/cli or lockfile change. main has since moved 3 more commits (to 5e5ce48), none of which touch the lockfile or packages/cli, and they were not merged.",
    "The dispatch-gates spelling conflicts. The dispatch says to pass the changed paths; os-dev.md says to pass none and let the script take the merge-base change set. I followed os-dev.md. The script's 13 derived paths equal this diff's 13.",
    "The packed-tarball smoke ran the extracted tarball against the workspace's linked node_modules. It was not a clean install; the install smoke is needs:pack-smoke in CI."
    ],
    "hypotheses": {
    "H1": "Confirmed: 18 lines at fbcc05f (the f3b16fc count). The re-derivation adds two sites with no version stamp, bin/run-dev.js:470-476 and bin/run.js:89-92, and both held.",
    "H2": "Confirmed with npm view: @oclif/core latest is 5.1.2; 5.0.0 through 5.1.2 all have engines.node >=22.0.0; plugin-help@7.0.2 and plugin-plugins@7.0.3 both depend on @oclif/core ^5.0.0; and one copy resolves.",
    "H3": "Superseded by the regenerated lockfile. nodemailer does not move, and the local CLI suites are green apart from the environmental CONTROL leg that also reds on base.",
    "H4": "Confirmed: the only stated breaking change is Node >=22. The unstated behavioural deltas are listed in item3_verdict.upstream, and none reaches this tree."
    },
    "pr_subscribed": "true. subscribe_pr_activity answered: 'Subscribed to activity on #21212. Comments, CI status changes, reviews, and other PR events will now be delivered into this conversation'",
    "mcp_calls": "1: mcp__claude-code-remote__subscribe_pr_activity, a session subscription. GitHub MCP calls: 0, and no write tool was used.",
    "api_writes": "3 REST writes, each executed by the fleet-write relay as objectstack-fleet[bot] and each sent as one POST /repos/objectstack-ai/objectstack/dispatches from this session. (1) pr_create: POST /repos/objectstack-ai/objectstack/pulls, giving #21212 (run 36894813479), read back at 8942 bytes sent and 8942 stored, identical. (2) assign: POST /repos//issues/21212/assignees os-bill (run 36894900612), read back as matching. (3) this os-dev-report comment: POST /repos//issues/21125/comments. git push 5 times (not REST): the empty-branch probe, 7649ab4, 20b92f5, cdfd7fd and ee3dbc6.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none (承接者:无) · noted in the PR Acceptance notes, not filed. In this cloud container, published-entry-node-env-source-reroute.test.ts > 'CONTROL: neutralising the declaration in the child reproduces the card verbatim' reds identically on base fbcc05f (@oclif/core 4.13.3) and on this branch. oclif registerTsx imports tsx/dist/esm/api/index.cjs, and its register() throws ERR_MODULE_NOT_FOUND for .../tsx/dist/esm/api/esm/index.mjs, so tsx never registers and the CLI prints its version with exit 0. The reroute itself still fires: the output names packages/cli/src/commands. It is not class a, b or c, because there is no public door (a local test-environment red only). Dedupe words: reroute CONTROL leg, registerTsx, tsx esm api index.cjs, ERR_MODULE_NOT_FOUND."
    ]
    }

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, iteratedependenciesPull 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