fix: handle with { type: "file" } import attributes in tsx dev mode#1009
Closed
betegon wants to merge 2 commits into
Closed
fix: handle with { type: "file" } import attributes in tsx dev mode#1009betegon wants to merge 2 commits into
betegon wants to merge 2 commits into
Conversation
Align CI secret references with the actual secret names set in the production environment: - `secrets.CSC_LINK` → `secrets.APPLE_CERT_DATA` - `secrets.CSC_KEY_PASSWORD` → `secrets.APPLE_CERT_PASSWORD` - `vars.APPLE_TEAM_ID` → `secrets.APPLE_TEAM_ID` The previous names were copied from Spotlight's workflow but the secrets were set with different names in this repo.
In Bun, `with { type: "file" }` import attributes work natively.
In esbuild builds, text-import-plugin transforms them at bundle time.
In tsx dev mode, Node.js throws ERR_IMPORT_ATTRIBUTE_UNSUPPORTED because
it only supports `with { type: "json" }`. This caused ink-ui.ts to fail
to load entirely, falling back to LoggingUI and producing:
Error: The interactive UI failed to load. Run with --yes for non-interactive mode.
Fix: register a synchronous Node.js module hook in require-shim.mjs via
registerHooks() (available from Node 22.15, our minimum) that intercepts
`with { type: "file" }` imports and returns the file's absolute path as
a default export — matching Bun's native behaviour.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Contributor
Codecov Results 📊✅ Patch coverage is 100.00%. Project has 4235 uncovered lines. Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 81.86% 81.87% +0.01%
==========================================
Files 328 328 —
Lines 23351 23359 +8
Branches 15114 15114 —
==========================================
+ Hits 19115 19124 +9
- Misses 4236 4235 -1
- Partials 1621 1621 —Generated by Codecov Action |
Member
|
Changes incorporated into #1008 (file import hook + createRequire fixes) |
BYK
added a commit
that referenced
this pull request
May 22, 2026
Documents the critical esbuild bundling rule that caused two post-migration bugs (#1008, #1009): **esbuild only statically resolves bare `require()` calls.** Any aliased require (`_require`, `localRequire`, etc.) passes through as-is into the bundle and breaks at runtime when used with relative paths. Adds a reference table and 4 key rules to AGENTS.md so AI agents and contributors avoid this pattern. Filed #1010 for the companion testing improvements (deeper smoke tests for binary + npm bundle).
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.
Depends on #1008.
Problem
ink-ui.tsimports the Ink app sidecar using awith { type: "file" }import attribute:This is a static module-level import, so Node.js evaluates it when
ink-ui.tsis first loaded. Node.js only supportswith { type: "json" }— everything else throwsERR_IMPORT_ATTRIBUTE_UNSUPPORTED. The factory catches the error and falls back toLoggingUI, butLoggingUIcan't do interactive prompts, so the wizard fails with:This affected anyone running
pnpm cli initorpnpm tsx /path/to/bin.ts initin a real terminal — the interactive wizard UI was never reachable in dev mode.Why it worked before: Bun supports
with { type: "file" }natively. In esbuild builds,text-import-plugintransforms the attribute away before Node.js ever sees it.Fix
Register a synchronous Node.js module hook in
require-shim.mjsusingregisterHooks()(available from Node 22.15, our minimum). When a module is imported withwith { type: "file" }, the hook returns a synthetic ESM module that exports the file's absolute path as a string — the same behaviour Bun provides natively.Test plan
Note: tsx v4.20.6 itself emits a
[DEP0205]deprecation warning formodule.register()— that's a tsx bug unrelated to this change.