Skip to content

feat(extensions): add custom dialog surfaces - #944

Draft
benvinegar wants to merge 12 commits into
feat/bundled-editor-extensionfrom
feat/bundled-agent-skill-extension
Draft

feat(extensions): add custom dialog surfaces#944
benvinegar wants to merge 12 commits into
feat/bundled-editor-extensionfrom
feat/bundled-agent-skill-extension

Conversation

@benvinegar

@benvinegar benvinegar commented Aug 31, 2026

Copy link
Copy Markdown
Member

Summary

  • add API v17 ctx.dialogs.open(...) for trusted extensions to render bounded React/OpenTUI components inside Hunk-owned modal chrome
  • provide exact clamped width/height, semantic theme colors, clipboard availability, and guarded close, copy, and notify actions to the mounted component
  • keep queueing, Escape, attribution, geometry, focus isolation/restoration, clipboard mediation, reload retirement, and render-failure containment under host control
  • remount reused component functions per request and make retained actions inert after close, queue promotion, reload, or unmount
  • register hunk.app.openAgentSkill through the bundled UI extension and implement its existing prompt as a custom dialog component

Why a generic dialog surface

The Agent Skill command is a product workflow rather than shared review semantics, so it belongs in a bundled extension. The dialog API now follows the pane model instead of adding a specialized read-only document method: trusted extension code owns the contents, while Hunk owns the modal boundary and lifecycle.

ctx.dialogs.open(...) joins the same FIFO queue as confirm, select, and input. A custom component receives only its bounded geometry, Hunk's public paint theme, clipboard capability, and request-scoped actions. User-installed extensions retain explicit attribution, render failures stay inside the frame, Escape remains host-owned, and unhandled component keys cannot mutate a focused review widget behind the modal.

Before / after

Both captures use the same diff and a 120x24 Linux tmux PTY. Before is the original stacked base; after is the bundled Agent Skill extension. The current generic component implementation preserves this native chrome and interaction.

Before

Agent Skill dialog before the extension migration

After

Agent Skill dialog after the extension migration

Stack

This PR is stacked on #943 and should merge after it. Its base is feat/bundled-editor-extension, so the diff contains only the Agent Skill and generic dialog work.

Verification

  • bun run typecheck
  • bun run lint
  • bun run format:check
  • bun run deps:check
  • bun run check:docs
  • bun run build:npm
  • bun run changeset:status
  • bun run test (3,658 passed, 12 skipped)
  • bun run test:integration (141 passed, 1 skipped)
  • bun run test:tty-smoke (9 passed)
  • website Astro check (0 errors, warnings, or hints)
  • source-run TTY launch on the actual 28-file working-tree diff

Interaction coverage

Integration coverage exercises custom rendering, nested focused inputs, component key hooks, mouse and keyboard copy, rejected clipboard writes, render failures, per-request remounting, stale actions, open-to-input queue promotion, soft reload cleanup, Escape, and prior-focus restoration.

@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
hunk-web Ignored Ignored Preview Sep 3, 2026 1:29pm UTC

Request Review

@greptile-apps

greptile-apps Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds API v17 host-rendered document dialogs and moves Agent Skill onboarding into the bundled UI extension.

  • Adds validated, terminal-safe document and clipboard request handling to the shared FIFO dialog queue.
  • Adds constrained document rendering and keyboard/mouse interactions to the extension dialog host.
  • Registers hunk.app.openAgentSkill as a bundled extension command and removes the dedicated modal implementation.
  • Updates extension API documentation and focused unit, host, PTY, and interaction tests.

Confidence Score: 4/5

The PR appears safe to merge after addressing two non-blocking UI-affordance and documentation-style issues.

The dialog lifecycle, FIFO settlement, keyboard ownership, and reload cancellation paths remain coherent; the accepted concerns are limited to an active unavailable-copy action and overlong documentation lines.

Files Needing Attention: src/ui/components/chrome/ExtensionDialog.tsx, docs/extension-architecture.md, website/src/content/docs/docs/extend/extension-api.md

Important Files Changed

