Skip to content

docs(examples): add inline-edit extension demonstrating the interactive surfaces - #691

Merged
benvinegar merged 2 commits into
mainfrom
claude/inline-diff-editing-esm5b8-example
Aug 8, 2026
Merged

docs(examples): add inline-edit extension demonstrating the interactive surfaces#691
benvinegar merged 2 commits into
mainfrom
claude/inline-diff-editing-esm5b8-example

Conversation

@benvinegar

Copy link
Copy Markdown
Member

Follow-up to the interactive-surfaces stack (#673, #674, #675, all merged): the demonstration those capabilities were built for, as a repo example.

What

examples/extensions/inline-edit/ — a miniature line editor for the file under review, ~550 commented lines, no dependencies. One ctrl+e opens the editor for the selected file; arrows move a caret, typing edits, Enter splits and Backspace joins lines, unused keys (], ?, q) pass through and keep working, ctrl+s writes through the attributed confirm dialog, Escape discards.

Why

Every one of the three capabilities is load-bearing, so the example proves they compose and doubles as reference material:

  • ctx.workspace.readDocument seeds the buffer, canWriteDocument gates entry, writeDocument completes the loop — the session reload after a save exits the mode cleanly.
  • The file-view mode routes real keystrokes; one enterMode selects the view and takes the keyboard.
  • fileViews.refresh(VIEW_ID, { fileId }) paints every keystroke, scoped to the edited file.
  • Keys are matched with the published matchesKey (both Ctrl-S forms, Enter/Return naming) rather than hand-read flags.

It also documents the two patterns extension authors will need and would otherwise invent badly:

  • The command handler as the mode's async runtime. onKey must answer synchronously and the mode context deliberately carries only file + fileViews, so a keystroke can only request a save; the handler that entered the mode parks on a session mailbox and performs the write with its still-valid ctx.workspace. The editor slot is claimed synchronously before the handler's first await, so rapid re-invocation cannot leak a parked handler.
  • A named provenance policy for source bindings. Each buffer line tracks the original document line it still is (typing keeps it, a split gives the tail null, a join keeps the head's), and sourceRanges/hunkRows derive from provenance, never row position — so inline notes and the hunk highlight stay honest through mid-document edits, and every layout passes the host validator's exactly-one-hunk-owner rule.

Testing

  • scripts/inline-edit-extension.test.ts (19 tests): registration/chord; read-only rendering with added-line tones and validated bindings; the re-entrancy claim (two concurrent invocations, one session, both handler promises settle); claim release on every failed entry; buffer/caret operations with exactly one scoped refresh per change; provenance through split/join/typing including hunk extents; Ctrl-S in both terminal encodings; failed/cancelled write behavior; Escape discard. Every layout assertion runs the real validateFileViewLayout.
  • PTY end-to-end (test/pty/file-views-integration.test.ts): real terminal, real git working tree — enter, type, ctrl+s, accept the attributed Write alpha.ts? dialog, assert the bytes on disk, the reloaded review, and that the mode exited.
  • Rebased onto current main (post-0.18.0-prep) and verified there: typecheck, unit suites, lint, check:pack, check:docs green; PTY suite green except two pre-existing failures (cursor-line, layout divider-drag) that reproduce identically on pristine origin/main in the same environment.

The example ships with an empty changeset (repo-example only, not part of the published package). examples/README.md lists it under installable extension examples.

🤖 Generated with Claude Code

https://claude.ai/code/session_015aJpBUupsP9L7Wtd7MEzmU


Generated by Claude Code

@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
hunk-web Ready Ready Preview Aug 8, 2026 8:14pm

Request Review

@greptile-apps

greptile-apps Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds an installable inline-edit example demonstrating interactive file-view modes, scoped refreshes, and host-mediated workspace writes.

  • Adds a stateful line editor with caret movement, editing, save/discard lifecycle, and source provenance.
  • Documents installation, controls, lifecycle design, and limitations.
  • Adds focused unit coverage and a real-terminal write/reload integration test.

Confidence Score: 4/5

The CR-only newline handling defect should be fixed before merging because supported writable text files can open with an incorrect line model.

The editor assumes every non-CRLF document uses LF, so CR-only files are presented as a single line and edited against the wrong structure; the remaining findings concern repository formatting and test-placement requirements.

Files Needing Attention: examples/extensions/inline-edit/index.ts, scripts/inline-edit-extension.test.ts

Important Files Changed

Filename Overview
examples/extensions/inline-edit/index.ts Adds the complete editor runtime and layout implementation; CR-only documents are not parsed into lines correctly.
scripts/inline-edit-extension.test.ts Adds broad unit coverage for editing, provenance, lifecycle, and writes, but is not colocated with the extension source.
test/pty/file-views-integration.test.ts Adds an end-to-end PTY test covering entry, typing, confirmation, disk write, reload, and mode exit.
examples/extensions/inline-edit/README.md Documents installation, controls, async lifecycle, provenance policy, and explicit limitations.
examples/extensions/inline-edit/package.json Declares the example extension entry point without additional dependencies.

Sequence Diagram

sequenceDiagram
    participant U as User
    participant M as File-view mode
    participant H as Command handler
    participant W as Workspace
    U->>H: Ctrl-E
    H->>W: readDocument
    W-->>H: document text
    H->>M: enterMode
    U->>M: Edit keys
    M->>M: Update buffer and refresh view
    U->>M: Ctrl-S
    M->>H: Queue save request
    H->>W: writeDocument
    W-->>H: Result and review reload
    H-->>M: Reload exits mode
Loading
Prompt To Fix All With AI
### Issue 1
examples/extensions/inline-edit/index.ts:125-128
**CR-only lines are not parsed**

When a writable document uses CR-only line endings, `splitDocumentLines` treats the entire document as one line and `createEditSession` defaults its terminator to LF, causing the editor to render, navigate, and edit against the wrong line structure.

### Issue 2
examples/extensions/inline-edit/index.ts:48-49
**TypeScript style conflicts with repository rules**

The new extension and test code consistently use two-space indentation and double-quoted strings, conflicting with the repository requirement for four spaces and single quotes and creating avoidable maintenance and formatting churn.

### Issue 3
scripts/inline-edit-extension.test.ts:1
**Extension test is not colocated**

This test directly exercises `examples/extensions/inline-edit/index.ts` but lives in the separate top-level `scripts` directory, conflicting with the repository rule that tests remain beside their corresponding source and making the extension's coverage harder to discover.

---

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

Reviews (1): Last reviewed commit: "docs(examples): add inline-edit extensio..." | Re-trigger Greptile

Comment thread examples/extensions/inline-edit/index.ts
Comment on lines +48 to +49
} from "hunkdiff/extension";

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 TypeScript style conflicts with repository rules

