Skip to content

chore: renderer crash fix, option-parsing refactor, CI, and docs - #7

Merged
aorumbayev merged 4 commits into
mainfrom
renderer-hook-fix
Jul 8, 2026
Merged

chore: renderer crash fix, option-parsing refactor, CI, and docs#7
aorumbayev merged 4 commits into
mainfrom
renderer-hook-fix

Conversation

@aorumbayev

Copy link
Copy Markdown
Member

Batch of four unrelated changes that accumulated on this branch. Listed separately since a squash merge collapses them into one commit.

fix: route renderer, keyboard, and keymap through TuiPluginApi

The npm-installed plugin bundles its own @opentui/solid and @opentui/keymap/solid copies, whose Solid context the host never populates. useTerminalDimensions / useKeyboard / useBindings therefore threw "No renderer found" / "Keymap not found" on install (the Ubuntu crash). All renderer dimensions, keyboard input, and keymap registration now go through the host-provided api — the one object identical across module copies.

  • board keys → api.keymap.registerLayer({ mode: "base" }), matching tui.tsx
  • dialog keys → api.keymap.intercept via a small useKeyIntercept wrapper
  • dimensions → useRendererDimensions over api.renderer resize events
  • reactivity-guard test fails the build if a context hook reappears
  • create-task: Enter reaches the description textarea as a newline again (ctrl+enter still submits)

refactor: centralize plugin option parsing in a single schema

Plugin option parsing consolidated into one schema (src/options.ts) with matching tests.

ci: cancel superseded check runs and add workflow linting

Concurrency cancels in-flight check runs on new pushes; adds a workflow-lint job.

docs: add CONTRIBUTING guide

Test plan

  • bun run check green: prettier, oxlint, tsc, 635 tests pass, package bundle check passes
  • Verified no @opentui/solid / @opentui/keymap/solid context-hook imports remain in src/

🤖 Generated with Claude Code

aorumbayev and others added 4 commits July 9, 2026 01:11
Replace the scattered per-field typeof/Number.isInteger option guards with one OptionsSchema in src/options.ts and a parseOptions() reader; task.ts, intake.ts, and validator.ts derive option values from it. Defaults and accept/reject behavior are unchanged. The complex commands/validatorModels readers are left as-is (they transform rather than validate).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a cancel-in-progress concurrency guard to check.yml so a newer push supersedes an in-flight run, and add a path-filtered lint-workflows.yml that runs actionlint (SHA-pinned) on workflow changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A short, plain-language starting point: prerequisites, local setup and dev-install, the bun run check gate, conventional-commit/PR conventions, and pointers to AGENTS.md and .specs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The npm-installed plugin bundles its own @opentui/solid and
@opentui/keymap/solid copies, whose Solid context the host never
populates. useTerminalDimensions/useKeyboard/useBindings therefore
threw "No renderer found" / "Keymap not found" on install (the Ubuntu
crash). Route all renderer dimensions, keyboard input, and keymap
registration through the host-provided TuiPluginApi instead — the one
object identical across module copies.

- board keys: api.keymap.registerLayer(mode "base"), matching tui.tsx
- dialog keys: api.keymap.intercept via useKeyIntercept
- dimensions: useRendererDimensions over api.renderer resize events
- reactivity-guard test fails the build if a context hook reappears
- create-task: let Enter reach the description textarea as a newline
  (ctrl+enter still submits) instead of consuming it

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown

Greptile Summary

This PR updates TUI input/rendering paths and adds supporting cleanup. The main changes are:

  • Routes renderer dimensions, keyboard input, and board keymap layers through TuiPluginApi.
  • Centralizes plugin option parsing in src/options.ts.
  • Adds workflow concurrency and a workflow-lint CI job.
  • Adds contributor setup and validation documentation.

Confidence Score: 4/5

One contained board keymap bug needs to be fixed before merging.

The refactor is mostly scoped and covered, but board commands remain active while dialogs are open, which can break input handling in the main TUI flow.

src/board.tsx

T-Rex T-Rex Logs

What T-Rex did

  • Reproduced the restore-dialog gating scenario by running a focused Bun/Solid repro test that mounts Board with api.ui.dialog.open set to true and captures the registered keymap layer.
  • Dispatched the registered kagan.new command while the dialog was open and observed api.ui.dialog.replace being invoked, showing the board command fires during an open dialog.
  • Collected and inspected artifacts demonstrating the repro: the focused test harness and its Bun test output support the dialog-open behavior verification.
  • Reviewed the check/test plan run, noting that Prettier halted due to internal non-PR files and the import-scan exited with no matches, making the overall result inconclusive.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
src/board.tsx Moves dimensions/keymap registration through TuiPluginApi, but the board layer no longer disables while dialogs are open.
src/tui-renderer.tsx Adds TuiPluginApi-backed renderer dimension and key intercept helpers.
src/options.ts Adds centralized zod parsing for supported plugin options.
src/create-task.tsx Routes create-task keyboard handling through api.keymap.intercept and preserves textarea Enter behavior.
src/settings.tsx Routes settings keyboard and dimensions through TuiPluginApi-backed helpers.
test/reactivity-guard.test.ts Adds a guard against OpenTUI/Solid context-hook imports in plugin source.
test/fixtures/api.ts Extends the TUI API fixture with renderer and keymap intercept mocks.
.github/workflows/lint-workflows.yml Adds actionlint coverage for workflow-file changes.

Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
src/board.tsx:179-188
**Restore dialog gating**
This layer is now always active after mount, so board hotkeys fire while a plugin dialog is open. The removed `useBindings` config explicitly disabled the board layer when `api.ui.dialog.open`; without the equivalent `enabled` guard here, typing `n`, `a`, `s`, etc. inside dialogs can trigger board commands instead of reaching the focused input.

Reviews (1): Last reviewed commit: "fix: route renderer, keyboard, and keyma..." | Re-trigger Greptile

Comment thread src/board.tsx
@aorumbayev
aorumbayev merged commit ca51e18 into main Jul 8, 2026
6 checks passed
@aorumbayev
aorumbayev deleted the renderer-hook-fix branch July 8, 2026 23:52
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 0.1.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant