Skip to content

fix(vim): keep extensions loadable when host pi-tui metadata is unresolvable - #1594

Merged
ElCaaarnal merged 1 commit into
Gentleman-Programming:mainfrom
dnlrsls:fix/1586-host-tui-version
Sep 30, 2026
Merged

ElCaaarnal merged 1 commit into
Gentleman-Programming:mainfrom
dnlrsls:fix/1586-host-tui-version

Conversation

@dnlrsls

@dnlrsls dnlrsls commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Linked issue

Closes #1586
Closes #1589

PR type

  • Bug fix
  • New feature
  • Documentation only
  • Code refactoring
  • Maintenance/tooling
  • Breaking change

Summary

Review path

lib/vim-editor-adapter.ts (one guarded expression), then tests/vim-editor-adapter-host-resolution.test.ts.

Changes

File Change
lib/vim-editor-adapter.ts Resolve pi-tui metadata in a try; unresolved → version unknown → unverified gate stays closed.
tests/vim-editor-adapter-host-resolution.test.ts Copies the adapter to a temp dir with no node_modules, aliases only the ES @earendil-works/pi-tui specifier (as Pi's loader does), and asserts the module loads, rejects an unverified editor and admits a verified one.

Test plan

  • Strict TDD: the new test failed on unchanged main with Cannot find module '@earendil-works/pi-tui/package.json' and passes with the fix.
  • Real Pi 0.99.1 (Windows, global npm install), clean git archive copies without node_modules, pi --mode rpc --offline --no-session -ne -e <copy>/extensions/gentle-shell.ts -e <copy>/extensions/gentle-agents.ts: main prints both Failed to load extension ... Cannot find module '@earendil-works/pi-tui/package.json' errors and exits 1; with the fix both extensions load and it exits 0.
  • tests/vim-editor-adapter.test.ts, tests/vim-editor-adapter-host-resolution.test.ts, tests/gentle-shell.test.ts: 278/281 pass. The 3 failures (customize Vim reports a persistence error…, customize previews installed source palette…, registered canonical root governs real Git discovery…) reproduce with identical signatures on untouched main on this Windows machine.
  • pnpm run typecheck: no regressions against the recorded baseline.
  • Global full-suite green is not claimed: on this Windows machine the full unit run shows many environment failures unrelated to the adapter (none reference vim-editor-adapter or pi-tui resolution). With dev dependencies installed the require resolves exactly as before, so behavior only differs when it would previously have thrown. CI remains the gate.

Contributor checklist

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling when the host package version cannot be determined, preventing initialization failures and correctly rejecting unsupported editor layouts or versions.
  • Tests

    • Added coverage for unknown host versions and verified compatibility with supported editor versions.

…olvable

Pi aliases only ES imports of host-provided packages. The module-level
createRequire of @earendil-works/pi-tui/package.json walks node_modules
from the extension directory, which a git install does not have since
the host packages became peers, so gentle-shell and gentle-agents failed
to load. An unresolvable host now leaves the imported TUI version unknown,
which keeps the unverified identity gate closed; the verified runtime
path from resolveVimRuntime is unchanged.

Fixes Gentleman-Programming#1586
@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 5c3b8be5-2fd1-40c5-91f3-7e0e09835c76

📥 Commits

Reviewing files that changed from the base of the PR and between 290c0dc and 686aede.

📒 Files selected for processing (2)
  • lib/vim-editor-adapter.ts
  • tests/vim-editor-adapter-host-resolution.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

The adapter now catches failures to resolve @earendil-works/pi-tui package metadata. An integration test checks that an unknown version is rejected and that verified constructor and version inputs produce an adapter with a move function.

Changes

Vim Adapter Host Resolution

Layer / File(s) Summary
Metadata failure handling and verification
lib/vim-editor-adapter.ts, tests/vim-editor-adapter-host-resolution.test.ts
The adapter treats metadata resolution failures as an unknown version, which the existing identity check rejects. The integration test checks this rejection and verifies adapter creation with a matching editor constructor and version.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: alan-thegentleman

Merge Risk: ⚪ Minimal · up to 686ae

The change prevents missing host metadata from aborting extension loading while retaining version verification. It is mergeable subject to normal CI checks.

Architecture Summary

Architecture risk: 🔵 Low · up to 686ae

The change affects 2 systems.

Changed systems: lib, tests

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — lib (service) was modified; 1 changed file maps to changed impact.
  • observed — tests (service) was modified; 1 changed file maps to changed impact.

Before / after behavior

  • observed — Modified behavior in lib/vim-editor-adapter.ts: The package metadata require is now inside a try/catch; resolution failures return undefined, leaving the imported version unknown for the existing identity check.
  • observed — Modified behavior in tests/vim-editor-adapter-host-resolution.test.ts: Adds an integration test that simulates an install without extension-local node_modules, aliases the host pi-tui import, and runs the adapter in a child process. The test checks that an unverified version is rejected with the expected error and that verified constructor and version arguments produce an adapter with a move function.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR meets the runtime loading objective in [#1586]. It catches unresolved @earendil-works/pi-tui/package.json metadata, keeps the version unknown, and prevents module-initialization failure. The … Implement the coding requirements from [#1589] by adding the three @earendil-works/* runtime packages to dependencies, retaining the required peer and development declarations, and setting the typebox dependency version to ^1.3.34, …
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: preventing extension load failures when the host pi-tui metadata cannot be resolved.
Out of Scope Changes check ✅ Passed The changed adapter logic directly addresses the host-package resolution failure in [#1586] and the related git-install crash in [#1589]. The added test directly verifies the missing extension-local `…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Full details: Linked Issues check

Explanation

The PR meets the runtime loading objective in [#1586]. It catches unresolved @earendil-works/pi-tui/package.json metadata, keeps the version unknown, and prevents module-initialization failure. The new host-resolution test covers the extension-like layout and the fail-closed identity gate. However, [#1589] specifies a layered dependency strategy. package.json still lists @earendil-works/pi-ai, @earendil-works/pi-coding-agent, and @earendil-works/pi-tui only as peer and development dependencies. It does not add them to dependencies, and it does not change typebox to ^1.3.34.

Resolution

Implement the coding requirements from [#1589] by adding the three @earendil-works/* runtime packages to dependencies, retaining the required peer and development declarations, and setting the typebox dependency version to ^1.3.34, or obtain an explicit issue decision that the alternative fail-closed loading behavior replaces those requirements.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ElCaaarnal

Copy link
Copy Markdown
Contributor

Reviewed and verified locally. This fixes the root cause, not just the symptom.

Root cause: the module-level createRequire(import.meta.url)("@earendil-works/pi-tui/package.json") bypasses Pi's ES-import alias for host packages and walks node_modules from the extension directory. Git installs have no local copy since 14f77e68, so both extensions failed to load. Re-adding host packages to dependencies (#1588) would bring back #1559 / #1564, so keeping them as peers is the right call.

Correctness: an unresolved host leaves the version undefined, so hasEditorIdentity rejects the unverified editor and falls back to ordinary editing (fail-closed). The verified path through resolveVimRuntime() is untouched, so Vim keeps working on 0.99.1.

Evidence (macOS):

  • RED: with the adapter from main, the new test fails with Cannot find module '@earendil-works/pi-tui/package.json'.
  • GREEN: vim-editor-adapter tests 41/41, gentle-shell.test.ts 240/240.
  • pnpm run typecheck: no regressions against the baseline.
  • CI: all checks green.

Minor, non-blocking: the catch swallows any error, not only MODULE_NOT_FOUND. The outcome is still fail-closed, so it's fine as is.

Thanks @dnlrsls, great write-up and a clean, well-scoped fix.

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

Labels

type:bug Bug fix

Projects

None yet

2 participants