Skip to content

feat(agents): export focused hunk prompts#288

Open
SalzDevs wants to merge 1 commit into
modem-dev:mainfrom
SalzDevs:feat/agent-prompt-export
Open

feat(agents): export focused hunk prompts#288
SalzDevs wants to merge 1 commit into
modem-dev:mainfrom
SalzDevs:feat/agent-prompt-export

Conversation

@SalzDevs
Copy link
Copy Markdown

Summary

  • add a focused-hunk agent prompt formatter shared by the TUI and session CLI
  • add p to copy the focused hunk prompt and c to add a user comment + copy the commented prompt
  • add hunk session prompt for agents/scripts to export the current focused hunk as a paste-ready prompt
  • document the workflow in README, agent workflows, and the bundled Hunk skill

Testing

  • bun run format:check
  • bun run typecheck
  • bun run lint
  • bun test src/core/agentPrompt.test.ts src/core/cli.test.ts src/session/commands.test.ts src/ui/lib/ui-lib.test.ts
  • bun test ./src ./packages ./scripts ./test/cli ./test/session (fails only on existing jj-dependent tests because jj is not installed in this environment)

Closes #114
Related #239

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 11, 2026

Greptile Summary

This PR introduces a focused-hunk prompt export shared by the TUI and the session CLI. In the TUI, p copies a paste-ready agent prompt for the focused hunk and c opens a comment dialog that attaches an inline live note before copying the commented prompt; hunk session prompt exposes the same export from scripts and agents.

  • src/core/agentPrompt.ts is a new shared module with buildAgentPrompt, extractHunkPatch, and createAgentPromptFile; the adaptive code-fence algorithm, hunk extraction, and OSC52 clipboard path with file fallback are all well-handled.
  • src/session/commands.ts adds a prompt case that fetches the session review with includePatch: true, guards against a missing focused hunk, and delegates to buildAgentPrompt; SessionReviewFile is structurally compatible with AgentPromptFile so no conversion step is needed.
  • The closing instruction "Please address my comment against this diff." is unconditionally included even when neither comment nor selectedText is provided (plain p press), producing a dangling reference that may confuse a coding agent parsing the prompt.

Confidence Score: 4/5

Safe to merge; the only issue is a minor prompt-text inconsistency that affects agent UX but not correctness or data integrity.

The feature is well-scoped, the new agentPrompt module is cleanly separated, and the keyboard/modal guard ordering is correct. The one notable issue is that the closing line "Please address my comment against this diff." is unconditionally included even for plain hunk-only exports (no comment, no selected text), which can produce a confusing instruction for an agent that sees no "My comment:" section.

src/core/agentPrompt.ts — the closing instruction at line 135 warrants a small conditional to avoid referencing a comment that does not exist in the prompt.

Important Files Changed

Filename Overview
src/core/agentPrompt.ts New module containing buildAgentPrompt, extractHunkPatch, and createAgentPromptFile. Logic is sound; the adaptive code-fence algorithm and hunk extraction are correct. Minor issue: the closing instruction line is included even when no comment is provided.
src/ui/App.tsx Adds publishAgentPrompt, copyAgentPrompt, openAgentCommentDialog, submitAgentComment callbacks plus modal state for the comment/preview dialogs. OSC52 clipboard with file fallback is well-guarded. repoRoot is correctly set to bootstrap.changeset.sourceLabel (which is the actual repo root path for VCS inputs, matching the pattern in sessionRegistration.ts).
src/session/commands.ts Adds the prompt case using getSessionReview with includePatch: true. SessionReviewFile is a structural superset of AgentPromptFile so passing it directly without createAgentPromptFile is type-safe.
src/ui/components/chrome/AgentPromptDialog.tsx New file containing AgentCommentDialog and AgentPromptPreviewDialog. Both use ModalFrame consistently with existing dialog patterns. Escape handling is correctly forwarded to onCancel/onClose.
src/ui/hooks/useAppKeyboardShortcuts.ts Adds p / c shortcuts and a handleModalShortcut guard that consumes all keys (returning Escape to closeModal) while a modal is open. Order in useKeyboard is correct — modal check runs before all other shortcut handlers.

