Merge pull request #1374 from superhedge22/fix-review-enter-submit

Fix /review custom instructions submission
This commit is contained in:
Can Bölük
2026-05-26 21:40:15 +03:00
committed by GitHub
10 changed files with 292 additions and 23 deletions
@@ -14,6 +14,8 @@
import { prompt } from "@oh-my-pi/pi-utils";
import type { CustomCommand, CustomCommandAPI } from "../../../../extensibility/custom-commands/types";
import type { HookCommandContext } from "../../../../extensibility/hooks/types";
import reviewCustomRequestTemplate from "../../../../prompts/review-custom-request.md" with { type: "text" };
import reviewHeadlessRequestTemplate from "../../../../prompts/review-headless-request.md" with { type: "text" };
import reviewRequestTemplate from "../../../../prompts/review-request.md" with { type: "text" };
import * as git from "../../../../utils/git";
@@ -225,6 +227,14 @@ function buildReviewPrompt(mode: string, stats: DiffStats, rawDiff: string, addi
});
}
function buildCustomReviewPrompt(instructions: string): string {
return prompt.render(reviewCustomRequestTemplate, { instructions });
}
function buildHeadlessReviewPrompt(focus?: string): string {
return prompt.render(reviewHeadlessRequestTemplate, { focus });
}
export class ReviewCommand implements CustomCommand {
name = "review";
description = "Launch interactive code review";
@@ -233,8 +243,7 @@ export class ReviewCommand implements CustomCommand {
async execute(args: string[], ctx: HookCommandContext): Promise<string | undefined> {
if (!ctx.hasUI) {
const base = "Use the Task tool to run the 'reviewer' agent to review recent code changes.";
return args.length > 0 ? `${base} Focus: ${args.join(" ")}` : base;
return buildHeadlessReviewPrompt(args.length > 0 ? args.join(" ") : undefined);
}
// Inline args act as additional instructions appended to the generated prompt.
@@ -379,7 +388,12 @@ export class ReviewCommand implements CustomCommand {
case 4: {
// Custom instructions - still uses the old approach since user provides context
const instructions = await ctx.ui.editor("Enter custom review instructions", "Review the following:\n\n");
const instructions = await ctx.ui.editor(
"Enter custom review instructions",
"Review the following:\n\n",
undefined,
{ promptStyle: true },
);
if (!instructions?.trim()) return undefined;
// For custom, we still try to get current diff for context
@@ -402,17 +416,7 @@ export class ReviewCommand implements CustomCommand {
);
}
// No diff available, just pass instructions
return `## Code Review Request
### Mode
Custom review instructions
### Instructions
${instructions}
Use the Task tool with \`agent: "reviewer"\` to execute this review.`;
return buildCustomReviewPrompt(instructions);
}
default:
@@ -139,9 +139,16 @@ export interface HookUIContext {
* Supports Ctrl+G to open external editor ($VISUAL or $EDITOR).
* @param title - Title describing what is being edited
* @param prefill - Optional initial text
* @param options - Optional dialog controls such as an abort signal
* @param editorOptions - Optional editor behavior; `promptStyle` makes Enter submit and Shift+Enter insert a newline
* @returns Edited text, or undefined if cancelled (Escape)
*/
editor(title: string, prefill?: string, options?: { signal?: AbortSignal }): Promise<string | undefined>;
editor(
title: string,
prefill?: string,
options?: { signal?: AbortSignal },
editorOptions?: { promptStyle?: boolean },
): Promise<string | undefined>;
/**
* Get the current theme for styling text with ANSI codes.
@@ -17,6 +17,10 @@ export interface HookEditorOptions {
promptStyle?: boolean;
}
function isCtrlEnterSubmit(keyData: string): boolean {
return matchesKey(keyData, "ctrl+enter") || (keyData.charCodeAt(0) === 10 && keyData.length > 1);
}
export class HookEditorComponent extends Container {
#editor: Editor;
#onSubmitCallback: (value: string) => void;
@@ -78,6 +82,10 @@ export class HookEditorComponent extends Container {
}
}
#submitCurrentText(): void {
this.#onSubmitCallback(this.#editor.getExpandedText());
}
/** Prompt-style: raw Enter submits; Editor owns newline-producing sequences. */
#handlePromptStyleInput(keyData: string): void {
// Prompt-style keeps Escape as an explicit cancel key and also honors app.interrupt remaps.
@@ -94,7 +102,7 @@ export class HookEditorComponent extends Container {
// Submit on any plain Enter encoding, including terminals that report unmodified Enter as LF.
if (matchesKey(keyData, "enter") || matchesKey(keyData, "return")) {
this.#onSubmitCallback(this.#editor.getText());
this.#submitCurrentText();
return;
}
@@ -105,8 +113,8 @@ export class HookEditorComponent extends Container {
/** Hook-style: Enter=newline, Ctrl+Enter=submit (original behavior) */
#handleHookStyleInput(keyData: string): void {
// Ctrl+Enter to submit. Use key matching so lock-key and keypad Enter variants work.
if (matchesKey(keyData, "ctrl+enter")) {
this.#onSubmitCallback(this.#editor.getText());
if (isCtrlEnterSubmit(keyData)) {
this.#submitCurrentText();
return;
}
@@ -0,0 +1,22 @@
## Code Review Request
### Mode
Custom review instructions
### Distribution Guidelines
Use the `task` tool with `agent: "reviewer"` and a `tasks` array.
Create exactly **1 reviewer task**. Its assignment must include the custom instructions below.
### Reviewer Instructions
Reviewer MUST:
1. Follow the custom instructions below
2. Read the referenced files or workspace context needed to evaluate them
3. Call `report_finding` per issue
4. Call `yield` with verdict when done
### Custom Instructions
{{instructions}}
@@ -0,0 +1,16 @@
## Code Review Request
### Mode
Headless review request
### Distribution Guidelines
Use the `task` tool with `agent: "reviewer"` and a `tasks` array.
Create exactly **1 reviewer task** for recent code changes.
{{#if focus}}
### Focus
{{focus}}
{{/if}}
@@ -23,14 +23,13 @@ _No files to review._
### Distribution Guidelines
{{#when agentCount "==" 1}}Use **1 reviewer agent**.{{else}}Spawn **{{agentCount}} reviewer agents** in parallel.{{/when}}
Use the `task` tool with `agent: "reviewer"` and a `tasks` array.
{{#when agentCount "==" 1}}Create exactly **1 reviewer task**.{{else}}Spawn **{{agentCount}} reviewer agents** in parallel.{{/when}}
{{#if multiAgent}}
Group files by locality, e.g.:
- Same directory/module → same agent
- Related functionality → same agent
- Tests with their implementation files → same agent
You MUST use Task tool with `agent: "reviewer"` and `tasks` array.
{{/if}}
### Reviewer Instructions