The new extension and test code consistently use two-space indentation and double-quoted strings, conflicting with the repository requirement for four spaces and single quotes and creating avoidable maintenance and formatting churn.

Context Used: guidelines.mdc Cursor rule (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: examples/extensions/inline-edit/index.ts
Line: 48-49

Comment:
**TypeScript style conflicts with repository rules**

The new extension and test code consistently use two-space indentation and double-quoted strings, conflicting with the repository requirement for four spaces and single quotes and creating avoidable maintenance and formatting churn.

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

The cited rule is from modem-dev/modem, not this repository. Hunk formats with oxfmt (bun run format / format:check gates CI), whose configuration here produces two-space indentation and double quotes — the entire existing codebase, including the sibling examples in examples/extensions/, uses that style, and this PR passes format:check as written. Switching these files to four spaces and single quotes would make them the only files in the repo to fail the formatter. Please scope this rule to the modem repo.


Generated by Claude Code

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.

You're right, I apologize for the incorrect comment. The formatting rule I applied was sourced from modem-dev/modem, not this repository. This repo uses oxfmt with two-space indentation and double quotes, the PR passes format:check, and switching to four spaces/single quotes would break the formatter.

Shall I remember this as a rule: "Do not flag two-space indentation or double-quoted strings in modem-dev/hunk — the repo uses oxfmt which enforces that style, and format:check gates CI"?

@@ -0,0 +1,637 @@
import { describe, expect, test } from "bun:test";

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 Extension test is not colocated

This test directly exercises examples/extensions/inline-edit/index.ts but lives in the separate top-level scripts directory, conflicting with the repository rule that tests remain beside their corresponding source and making the extension's coverage harder to discover.

Context Used: testing.mdc Cursor rule (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/inline-edit-extension.test.ts
Line: 1

Comment:
**Extension test is not colocated**

This test directly exercises `examples/extensions/inline-edit/index.ts` but lives in the separate top-level `scripts` directory, conflicting with the repository rule that tests remain beside their corresponding source and making the extension's coverage harder to discover.

**Context Used:** testing.mdc Cursor rule ([source](https://github.com/modem-dev/modem/blob/main/.cursor/rules/testing.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.

The cited rule is from modem-dev/modem, not this repository. In hunk, scripts/<name>-extension.test.ts is the established home for example-extension factory tests (scripts/rendered-markdown-extension.test.ts, scripts/jsx-file-view-gallery.test.ts are the precedents this follows). Colocating it inside examples/extensions/inline-edit/ would silently drop it from CI: the repo's test script runs ./src ./packages ./scripts ./test/cli ./test/session, which does not sweep examples/. Hunk's colocation rule (CLAUDE.md) governs src/; example coverage deliberately lives where the runner sees it.


Generated by Claude Code

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.

You're right, I was wrong to apply that rule here. scripts/ is the correct home for example-extension tests in this repo, and the CI coverage argument settles it — dropping coverage silently by moving the file would be strictly worse.

Shall I remember this as a rule: "In hunk, example-extension tests belong in scripts/<name>-extension.test.ts, not colocated inside examples/, because the test runner does not sweep examples/"?

…ve surfaces

A miniature line editor proving the three new capabilities compose:
workspace reads seed the buffer, a file-view mode routes keystrokes,
fileViews.refresh redraws each change, and a consented workspace write
lands on disk and reloads the review. The command handler doubles as the
mode's async runtime — the pattern the mode context's deliberate
minimalism asks extension authors to use — and the PTY test drives the
whole loop from typed keys to written file in a real terminal.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015aJpBUupsP9L7Wtd7MEzmU
@benvinegar
benvinegar enabled auto-merge (squash) August 8, 2026 20:14
@benvinegar
benvinegar merged commit 1306bd8 into main Aug 8, 2026
12 checks passed
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.

2 participants