Skip to content

fix(commands): construct complete synthetic key events - #774

Open
nightcityblade wants to merge 2 commits into
modem-dev:mainfrom
nightcityblade:fix/issue-767
Open

fix(commands): construct complete synthetic key events#774
nightcityblade wants to merge 2 commits into
modem-dev:mainfrom
nightcityblade:fix/issue-767

Conversation

@nightcityblade

Copy link
Copy Markdown

Problem and impact

Synthetic command events were partial objects asserted as KeyEvent. Matchers or programmatic handlers that inspected required event metadata or propagation state could observe missing or inert behavior.

Approach

Construct OpenTUI's exported KeyEvent with the existing chord fields plus explicit press / raw synthetic defaults. This keeps chord matching unchanged while using OpenTUI's real prevention and propagation state. No command-dispatch or public extension API behavior is otherwise changed.

This belongs in the existing core command-key helper because it owns synthetic events used by conflict detection and command invocation.

Verification

  • bun test src/lib/commandKeys.test.ts (3 passed)
  • bunx oxfmt --check src/lib/commandKeys.ts src/lib/commandKeys.test.ts .changeset/complete-synthetic-key-events.md
  • bunx oxlint src/lib/commandKeys.ts src/lib/commandKeys.test.ts --deny-warnings
  • bun run typecheck

Tested on macOS. No visual evidence is applicable because this changes the internal event contract without altering rendering.

Fixes #767

@greptile-apps

greptile-apps Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

PR author is not in the allowed authors list.

@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the Modem Team on Vercel.

A member of the Team first needs to authorize it.

@benvinegar

Copy link
Copy Markdown
Member

The intended fix here makes sense: constructing a real KeyEvent provides the missing metadata and functional propagation state.

However, changing the type-only import to a runtime @opentui/core import introduces a headless-path regression. src/lib/commandKeys.ts is also imported by src/extensions/runExtension.ts for parsing helpers, so compiled static-pager execution now evaluates OpenTUI and extracts its native library even though no synthetic event is created.

This reproduces in test/cli/compiled-headless-native-lib.test.ts: current main passes all five tests, while this change causes keeps captured-host static pager rendering OpenTUI-free to fail with an extracted .so.

Could we split the runtime-dependent synthesis into an interactive-only module—for example, src/ui/lib/syntheticKeyEvent.ts—and leave parseKeyChord/toKeyChordList in the headless-safe commandKeys.ts module? appCommands.ts and extensionCommands.ts could import the synthesis helper directly. That preserves the synchronous API and real KeyEvent behavior without pulling OpenTUI into headless consumers.

This comment was generated by Pi using GPT-5.6 Sol

@nightcityblade

Copy link
Copy Markdown
Author

Thanks for the precise report. Fixed in 633ba60: the runtime KeyEvent construction now lives in the interactive-only src/ui/lib/syntheticKeyEvent.ts, while src/lib/commandKeys.ts is back to a type-only OpenTUI import. The interactive command builders import the synthesis helper directly.

Verification:

  • bun run typecheck
  • bunx oxlint ... --deny-warnings
  • 35 focused command tests passed
  • compiled headless suite: 3 passed, 1 Linux-only static-pager case skipped on macOS (CI will exercise it)

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.

Construct complete OpenTUI KeyEvent instances for synthetic command events

2 participants