@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.
Files changed (106) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/package.json +7 -7
  3. package/src/commit/prompts/analysis-system.md +3 -3
  4. package/src/commit/prompts/analysis-user.md +14 -14
  5. package/src/commit/prompts/changelog-system.md +4 -4
  6. package/src/commit/prompts/changelog-user.md +4 -4
  7. package/src/commit/prompts/file-observer-system.md +2 -2
  8. package/src/commit/prompts/file-observer-user.md +2 -2
  9. package/src/commit/prompts/reduce-system.md +4 -4
  10. package/src/commit/prompts/reduce-user.md +6 -6
  11. package/src/commit/prompts/summary-system.md +4 -4
  12. package/src/commit/prompts/summary-user.md +6 -6
  13. package/src/config/settings-schema.ts +0 -11
  14. package/src/discovery/helpers.ts +13 -1
  15. package/src/internal-urls/docs-index.generated.ts +2 -2
  16. package/src/internal-urls/index.ts +8 -3
  17. package/src/internal-urls/local-protocol.ts +223 -0
  18. package/src/internal-urls/{docs-protocol.ts → pi-protocol.ts} +12 -12
  19. package/src/internal-urls/router.ts +1 -1
  20. package/src/internal-urls/types.ts +1 -1
  21. package/src/ipy/executor.ts +4 -32
  22. package/src/main.ts +0 -1
  23. package/src/memories/index.ts +1 -1
  24. package/src/modes/components/settings-defs.ts +0 -5
  25. package/src/modes/controllers/event-controller.ts +4 -4
  26. package/src/modes/interactive-mode.ts +84 -64
  27. package/src/modes/types.ts +11 -3
  28. package/src/modes/utils/ui-helpers.ts +5 -3
  29. package/src/patch/hashline.ts +42 -42
  30. package/src/patch/index.ts +24 -21
  31. package/src/patch/shared.ts +21 -43
  32. package/src/plan-mode/approved-plan.ts +55 -0
  33. package/src/prompts/agents/designer.md +6 -6
  34. package/src/prompts/agents/explore.md +4 -4
  35. package/src/prompts/agents/frontmatter.md +1 -0
  36. package/src/prompts/agents/init.md +10 -10
  37. package/src/prompts/agents/plan.md +6 -6
  38. package/src/prompts/agents/reviewer.md +4 -3
  39. package/src/prompts/agents/task.md +10 -10
  40. package/src/prompts/compaction/branch-summary.md +3 -3
  41. package/src/prompts/compaction/compaction-short-summary.md +7 -7
  42. package/src/prompts/compaction/compaction-summary-context.md +1 -1
  43. package/src/prompts/compaction/compaction-summary.md +5 -5
  44. package/src/prompts/compaction/compaction-turn-prefix.md +3 -3
  45. package/src/prompts/compaction/compaction-update-summary.md +11 -11
  46. package/src/prompts/memories/consolidation.md +5 -5
  47. package/src/prompts/memories/read-path.md +11 -0
  48. package/src/prompts/memories/stage_one_input.md +1 -1
  49. package/src/prompts/memories/stage_one_system.md +5 -5
  50. package/src/prompts/review-request.md +4 -4
  51. package/src/prompts/system/agent-creation-architect.md +17 -17
  52. package/src/prompts/system/agent-creation-user.md +2 -2
  53. package/src/prompts/system/custom-system-prompt.md +6 -6
  54. package/src/prompts/system/plan-mode-active.md +20 -20
  55. package/src/prompts/system/plan-mode-approved.md +9 -7
  56. package/src/prompts/system/plan-mode-reference.md +2 -2
  57. package/src/prompts/system/plan-mode-subagent.md +8 -8
  58. package/src/prompts/system/subagent-submit-reminder.md +5 -5
  59. package/src/prompts/system/subagent-system-prompt.md +9 -9
  60. package/src/prompts/system/subagent-user-prompt.md +3 -5
  61. package/src/prompts/system/summarization-system.md +1 -1
  62. package/src/prompts/system/system-prompt.md +109 -84
  63. package/src/prompts/system/title-system.md +2 -2
  64. package/src/prompts/system/ttsr-interrupt.md +2 -2
  65. package/src/prompts/system/web-search.md +16 -16
  66. package/src/prompts/tools/ask.md +6 -6
  67. package/src/prompts/tools/bash.md +9 -9
  68. package/src/prompts/tools/browser.md +5 -5
  69. package/src/prompts/tools/cancel-job.md +2 -2
  70. package/src/prompts/tools/exit-plan-mode.md +13 -10
  71. package/src/prompts/tools/find.md +2 -2
  72. package/src/prompts/tools/gemini-image.md +7 -7
  73. package/src/prompts/tools/grep.md +4 -3
  74. package/src/prompts/tools/hashline.md +37 -39
  75. package/src/prompts/tools/patch.md +5 -5
  76. package/src/prompts/tools/poll-jobs.md +1 -1
  77. package/src/prompts/tools/python.md +8 -10
  78. package/src/prompts/tools/read.md +2 -12
  79. package/src/prompts/tools/replace.md +6 -6
  80. package/src/prompts/tools/ssh.md +2 -7
  81. package/src/prompts/tools/task.md +34 -23
  82. package/src/prompts/tools/todo-write.md +65 -49
  83. package/src/prompts/tools/web-search.md +2 -2
  84. package/src/prompts/tools/write.md +4 -3
  85. package/src/sdk.ts +11 -9
  86. package/src/session/agent-session.ts +92 -51
  87. package/src/session/artifacts.ts +1 -1
  88. package/src/session/messages.ts +1 -0
  89. package/src/task/agents.ts +1 -0
  90. package/src/task/index.ts +2 -1
  91. package/src/task/render.ts +2 -2
  92. package/src/task/types.ts +1 -0
  93. package/src/tools/bash-interactive.ts +1 -1
  94. package/src/tools/bash-skill-urls.ts +3 -2
  95. package/src/tools/bash.ts +38 -19
  96. package/src/tools/exit-plan-mode.ts +30 -2
  97. package/src/tools/grep.ts +131 -75
  98. package/src/tools/index.ts +13 -3
  99. package/src/tools/path-utils.ts +2 -1
  100. package/src/tools/plan-mode-guard.ts +8 -8
  101. package/src/tools/python.ts +0 -2
  102. package/src/tools/read.ts +2 -2
  103. package/src/tools/todo-write.ts +276 -146
  104. package/src/internal-urls/plan-protocol.ts +0 -95
  105. package/src/modes/components/todo-display.ts +0 -114
  106. package/src/prompts/memories/read_path.md +0 -11
