@oh-my-pi/pi-coding-agent 12.19.2 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/package.json +7 -7
- package/src/commit/prompts/analysis-system.md +3 -3
- package/src/commit/prompts/analysis-user.md +14 -14
- package/src/commit/prompts/changelog-system.md +4 -4
- package/src/commit/prompts/changelog-user.md +4 -4
- package/src/commit/prompts/file-observer-system.md +2 -2
- package/src/commit/prompts/file-observer-user.md +2 -2
- package/src/commit/prompts/reduce-system.md +4 -4
- package/src/commit/prompts/reduce-user.md +6 -6
- package/src/commit/prompts/summary-system.md +4 -4
- package/src/commit/prompts/summary-user.md +6 -6
- package/src/config/settings-schema.ts +0 -11
- package/src/discovery/helpers.ts +13 -1
- package/src/internal-urls/docs-index.generated.ts +2 -2
- package/src/internal-urls/index.ts +8 -3
- package/src/internal-urls/local-protocol.ts +223 -0
- package/src/internal-urls/{docs-protocol.ts → pi-protocol.ts} +12 -12
- package/src/internal-urls/router.ts +1 -1
- package/src/internal-urls/types.ts +1 -1
- package/src/ipy/executor.ts +4 -32
- package/src/main.ts +0 -1
- package/src/memories/index.ts +1 -1
- package/src/modes/components/settings-defs.ts +0 -5
- package/src/modes/controllers/event-controller.ts +4 -4
- package/src/modes/interactive-mode.ts +84 -64
- package/src/modes/types.ts +11 -3
- package/src/modes/utils/ui-helpers.ts +5 -3
- package/src/patch/hashline.ts +42 -42
- package/src/patch/index.ts +24 -21
- package/src/patch/shared.ts +21 -43
- package/src/plan-mode/approved-plan.ts +55 -0
- package/src/prompts/agents/designer.md +6 -6
- package/src/prompts/agents/explore.md +4 -4
- package/src/prompts/agents/frontmatter.md +1 -0
- package/src/prompts/agents/init.md +10 -10
- package/src/prompts/agents/plan.md +6 -6
- package/src/prompts/agents/reviewer.md +4 -3
- package/src/prompts/agents/task.md +10 -10
- package/src/prompts/compaction/branch-summary.md +3 -3
- package/src/prompts/compaction/compaction-short-summary.md +7 -7
- package/src/prompts/compaction/compaction-summary-context.md +1 -1
- package/src/prompts/compaction/compaction-summary.md +5 -5
- package/src/prompts/compaction/compaction-turn-prefix.md +3 -3
- package/src/prompts/compaction/compaction-update-summary.md +11 -11
- package/src/prompts/memories/consolidation.md +5 -5
- package/src/prompts/memories/read-path.md +11 -0
- package/src/prompts/memories/stage_one_input.md +1 -1
- package/src/prompts/memories/stage_one_system.md +5 -5
- package/src/prompts/review-request.md +4 -4
- package/src/prompts/system/agent-creation-architect.md +17 -17
- package/src/prompts/system/agent-creation-user.md +2 -2
- package/src/prompts/system/custom-system-prompt.md +6 -6
- package/src/prompts/system/plan-mode-active.md +20 -20
- package/src/prompts/system/plan-mode-approved.md +9 -7
- package/src/prompts/system/plan-mode-reference.md +2 -2
- package/src/prompts/system/plan-mode-subagent.md +8 -8
- package/src/prompts/system/subagent-submit-reminder.md +5 -5
- package/src/prompts/system/subagent-system-prompt.md +9 -9
- package/src/prompts/system/subagent-user-prompt.md +3 -5
- package/src/prompts/system/summarization-system.md +1 -1
- package/src/prompts/system/system-prompt.md +109 -84
- package/src/prompts/system/title-system.md +2 -2
- package/src/prompts/system/ttsr-interrupt.md +2 -2
- package/src/prompts/system/web-search.md +16 -16
- package/src/prompts/tools/ask.md +6 -6
- package/src/prompts/tools/bash.md +9 -9
- package/src/prompts/tools/browser.md +5 -5
- package/src/prompts/tools/cancel-job.md +2 -2
- package/src/prompts/tools/exit-plan-mode.md +13 -10
- package/src/prompts/tools/find.md +2 -2
- package/src/prompts/tools/gemini-image.md +7 -7
- package/src/prompts/tools/grep.md +4 -3
- package/src/prompts/tools/hashline.md +37 -39
- package/src/prompts/tools/patch.md +5 -5
- package/src/prompts/tools/poll-jobs.md +1 -1
- package/src/prompts/tools/python.md +8 -10
- package/src/prompts/tools/read.md +2 -12
- package/src/prompts/tools/replace.md +6 -6
- package/src/prompts/tools/ssh.md +2 -7
- package/src/prompts/tools/task.md +34 -23
- package/src/prompts/tools/todo-write.md +65 -49
- package/src/prompts/tools/web-search.md +2 -2
- package/src/prompts/tools/write.md +4 -3
- package/src/sdk.ts +11 -9
- package/src/session/agent-session.ts +92 -51
- package/src/session/artifacts.ts +1 -1
- package/src/session/messages.ts +1 -0
- package/src/task/agents.ts +1 -0
- package/src/task/index.ts +2 -1
- package/src/task/render.ts +2 -2
- package/src/task/types.ts +1 -0
- package/src/tools/bash-interactive.ts +1 -1
- package/src/tools/bash-skill-urls.ts +3 -2
- package/src/tools/bash.ts +38 -19
- package/src/tools/exit-plan-mode.ts +30 -2
- package/src/tools/grep.ts +131 -75
- package/src/tools/index.ts +13 -3
- package/src/tools/path-utils.ts +2 -1
- package/src/tools/plan-mode-guard.ts +8 -8
- package/src/tools/python.ts +0 -2
- package/src/tools/read.ts +2 -2
- package/src/tools/todo-write.ts +276 -146
- package/src/internal-urls/plan-protocol.ts +0 -95
- package/src/modes/components/todo-display.ts +0 -114
- package/src/prompts/memories/read_path.md +0 -11
package/src/patch/hashline.ts
CHANGED
|
@@ -16,7 +16,7 @@ import type { HashMismatch } from "./types";
|
|
|
16
16
|
|
|
17
17
|
export type LineTag = { line: number; hash: string };
|
|
18
18
|
export type HashlineEdit =
|
|
19
|
-
| { op: "
|
|
19
|
+
| { op: "replace"; tag: LineTag; content: string[] }
|
|
20
20
|
| { op: "replace"; first: LineTag; last: LineTag; content: string[] }
|
|
21
21
|
| { op: "append"; after?: LineTag; content: string[] }
|
|
22
22
|
| { op: "prepend"; before?: LineTag; content: string[] }
|
|
@@ -414,7 +414,7 @@ export function validateLineRef(ref: { line: number; hash: string }, fileLines:
|
|
|
414
414
|
/**
|
|
415
415
|
* Apply an array of hashline edits to file content.
|
|
416
416
|
*
|
|
417
|
-
* Each edit operation identifies target lines directly (`
|
|
417
|
+
* Each edit operation identifies target lines directly (`replace`,
|
|
418
418
|
* `insert`). Line references are resolved via {@link parseTag}
|
|
419
419
|
* and hashes validated before any mutation.
|
|
420
420
|
*
|
|
@@ -456,8 +456,17 @@ export function applyHashlineEdits(
|
|
|
456
456
|
}
|
|
457
457
|
for (const edit of edits) {
|
|
458
458
|
switch (edit.op) {
|
|
459
|
-
case "
|
|
460
|
-
if (
|
|
459
|
+
case "replace": {
|
|
460
|
+
if ("tag" in edit) {
|
|
461
|
+
if (!validateRef(edit.tag)) continue;
|
|
462
|
+
} else {
|
|
463
|
+
if (edit.first.line > edit.last.line) {
|
|
464
|
+
throw new Error(`Range start line ${edit.first.line} must be <= end line ${edit.last.line}`);
|
|
465
|
+
}
|
|
466
|
+
const startValid = validateRef(edit.first);
|
|
467
|
+
const endValid = validateRef(edit.last);
|
|
468
|
+
if (!startValid || !endValid) continue;
|
|
469
|
+
}
|
|
461
470
|
break;
|
|
462
471
|
}
|
|
463
472
|
case "append": {
|
|
@@ -486,16 +495,6 @@ export function applyHashlineEdits(
|
|
|
486
495
|
if (!afterValid || !beforeValid) continue;
|
|
487
496
|
break;
|
|
488
497
|
}
|
|
489
|
-
case "replace": {
|
|
490
|
-
if (edit.first.line > edit.last.line) {
|
|
491
|
-
throw new Error(`Range start line ${edit.first.line} must be <= end line ${edit.last.line}`);
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
const startValid = validateRef(edit.first);
|
|
495
|
-
const endValid = validateRef(edit.last);
|
|
496
|
-
if (!startValid || !endValid) continue;
|
|
497
|
-
break;
|
|
498
|
-
}
|
|
499
498
|
}
|
|
500
499
|
}
|
|
501
500
|
if (mismatches.length > 0) {
|
|
@@ -508,11 +507,12 @@ export function applyHashlineEdits(
|
|
|
508
507
|
const edit = edits[i];
|
|
509
508
|
let lineKey: string;
|
|
510
509
|
switch (edit.op) {
|
|
511
|
-
case "set":
|
|
512
|
-
lineKey = `s:${edit.tag.line}`;
|
|
513
|
-
break;
|
|
514
510
|
case "replace":
|
|
515
|
-
|
|
511
|
+
if ("tag" in edit) {
|
|
512
|
+
lineKey = `s:${edit.tag.line}`;
|
|
513
|
+
} else {
|
|
514
|
+
lineKey = `r:${edit.first.line}:${edit.last.line}`;
|
|
515
|
+
}
|
|
516
516
|
break;
|
|
517
517
|
case "append":
|
|
518
518
|
if (edit.after) {
|
|
@@ -550,12 +550,12 @@ export function applyHashlineEdits(
|
|
|
550
550
|
let sortLine: number;
|
|
551
551
|
let precedence: number;
|
|
552
552
|
switch (edit.op) {
|
|
553
|
-
case "set":
|
|
554
|
-
sortLine = edit.tag.line;
|
|
555
|
-
precedence = 0;
|
|
556
|
-
break;
|
|
557
553
|
case "replace":
|
|
558
|
-
|
|
554
|
+
if ("tag" in edit) {
|
|
555
|
+
sortLine = edit.tag.line;
|
|
556
|
+
} else {
|
|
557
|
+
sortLine = edit.last.line;
|
|
558
|
+
}
|
|
559
559
|
precedence = 0;
|
|
560
560
|
break;
|
|
561
561
|
case "append":
|
|
@@ -579,26 +579,26 @@ export function applyHashlineEdits(
|
|
|
579
579
|
// Apply edits bottom-up
|
|
580
580
|
for (const { edit, idx } of annotated) {
|
|
581
581
|
switch (edit.op) {
|
|
582
|
-
case "set": {
|
|
583
|
-
const origLines = originalFileLines.slice(edit.tag.line - 1, edit.tag.line);
|
|
584
|
-
const newLines = edit.content;
|
|
585
|
-
if (origLines.every((line, i) => line === newLines[i])) {
|
|
586
|
-
noopEdits.push({
|
|
587
|
-
editIndex: idx,
|
|
588
|
-
loc: `${edit.tag.line}#${edit.tag.hash}`,
|
|
589
|
-
currentContent: origLines.join("\n"),
|
|
590
|
-
});
|
|
591
|
-
break;
|
|
592
|
-
}
|
|
593
|
-
fileLines.splice(edit.tag.line - 1, 1, ...newLines);
|
|
594
|
-
trackFirstChanged(edit.tag.line);
|
|
595
|
-
break;
|
|
596
|
-
}
|
|
597
582
|
case "replace": {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
583
|
+
if ("tag" in edit) {
|
|
584
|
+
const origLines = originalFileLines.slice(edit.tag.line - 1, edit.tag.line);
|
|
585
|
+
const newLines = edit.content;
|
|
586
|
+
if (origLines.every((line, i) => line === newLines[i])) {
|
|
587
|
+
noopEdits.push({
|
|
588
|
+
editIndex: idx,
|
|
589
|
+
loc: `${edit.tag.line}#${edit.tag.hash}`,
|
|
590
|
+
currentContent: origLines.join("\n"),
|
|
591
|
+
});
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
594
|
+
fileLines.splice(edit.tag.line - 1, 1, ...newLines);
|
|
595
|
+
trackFirstChanged(edit.tag.line);
|
|
596
|
+
} else {
|
|
597
|
+
const count = edit.last.line - edit.first.line + 1;
|
|
598
|
+
const newLines = edit.content;
|
|
599
|
+
fileLines.splice(edit.first.line - 1, count, ...newLines);
|
|
600
|
+
trackFirstChanged(edit.first.line);
|
|
601
|
+
}
|
|
602
602
|
break;
|
|
603
603
|
}
|
|
604
604
|
case "append": {
|
package/src/patch/index.ts
CHANGED
|
@@ -194,9 +194,9 @@ export function hashlineParseContent(edit: string | string[] | null): string[] {
|
|
|
194
194
|
if (lines[lines.length - 1].trim() === "") return lines.slice(0, -1);
|
|
195
195
|
return lines;
|
|
196
196
|
}
|
|
197
|
-
const
|
|
197
|
+
const hashlineReplaceTagEditSchema = Type.Object(
|
|
198
198
|
{
|
|
199
|
-
op: Type.Literal("
|
|
199
|
+
op: Type.Literal("replace"),
|
|
200
200
|
tag: hashlineTagFormat("line being replaced"),
|
|
201
201
|
content: hashlineReplaceContentFormat("Replacement"),
|
|
202
202
|
},
|
|
@@ -221,7 +221,7 @@ const hashlinePrependEditSchema = Type.Object(
|
|
|
221
221
|
{ additionalProperties: false },
|
|
222
222
|
);
|
|
223
223
|
|
|
224
|
-
const
|
|
224
|
+
const hashlineReplaceRangeEditSchema = Type.Object(
|
|
225
225
|
{
|
|
226
226
|
op: Type.Literal("replace"),
|
|
227
227
|
first: hashlineTagFormat("first line"),
|
|
@@ -242,8 +242,8 @@ const hashlineInsertEditSchema = Type.Object(
|
|
|
242
242
|
);
|
|
243
243
|
|
|
244
244
|
const hashlineEditSpecSchema = Type.Union([
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
hashlineReplaceTagEditSchema,
|
|
246
|
+
hashlineReplaceRangeEditSchema,
|
|
247
247
|
hashlineAppendEditSchema,
|
|
248
248
|
hashlinePrependEditSchema,
|
|
249
249
|
hashlineInsertEditSchema,
|
|
@@ -556,19 +556,21 @@ export class EditTool implements AgentTool<TInput> {
|
|
|
556
556
|
const anchorEdits: HashlineEdit[] = [];
|
|
557
557
|
for (const edit of edits) {
|
|
558
558
|
switch (edit.op) {
|
|
559
|
-
case "set": {
|
|
560
|
-
const { tag, content } = edit;
|
|
561
|
-
anchorEdits.push({ op: "set", tag: parseTag(tag), content: hashlineParseContent(content) });
|
|
562
|
-
break;
|
|
563
|
-
}
|
|
564
559
|
case "replace": {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
}
|
|
560
|
+
if ("tag" in edit) {
|
|
561
|
+
anchorEdits.push({
|
|
562
|
+
op: "replace",
|
|
563
|
+
tag: parseTag(edit.tag),
|
|
564
|
+
content: hashlineParseContent(edit.content),
|
|
565
|
+
});
|
|
566
|
+
} else {
|
|
567
|
+
anchorEdits.push({
|
|
568
|
+
op: "replace",
|
|
569
|
+
first: parseTag(edit.first),
|
|
570
|
+
last: parseTag(edit.last),
|
|
571
|
+
content: hashlineParseContent(edit.content),
|
|
572
|
+
});
|
|
573
|
+
}
|
|
572
574
|
break;
|
|
573
575
|
}
|
|
574
576
|
case "append": {
|
|
@@ -656,11 +658,12 @@ export class EditTool implements AgentTool<TInput> {
|
|
|
656
658
|
for (const edit of anchorEdits) {
|
|
657
659
|
refs.length = 0;
|
|
658
660
|
switch (edit.op) {
|
|
659
|
-
case "set":
|
|
660
|
-
refs.push(edit.tag);
|
|
661
|
-
break;
|
|
662
661
|
case "replace":
|
|
663
|
-
|
|
662
|
+
if ("tag" in edit) {
|
|
663
|
+
refs.push(edit.tag);
|
|
664
|
+
} else {
|
|
665
|
+
refs.push(edit.first, edit.last);
|
|
666
|
+
}
|
|
664
667
|
break;
|
|
665
668
|
case "append":
|
|
666
669
|
if (edit.after) refs.push(edit.after);
|
package/src/patch/shared.ts
CHANGED
|
@@ -87,10 +87,11 @@ interface EditRenderArgs {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
type HashlineEditPreview =
|
|
90
|
-
| {
|
|
91
|
-
| { first: string; last: string;
|
|
92
|
-
| {
|
|
93
|
-
| {
|
|
90
|
+
| { op: "replace"; tag: string; content: string[] }
|
|
91
|
+
| { op: "replace"; first: string; last: string; content: string[] }
|
|
92
|
+
| { op: "append"; after?: string; content: string[] }
|
|
93
|
+
| { op: "prepend"; before?: string; content: string[] }
|
|
94
|
+
| { op: "insert"; before: string; after: string; content: string[] };
|
|
94
95
|
|
|
95
96
|
/** Extended context for edit tool rendering */
|
|
96
97
|
export interface EditRenderContext {
|
|
@@ -158,56 +159,33 @@ function formatStreamingHashlineEdits(edits: unknown[], uiTheme: Theme): string
|
|
|
158
159
|
|
|
159
160
|
return text.trimEnd();
|
|
160
161
|
function formatHashlineEdit(edit: unknown): { srcLabel: string; dst: string } {
|
|
161
|
-
const
|
|
162
|
-
if (typeof value === "object" && value !== null) return value as Record<string, unknown>;
|
|
163
|
-
return undefined;
|
|
164
|
-
};
|
|
165
|
-
const editRecord = asRecord(edit);
|
|
162
|
+
const editRecord = typeof edit === "object" && edit !== null ? (edit as Record<string, unknown>) : undefined;
|
|
166
163
|
if (!editRecord) {
|
|
167
|
-
return {
|
|
168
|
-
srcLabel: "• (incomplete edit)",
|
|
169
|
-
dst: "",
|
|
170
|
-
};
|
|
164
|
+
return { srcLabel: "• (incomplete edit)", dst: "" };
|
|
171
165
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
};
|
|
166
|
+
|
|
167
|
+
const contentLines = Array.isArray(editRecord.content) ? (editRecord.content as string[]).join("\n") : "";
|
|
168
|
+
|
|
169
|
+
// replace with tag (single line)
|
|
170
|
+
if ("tag" in editRecord && !("first" in editRecord)) {
|
|
171
|
+
const tag = typeof editRecord.tag === "string" ? editRecord.tag : "…";
|
|
172
|
+
return { srcLabel: `• line ${tag}`, dst: contentLines };
|
|
179
173
|
}
|
|
174
|
+
// replace with first..last (range)
|
|
180
175
|
if ("first" in editRecord || "last" in editRecord) {
|
|
181
176
|
const first = typeof editRecord.first === "string" ? editRecord.first : "…";
|
|
182
177
|
const last = typeof editRecord.last === "string" ? editRecord.last : "…";
|
|
183
|
-
|
|
184
|
-
return {
|
|
185
|
-
srcLabel: `• range ${first}..${last}`,
|
|
186
|
-
dst: Array.isArray(newContent) ? (newContent as string[]).join("\n") : "",
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
if ("old_text" in editRecord || "new_text" in editRecord) {
|
|
190
|
-
const all = typeof editRecord.all === "boolean" ? editRecord.all : false;
|
|
191
|
-
return {
|
|
192
|
-
srcLabel: `• replace old_text→new_text${all ? " (all)" : ""}`,
|
|
193
|
-
dst: typeof editRecord.new_text === "string" ? editRecord.new_text : "",
|
|
194
|
-
};
|
|
178
|
+
return { srcLabel: `• range ${first}..${last}`, dst: contentLines };
|
|
195
179
|
}
|
|
196
|
-
|
|
180
|
+
// append/prepend/insert
|
|
181
|
+
if ("before" in editRecord || "after" in editRecord) {
|
|
197
182
|
const after = typeof editRecord.after === "string" ? editRecord.after : undefined;
|
|
198
183
|
const before = typeof editRecord.before === "string" ? editRecord.before : undefined;
|
|
199
|
-
const insertedLines = editRecord.inserted_lines;
|
|
200
|
-
const text = Array.isArray(insertedLines) ? (insertedLines as string[]).join("\n") : "";
|
|
201
184
|
const refs = [after, before].filter(Boolean).join("..") || "…";
|
|
202
|
-
return {
|
|
203
|
-
srcLabel: `• insert ${refs}`,
|
|
204
|
-
dst: text,
|
|
205
|
-
};
|
|
185
|
+
return { srcLabel: `• insert ${refs}`, dst: contentLines };
|
|
206
186
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
dst: "",
|
|
210
|
-
};
|
|
187
|
+
|
|
188
|
+
return { srcLabel: "• (incomplete edit)", dst: "" };
|
|
211
189
|
}
|
|
212
190
|
}
|
|
213
191
|
function formatMetadataLine(lineCount: number | null, language: string | undefined, uiTheme: Theme): string {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import { isEnoent } from "@oh-my-pi/pi-utils";
|
|
3
|
+
import { resolveLocalUrlToPath } from "../internal-urls";
|
|
4
|
+
|
|
5
|
+
interface RenameApprovedPlanFileOptions {
|
|
6
|
+
planFilePath: string;
|
|
7
|
+
finalPlanFilePath: string;
|
|
8
|
+
getArtifactsDir: () => string | null;
|
|
9
|
+
getSessionId: () => string | null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function assertLocalUrl(path: string, label: "source" | "destination"): void {
|
|
13
|
+
if (!path.startsWith("local://")) {
|
|
14
|
+
throw new Error(`Approved plan ${label} path must use local:// (received ${path}).`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function renameApprovedPlanFile(options: RenameApprovedPlanFileOptions): Promise<void> {
|
|
19
|
+
const { planFilePath, finalPlanFilePath, getArtifactsDir, getSessionId } = options;
|
|
20
|
+
assertLocalUrl(planFilePath, "source");
|
|
21
|
+
assertLocalUrl(finalPlanFilePath, "destination");
|
|
22
|
+
|
|
23
|
+
const resolveOptions = {
|
|
24
|
+
getArtifactsDir: () => getArtifactsDir(),
|
|
25
|
+
getSessionId: () => getSessionId(),
|
|
26
|
+
};
|
|
27
|
+
const resolvedSource = resolveLocalUrlToPath(planFilePath, resolveOptions);
|
|
28
|
+
const resolvedDestination = resolveLocalUrlToPath(finalPlanFilePath, resolveOptions);
|
|
29
|
+
|
|
30
|
+
if (resolvedSource === resolvedDestination) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const destinationStat = await fs.stat(resolvedDestination);
|
|
36
|
+
if (destinationStat.isFile()) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Plan destination already exists at ${finalPlanFilePath}. Choose a different title and call exit_plan_mode again.`,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
throw new Error(`Plan destination exists but is not a file: ${finalPlanFilePath}`);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (!isEnoent(error)) {
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
await fs.rename(resolvedSource, resolvedDestination);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Failed to rename approved plan from ${planFilePath} to ${finalPlanFilePath}: ${error instanceof Error ? error.message : String(error)}`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -8,7 +8,7 @@ model: google-gemini-cli/gemini-3-pro, gemini-3-pro, gemini-3, pi/default
|
|
|
8
8
|
<role>Senior design engineer with 10+ years shipping production interfaces. Implements UI, conducts design reviews, refines components.</role>
|
|
9
9
|
|
|
10
10
|
<critical>
|
|
11
|
-
You
|
|
11
|
+
You MAY make file edits, create components, and run commands—and SHOULD do so when needed.
|
|
12
12
|
</critical>
|
|
13
13
|
|
|
14
14
|
<strengths>
|
|
@@ -35,9 +35,9 @@ You CAN and SHOULD make file edits, create components, run commands.
|
|
|
35
35
|
</procedure>
|
|
36
36
|
|
|
37
37
|
<directives>
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
38
|
+
- You SHOULD prefer editing existing files over creating new ones
|
|
39
|
+
- Changes MUST be minimal and consistent with existing code style
|
|
40
|
+
- You MUST NOT create documentation files (*.md) unless explicitly requested
|
|
41
41
|
</directives>
|
|
42
42
|
|
|
43
43
|
<avoid>
|
|
@@ -66,6 +66,6 @@ You CAN and SHOULD make file edits, create components, run commands.
|
|
|
66
66
|
|
|
67
67
|
<critical>
|
|
68
68
|
Every interface should prompt "how was this made?" not "which AI made this?"
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
You MUST commit to clear aesthetic direction and execute with precision.
|
|
70
|
+
You MUST keep going until implementation is complete.
|
|
71
71
|
</critical>
|
|
@@ -77,7 +77,7 @@ output:
|
|
|
77
77
|
<role>File search specialist and codebase scout. Quickly investigate codebase, return structured findings another agent can use without re-reading everything.</role>
|
|
78
78
|
|
|
79
79
|
<critical>
|
|
80
|
-
|
|
80
|
+
You MUST operate as read-only. You MUST NOT:
|
|
81
81
|
- Creating/modifying files (no Write/Edit/touch/rm/mv/cp)
|
|
82
82
|
- Creating temporary files anywhere (incl /tmp)
|
|
83
83
|
- Using redirects (>, >>, |) or heredocs to write files
|
|
@@ -88,8 +88,8 @@ READ-ONLY. STRICTLY PROHIBITED from:
|
|
|
88
88
|
- Use find for broad pattern matching
|
|
89
89
|
- Use grep for regex content search
|
|
90
90
|
- Use read when path is known
|
|
91
|
-
-
|
|
92
|
-
-
|
|
91
|
+
- You MUST use bash ONLY for git status/log/diff; you MUST use read/grep/find/ls for file/search operations
|
|
92
|
+
- You SHOULD spawn parallel tool calls when possible—this agent is meant to be fast
|
|
93
93
|
- Return absolute file paths in final response
|
|
94
94
|
</directives>
|
|
95
95
|
|
|
@@ -108,5 +108,5 @@ Infer from task; default medium:
|
|
|
108
108
|
</procedure>
|
|
109
109
|
|
|
110
110
|
<critical>
|
|
111
|
-
|
|
111
|
+
You MUST call `submit_result` with findings when done.
|
|
112
112
|
</critical>
|
|
@@ -5,5 +5,6 @@ description: {{jsonStringify description}}
|
|
|
5
5
|
{{#if spawns}}spawns: {{jsonStringify spawns}}
|
|
6
6
|
{{/if}}{{#if model}}model: {{jsonStringify model}}
|
|
7
7
|
{{/if}}{{#if thinkingLevel}}thinking-level: {{jsonStringify thinkingLevel}}
|
|
8
|
+
{{/if}}{{#if blocking}}blocking: true
|
|
8
9
|
{{/if}}---
|
|
9
10
|
{{body}}
|
|
@@ -17,20 +17,20 @@ Analyze codebase, generate AGENTS.md documenting:
|
|
|
17
17
|
</task>
|
|
18
18
|
|
|
19
19
|
<parallel>
|
|
20
|
-
|
|
20
|
+
You MUST launch multiple `explore` agents in parallel (via `task` tool) scanning different areas (core src, tests, configs/build, scripts/docs), then synthesize.
|
|
21
21
|
</parallel>
|
|
22
22
|
|
|
23
23
|
<directives>
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
24
|
+
- You MUST title the document "Repository Guidelines"
|
|
25
|
+
- You MUST use Markdown headings for structure
|
|
26
|
+
- You MUST be concise and practical
|
|
27
|
+
- You MUST focus on what an AI assistant needs to help with the codebase
|
|
28
|
+
- You SHOULD include examples where helpful (commands, paths, naming patterns)
|
|
29
|
+
- You SHOULD include file paths where relevant
|
|
30
|
+
- You MUST call out architecture and code patterns explicitly
|
|
31
|
+
- You SHOULD omit information obvious from code structure
|
|
32
32
|
</directives>
|
|
33
33
|
|
|
34
34
|
<output>
|
|
35
|
-
After analysis, write AGENTS.md to project root.
|
|
35
|
+
After analysis, you MUST write AGENTS.md to the project root.
|
|
36
36
|
</output>
|
|
@@ -8,14 +8,14 @@ thinking-level: high
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
<critical>
|
|
11
|
-
|
|
11
|
+
You MUST operate as read-only. You MUST NOT:
|
|
12
12
|
- Create/modify files (no Write/Edit/touch/rm/mv/cp)
|
|
13
13
|
- Create temp files anywhere (including /tmp)
|
|
14
14
|
- Using redirects (>, >>) or heredocs
|
|
15
15
|
- Running state-changing commands (git add/commit, npm install)
|
|
16
16
|
- Using bash for file/search ops—use read/grep/find/ls
|
|
17
17
|
|
|
18
|
-
Bash ONLY for: git status/log/diff.
|
|
18
|
+
You MUST use Bash ONLY for: git status/log/diff.
|
|
19
19
|
</critical>
|
|
20
20
|
|
|
21
21
|
<role>
|
|
@@ -34,7 +34,7 @@ Senior software architect producing implementation plans.
|
|
|
34
34
|
4. Identify types, interfaces, contracts
|
|
35
35
|
5. Note dependencies between components
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
You MUST spawn `explore` agents for independent areas and synthesize findings.
|
|
38
38
|
|
|
39
39
|
## Phase 3: Design
|
|
40
40
|
1. List concrete changes (files, functions, types)
|
|
@@ -45,7 +45,7 @@ Spawn `explore` agents for independent areas; synthesize findings.
|
|
|
45
45
|
|
|
46
46
|
## Phase 4: Produce Plan
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
You MUST write a plan executable without re-exploration.
|
|
49
49
|
</procedure>
|
|
50
50
|
|
|
51
51
|
<output>
|
|
@@ -107,6 +107,6 @@ Add rate limiting to API gateway preventing abuse. Requires middleware insertion
|
|
|
107
107
|
</requirements>
|
|
108
108
|
|
|
109
109
|
<critical>
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
You MUST operate as read-only. You MUST NOT write, edit, or modify files.
|
|
111
|
+
You MUST keep going until complete.
|
|
112
112
|
</critical>
|
|
@@ -5,6 +5,7 @@ tools: read, grep, find, bash, report_finding
|
|
|
5
5
|
spawns: explore, task
|
|
6
6
|
model: pi/slow
|
|
7
7
|
thinking-level: high
|
|
8
|
+
blocking: true
|
|
8
9
|
output:
|
|
9
10
|
properties:
|
|
10
11
|
overall_correctness:
|
|
@@ -64,7 +65,7 @@ output:
|
|
|
64
65
|
4. Call `report_finding` per issue
|
|
65
66
|
5. Call `submit_result` with verdict
|
|
66
67
|
|
|
67
|
-
Bash read-only: `git diff`, `git log`, `git show`, `gh pr diff`.
|
|
68
|
+
Bash MUST be used read-only: `git diff`, `git log`, `git show`, `gh pr diff`. You MUST NOT make file edits or trigger builds.
|
|
68
69
|
</procedure>
|
|
69
70
|
|
|
70
71
|
<criteria>
|
|
@@ -116,11 +117,11 @@ Final `submit_result` call (payload under `data`):
|
|
|
116
117
|
- `data.confidence`: 0.0-1.0
|
|
117
118
|
- `data.findings`: Optional; MUST omit (auto-populated from `report_finding`)
|
|
118
119
|
|
|
119
|
-
|
|
120
|
+
You MUST NOT output JSON or code blocks.
|
|
120
121
|
|
|
121
122
|
Correctness ignores non-blocking issues (style, docs, nits).
|
|
122
123
|
</output>
|
|
123
124
|
|
|
124
125
|
<critical>
|
|
125
|
-
Every finding
|
|
126
|
+
Every finding MUST be patch-anchored and evidence-backed.
|
|
126
127
|
</critical>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<role>Worker agent for delegated tasks. You have FULL access to all tools (edit, write, bash, grep, read, etc.) - use them as needed to complete your task.</role>
|
|
2
2
|
|
|
3
3
|
<directives>
|
|
4
|
-
|
|
5
|
-
- You
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
4
|
+
You MUST finish only the assigned work and return the minimum useful result.
|
|
5
|
+
- You MAY make file edits, run commands, and create files when your task requires it—and SHOULD do so.
|
|
6
|
+
- You MUST be concise. You MUST NOT include filler, repetition, or tool transcripts.
|
|
7
|
+
- You SHOULD prefer narrow search (grep/find) then read only needed ranges.
|
|
8
|
+
- You SHOULD NOT do full-file reads unless necessary.
|
|
9
|
+
- You SHOULD prefer edits to existing files over creating new ones.
|
|
10
|
+
- You MUST NOT create documentation files (*.md) unless explicitly requested.
|
|
11
|
+
- You MUST include a 5-8 word user-facing description when spawning subagents with the Task tool.
|
|
12
|
+
- You MUST include the smallest relevant code snippet when discussing code or config.
|
|
13
|
+
- You MUST follow the main agent's instructions.
|
|
14
14
|
</directives>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
You MUST create a structured summary of the conversation branch for context when returning.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
You MUST use EXACT format:
|
|
4
4
|
|
|
5
5
|
## Goal
|
|
6
6
|
|
|
@@ -27,4 +27,4 @@ Use EXACT format:
|
|
|
27
27
|
## Next Steps
|
|
28
28
|
1. [What should happen next to continue]
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Sections MUST be kept concise. You MUST preserve exact file paths, function names, error messages.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
You MUST summarize what was done in this conversation, written like a pull request description.
|
|
2
2
|
|
|
3
3
|
Rules:
|
|
4
|
-
- 2-3 sentences max
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
4
|
+
- MUST be 2-3 sentences max
|
|
5
|
+
- MUST describe the changes made, not the process
|
|
6
|
+
- MUST NOT mention running tests, builds, or other validation steps
|
|
7
|
+
- MUST NOT explain what the user asked for
|
|
8
|
+
- MUST write in first person (I added..., I fixed...)
|
|
9
|
+
- MUST NOT ask questions
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Another language model started to solve this problem and produced a summary of its thinking process. You also have access to the state of the tools that were used by that language model.
|
|
1
|
+
Another language model started to solve this problem and produced a summary of its thinking process. You also have access to the state of the tools that were used by that language model. You MUST use this to build on the work that has already been done and MUST NOT duplicate work. Here is the summary produced by the other language model; you MUST use the information in this summary to assist with your own analysis:
|
|
2
2
|
|
|
3
3
|
<summary>
|
|
4
4
|
{{summary}}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
You MUST summarize the conversation above into a structured context checkpoint handoff summary for another LLM to resume task.
|
|
2
2
|
|
|
3
|
-
IMPORTANT: If conversation ends with unanswered question to user or imperative/request awaiting user response (e.g., "Please run command and paste output"), preserve that exact question/request.
|
|
3
|
+
IMPORTANT: If conversation ends with unanswered question to user or imperative/request awaiting user response (e.g., "Please run command and paste output"), you MUST preserve that exact question/request.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
You MUST use this format (sections can be omitted if not applicable):
|
|
6
6
|
|
|
7
7
|
## Goal
|
|
8
8
|
[User goals; list multiple if session covers different tasks.]
|
|
@@ -33,6 +33,6 @@ Use this format (sections can be omitted if not applicable):
|
|
|
33
33
|
## Additional Notes
|
|
34
34
|
[Anything else important not covered above]
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
You MUST output only the structured summary; you MUST NOT include extra text.
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
Sections MUST be kept concise. You MUST preserve exact file paths, function names, error messages, and relevant tool outputs or command results. You MUST include repository state changes (branch, uncommitted changes) if mentioned.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
You MUST summarize the prefix to provide context for the retained suffix:
|
|
4
4
|
|
|
5
5
|
## Original Request
|
|
6
6
|
|
|
@@ -12,6 +12,6 @@ Summarize the prefix to provide context for the retained suffix:
|
|
|
12
12
|
## Context for Suffix
|
|
13
13
|
- [Information needed to understand the retained recent work]
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
You MUST output only the structured summary. You MUST NOT include extra text.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
You MUST be concise. You MUST preserve exact file paths, function names, error messages, and relevant tool outputs or command results if they appear. You MUST focus on what's needed to understand the kept suffix.
|