Filename Overview
src/ui/lib/extensionDialogs.ts Adds document request validation, terminal sanitization, bounded payloads, FIFO settlement, and cancellation semantics.
src/ui/components/chrome/ExtensionDialog.tsx Adds constrained document rendering; the unsupported clipboard action remains interactive despite its unavailable label.
src/ui/App.tsx Routes Agent Skill through the bundled extension command and connects document dialogs to clipboard and review-generation lifecycle handling.
src/ui/hooks/useAppKeyboardShortcuts.ts Gives document dialogs Escape, Enter suppression, and copy-key ownership ahead of underlying application shortcuts.
src/extensions/default/ui/agentSkill/index.ts Registers Agent Skill onboarding as a bundled command using the public document-dialog API.
src/extension-api/types.ts Advances the extension API to v17 and exposes the document-dialog contract.
docs/extension-architecture.md Documents document dialogs in the shared host architecture but introduces an overlong line.
website/src/content/docs/docs/extend/extension-api.md Updates public extension API documentation but introduces another overlong line.

Sequence Diagram

sequenceDiagram
  participant User
  participant App
  participant Bundled as Bundled Agent Skill Extension
  participant Queue as Extension Dialog Queue
  participant Host as Shared Dialog Host
  User->>App: Select Agent skill
  App->>Bundled: Run hunk.app.openAgentSkill
  Bundled->>Queue: ctx.dialogs.document(...)
  Queue->>Host: Render normalized document
  User->>Host: Copy or dismiss
  Host->>Queue: Cancel/settle request
  Queue-->>Bundled: "Resolve Promise<void>"
Loading
Prompt To Fix All With AI
### Issue 1
src/ui/components/chrome/ExtensionDialog.tsx:307
**Unavailable copy remains interactive**

When OSC 52 support is absent, the action is labeled `unavailable` but remains clickable and invokes `onCopyDocument`, producing an unsupported-clipboard notice instead of behaving like a disabled action.

### Issue 2
docs/extension-architecture.md:241
**Documentation exceeds line limit**

This edited line exceeds the repository's 120-character limit; the same pattern occurs in `website/src/content/docs/docs/extend/extension-api.md:318`. Wrapping both lines keeps the documentation consistent with the project style guide.

---

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 agent skill into ..." | Re-trigger Greptile

? [
{
keyLabel: "c",
label: copySupported ? "Copy" : "unavailable",

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 Unavailable copy remains interactive

When OSC 52 support is absent, the action is labeled unavailable but remains clickable and invokes onCopyDocument, producing an unsupported-clipboard notice instead of behaving like a disabled action.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/ui/components/chrome/ExtensionDialog.tsx
Line: 307

Comment:
**Unavailable copy remains interactive**

When OSC 52 support is absent, the action is labeled `unavailable` but remains clickable and invokes `onCopyDocument`, producing an unsupported-clipboard notice instead of behaving like a disabled action.

---

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in c206852. Unsupported clipboard state now renders as inert muted text instead of a DialogActionRow, and the host no longer emits an unsupported-copy action. Added regression coverage proving both c and mouse clicks leave the clipboard untouched while the document remains open.

Responded by OpenCode using openai/gpt-5.6-sol.

@@ -241,7 +241,7 @@ text into a request the host draws, and answering by request id so a duplicated
Enter cannot spill onto whatever was queued behind. App subscribes with

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 Documentation exceeds line limit

This edited line exceeds the repository's 120-character limit; the same pattern occurs in website/src/content/docs/docs/extend/extension-api.md:318. Wrapping both lines keeps the documentation consistent with the project style guide.

Context Used: guidelines.mdc Cursor rule (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/extension-architecture.md
Line: 241

Comment:
**Documentation exceeds line limit**

This edited line exceeds the repository's 120-character limit; the same pattern occurs in `website/src/content/docs/docs/extend/extension-api.md:318`. Wrapping both lines keeps the documentation consistent with the project style guide.

**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!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in c206852. Wrapped the edited architecture paragraph and the website API documentation, including the newly documented document-size limits and clipboard normalization behavior.

Responded by OpenCode using openai/gpt-5.6-sol.

@benvinegar
benvinegar marked this pull request as draft August 31, 2026 12:30
…skill-extension

# Conflicts:
#	docs/extensions.md
#	skills/hunk-extensions/SKILL.md
#	website/src/content/docs/docs/extend/extension-api.md
…skill-extension

# Conflicts:
#	docs/extensions.md
#	src/ui/App.tsx
#	website/src/content/docs/docs/extend/extension-api.md
@benvinegar benvinegar changed the title feat(extensions): move agent skill into bundled extension feat(extensions): add custom dialog surfaces Sep 1, 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