@@ -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: "set"; tag: LineTag; content: string[] }
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 (`set`, `set_range`,
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 "set": {
460
- if (!validateRef(edit.tag)) continue;
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
- lineKey = `r:${edit.first.line}:${edit.last.line}`;
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
- sortLine = edit.last.line;
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
- const count = edit.last.line - edit.first.line + 1;
599
- const newLines = edit.content;
600
- fileLines.splice(edit.first.line - 1, count, ...newLines);
601
- trackFirstChanged(edit.first.line);
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": {
@@ -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 hashlineTargetEditSchema = Type.Object(
197
+ const hashlineReplaceTagEditSchema = Type.Object(
198
198
  {
199
- op: Type.Literal("set"),
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 hashlineRangeEditSchema = Type.Object(
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
- hashlineTargetEditSchema,
246
- hashlineRangeEditSchema,
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
- const { first, last, content } = edit;
566
- anchorEdits.push({
567
- op: "replace",
568
- first: parseTag(first),
569
- last: parseTag(last),
570
- content: hashlineParseContent(content),
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
- refs.push(edit.first, edit.last);
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);
@@ -87,10 +87,11 @@ interface EditRenderArgs {
87
87
  }
88
88
 
89
89
  type HashlineEditPreview =
90
- | { target: string; new_content: string[] }
91
- | { first: string; last: string; new_content: string[] }
92
- | { before?: string; after?: string; inserted_lines: string[] }
93
- | { old_text: string; new_text: string; all?: boolean };
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 asRecord = (value: unknown): Record<string, unknown> | undefined => {
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
- if ("target" in editRecord) {
173
- const target = typeof editRecord.target === "string" ? editRecord.target : "";
174
- const newContent = editRecord.new_content;
175
- return {
176
- srcLabel: `• line ${target}`,
177
- dst: Array.isArray(newContent) ? (newContent as string[]).join("\n") : "",
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
- const newContent = editRecord.new_content;
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
- if ("inserted_lines" in editRecord || "before" in editRecord || "after" in editRecord) {
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
- return {
208
- srcLabel: "• (incomplete edit)",
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 CAN and SHOULD make file edits, create components, run commands.
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
- - Prefer editing existing files over creating new ones
39
- - Keep changes minimal and consistent with existing code style
40
- - NEVER create documentation files (*.md) unless explicitly requested
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
- Commit to clear aesthetic direction; execute with precision.
70
- Keep going until implementation complete.
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
- READ-ONLY. STRICTLY PROHIBITED from:
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
- - Use bash ONLY for git status/log/diff; use read/grep/find/ls for file/search operations
92
- - Spawn parallel tool calls when possible—meant to be fast
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
- Call `submit_result` with findings when done.
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
- Launch multiple `explore` agents in parallel (via `task` tool) scanning different areas (core src, tests, configs/build, scripts/docs), then synthesize.
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
- - Title document "Repository Guidelines"
25
- - Use Markdown headings for structure
26
- - Be concise and practical
27
- - Focus on what AI assistant needs to help with codebase
28
- - Include examples where helpful (commands, paths, naming patterns)
29
- - Include file paths where relevant
30
- - Call out architecture and code patterns explicitly
31
- - Omit information obvious from code structure
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
- READ-ONLY. STRICTLY PROHIBITED from:
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
- Spawn `explore` agents for independent areas; synthesize findings.
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
- Write plan executable without re-exploration.
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
- READ-ONLY. CANNOT write/edit/modify files.
111
- Keep going until complete.
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`. No file edits or builds.
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
- Don't output JSON or code blocks.
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 must be patch-anchored and evidence-backed.
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
- Finish only the assigned work and return the minimum useful result.
5
- - You CAN and SHOULD make file edits, run commands, and create files when your task requires it.
6
- - Be concise. No filler, repetition, or tool transcripts.
7
- - Prefer narrow search (grep/find) then read only needed ranges.
8
- - Avoid full-file reads unless necessary.
9
- - Prefer edits to existing files over creating new ones.
10
- - NEVER create documentation files (*.md) unless explicitly requested.
11
- - When spawning subagents with the Task tool, include a 5-8 word user-facing description.
12
- - Include the smallest relevant code snippet when discussing code or config.
13
- - Follow the main agent's instructions.
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
- Create structured summary of conversation branch for context when returning.
1
+ You MUST create a structured summary of the conversation branch for context when returning.
2
2
 
3
- Use EXACT format:
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
- Keep sections concise. Preserve exact file paths, function names, error messages.
30
+ Sections MUST be kept concise. You MUST preserve exact file paths, function names, error messages.
@@ -1,9 +1,9 @@
1
- Summarize what was done in this conversation. Write like a pull request description.
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
- - Describe the changes made, not the process
6
- - Do not mention running tests, builds, or other validation steps
7
- - Do not explain what the user asked for
8
- - Write in first person (I added..., I fixed...)
9
- - Never ask questions
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. Use this to build on the work that has already been done and avoid duplicating work. Here is the summary produced by the other language model, use the information in this summary to assist with your own analysis:
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
- Summarize conversation above into structured context checkpoint handoff summary for another LLM to resume task.
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
- Use this format (sections can be omitted if not applicable):
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
- Output only structured summary; no extra text.
36
+ You MUST output only the structured summary; you MUST NOT include extra text.
37
37
 
38
- Keep sections concise. Preserve exact file paths, function names, error messages, and relevant tool outputs or command results. Include repository state changes (branch, uncommitted changes) if mentioned.
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
- Summarize the prefix to provide context for the retained suffix:
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
- Output only the structured summary. No extra text.
15
+ You MUST output only the structured summary. You MUST NOT include extra text.
16
16
 
17
- Be concise. Preserve exact file paths, function names, error messages, and relevant tool outputs or command results if they appear. Focus on what's needed to understand the kept suffix.
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.