Skip to content

Commit 49d60d3

Browse files
test(cli): spawn the source entry under node, not the tsx binary, in 34 test files (#28625)
<!-- claude-projects-attribution: {"github_login":"os-project-manager"} --> _Requested by **Leehom** · [project thread](https://claude.ai/code/project/chan_01TenzsRopZj4jMbvjX8uz1X?thread=cmsg_01TenzsRopZj4jMbvjX8uz1X6ekcr8QawcG79EtN7Tzdbo)_ Part of #23181 (slice 29, the tsx wrapper lever across the cli test files outside slices 24–28). The card stays open for later slices. Clause-②: no Metadata-protocol: none ## 维护者速读 - **改了什么**:`packages/cli` 里 34 个测试文件起 CLI 子进程时,不再经 `node_modules/.bin/tsx` 包一层,改为用当前进程自己的 `node`(`process.execPath`)直接跑 `bin/run-dev.js`,与 slice 12 对 migrate 文件的做法一致。入口、`src/`、`NODE_ENV=development`、子进程的 env、cwd、参数、超时都不变。 - **为什么改**:卡 #23181 的测试提速职责。tsx 包装只多出一个进程和一次自身的转译,每次子进程白付几秒;slice 27 实测同一条命令 tsx 9.5–11.8 s、node 5.3–5.4 s,stdout 字节相同。 - **风险与回滚**:只改测试文件,不发布任何东西(cli 的 `files[]` 只有 dist、README、CHANGELOG);没有改任何断言、用例名、超时、分层或 `// test-budget:` 头;回滚即 revert。 - **先看**:`packages/cli/test/generate-skill.e2e.test.ts`(唯一手改:CLI 走 node,解析探针是裸 `.ts` 文件,仍走 tsx);`packages/cli/test/package-install-local-handlers.integration.test.ts`(`os start` 启动走 node);其余 32 个文件只是 `TSX` → `process.execPath` 并删掉常量。 - **两分钟验证**:`pnpm --filter @objectstack/cli exec vitest run test/build-strict-body-count.test.ts` → 6/6 通过,墙钟约 26 s(改前约 33 s)。 - **需要你做的**:无,席位落地。 ## What changes The order lists 45 `packages/cli` test files that still name `tsx` on `origin/main` outside slices 24–28 and `test/helpers/**`. I sorted each one first. **(a) The switch applies: 34 files.** Each spawned `bin/run-dev.js` through the tsx binary, and none of them is about that entry. Each now spawns `process.execPath` with `bin/run-dev.js` as the first argument, slice 12's way. The child env, cwd, argv, stdin, `maxBuffer` and timeouts are unchanged. The local `const TSX` (or the `TSX` import from the shared helper) goes, a runner named `runTsx` whose every call spawns the CLI is renamed `runCli`, and the prose that said "through tsx" now says `node`. `src/commands/validate-json-strict-exit.e2e` · `test/build-callable-names` · `build-connector-spec-file-artifact.e2e` · `build-demo-staff-artifact` · `build-docs-step-count.e2e` · `build-runtime-bundle-bodyless` · `build-seed-files-artifact.e2e` · `build-strict-body-count` · `build-view-container-name` · `create-refuses-invalid-project-name.e2e` · `dev-no-watch.pin` · `generate-agent-retired.e2e` · `generate-object-namespace-prefix.e2e` · `generate-refuses-name-outside-charset` · `generate-refuses-unimportable-alias` · `generate-refuses-unparseable-name` · `generate-skill.e2e` · `hook-body-build-reach.e2e` · `migrate-apply-refuses-before-ddl.e2e` · `migrate-exit-code.e2e` · `migrate-unloadable-host-config-exit.e2e` · `package-install-local-handlers.integration` · `qa-names-and-tags-run` · `qa-requires-skip-run` · `refusal-renders-once.e2e` · `retry-policy-key-validate-door` · `rule-line-explain-pointer.e2e` · `scaffold-emission-policy.e2e` · `serve-host-config-metadata-door.integration` · `stack-datasource-default-validate-door` · `validate-field-predicate-traversal` · `validate-json-warning-parity.e2e` · `validate-top-level-strict.e2e` · `validate-view-container-name` - `generate-skill.e2e` is the one mixed file. Its two CLI spawns move to node. Its parse probe imports a generated bare `.ts` module with an extensionless specifier, which plain node cannot load, so the probe stays on the tsx binary through a two-argument `runChild(bin, args, cwd)`. - `migrate-apply-refuses-before-ddl.e2e`, `migrate-unloadable-host-config-exit.e2e`, `qa-names-and-tags-run`, `qa-requires-skip-run`, `package-install-local-handlers.integration` and `serve-host-config-metadata-door.integration` imported `TSX` from `test/helpers/serve-process.ts` but spawn in their own code, so only the import changes; the helper is untouched. - The tier is unchanged: `vitest-tiers.ts` still reads every file as a spawner through its `run-dev.js` entry name. **(b) Already on node, or tsx in prose only: 6 files, nothing to do.** | file | why | |:--|:--| | `src/commands/child-env-source-loader.pin` | spawns nothing; tsx appears in prose and in a specimen string | | `src/commands/migrate/plan.declared-default-datasource.integration` | slice 12 moved it to `process.execPath`; prose only | | `src/commands/migrate/plan.telemetry-sibling.integration` | same | | `src/commands/dev-database-directory` | already `process.execPath`; `--import tsx` loads an inline `-e` script that imports `src/` (`.js` specifiers onto `.ts` files), not the CLI entry, and plain node cannot resolve those | | `src/utils/make-directory` | same shape as `dev-database-directory` | | `test/serve-built-cli-prerequisite` | spawns nothing; tsx in prose only | **(c) The test pins the tsx or `run-dev.js` entry itself: 5 files, keep tsx.** | file | why | |:--|:--| | `test/run-dev-cwd-tsconfig-redirect.e2e` | its subject is tsx honouring the cwd tsconfig and the shim's re-exec with `TSX_TSCONFIG_PATH` | | `test/start-signal-forwarding.e2e` | already `process.execPath`, with the tsx loader as `--import` on purpose: the tsx CLI would put a relay process between the test and the pid it signals | | `test/invocation-loudness.e2e` | pins what a shell sees when the package barrel `src/index.ts` is run as if it were the CLI (only tsx runs a bare `.ts` file), plus the shims' own success path | | `test/released-port-production-spawn.pin` | a source census; spawns nothing; `TSX` appears only in specimen sources and in its own vocabulary | | `test/unbuilt-workspace-lead.test` | spawns nothing; pins the remedy text, which names tsx | Not changed: no assertion, expected output, case name, timeout, tier, project, `// test-budget:` header or test helper. No source file. ## Tests - **A/B** (one box, one lock hold, N=3, `--maxWorkers=1`, base and head interleaved, base first in rounds 1 and 3, head first in round 2): for each base leg the base file's bytes were written into the same path and restored from `HEAD` after it, checked by blob hash, so both legs ran in the same tier slot. `.e2e` files ran with `OS_TEST_TIERS=nightly`, the rest with `queue` (the queue tier writes the oclif test manifest once per run, as in CI). Whole process wall per run, in seconds: | file | command | base | head | mean | change | |:--|:--|:--|:--|:--|--:| | `build-strict-body-count` | `os build` | 36.2, 31.5, 32.7 | 26.6, 26.6, 26.0 | 33.5 → 26.4 | −21.0% | | `generate-refuses-unparseable-name` | `os generate` | 20.3, 20.9, 20.6 | 18.1, 18.6, 18.4 | 20.6 → 18.4 | −10.9% | | `validate-view-container-name` | `os validate` | 32.3, 31.6, 31.6 | 28.9, 28.2, 28.8 | 31.8 → 28.6 | −10.0% | | `qa-requires-skip-run` | `os qa` | 14.7, 13.3, 14.6 | 13.5, 13.2, 14.1 | 14.2 → 13.6 | −4.2% | | `dev-no-watch.pin` | `os dev` | 53.2, 49.7, 50.4 | 41.4, 42.6, 41.0 | 51.1 → 41.6 | −18.5% | | `migrate-exit-code.e2e` | `os migrate` | 40.2, 37.7, 39.3 | 23.8, 23.1, 23.2 | 39.1 → 23.4 | −40.1% | | `create-refuses-invalid-project-name.e2e` | `os create` | 43.8, 42.2, 46.1 | 28.6, 28.9, 30.1 | 44.0 → 29.2 | −33.7% | Every leg exit 0, with the same test count on both sides (6, 13, 5, 7, 8, 5, 6). The saving is larger on the nightly `.e2e` files, which run without the queue tier's oclif manifest, so each tsx spawn there also paid the full command import twice over. - **All 34 switched files on head** `01d2b0d5` (and again on the merged head, below): queue tier 17/17 files, 125/125 tests; nightly tier 17/17 files, 113/113 tests. - Same output through both binaries: `node bin/run-dev.js --version` and `tsx bin/run-dev.js --version` give byte-identical stdout and stderr on this tree. - `pnpm --filter @objectstack/cli typecheck` (tsc plus `check:test-typecheck`) exit 0. - No ablation: test-only, no tested behaviour changed. ## Acceptance notes - **The biggest remaining tsx lever is the shared helper.** `test/helpers/serve-process.ts` exports `TSX`, and `runServe()` spawns `serve` through it; 20 cli test files call `runServe(`. The order keeps `test/helpers/**` out of this slice because slices 24–28 run on top of it. Carrier: #23181. - **`invocation-loudness.e2e` could move half.** Its two `bin/run-dev.js` spawns (`dev --no-ui`, `--version`) share one runner with the barrel spawns. Kept on tsx as the order names the file, which pins the shims. Carrier: #23181. - **`package-install-local-handlers.integration`'s line-2 header still says "the tsx source entry".** The order forbids touching `// test-budget:` headers in this slice; the next shard-timings refresh resizes and can reword it. - **`skip-changeset`.** Test-only. `@objectstack/cli`'s `files[]` is `dist`, `README.md`, `CHANGELOG.md`; `test/` and `src/**/*.test.ts` do not build into `dist/`, so no `files[]` content changes. ## Verification All readings on head `b2400351` (`git rev-parse --short HEAD`), the merge of `origin/main` after slices 25, 26 and 27 landed (#28601, #28599, #28592). None of them touched these 34 files; the merge had no conflict. - **Derived gate families:** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` gives 52 families. Each ran with its exit code captured before any pipe, after a full `pnpm exec turbo run build --concurrency=2` (118/118 tasks) on the merged tree. `--ran` reconciliation: `✓ dispatch-gates --ran: 52 derived famil(ies) accounted for — 52 run, 0 NOT-MEASURED`. On the pre-merge head `01d2b0d5` the same set (51 families) was green too; there `check:i18n-coverage` first exited 3 (an unbuilt `@objectstack/connector-slack`) and read 0 after the full build, and `check-plugin-teardown-shape.mjs --self-test` needed its positive-control commit fetched on the shallow clone. - **The 34 switched files on the merged head:** queue tier 17/17 files, 125/125 tests; nightly tier 17/17 files, 113/113 tests. - **Hand gates:** `pnpm --filter @objectstack/cli typecheck` exit 0. `pnpm exec eslint --no-inline-config` over the 34 files exit 0 (`@objectstack/cli` has no `lint` script; the repo-wide `pnpm lint` runs in CI). `node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD` exit 0. - **CI** families (Test Core with both cli tiers, the nightly `.e2e` tier on `main`, the lint farm, the type-check lanes) are read off this PR's check-runs by the seat. - Evidence (gate lists with exit codes for both heads, every A/B row, the A/B script): `pm-orders/server/evidence/23181-s29/` in the project files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01FEkQ5pFGjmwfPzsnkVqJPu Co-authored-by: Claude <noreply@anthropic.com>
1 parent d6e0967 commit 49d60d3

34 files changed

Lines changed: 135 additions & 159 deletions

‎packages/cli/src/commands/validate-json-strict-exit.e2e.test.ts‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
* number only exists once Node has exited and the kernel has masked it to
9999
* `& 0xFF`. `test/migrate-exit-code.e2e.test.ts` is the precedent and states
100100
* this in the same words — the audience `--json` exists for reads the SHELL, so
101-
* that is what gets asserted. Spawned through `bin/run-dev.js` + tsx, so the
101+
* that is what gets asserted. Spawned through `bin/run-dev.js` + `node`, so the
102102
* suite does not depend on `packages/cli/dist` having been built.
103103
*
104104
* ## Why this file is not beside its siblings in `packages/cli/test/`
@@ -143,7 +143,6 @@ function linkSpec(dir: string): void {
143143

144144
const HERE = resolve(fileURLToPath(import.meta.url), '..');
145145
const CLI = resolve(HERE, '../../bin/run-dev.js');
146-
const TSX = resolve(HERE, '../../../../node_modules/.bin/tsx');
147146

148147
/**
149148
* The test-only live conversion the child loads with `--import` (its header
@@ -230,7 +229,7 @@ interface Run {
230229
function runCli(args: string[], cwd: string): Promise<Run> {
231230
return new Promise((resolvePromise) => {
232231
execFile(
233-
TSX,
232+
process.execPath,
234233
[CLI, ...args],
235234
{
236235
cwd,

‎packages/cli/test/build-callable-names.test.ts‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
*
4343
* Each kind's fixture carries both collisions against an authored `functions`
4444
* entry (a shared function; an equal name) under disjoint names, round-trips
45-
* through `objectstack build` (`bin/run-dev.js`, source via tsx) and then the
45+
* through `objectstack build` (`bin/run-dev.js`, source under `node`) and then the
4646
* runtime's own `loadArtifactBundle`, and asserts that each authored name ships
4747
* under itself and answers its own code, and that each hook or action ref
4848
* answers its own code. Every callable names a module-scope constant, so no
@@ -66,9 +66,8 @@ import { locateCallables } from '../src/utils/build-runtime.js';
6666

6767
const HERE = resolve(fileURLToPath(import.meta.url), '..');
6868
const CLI = resolve(HERE, '../bin/run-dev.js');
69-
const TSX = resolve(HERE, '../../../node_modules/.bin/tsx');
7069
const LOWER_CALLABLES = resolve(HERE, '../src/utils/lower-callables.ts');
71-
/** A cold `tsx` spawn of the CLI source entry runs well past vitest's 5 s default. */
70+
/** A cold spawn of the CLI source entry runs well past vitest's 5 s default. */
7271
const SPAWN_TIMEOUT_MS = 120_000;
7372

7473
// ── The census ──────────────────────────────────────────────────────────────
@@ -258,7 +257,7 @@ interface Run {
258257
function runCli(args: string[], cwd: string): Promise<Run> {
259258
return new Promise((resolvePromise) => {
260259
execFile(
261-
TSX,
260+
process.execPath,
262261
[CLI, ...args],
263262
{ cwd, maxBuffer: 16 * 1024 * 1024, env: childEnv({ NO_COLOR: '1' }) },
264263
(err, stdout, stderr) => {

‎packages/cli/test/build-connector-spec-file-artifact.e2e.test.ts‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* are kept. The control for the refusal is the same stack with the file
1111
* present, which both commands accept.
1212
*
13-
* Runs the CLI from source (`bin/run-dev.js` through tsx), as the other build
13+
* Runs the CLI from source (`bin/run-dev.js` under `node`), as the other build
1414
* suites do, so `compile.ts` and `validate.ts` are measured without a rebuild.
1515
*/
1616

@@ -25,7 +25,6 @@ import { linkSpec } from './helpers/define-stack-fixture.js';
2525

2626
const HERE = resolve(fileURLToPath(import.meta.url), '..');
2727
const CLI = resolve(HERE, '../bin/run-dev.js');
28-
const TSX = resolve(HERE, '../../../node_modules/.bin/tsx');
2928

3029
const DOCUMENT = {
3130
openapi: '3.0.3',
@@ -72,7 +71,7 @@ afterAll(() => {
7271
function run(command: 'build' | 'validate', cwd: string): Promise<{ code: number; stdout: string; stderr: string }> {
7372
return new Promise((done) => {
7473
execFile(
75-
TSX,
74+
process.execPath,
7675
[CLI, command, '--json'],
7776
{ cwd, maxBuffer: 16 * 1024 * 1024, env: childEnv({ NO_COLOR: '1' }) },
7877
(err, stdout, stderr) =>

‎packages/cli/test/build-demo-staff-artifact.test.ts‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* `functions` entry runs, so a green here is "this one key was left out", not
2424
* "the build wrote nothing".
2525
*
26-
* Runs the CLI from source (`bin/run-dev.js` through tsx), as the other build
26+
* Runs the CLI from source (`bin/run-dev.js` under `node`), as the other build
2727
* suites do, so `compile.ts` is measured without a rebuild.
2828
*/
2929

@@ -39,7 +39,6 @@ import { linkSpec } from './helpers/define-stack-fixture.js';
3939

4040
const HERE = resolve(fileURLToPath(import.meta.url), '..');
4141
const CLI = resolve(HERE, '../bin/run-dev.js');
42-
const TSX = resolve(HERE, '../../../node_modules/.bin/tsx');
4342
const RUNTIME_MODULE = /^objectstack-runtime\.[a-f0-9]+\.mjs$/;
4443

4544
const STAFF_EMAIL = 'counsel1@legal.example';
@@ -79,7 +78,7 @@ afterAll(() => {
7978
function build(cwd: string): Promise<{ code: number; stdout: string; stderr: string }> {
8079
return new Promise((done) => {
8180
execFile(
82-
TSX,
81+
process.execPath,
8382
[CLI, 'build', '--json'],
8483
{ cwd, maxBuffer: 16 * 1024 * 1024, env: childEnv({ NO_COLOR: '1' }) },
8584
(err, stdout, stderr) =>

‎packages/cli/test/build-docs-step-count.e2e.test.ts‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
* and the `--json` face must stay one JSON document, so the machine face is
4545
* asserted to parse and to carry no step text at all.
4646
*
47-
* ALTITUDE: this spawns the CLI (`bin/run-dev.js` through tsx) rather than
47+
* ALTITUDE: this spawns the CLI (`bin/run-dev.js` under `node`) rather than
4848
* calling a helper, because the defect is in the ORDER of two statements inside
4949
* the command body — there is no seam below the process that can observe it.
5050
* Same spawn shape and the same `childEnv()` as
@@ -62,7 +62,6 @@ import { linkSpec } from './helpers/define-stack-fixture.js';
6262

6363
const HERE = resolve(fileURLToPath(import.meta.url), '..');
6464
const CLI = resolve(HERE, '../bin/run-dev.js');
65-
const TSX = resolve(HERE, '../../../node_modules/.bin/tsx');
6665

6766
interface Run {
6867
code: number;
@@ -73,7 +72,7 @@ interface Run {
7372
function runCli(args: string[], cwd: string): Promise<Run> {
7473
return new Promise((resolvePromise) => {
7574
execFile(
76-
TSX,
75+
process.execPath,
7776
[CLI, ...args],
7877
{ cwd, maxBuffer: 16 * 1024 * 1024, env: childEnv({ NO_COLOR: '1' }) },
7978
(err, stdout, stderr) => {

‎packages/cli/test/build-runtime-bundle-bodyless.test.ts‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* `functions` entry resolving to a callable that runs through the runtime's own
2929
* artifact loader (`loadArtifactBundle`, which merges the module's `functions`).
3030
*
31-
* The CLI runs through `bin/run-dev.js` (source, via tsx). Its dependencies,
31+
* The CLI runs through `bin/run-dev.js` (source, under `node`). Its dependencies,
3232
* `@objectstack/runtime` included, resolve through `exports` to `dist/`.
3333
*/
3434

@@ -44,8 +44,7 @@ import { linkSpec } from './helpers/define-stack-fixture.js';
4444

4545
const HERE = resolve(fileURLToPath(import.meta.url), '..');
4646
const CLI = resolve(HERE, '../bin/run-dev.js');
47-
const TSX = resolve(HERE, '../../../node_modules/.bin/tsx');
48-
/** A cold `tsx` spawn of the CLI source entry runs well past vitest's 5 s default. */
47+
/** A cold spawn of the CLI source entry runs well past vitest's 5 s default. */
4948
const SPAWN_TIMEOUT_MS = 120_000;
5049

5150
interface Run {
@@ -57,7 +56,7 @@ interface Run {
5756
function runCli(args: string[], cwd: string): Promise<Run> {
5857
return new Promise((resolvePromise) => {
5958
execFile(
60-
TSX,
59+
process.execPath,
6160
[CLI, ...args],
6261
{ cwd, maxBuffer: 16 * 1024 * 1024, env: childEnv({ NO_COLOR: '1' }) },
6362
(err, stdout, stderr) => {

‎packages/cli/test/build-seed-files-artifact.e2e.test.ts‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* and SHA-256 under `files`, keyed by the path. The control for the refusal is
1212
* the same stack with the file present, which both commands accept.
1313
*
14-
* Runs the CLI from source (`bin/run-dev.js` through tsx), as the other build
14+
* Runs the CLI from source (`bin/run-dev.js` under `node`), as the other build
1515
* suites do, so `compile.ts` and `validate.ts` are measured without a rebuild.
1616
*/
1717

@@ -28,7 +28,6 @@ import { linkSpec } from './helpers/define-stack-fixture.js';
2828

2929
const HERE = resolve(fileURLToPath(import.meta.url), '..');
3030
const CLI = resolve(HERE, '../bin/run-dev.js');
31-
const TSX = resolve(HERE, '../../../node_modules/.bin/tsx');
3231

3332
const PDF = '%PDF-1.7 a seeded contract';
3433

@@ -76,7 +75,7 @@ afterAll(() => {
7675
function run(command: 'build' | 'validate', cwd: string): Promise<{ code: number; stdout: string; stderr: string }> {
7776
return new Promise((done) => {
7877
execFile(
79-
TSX,
78+
process.execPath,
8079
[CLI, command, '--json'],
8180
{ cwd, maxBuffer: 16 * 1024 * 1024, env: childEnv({ NO_COLOR: '1' }) },
8281
(err, stdout, stderr) =>

‎packages/cli/test/build-strict-body-count.test.ts‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
* This file pins the door: the header's number, and the `--json` list, on the
2222
* real command.
2323
*
24-
* The CLI runs through `bin/run-dev.js` (source, via tsx). Its dependencies
24+
* The CLI runs through `bin/run-dev.js` (source, under `node`). Its dependencies
2525
* resolve through `exports` to `dist/`.
2626
*/
2727

@@ -36,8 +36,7 @@ import { defineStackSourceFromLiteral, linkSpec } from './helpers/define-stack-f
3636

3737
const HERE = resolve(fileURLToPath(import.meta.url), '..');
3838
const CLI = resolve(HERE, '../bin/run-dev.js');
39-
const TSX = resolve(HERE, '../../../node_modules/.bin/tsx');
40-
/** A cold `tsx` spawn of the CLI source entry runs well past vitest's 5 s default. */
39+
/** A cold spawn of the CLI source entry runs well past vitest's 5 s default. */
4140
const SPAWN_TIMEOUT_MS = 120_000;
4241

4342
interface Run {
@@ -49,7 +48,7 @@ interface Run {
4948
function runCli(args: string[], cwd: string): Promise<Run> {
5049
return new Promise((resolvePromise) => {
5150
execFile(
52-
TSX,
51+
process.execPath,
5352
[CLI, ...args],
5453
{ cwd, maxBuffer: 16 * 1024 * 1024, env: childEnv({ NO_COLOR: '1' }) },
5554
(err, stdout, stderr) => {

‎packages/cli/test/build-view-container-name.test.ts‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* actually throws for the same payload, driven through `ObjectQL.registerApp`,
2727
* rather than a literal copy of the words.
2828
*
29-
* The CLI runs through `bin/run-dev.js` (source, via tsx); its dependencies —
29+
* The CLI runs through `bin/run-dev.js` (source, under `node`); its dependencies —
3030
* `@objectstack/objectql` among them — resolve through `exports` to `dist/`.
3131
*/
3232

@@ -42,8 +42,7 @@ import { defineStackSource, linkSpec } from './helpers/define-stack-fixture.js';
4242

4343
const HERE = resolve(fileURLToPath(import.meta.url), '..');
4444
const CLI = resolve(HERE, '../bin/run-dev.js');
45-
const TSX = resolve(HERE, '../../../node_modules/.bin/tsx');
46-
/** A cold `tsx` spawn of the CLI source entry runs well past vitest's 5 s default. */
45+
/** A cold spawn of the CLI source entry runs well past vitest's 5 s default. */
4746
const SPAWN_TIMEOUT_MS = 120_000;
4847
/** `os build`'s default `--output`, relative to the working directory. */
4948
const ARTIFACT = join('dist', 'objectstack.json');
@@ -57,7 +56,7 @@ interface Run {
5756
function runCli(args: string[], cwd: string): Promise<Run> {
5857
return new Promise((resolvePromise) => {
5958
execFile(
60-
TSX,
59+
process.execPath,
6160
[CLI, ...args],
6261
{ cwd, maxBuffer: 16 * 1024 * 1024, env: childEnv({ NO_COLOR: '1' }) },
6362
(err, stdout, stderr) => {

‎packages/cli/test/create-refuses-invalid-project-name.e2e.test.ts‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
* length rule into the shared validator would break `init` for a name npm
4545
* accepts; this test is what says so.
4646
*
47-
* Spawned through `bin/run-dev.js` + tsx, so the suite does not depend on
47+
* Spawned through `bin/run-dev.js` + `node`, so the suite does not depend on
4848
* `packages/cli/dist` having been built — `@objectstack/cli#test` depends on
4949
* `^build` only (the reason `invocation-loudness.e2e.test.ts` spawns that way).
5050
*/
@@ -67,9 +67,8 @@ import { NPM_PACKAGE_NAME_MAX_LENGTH, validateProjectName } from '../src/command
6767

6868
const HERE = resolve(fileURLToPath(import.meta.url), '..');
6969
const CLI = resolve(HERE, '../bin/run-dev.js');
70-
const TSX = resolve(HERE, '../../../node_modules/.bin/tsx');
7170

72-
/** oclif + tsx cold start with every command module loaded; ~2-10 s when healthy. */
71+
/** oclif cold start with every command module loaded; ~2-10 s when healthy. */
7372
const RUN_TIMEOUT_MS = 180_000;
7473

7574
/** The card's input: a capital and a space, both npm-invalid. */
@@ -93,7 +92,7 @@ interface Run {
9392
function runCli(args: string[], cwd: string): Promise<Run> {
9493
return new Promise((resolvePromise) => {
9594
execFile(
96-
TSX,
95+
process.execPath,
9796
[CLI, ...args],
9897
{ cwd, maxBuffer: 8 * 1024 * 1024, env: childEnv({ NO_COLOR: '1' }) },
9998
(err, stdout, stderr) => {

0 commit comments

Comments
 (0)