Repository navigation
test(cli): spawn the CLI source entry with node, not the tsx binary, in 76 test files - #28637
Merged
Merged
Conversation
The tsx binary in front of the source entry is a second node process with its own transform; @oclif/core registers tsx in-process for the src/ command tree either way, so the entry, src/ and the pinned NODE_ENV stay the same. Claude-Session: https://claude.ai/code/session_01FEkQ5n9VfyHfEFRqzGZkWN Co-Authored-By: Claude <noreply@anthropic.com>
…alse The verify files said plain node resolves the command from dist/; with NODE_ENV=development @oclif/core maps the command tree to src/ and registers tsx in-process. The serve boot files described a tsx shim and grandchild that no longer exist. Claude-Session: https://claude.ai/code/session_01FEkQ5n9VfyHfEFRqzGZkWN Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
Contributor
Author
|
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC 席位核对 · ACCEPT ·
|
| item | reading |
|---|---|
| Shape | Draft, base main, Part of #23181. 76 of slice 34's 78 listed packages/cli test files (2 keep tsx with a named reason), labels tests + skip-changeset. Clause-②: no, Metadata-protocol: none. |
| Diff check (seat) | Every removed non-prose line names TSX/tsx, and every added non-prose line is its process.execPath replacement, an import list without TSX, or a local runTsx renamed runCli with its calls (argv, cwd and env unchanged). No timeout changed (the SPAWN_TIMEOUT_MS = 180_000 constants keep their value; only their comment drops "tsx"), and no shared helper is touched. The one assertion edit is diff-usage-error-stream's control precondition, existsSync(TSX) → existsSync(process.execPath), which follows the launcher it checks. Prose that the switch made false is corrected, including the stop() note in the serve file whose SIGTERM-first reason now reads as history. The two kept files: run-dev-unbuilt-workspace.e2e pins bin/run-dev.js's own stderr drain under tsx, and serve-host-fallback-base.e2e spawns a probe.mjs that imports src/commands/serve.ts, which needs the tsx loader. |
| Evidence | CI green on head 95b877c4 (35 success, 23 skipped, 0 failed; the CI and Lint & Type Check workflow runs both success, and the required Test Core, TypeScript Type Check and Lint & Repo Gates contexts are success in the latest reading). Governed check: NOT governed, 404 changed lines. The report gives 76/76 switched files passing (29 queue-tier files, 213 tests; 47 nightly files, 671 tests) on the merged head, 48 of 48 derived gates exit 0, and A/B N=3 on six files of −25 % to −43 %. |
| Landing | 「按照 pm-dispatch 规则复核过的都授权」 (Leehom, 2026-10-25T11:35Z): ready and auto-merge through the relay, once every check on this head is green or an expected skip. |
Generated by Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Leehom · project thread
Part of #23181 (slice 34). The card stays open for later slices: this one takes only the tsx →
process.execPathlever on the 78packages/clitest files in the order's list.Clause-②: no
Metadata-protocol: none
维护者速读
packages/cli里 76 个测试文件起 CLI 源码入口bin/run-dev.js时,不再经node_modules/.bin/tsx包装层,改为直接用process.execPath(测试自己的 node)起同一个入口,与 migrate 系列(slice 12)、slice 25、slice 28 已有写法一致。其中 23 个文件还改正了因此变假的注释。清单里其余 2 个文件保留 tsx,原因见下。src/、NODE_ENV=development两种起法都一样(oclif 在 development 下自己在进程内注册 tsx,把命令树映射到src/,已用 debug 日志实测)。A/B 六个文件,每个快 25%–43%。files[]只有 dist、README、CHANGELOG);没有删、没有放宽任何断言,用例名和数量不变,层级划分不变;回滚即 revert。packages/cli/test/verify-json-stdout.test.ts(改正了"纯 node 会从 dist 读命令"这句错注释);packages/cli/test/serve-publishes-bound-port.e2e.test.ts(进程组清理的注释,不再有 tsx 孙进程);packages/cli/test/diff-usage-error-stream.e2e.test.ts(唯一一处断言改动:对照用例检查的启动器从 tsx 换成process.execPath)。pnpm --filter @objectstack/cli exec vitest run --project integration test/verify-json-stdout.test.ts test/generate-refuses-retired-generator.test.ts→ 11/11 通过。What changes
Sort. The order's list (
pm-orders/server/evidence/23181-s34/files.txt) re-derived on base7449e479c4:git grep -lw TSXoverpackages/cligives 131 paths; minustest/helpers/**, the 53 left over are every file slices 24–33 own plus two non-test sources (src/utils/authored-source-codemod.ts,vitest-tiers.ts). So the list is exactly the 78 files, no difference. One note on the order's wording: 33 of the 78 importTSXfromtest/helpers/serve-process.ts; the other 45 declare their ownconst TSX = resolve(…, 'node_modules/.bin/tsx'). Both spawn the same way.bin/run-dev.jsthrough the tsx binary, and the test is not about that launcherprocess.execPathprocess.execPath, tsx only in proserun-dev-unbuilt-workspace.e2e: it pinsbin/run-dev.js's own stderr drain and EPIPE survival, and the shim's header measures that listener shape under tsx (tsx's hooks worker pipes intoprocess.stderr, so Console's keep-alive is never installed); it also drives the run with a--importhook throughNODE_OPTIONS.serve-host-fallback-base.e2e: its child is not the CLI entry but aprobe.mjsthat importssrc/commands/serve.tsdirectly, which needs the tsx loader (the slice 25 reading: no gain for a.tshelper child)The switch, bucket (a). Every spawn site passes
process.execPathwhere it passedTSX, withbin/run-dev.jsstill the first argument; the child env, cwd, argv, stdio and timeouts are unchanged. A localTSXconstant is removed; a helper import dropsTSX(the export stays). Spawn shapes covered:spawn,spawnSync,execFile,execFileSync, promisifiedexecFile, the files' ownrun(file, …)wrappers, thescript(1)command line of the two login NDJSON files, theosshell shim ini18n-extract-check-hint, and the{ exec, argv }entry ofstart-port-banner-agreement's auto-shift leg. The three generate files'runTsxhelper is nowrunCli.Why the child is the same.
bin/run-dev.jspinsNODE_ENV=development; under it @oclif/core 5.1.2 (config/ts-path.js) registers tsx in-process and mapsdist/commandstosrc/commands, withpackages/cli/distbuilt or not. Probe on this branch withdist/built:DEBUG='*ts-path*' node bin/run-dev.js --versionlogsregistering tsx at …/packages/cli,Successfully imported tsxandFound source directory for …/dist/commands at …/src/commands(pm-orders/server/evidence/23181-s34/oclif-ts-path-probe.txt). The entry's own static../src/utils/*.tsimports load through Node 22's type stripping (.nvmrc= 22), as on the slice 12 files.Prose that became false, corrected in 23 files: the eight
verify-*files said plain node makes oclif resolve the command fromdist/(the probe above says otherwise);serve-publishes-bound-port,serve-port-drift-noticeandpackage-install-local-jobs-shared-namedescribed a tsx shim with the CLI in a grandchild; the rest said "spawns the CLI throughtsx", "coldtsxstarts" or "bin/run-dev.js+ tsx". Prose that stays true is unchanged ("src/through tsx", "oclif + tsx cold start", quotes ofbin/run-dev.js's header). The// test-budget:headers of the sixpackage-install-local-*files still say "the tsx source entry"; this slice does not touch headers.The one assertion edit:
diff-usage-error-stream's control caseresolves the dev entry it drivescheckedexistsSync(TSX); it now checksexistsSync(process.execPath), the launcher it drives. Same meaning.Not changed: no case name, case count, timeout, tier, project or
// test-budget:header; no file undertest/helpers/**; no source file.Tests
All 76 switched files pass on
6410254c(the fix commits, before the merge). Queue tier:vitest run --project integration --maxWorkers=2over the 29 non-.e2efiles: 29/29 files, 213/213 tests. Nightly tier (OS_TEST_TIERS=nightly), the 47.e2efiles: 47/47 files, 671/671 tests. Lock VERDICT command-exit 0 on both.Tiers unchanged.
tierSignalsfrompackages/cli/vitest-tiers.tson all 78 files before and after: 78integration, identical. The switched files still import or nameCLI/run-dev.js.A/B, six files over six commands. Head
6410254cvs base7449e479c4, one box, one lock hold, N=3,--maxWorkers=1. Base bytes swapped into the same path (blob hash checked) so both legs keep the same tier and config; each leg its own vitest invocation, order alternated per round; restored fromHEADandgit diff HEADempty after. Reading: the default reporter's per-file line. Every leg exit 0, same test counts per side.generate-refuses-retired-generatorverify-json-stdoutserve-migrate-exit-schema-parity.integrationi18n-check-platform-bucket.e2elogin-json-ndjson.e2erequires-retired-capability.e2eRaw legs and the script:
pm-orders/server/evidence/23181-s34/ab-summary.txt,ab.sh.pnpm --filter @objectstack/cli typecheck(tsc andcheck:test-typecheck, which compiles the test layer undertsconfig.test.json) exit 0 on6410254c, withNODE_OPTIONS=--max-old-space-size=4096; the debt ledger is unchanged (3 files, 28 errors, 6 pinned signatures).eslint --no-inline-configover the 76 files exit 0 (@objectstack/clihas nolintscript).No ablation: no tested behaviour changed (test-only).
Acceptance notes
servespawn (test/helpers/serve-process.ts,runServe(), around line 982) still goes throughTSX. 12 test files callrunServe(in code position:artifact-pinned-boot.e2e,serve-app-runtime-hooks.e2e,serve-boot-diagnostics-noise-budget.e2e,serve-boot-diagnostics.e2e,serve-cluster-driver-diagnosis.e2e,serve-no-artifact.e2e,serve-organizations-host-resolution.e2e,serve-organizations-mount-failure.e2e,serve-package-declared-capabilities,serve-package-registry-always-on.e2e,serve-port-readback.e2e,uncreatable-directory-doors.integration. Carrier: test budget (domain:cli): 119 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23181.skip-changeset. Test-only.@objectstack/cli'sfiles[]isdist,README.md,CHANGELOG.md; its build emits no*.test.tsintodist/. Nofiles[]content changes.Verification
Head
95b877c4: the two fix commits106e7364(the switch) and6410254c(the prose), plus one merge oforigin/mainafter slices 24 (#28610), 26 (#28599) and 28 (#28616) landed, as the order asks. The merge touches none of the 78 files and nothing undertest/helpers/**.pnpm install --frozen-lockfile && pnpm build(117/117 tasks), then the 29 queue-tier switched files again: 29/29 files, 213/213 tests. The 47 nightly files, the A/B and the typecheck above were taken on6410254c.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackon95b877c4, the same 48 as before the merge): 48/48 exit 0, exit codes captured before any pipe.--ranreconcile: 48 accounted, 48 run, 0 NOT-MEASURED, exit 0 (pm-orders/server/evidence/23181-s34/gates-ran-95b877c4.txt). Prerequisites:check-plugin-teardown-shape --self-testafter fetching its control commit;check:dual-build-cjs-loadsafter the full build.check-commit-card-trailers --range origin/main..HEADexit 0;check-nul-bytesexit 0.Generated by Claude Code