Skip to content

fix(modifiers): fail closed when modifiers-napi is the public stub#47

Merged
xjdr-noumena merged 2 commits into
mainfrom
fix/apple-terminal-modifiers-stub-44
Jul 1, 2026
Merged

fix(modifiers): fail closed when modifiers-napi is the public stub#47
xjdr-noumena merged 2 commits into
mainfrom
fix/apple-terminal-modifiers-stub-44

Conversation

@xjdr-noumena

@xjdr-noumena xjdr-noumena commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

modifiers-napi@0.0.1 on public npm is a reservation stub with no exports. isModifierPressed previously destructured isModifierPressed from require('modifiers-napi') and called it unconditionally — when the stub resolves, the function is undefined and the call throws TypeError: nativeIsModifierPressed is not a function on every Enter keystroke.

The only call site (src/hooks/useTextInput.ts:263 in handleEnter) is gated on env.terminal === 'Apple_Terminal' as a workaround for Apple Terminal not supporting custom Shift+Enter keybindings. The throw bubbles up through the Ink input dispatch and blocks the Enter submit pipeline, so Terminal.app users cannot submit prompts interactively. Every other terminal (iTerm2, Ghostty, Kitty, VSCode) takes a different branch and is unaffected.

Fix

Guard the destructure. If the export is not a function, fail closed: report the modifier as not pressed. This disables best-effort Shift+Enter newline detection on Apple Terminal (a nicety) while restoring Enter submit. Returning false is the safe fallback — the path only ever asked whether Shift was held.

prewarmModifiers is already wrapped in try/catch and is unaffected.

Tests

src/utils/modifiers.test.ts adds two cases:

  • darwin + stub-shape (no isModifierPressed export): returns false instead of throwing. This is the exact regression that blocked Enter on Apple Terminal.
  • non-darwin: returns false without ever consulting the stub.

Verified locally: bun test src/utils/modifiers.test.ts → 2 pass, 0 fail. Package smoke (bun run test:package-smoke) builds clean on this branch.

What this doesn't claim

  • I did not run an end-to-end Enter-submit test under real TERM_PROGRAM=Apple_Terminal — that requires macOS Terminal.app. The unit test proves the guard path runs and returns false rather than throwing the TypeError; reporter (@RasputinKaiser) can verify the interactive Enter submit.

Closes #44.

Follow-up

The deeper pattern — modifiers-napi being a reservation stub in the OSS dependency tree — is the same class of stub problem tracked in #42 (native image processor). A real modifiers-napi N-API binding to CGEventSourceFlagsState would close the gap permanently and re-enable the Apple Terminal Shift+Enter newline detection. That belongs with #42, not this fix.

modifiers-napi@0.0.1 on public npm is a reservation stub with no
exports. The previous isModifierPressed destructured
isModifierPressed: nativeIsModifierPressed from require('modifiers-napi')
and called it unconditionally. When the stub is the resolved package,
nativeIsModifierPressed is undefined and the call throws
'nativeIsModifierPressed is not a function' on every Enter keystroke
at useTextInput.ts:263, which gates on env.terminal === 'Apple_Terminal'
to work around Apple Terminal not supporting custom Shift+Enter
keybindings. The throw bubbles up through the Ink input dispatch and
blocks the Enter submit pipeline, so Terminal.app users cannot submit
prompts interactively.

Guard the destructure: if the export is not a function, report the
modifier as not pressed. This disables best-effort Shift+Enter newline
detection on Apple Terminal (a nicety) while restoring Enter submit.
Returning false is the safe fallback since the path only ever asked
whether Shift was held. The prewarm path is already wrapped in
try/catch and is unaffected.

Adds src/utils/modifiers.test.ts with two cases:
- darwin + stub (no isModifierPressed export): returns false instead
  of throwing. This is the regression that blocked Enter on Apple
  Terminal.
- non-darwin: returns false without consulting the stub.

Refs: #44
@RasputinKaiser

Copy link
Copy Markdown

It's working for me

@RasputinKaiser RasputinKaiser left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works locally for me

@xjdr-noumena xjdr-noumena merged commit 131b6f8 into main Jul 1, 2026
3 checks passed
@xjdr-noumena xjdr-noumena deleted the fix/apple-terminal-modifiers-stub-44 branch July 1, 2026 03:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enter/Return doesn't submit on Apple Terminal — modifiers-napi is an empty reservation stub

2 participants