Sequence Diagram

sequenceDiagram
    participant User
    participant TUI as App.tsx (TUI)
    participant AP as agentPrompt.ts
    participant FS as Filesystem
    participant Clip as Clipboard (OSC52)

    User->>TUI: press p
    TUI->>AP: "buildAgentPrompt({ file, hunkIndex })"
    AP-->>TUI: prompt string
    TUI->>Clip: copyToClipboardOSC52(prompt)
    alt copy succeeded
        Clip-->>TUI: true
        TUI-->>User: status notice "Copied"
    else copy failed
        Clip-->>TUI: false
        TUI->>FS: writeAgentPromptFallback(prompt)
        FS-->>TUI: savedPath
        TUI-->>User: AgentPromptPreviewDialog
    end

    User->>TUI: press c
    TUI-->>User: AgentCommentDialog
    User->>TUI: type comment + Enter
    TUI->>TUI: review.addLiveComment(...)
    TUI->>AP: "buildAgentPrompt({ file, hunkIndex, comment })"
    AP-->>TUI: prompt string
    TUI->>Clip: copyToClipboardOSC52(prompt)

    User->>CLI: hunk session prompt --repo .
    CLI->>AP: "buildAgentPrompt({ file, hunkIndex, comment? })"
    AP-->>CLI: prompt string
    CLI-->>User: stdout (text or JSON)
Loading
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/core/agentPrompt.ts:131-136
The closing instruction unconditionally tells the agent to "address my comment" even when no comment was provided. When `p` is used to copy a plain hunk prompt, there is no "My comment:" section, so the imperative becomes a dangling reference that may confuse the agent. The instruction should only appear when a comment or selected text is actually present, with a lighter-touch fallback for the context-only case.

```suggestion
      "",
      "Diff hunk:",
      codeFence("diff", diffSnippet),
      "",
      normalizedComment || normalizedSelection
        ? "Please address my comment against this diff. If you need more surrounding code, ask before editing."
        : "Please use this diff hunk as context. If you need more surrounding code, ask before editing.",
    ].join("\n"),
```

Reviews (1): Last reviewed commit: "feat(agents): export focused hunk prompt..." | Re-trigger Greptile

Comment thread src/core/agentPrompt.ts
Comment on lines +131 to +136
"",
"Diff hunk:",
codeFence("diff", diffSnippet),
"",
"Please address my comment against this diff. If you need more surrounding code, ask before editing.",
].join("\n"),
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 The closing instruction unconditionally tells the agent to "address my comment" even when no comment was provided. When p is used to copy a plain hunk prompt, there is no "My comment:" section, so the imperative becomes a dangling reference that may confuse the agent. The instruction should only appear when a comment or selected text is actually present, with a lighter-touch fallback for the context-only case.

Suggested change
"",
"Diff hunk:",
codeFence("diff", diffSnippet),
"",
"Please address my comment against this diff. If you need more surrounding code, ask before editing.",
].join("\n"),
"",
"Diff hunk:",
codeFence("diff", diffSnippet),
"",
normalizedComment || normalizedSelection
? "Please address my comment against this diff. If you need more surrounding code, ask before editing."
: "Please use this diff hunk as context. If you need more surrounding code, ask before editing.",
].join("\n"),
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/core/agentPrompt.ts
Line: 131-136

Comment:
The closing instruction unconditionally tells the agent to "address my comment" even when no comment was provided. When `p` is used to copy a plain hunk prompt, there is no "My comment:" section, so the imperative becomes a dangling reference that may confuse the agent. The instruction should only appear when a comment or selected text is actually present, with a lighter-touch fallback for the context-only case.

```suggestion
      "",
      "Diff hunk:",
      codeFence("diff", diffSnippet),
      "",
      normalizedComment || normalizedSelection
        ? "Please address my comment against this diff. If you need more surrounding code, ask before editing."
        : "Please use this diff hunk as context. If you need more surrounding code, ask before editing.",
    ].join("\n"),
```

How can I resolve this? If you propose a fix, please make it concise.

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.

Expose Hunk selections to coding agents, with exact text selection when possible

1 participant