Skip to content

feat(extensions): add app handoff for bundled editor - #943

Draft
benvinegar wants to merge 4 commits into
mainfrom
feat/bundled-editor-extension
Draft

feat(extensions): add app handoff for bundled editor#943
benvinegar wants to merge 4 commits into
mainfrom
feat/bundled-editor-extension

Conversation

@benvinegar

@benvinegar benvinegar commented Aug 31, 2026

Copy link
Copy Markdown
Member

Summary

  • expose generic ctx.openInApp(callback) terminal handoff and ctx.workspace.resolveLocation(...) source metadata translation to extension commands
  • run Hunk's existing hunk.review.editSelectedFile workflow through a bundled extension that owns editor selection, arguments, asynchronous process execution, exit handling, and refresh
  • propagate explicit per-side filesystem provenance through direct comparisons and bundled VCS adapters instead of inferring working-tree paths from display metadata
  • preserve terminal ownership across review remounts, cancel host dialogs before application handoff, and refuse consent-gated workspace writes while an application owns the renderer
  • advance the extension API to v16 and document the new capabilities

Why

Opening an editor is one instance of a broader extension workflow: trusted extensions may launch editors, debuggers, browsers, or other terminal applications. Hunk now owns only renderer suspension and restoration while the extension owns application-specific execution and metadata.

The bundled editor exercises that same public contract. Terminal editors run inside openInApp; Code-family GUI editors remain visible and receive --wait so Hunk refreshes after editing completes.

Lifecycle guarantees

  • one application owns a renderer at a time, including across hard review remounts
  • controls retained past a review generation reject before running extension code
  • existing and newly requested dialogs settle before or refuse during application ownership
  • consent-gated workspace writes recheck review and terminal authority around every await and before the filesystem write
  • renderer restoration runs in finally after callback success or failure
  • renderer destruction skips restoration, and restoration failures do not replace the application's result
  • historical, staged, patch, merged, absent, and otherwise virtual review sides return no unattested filesystem location
  • direct file comparisons and working-tree-backed VCS sides retain their exact attested paths

Verification

  • bun run typecheck
  • bun run lint
  • bun run format:check
  • bun run deps:check
  • bun run check:docs
  • bun run check:pack
  • bun run changeset:status
  • bun run test (3,639 passed, 12 skipped)
  • bun run test:integration (140 passed, 1 skipped), including real child-process terminal handoff and restoration
  • bun run test:tty-smoke (9 passed)
  • final independent review found no actionable issues

Visual evidence

No intended visual change. The existing e shortcut and File-menu action retain their behavior; failures travel through the bundled extension notification surface.

Platform notes

Tested on Linux. Cross-platform command construction covers quoted Windows executable paths and shell-free arguments.

@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hunk-web Ignored Ignored Preview Aug 31, 2026 9:52pm

Request Review

@greptile-apps

greptile-apps Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR moves the existing open-in-editor workflow behind a new version-16 extension workspace capability while retaining host ownership of path resolution, process execution, terminal lifecycle, and review refreshes.

  • Adds and documents ctx.workspace.openInEditor(...).
  • Registers the existing editor command through the bundled UI extension.
  • Adapts editor results to the extension result contract and adds coverage for forwarding, validation, lifecycle retirement, line mapping, and reconciliation.

Confidence Score: 4/5

The PR appears safe to merge, with only a non-blocking test-maintainability issue around direct environment mutation.

The bundled command remains aligned with the existing command catalog and receives current, lease-guarded workspace controls; editor execution and reload eligibility remain host-owned, and no blocking behavioral or security failure was established.

Files Needing Attention: src/ui/hooks/useExtensionWorkspaceControls.test.tsx

Important Files Changed

Filename Overview
src/ui/hooks/useExtensionWorkspaceControls.ts Adds the reviewed-file editor capability, validates source locations and capability lifetime, delegates process ownership to the existing host helper, and requests reconciliation after success.
src/ui/App.tsx Resolves the bundled editor command and routes the existing host command shell through the normal extension command runner.
src/extensions/default/ui/editor/index.ts Registers the existing qualified command identity and forwards the captured review selection to the workspace capability.
src/extensions/default/ui/index.ts Combines the bundled files pane and editor command under one validated, process-static bundled registry.
src/ui/lib/openInEditor.ts Preserves existing editor spawning and line mapping while returning the public structured workspace result.
src/ui/lib/extensionWorkspace.ts Adds runtime normalization for editor file ids, hunk indexes, sides, and one-based line numbers.
src/extension-api/types.ts Advances the API to version 16 and publishes the editor request, source address, result, and workspace method contracts.
src/ui/hooks/useExtensionWorkspaceControls.test.tsx Covers editor launch policy, reconciliation, retired controls, and old-side mapping, but directly mutates process.env.EDITOR contrary to the repository environment-access convention.

Sequence Diagram

sequenceDiagram
  participant U as User
  participant C as Shared command catalog
  participant E as Bundled editor extension
  participant W as Workspace capability
  participant H as Host editor lifecycle
  participant R as Review refresh
  U->>C: Press e / choose File menu action
  C->>E: Run hunk.review.editSelectedFile
  E->>W: openInEditor(fileId, hunkIndex, line)
  W->>W: Validate lease, reviewed file, and source address
  W->>H: Resolve path and mapped line
  H->>H: Suspend terminal and spawn configured editor
  H->>H: Resume terminal
  alt Editor succeeds and input is reloadable
    W->>R: Queue reconciliation
    W-->>E: "{ ok: true }"
  else Request unavailable or editor fails
    W-->>E: "{ ok: false, reason, detail }"
    E-->>U: Attributed notification
  end
Loading
Prompt To Fix All With AI
### Issue 1
src/ui/hooks/useExtensionWorkspaceControls.test.tsx:24
**Direct environment mutation**

The new editor-control tests read and mutate `process.env.EDITOR` directly in setup, cleanup, and individual cases. This bypasses the repository’s required environment-access pattern and adds global mutable state that makes test isolation and future environment validation harder to maintain.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "feat(extensions): move editor workflow i..." | Re-trigger Greptile

} as const;
const WRITABLE_INPUT: CliInput = { kind: "vcs", staged: false, options: {} };
const tempDirs: string[] = [];
const originalEditor = process.env.EDITOR;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Direct environment mutation

The new editor-control tests read and mutate process.env.EDITOR directly in setup, cleanup, and individual cases. This bypasses the repository’s required environment-access pattern and adds global mutable state that makes test isolation and future environment validation harder to maintain.

Context Used: guidelines.mdc Cursor rule (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/ui/hooks/useExtensionWorkspaceControls.test.tsx
Line: 24

Comment:
**Direct environment mutation**

The new editor-control tests read and mutate `process.env.EDITOR` directly in setup, cleanup, and individual cases. This bypasses the repository’s required environment-access pattern and adds global mutable state that makes test isolation and future environment validation harder to maintain.

**Context Used:** guidelines.mdc Cursor rule ([source](https://github.com/modem-dev/modem/blob/main/.cursor/rules/guidelines.mdc))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@benvinegar benvinegar changed the title feat(extensions): move editor workflow into bundled extension feat(extensions): add app handoff for bundled editor Aug 31, 2026
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.

1 participant