refactor(repo): drop bun for vitest, node, and esbuild - #130
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ce08fe4a6e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Addresses review on #130. - tryCatch branched on `fn instanceof Promise`, so an execa subprocess — a thenable that is NOT a native Promise, yet typed `extends Promise<Result>` — fell through to the sync path and got *called*. Every deploy would have reported "Railway CLI not found" from assertCli() before reaching Railway. It now branches on callable and assimilates the thenable via Promise.resolve, which also lets the ad-hoc Promise.resolve() wrappers at the other execa call sites go away so all of them read the same. - Restored `prestart` on all four bots. `start` runs `dist/src/index.js`, which a clean checkout does not have; the images build at image-build time and their CMD never fires a pre-script, so this only affects the documented local path. `{.}...` scopes the build to the bot plus its workspace deps. - market-making declares `vite` (its vitest.config.ts imports loadEnv) instead of relying on root hoisting, matching the two liquidation bots. - Registered scripts/bundle-failed.error.ts in check-jsdoc.ts, typedoc.json, and the build-jsdoc skill inventory. - .claude/commands: babysit-pr's validate block runs `pnpm test`, review.md's stack list names vitest/esbuild/Node. (CLAUDE.md's remaining "bun" is a verbatim past commit title used as a format example, so it stays.) - Declaring vite in market-making shifted knip's peer attribution and exposed root `tsx` as unused. It is not: `node --import tsx` and the CLI subprocess tests resolve it from the root, and dropping it fails two market-making tests. knip now ignores it explicitly, with the reason recorded at the usage. Verified: 1417 pass / 1 skip / 136 files (fork suites included, RPC_URL_8453 supplied); the two new tryCatch tests reproduce `fn is not a function` against the old implementation; a real execa call through tryCatch now succeeds for a present binary and still errors for a missing one; all four bots build from wiped dists via prestart and reach their fail-loud config check; all three images build, run as uid=1000(node), carry no bun binary, and reach that same check; pnpm lint 0/0, knip clean, 12/12 typecheck, jsdoc:build exits 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Addresses review on #130. - tryCatch branched on `fn instanceof Promise`, so an execa subprocess — a thenable that is NOT a native Promise, yet typed `extends Promise<Result>` — fell through to the sync path and got *called*. Every deploy would have reported "Railway CLI not found" from assertCli() before reaching Railway. It now branches on callable and assimilates the thenable via Promise.resolve, which also lets the ad-hoc Promise.resolve() wrappers at the other execa call sites go away so all of them read the same. - Restored `prestart` on all four bots. `start` runs `dist/src/index.js`, which a clean checkout does not have; the images build at image-build time and their CMD never fires a pre-script, so this only affects the documented local path. `{.}...` scopes the build to the bot plus its workspace deps. - market-making declares `vite` (its vitest.config.ts imports loadEnv) instead of relying on root hoisting, matching the two liquidation bots. - Registered scripts/bundle-failed.error.ts in check-jsdoc.ts, typedoc.json, and the build-jsdoc skill inventory. - .claude/commands: babysit-pr's validate block runs `pnpm test`, review.md's stack list names vitest/esbuild/Node. (CLAUDE.md's remaining "bun" is a verbatim past commit title used as a format example, so it stays.) - Declaring vite in market-making shifted knip's peer attribution and exposed root `tsx` as unused. It is not: `node --import tsx` and the CLI subprocess tests resolve it from the root, and dropping it fails two market-making tests. knip now ignores it explicitly, with the reason recorded at the usage. Verified: 1417 pass / 1 skip / 136 files (fork suites included, RPC_URL_8453 supplied); the two new tryCatch tests reproduce `fn is not a function` against the old implementation; a real execa call through tryCatch now succeeds for a present binary and still errors for a missing one; all four bots build from wiped dists via prestart and reach their fail-loud config check; all three images build, run as uid=1000(node), carry no bun binary, and reach that same check; pnpm lint 0/0, knip clean, 12/12 typecheck, jsdoc:build exits 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
c135e89 to
c644283
Compare
Heads-up: GitHub reports this stacked PR as conflicting, and git disagreesGitHub shows There was a real conflict, and it is now fixed. After that merge, git reports no conflict from any angle: GitHub has not recomputed. The usual escape hatches are both closed for a stack:
A rebase onto the updated parent (verified byte-identical tree) and a fresh push did not clear it either. What is needed: someone with the PR open in the browser hitting the stack's Restack / Update control, which is the only path the API leaves for a stacked PR. Merging #129 first would also collapse the stack and moot it. Once the state clears, Checks will run on the next push. Everything is verified locally in the meantime: 1459 pass / 1 skip / 141 files (fork suites included), vitest collects exactly the 141 tracked |
ddacbad to
0244681
Compare
Resolved — the stack is rebased and checks are runningMy previous comment said this needed the Restack control in the browser. That was wrong: the fix is All three PRs now report Two notes on what the rebase needed by hand:
Verified after the restack, per branch:
|
Addresses review on #130. - tryCatch branched on `fn instanceof Promise`, so an execa subprocess — a thenable that is NOT a native Promise, yet typed `extends Promise<Result>` — fell through to the sync path and got *called*. Every deploy would have reported "Railway CLI not found" from assertCli() before reaching Railway. It now branches on callable and assimilates the thenable via Promise.resolve, which also lets the ad-hoc Promise.resolve() wrappers at the other execa call sites go away so all of them read the same. - Restored `prestart` on all four bots. `start` runs `dist/src/index.js`, which a clean checkout does not have; the images build at image-build time and their CMD never fires a pre-script, so this only affects the documented local path. `{.}...` scopes the build to the bot plus its workspace deps. - market-making declares `vite` (its vitest.config.ts imports loadEnv) instead of relying on root hoisting, matching the two liquidation bots. - Registered scripts/bundle-failed.error.ts in check-jsdoc.ts, typedoc.json, and the build-jsdoc skill inventory. - .claude/commands: babysit-pr's validate block runs `pnpm test`, review.md's stack list names vitest/esbuild/Node. (CLAUDE.md's remaining "bun" is a verbatim past commit title used as a format example, so it stays.) - Declaring vite in market-making shifted knip's peer attribution and exposed root `tsx` as unused. It is not: `node --import tsx` and the CLI subprocess tests resolve it from the root, and dropping it fails two market-making tests. knip now ignores it explicitly, with the reason recorded at the usage. Verified: 1417 pass / 1 skip / 136 files (fork suites included, RPC_URL_8453 supplied); the two new tryCatch tests reproduce `fn is not a function` against the old implementation; a real execa call through tryCatch now succeeds for a present binary and still errors for a missing one; all four bots build from wiped dists via prestart and reach their fail-loud config check; all three images build, run as uid=1000(node), carry no bun binary, and reach that same check; pnpm lint 0/0, knip clean, 12/12 typecheck, jsdoc:build exits 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
0244681 to
fc4087e
Compare
Addresses review on #130. - tryCatch branched on `fn instanceof Promise`, so an execa subprocess — a thenable that is NOT a native Promise, yet typed `extends Promise<Result>` — fell through to the sync path and got *called*. Every deploy would have reported "Railway CLI not found" from assertCli() before reaching Railway. It now branches on callable and assimilates the thenable via Promise.resolve, which also lets the ad-hoc Promise.resolve() wrappers at the other execa call sites go away so all of them read the same. - Restored `prestart` on all four bots. `start` runs `dist/src/index.js`, which a clean checkout does not have; the images build at image-build time and their CMD never fires a pre-script, so this only affects the documented local path. `{.}...` scopes the build to the bot plus its workspace deps. - market-making declares `vite` (its vitest.config.ts imports loadEnv) instead of relying on root hoisting, matching the two liquidation bots. - Registered scripts/bundle-failed.error.ts in check-jsdoc.ts, typedoc.json, and the build-jsdoc skill inventory. - .claude/commands: babysit-pr's validate block runs `pnpm test`, review.md's stack list names vitest/esbuild/Node. (CLAUDE.md's remaining "bun" is a verbatim past commit title used as a format example, so it stays.) - Declaring vite in market-making shifted knip's peer attribution and exposed root `tsx` as unused. It is not: `node --import tsx` and the CLI subprocess tests resolve it from the root, and dropping it fails two market-making tests. knip now ignores it explicitly, with the reason recorded at the usage. Verified: 1417 pass / 1 skip / 136 files (fork suites included, RPC_URL_8453 supplied); the two new tryCatch tests reproduce `fn is not a function` against the old implementation; a real execa call through tryCatch now succeeds for a present binary and still errors for a missing one; all four bots build from wiped dists via prestart and reach their fail-loud config check; all three images build, run as uid=1000(node), carry no bun binary, and reach that same check; pnpm lint 0/0, knip clean, 12/12 typecheck, jsdoc:build exits 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fc4087e to
b9e5524
Compare
Addresses review on #130. - tryCatch branched on `fn instanceof Promise`, so an execa subprocess — a thenable that is NOT a native Promise, yet typed `extends Promise<Result>` — fell through to the sync path and got *called*. Every deploy would have reported "Railway CLI not found" from assertCli() before reaching Railway. It now branches on callable and assimilates the thenable via Promise.resolve, which also lets the ad-hoc Promise.resolve() wrappers at the other execa call sites go away so all of them read the same. - Restored `prestart` on all four bots. `start` runs `dist/src/index.js`, which a clean checkout does not have; the images build at image-build time and their CMD never fires a pre-script, so this only affects the documented local path. `{.}...` scopes the build to the bot plus its workspace deps. - market-making declares `vite` (its vitest.config.ts imports loadEnv) instead of relying on root hoisting, matching the two liquidation bots. - Registered scripts/bundle-failed.error.ts in check-jsdoc.ts, typedoc.json, and the build-jsdoc skill inventory. - .claude/commands: babysit-pr's validate block runs `pnpm test`, review.md's stack list names vitest/esbuild/Node. (CLAUDE.md's remaining "bun" is a verbatim past commit title used as a format example, so it stays.) - Declaring vite in market-making shifted knip's peer attribution and exposed root `tsx` as unused. It is not: `node --import tsx` and the CLI subprocess tests resolve it from the root, and dropping it fails two market-making tests. knip now ignores it explicitly, with the reason recorded at the usage. Verified: 1417 pass / 1 skip / 136 files (fork suites included, RPC_URL_8453 supplied); the two new tryCatch tests reproduce `fn is not a function` against the old implementation; a real execa call through tryCatch now succeeds for a present binary and still errors for a missing one; all four bots build from wiped dists via prestart and reach their fail-loud config check; all three images build, run as uid=1000(node), carry no bun binary, and reach that same check; pnpm lint 0/0, knip clean, 12/12 typecheck, jsdoc:build exits 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
b9e5524 to
9b903a6
Compare
e0783c9 to
cfd1133
Compare
Completes the toolchain consolidation started by the pnpm migration. All 136 test files move from bun:test to vitest (soltag sol`` via its vite adapter, fork-suite env via loadEnv); bots bundle with esbuild and run plain node dist/src/index.js; images are node-slim with no bun binary; CI drops setup-bun and runs pnpm test. Bun APIs replaced: Bun.env->process.env (59), Bun.spawn->node:child_process, Bun.serve->node:http, Bun.file->readFile, Bun.sleep->node:timers/promises, Bun.which, Bun.argv->process.argv, import.meta.dir/main, bun's $ shell->execa, global confirm()->node:readline/promises, and the `bun` module type imports. Bun.build in @repo/contracts also moves to esbuild. Three latent bugs surfaced and are fixed: - 24 floating expect(...).rejects assertions that bun's typings hid. They never asserted anything; oxlint's no-floating-promises catches them under vitest typings. - Anvil fork ports collided once files ran in parallel. bun's runner was serial, so fixed ports were only deconflicted within a bot. Every fork suite now claims a distinct port and the registry is documented. - fetch.preconnect in http-json.utils.ts was a bun-only extension to fetch. Two bounds are raised because the interpreter genuinely changed: a tsx cold start costs ~1.3s against bun's ~0.1s, so the market-making subprocess tests get a 30s ceiling and the FIFO fail-closed probe a 10s bound. Both still prove what they were written to prove. Evidence: vitest collects exactly the same 136 files as bun (diffed, zero delta, including the one test outside test/); @repo/contracts' abis/*.json and dist/index.d.ts are byte-identical across Bun.build->esbuild; the secret path in deploy-railway still reaches stdin and never argv (probed); all 11 projects verified non-vacuous. Full suite green: 1415 pass, 1 skip. CRTR-2822 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Addresses review on #130. - tryCatch branched on `fn instanceof Promise`, so an execa subprocess — a thenable that is NOT a native Promise, yet typed `extends Promise<Result>` — fell through to the sync path and got *called*. Every deploy would have reported "Railway CLI not found" from assertCli() before reaching Railway. It now branches on callable and assimilates the thenable via Promise.resolve, which also lets the ad-hoc Promise.resolve() wrappers at the other execa call sites go away so all of them read the same. - Restored `prestart` on all four bots. `start` runs `dist/src/index.js`, which a clean checkout does not have; the images build at image-build time and their CMD never fires a pre-script, so this only affects the documented local path. `{.}...` scopes the build to the bot plus its workspace deps. - market-making declares `vite` (its vitest.config.ts imports loadEnv) instead of relying on root hoisting, matching the two liquidation bots. - Registered scripts/bundle-failed.error.ts in check-jsdoc.ts, typedoc.json, and the build-jsdoc skill inventory. - .claude/commands: babysit-pr's validate block runs `pnpm test`, review.md's stack list names vitest/esbuild/Node. (CLAUDE.md's remaining "bun" is a verbatim past commit title used as a format example, so it stays.) - Declaring vite in market-making shifted knip's peer attribution and exposed root `tsx` as unused. It is not: `node --import tsx` and the CLI subprocess tests resolve it from the root, and dropping it fails two market-making tests. knip now ignores it explicitly, with the reason recorded at the usage. Verified: 1417 pass / 1 skip / 136 files (fork suites included, RPC_URL_8453 supplied); the two new tryCatch tests reproduce `fn is not a function` against the old implementation; a real execa call through tryCatch now succeeds for a present binary and still errors for a missing one; all four bots build from wiped dists via prestart and reach their fail-loud config check; all three images build, run as uid=1000(node), carry no bun binary, and reach that same check; pnpm lint 0/0, knip clean, 12/12 typecheck, jsdoc:build exits 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
main gained #121/#124/#125 after this branch's merge-base, adding test files that still import bun:test and call bun's mock(). Linearizing the stack dropped these conversions along with the merge commit that carried them, so they are restored here as their own commit: 7 files moved to vitest imports and mock() -> vi.fn(). Tree is byte-identical to the verified pre-rebase state. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fbf6a3d to
c4bc9c0
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c4bc9c0ab0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
cashd
left a comment
There was a problem hiding this comment.
I think this can use a /simplify run - otherwise lgtm
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c1c85dbd73
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Remove Bun in favor of Vitest, Node, and esbuild
#129 has merged, so this PR targets
maindirectly and completes the repository migration away from Bun:The reconciliation also ports the market-making bootstrap, field-visibility, Railway deployment, and Railway utility work inherited from
main.Review remediation
market-making:playgroundalias and removes remaining live Bun commands and runtime descriptions;--outDircontract and adds an executable regression test; andValidation
pnpm install --frozen-lockfilewith pnpm's isolated layoutpnpm -r run typecheckpnpm lintpnpm formatpnpm knippnpm --filter @morpho-org/market-making-bot run jsdoc:buildforge test --root packages/contracts --offline -vv— 16 passedgit diff --checkThe local
pnpm testrun completed 1,666 tests with 2 skipped; its only three failing suites require the unavailableRPC_URL_8453credential. GitHub Actions supplies that credential and is authoritative for the full-suite result.