test(cli): three e2e spawners name the entrypoint they actually reach - #11462
Draft
claude[bot] wants to merge 1 commit into
Draft
test(cli): three e2e spawners name the entrypoint they actually reach#11462claude[bot] wants to merge 1 commit into
claude[bot] wants to merge 1 commit into
Conversation
The identical `bin/run.js` — the SHIPPED entrypoint` comment in serve-mcp-stdio-answers, serve-mcp-capability-collision and serve-stdio-stdout-purity was false: all three pin NODE_ENV=development on the child for the --dev admin seed, and @oclif/core 4.13.3 reroutes command resolution from ./dist/commands to ./src/commands for exactly that value, so packages/cli/dist was never consulted. Spawn bin/run-dev.js through tsx like the ~20 sibling e2e files here, and replace the comment with the mechanism. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019siH5jDmk5hrayvfyojUqR
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. |
This was referenced Aug 24, 2026
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.
Part of #11317.
Part of, not the closing keyword, is deliberate — see "A ruling isneeded before this merges" below. The card's direction is settled by triage,
but one of the two facts that settled it has since become false, and the
option triage rejected now measures cheaper and truthful. Flip this line to
the closing keyword (or close the card by hand) once the ruling lands.
What was false
serve-mcp-stdio-answers.e2e.test.ts,serve-mcp-capability-collision.e2e.test.tsand
serve-stdio-stdout-purity.e2e.test.tseach carried the identical comment:They spawned that stub and never reached
packages/cli/dist. All three pinNODE_ENV=developmenton the child for the--devadmin seed, and@oclif/core@4.13.3skips its TypeScript path lookup only whenisProd(),which
lib/util/util.js:66defines as a negated membership test — aleading logical-NOT applied to
['development', 'test'].includes(process.env.NODE_ENV ?? ''). Under either ofthose two values oclif rewrites the command target from the declared
./dist/commandsto./src/commands.Re-derived here rather than transcribed, with
packages/cli/distpresent(
@oclif/core's ownConfig.load()againstpackages/cli, reading back theroot plugin's resolved
commandsDir):NODE_ENVcommandsDirpackages/cli/dist/commandsdevelopmentpackages/cli/src/commandstestpackages/cli/src/commandsproductionpackages/cli/dist/commandsPremise correction — the card's fact (1) is stale
The card composes two facts. Fact (1) is no longer true. It states
turbo.jsondeclares"@objectstack/cli#test": { "dependsOn": ["^build"] }—dependencies only — so
distis never built for these tests. Onmaintodaythat entry reads
"dependsOn": ["build"]. It was changed by #11268(
918988ad), the same PR the card was filed from, and the card's base(
adb1b9ea8c) predates it.Re-measured with the card's own instrument,
pnpm exec turbo run test --filter=@objectstack/cli --dry=json:adb1b9ea8cmain@5a916c4d#buildtasks@objectstack/cli#testdeps contain@objectstack/cli#buildSo
packages/cli/distis built for these tests now. The defect survives onfact (2) alone — the ts-path reroute — which is sufficient on its own, so the
card's conclusion stands and its cause is now single, not composite.
What this PR does
The triage-settled remedy (
5386559160: "test-truthfulness restoration, noproduct fork"): the three files stop claiming an entrypoint they do not reach.
They now spawn
bin/run-dev.jsthroughtsx, exactly like the sibling e2efiles in this directory and like
helpers/serve-process.ts's ownrunServe(),and the false comment is replaced by the mechanism that made it false.
Per file the diff is four things: the
CLIconstant, the comment above it,spawn(process.execPath, …)becomingspawn(TSX, …)(TSXimported from theexisting helper, so no new package-escaping path literal), and three lines
recording why the
NODE_ENVoverride stays even thoughbin/run-dev.jsassigns it too — the shim's assignment runs after its own static imports have
evaluated, so only the child env pins the value for the whole process lifetime.
Nothing else changed.
turbo.jsonis untouched (no build dependency is beingdeclared here — a false claim is being removed).
vitest.config.tsisuntouched, for a reason given below.
serve-node-env-production-default.e2e.test.ts— the one file in
packages/clithat genuinely consumesdist/, because it isthe only one spawning with
NODE_ENVunset — is untouched, and nothing herealters what it measures.
A ruling is needed before this merges
The card offered a second option and triage rejected it as "new engineering"
because it needed a build dependency declared and another route to the
--devadmin seed. Both halves have since landed on their own, so measuredtoday option 2 is a three-line change confined to the same three files:
NODE_ENV=developmentfrom the parent.commands/serve.ts:1272sets it in-process:if (flags.dev) { if (!process.env.NODE_ENV) process.env.NODE_ENV = 'development'; }, andplugin-auth'smaybeSeedDevAdminreadsprocess.env.NODE_ENV !== 'development'at call time, insideruntime.start()— after thatassignment. Passing
NODE_ENV: undefinedtherefore keeps the seed andleaves the reroute disabled.
Measured, all three suites, same tree, same box, one lock acquisition for the
two legs that share one:
NODE_ENVmain)node bin/run.jsdevelopmentsrc/commandstsx bin/run-dev.jsdevelopmentsrc/commandsnode bin/run.jsdist/commandsOption 2 passes, is the fastest of the three, and is the only one that makes
the original comment true. This PR is the slowest of the three: moving onto
tsxcosts these files roughly +21s of test time, which runs against thedirection
vitest.config.ts's cost header reasons in.⛔ Not taken unilaterally. The argument against option 2 is real and is this
repo's stated policy: it would make these three suites verdicts about build
state, which is exactly what
scripts/check-test-source-alias.mjsand thevitest.config.tsheader exist to refuse — a suite that passes green against astale artifact, with nothing in the output saying so. Turbo now guarantees the
build in CI; it guarantees nothing for a developer running
vitestdirectly,who would get oclif's "command not found". Option 2 also leaves the two
properties silently self-cancelling again for the next author, which is why the
card floated a lint rule.
Maintainer/PM call. This PR implements the settled direction and is mergeable
as-is; option 2 is one
NODE_ENV: 'development'→NODE_ENV: undefinedperfile away, in the same declared surface.
Verification
Union re-run on the final commit,
4b7a8453, working tree clean.(
pnpm --filter @objectstack/cli exec vitest run … --maxWorkers=2). Thebefore/after table above is the evidence the coverage survived, not the green
alone: same 3 files, same 5 tests, same assertions, both legs green.
pnpm --filter @objectstack/cli typecheck— green (tsc --noEmit).does not cover the edited files:
packages/cli/tsconfig.jsonhasinclude: ["src"], sotest/**sits outside the program. What exercises theedits is the vitest run above, which executed them.
check:nul-bytes,check:test-source-alias,check:cross-package-test-inputs,check:published-files,check:slot-lookup,check:type-source-resolution,check:engine-double-contract,check:where-matcher,check:query-options-erasure,check:type-check-coverage,check-ci-filter-parity.mjs,check-plugin-teardown-shape.mjs,docs-audit/check-affected-docs.mjs.check:type-check-debt— not measured locally, and it says so itselfrather than going red:
--re-measurerefuses without the whole workspaceclosure built (
@objectstack/service-knowledgehas no built type entrypoint). That is a full-repo build and belongs to CI's lint job, which runs it
after exactly that build. Its structural half printed OK before the refusal.
pnpm lintwas not run; targeted eslintwas, with the three pieces of evidence that make the narrowing a
measurement rather than a gap: (1) population read from eslint's own
resolution — all three files came back as results with no "file ignored"
warning, so eslint's own config puts them in scope; (2) file count read from
--format json— 3 results, 0 errors, 0 warnings, exit 0; (3) configinvariance — this repo runs one
eslint.config.mjswhich never enablestype-aware linting for any file (
no parserOptions.project, no typed @typescript-eslint rules, documented and measured with a positive control ateslint.config.mjs:327-328), so this diff cannot move the verdict on anyfile it does not touch.
Not changed, and why
vitest.config.ts— the declared surface admits it only where the costheader names these three files, and it does not name them. Its numbers are an
explicitly dated 2026-08-20 measurement ("The 20 files that spawn the real
CLI as a subprocess"); the directory holds ~30 such files today, so that
count was already historical before this PR, and restating a dated
measurement is not this card's business.
helpers/serve-process.ts— itsNODE_ENVnote stays true after thischange (these files still pin
NODE_ENVinenv, andserve-node-env-production-default.e2e.test.tsis still abin/run.jsspawner). Its pointer at packages/cli e2e tests that spawn
bin/run.jsas "the SHIPPED entrypoint" never reachdist/— oclif's ts-path reroutes them tosrc/under NODE_ENV=test|development #11317 becomes historical rather than false, and its⛔ stands on its own merits, so it is left alone.
...process.envworklist is two files short, and one of them spawns a realos serve#11441's worklist — nothing to add. All three of these files already usechildEnv(), not a bare...process.env. Re-derived the directory: the onlybare-spread children that boot a real
os serveare the two finding: #11341's bare-...process.envworklist is two files short, and one of them spawns a realos serve#11441 alreadynames, and
serve-app-runtime-hooks.e2e.test.ts:84uses the bare spread foros compileonly while its serve boot goes throughrunServe()— so finding: nothing stops the nextpackages/cli/testspawner from re-introducing the bare...process.envchild env #11341'sassessment of that file is accurate as written.
Changeset
None, deliberately. The diff is three files under
packages/cli/test/;nothing published changes and there is nothing for release notes to say. The
skip-changesetlabel carries that declaration.Generated by Claude Code
Generated by Claude Code