@oh-my-pi/pi-coding-agent 13.0.0 → 13.0.2

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 (44) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.json +7 -7
  3. package/scripts/format-prompts.ts +33 -3
  4. package/src/commit/prompts/analysis-system.md +3 -3
  5. package/src/commit/prompts/changelog-system.md +3 -3
  6. package/src/commit/prompts/summary-system.md +5 -5
  7. package/src/extensibility/custom-tools/wrapper.ts +1 -0
  8. package/src/extensibility/extensions/wrapper.ts +2 -0
  9. package/src/extensibility/hooks/tool-wrapper.ts +1 -0
  10. package/src/lsp/index.ts +1 -0
  11. package/src/patch/diff.ts +2 -2
  12. package/src/patch/hashline.ts +88 -119
  13. package/src/patch/index.ts +138 -224
  14. package/src/patch/shared.ts +21 -35
  15. package/src/prompts/compaction/compaction-short-summary.md +1 -1
  16. package/src/prompts/system/agent-creation-architect.md +6 -6
  17. package/src/prompts/system/system-prompt.md +1 -1
  18. package/src/prompts/tools/bash.md +1 -1
  19. package/src/prompts/tools/find.md +9 -0
  20. package/src/prompts/tools/hashline.md +130 -154
  21. package/src/prompts/tools/patch.md +1 -1
  22. package/src/prompts/tools/python.md +2 -2
  23. package/src/prompts/tools/replace.md +1 -1
  24. package/src/prompts/tools/task.md +18 -19
  25. package/src/task/index.ts +1 -0
  26. package/src/tools/ask.ts +1 -0
  27. package/src/tools/bash.ts +1 -0
  28. package/src/tools/browser.ts +1 -0
  29. package/src/tools/calculator.ts +1 -0
  30. package/src/tools/cancel-job.ts +1 -0
  31. package/src/tools/exit-plan-mode.ts +1 -0
  32. package/src/tools/fetch.ts +1 -0
  33. package/src/tools/find.ts +1 -0
  34. package/src/tools/grep.ts +1 -0
  35. package/src/tools/notebook.ts +1 -0
  36. package/src/tools/plan-mode-guard.ts +2 -2
  37. package/src/tools/poll-jobs.ts +1 -0
  38. package/src/tools/python.ts +1 -0
  39. package/src/tools/read.ts +1 -0
  40. package/src/tools/ssh.ts +1 -0
  41. package/src/tools/submit-result.ts +1 -0
  42. package/src/tools/todo-write.ts +1 -0
  43. package/src/tools/write.ts +1 -0
  44. package/src/web/search/index.ts +1 -0
@@ -19,7 +19,6 @@ Subagents have no access to your conversation history. They don't know:
19
19
  Subagents CAN grep the parent conversation file for supplementary details.
20
20
 
21
21
  For large intermediate outputs (long traces, JSON payloads, temporary analysis snapshots), you SHOULD write them to `local://<path>` and pass the path in task context instead of inlining bulky text.
22
- ---
23
22
 
24
23
  ## Parameters
25
24
 
@@ -128,9 +127,9 @@ Use structure every assignment:
128
127
  - Patterns/APIs to use; reference files if applicable
129
128
 
130
129
  ## Edge Cases / Don't Break
131
- - Tricky case 1: ...
132
- - Tricky case 2: ...
133
- - Existing behavior must survive: ...
130
+ - Tricky case 1:
131
+ - Tricky case 2:
132
+ - Existing behavior must survive:
134
133
 
135
134
  ## Acceptance (task-local)
136
135
  - Expected behavior or observable result
@@ -145,11 +144,11 @@ Use structure every assignment:
145
144
  - "Migrate to N-API."
146
145
  - "Fix the bug in streaming."
147
146
  - "Update all constructors in `src/**/*.ts`."
148
- **Vague context** — forces agent invent conventions:
147
+ **Vague context** — forces agent invent conventions:
149
148
  - "Use existing patterns."
150
149
  - "Follow conventions."
151
150
  - "No WASM."
152
- **Redundant context** — wastes tokens repeating what subagents already have:
151
+ **Redundant context** — wastes tokens repeating what subagents already have:
153
152
  - Restating AGENTS.md rules (coding style, import conventions, formatting commands, logger usage, etc.)
154
153
  - Repeating project constraints from context files
155
154
  - Listing tool/framework preferences already documented in the repo
@@ -173,7 +172,7 @@ Micromanaging (you think, agent types):
173
172
  ```
174
173
  assignment: "In src/api/handler.ts, line 47, change `throw err` to `throw new ApiError(err.message, 500)`.
175
174
  On line 63, wrap fetch call try/catch return 502 on failure.
176
- On line 89, add null check before accessing resp.body..."
175
+ On line 89, add null check before accessing resp.body"
177
176
  ```
178
177
 
179
178
  Delegating (agent thinks within constraints):
@@ -192,9 +191,9 @@ First style wastes your time, brittle if code shifts. Second gives agent room to
192
191
  <example type="bad" label="Duplicated context inflates tokens">
193
192
  <tasks>
194
193
  <task name="Grep">
195
- <description>Port grep module from WASM to N-API...</description>
196
- <assignment>Port grep module from WASM to N-API... (same blob repeated)</assignment>
197
- </task>
194
+ <description>Port grep module from WASM to N-API…</description>
195
+ <assignment>Port grep module from WASM to N-API (same blob repeated)</assignment>
196
+ </task>
198
197
  </tasks>
199
198
  </example>
200
199
 
@@ -210,7 +209,7 @@ Do not touch TS bindings or downstream consumers — separate phase.
210
209
  - MUST use `#[napi]` attribute macro on all exports
211
210
  - MUST return `napi::Result<T>` for fallible ops; never panic
212
211
  - MUST use `spawn_blocking` for filesystem I/O or >1ms work
213
- ...
212
+
214
213
 
215
214
  ## Acceptance (global)
216
215
  - Caller verifies after all tasks: `cargo test -p pi-natives` and `cargo build -p pi-natives` with no warnings
@@ -227,22 +226,22 @@ Do not touch TS bindings or downstream consumers — separate phase.
227
226
 
228
227
  ## Change
229
228
  - Implement three N-API exports in grep.rs:
230
- - `search(pattern: JsString, path: JsString, env: Env) -> napi::Result<Vec<Match>>`
231
- ...
229
+ - `search(pattern: JsString, path: JsString, env: Env) napi::Result<Vec<Match>>`
230
+
232
231
 
233
232
  ## Acceptance (task-local)
234
233
  - Three functions exported with correct signatures (caller verifies build after all tasks)
235
- </assignment>
236
- </task>
234
+ </assignment>
235
+ </task>
237
236
 
238
237
  <task name="PortHighlight">
239
238
  <description>Port highlight module to N-API</description>
240
239
  <assignment>
241
240
  ## Target
242
241
  - Files: `src/highlight.rs`, `src/lib.rs` (registration only)
243
- ...
244
- </assignment>
245
- </task>
242
+
243
+ </assignment>
244
+ </task>
246
245
  </tasks>
247
246
  </example>
248
247
  ---
@@ -254,7 +253,7 @@ Each task MUST have small, well-defined scope — **at most 3–5 files**.
254
253
  - File paths use globs (`src/**/*.ts`) instead of explicit names
255
254
  - Assignment says "update all" / "migrate everything" / "refactor across"
256
255
  - Scope covers entire package or directory tree
257
- **Fix:** You MUST enumerate files first (grep/glob discovery), then fan out one task per file or small cluster.
256
+ **Fix:** You MUST enumerate files first (grep/glob discovery), then fan out one task per file or small cluster.
258
257
  ---
259
258
 
260
259
  ## Parallelization
package/src/task/index.ts CHANGED
@@ -134,6 +134,7 @@ function renderDescription(
134
134
  export class TaskTool implements AgentTool<TaskSchema, TaskToolDetails, Theme> {
135
135
  readonly name = "task";
136
136
  readonly label = "Task";
137
+ readonly strict = true;
137
138
  readonly parameters: TaskSchema;
138
139
  readonly renderCall = renderCall;
139
140
  readonly renderResult = renderResult;
package/src/tools/ask.ts CHANGED
@@ -246,6 +246,7 @@ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
246
246
  readonly label = "Ask";
247
247
  readonly description: string;
248
248
  readonly parameters = askSchema;
249
+ readonly strict = true;
249
250
 
250
251
  constructor(private readonly session: ToolSession) {
251
252
  this.description = renderPromptTemplate(askDescription);
package/src/tools/bash.ts CHANGED
@@ -91,6 +91,7 @@ export class BashTool implements AgentTool<BashToolSchema, BashToolDetails> {
91
91
  readonly description: string;
92
92
  readonly parameters: BashToolSchema;
93
93
  readonly concurrency = "exclusive";
94
+ readonly strict = true;
94
95
  readonly #asyncEnabled: boolean;
95
96
 
96
97
  constructor(private readonly session: ToolSession) {
@@ -484,6 +484,7 @@ export class BrowserTool implements AgentTool<typeof browserSchema, BrowserToolD
484
484
  readonly label = "Puppeteer";
485
485
  readonly description: string;
486
486
  readonly parameters = browserSchema;
487
+ readonly strict = true;
487
488
  #browser: Browser | null = null;
488
489
  #page: Page | null = null;
489
490
  #currentHeadless: boolean | null = null;
@@ -399,6 +399,7 @@ export class CalculatorTool implements AgentTool<typeof calculatorSchema, Calcul
399
399
  readonly label = "Calc";
400
400
  readonly description: string;
401
401
  readonly parameters = calculatorSchema;
402
+ readonly strict = true;
402
403
 
403
404
  constructor(_session: ToolSession) {
404
405
  this.description = renderPromptTemplate(calculatorDescription);
@@ -20,6 +20,7 @@ export class CancelJobTool implements AgentTool<typeof cancelJobSchema, CancelJo
20
20
  readonly label = "CancelJob";
21
21
  readonly description: string;
22
22
  readonly parameters = cancelJobSchema;
23
+ readonly strict = true;
23
24
 
24
25
  constructor(private readonly session: ToolSession) {
25
26
  this.description = renderPromptTemplate(cancelJobDescription);
@@ -45,6 +45,7 @@ export class ExitPlanModeTool implements AgentTool<typeof exitPlanModeSchema, Ex
45
45
  readonly label = "ExitPlanMode";
46
46
  readonly description: string;
47
47
  readonly parameters = exitPlanModeSchema;
48
+ readonly strict = true;
48
49
 
49
50
  constructor(private readonly session: ToolSession) {
50
51
  this.description = renderPromptTemplate(exitPlanModeDescription);
@@ -856,6 +856,7 @@ export class FetchTool implements AgentTool<typeof fetchSchema, FetchToolDetails
856
856
  readonly label = "Fetch";
857
857
  readonly description: string;
858
858
  readonly parameters = fetchSchema;
859
+ readonly strict = true;
859
860
 
860
861
  constructor(private readonly session: ToolSession) {
861
862
  this.description = renderPromptTemplate(fetchDescription);
package/src/tools/find.ts CHANGED
@@ -127,6 +127,7 @@ export class FindTool implements AgentTool<typeof findSchema, FindToolDetails> {
127
127
  readonly label = "Find";
128
128
  readonly description: string;
129
129
  readonly parameters = findSchema;
130
+ readonly strict = true;
130
131
 
131
132
  readonly #customOps?: FindOperations;
132
133
 
package/src/tools/grep.ts CHANGED
@@ -60,6 +60,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
60
60
  readonly label = "Grep";
61
61
  readonly description: string;
62
62
  readonly parameters = grepSchema;
63
+ readonly strict = true;
63
64
 
64
65
  constructor(private readonly session: ToolSession) {
65
66
  const displayMode = resolveFileDisplayMode(session);
@@ -65,6 +65,7 @@ export class NotebookTool implements AgentTool<typeof notebookSchema, NotebookTo
65
65
  readonly description =
66
66
  "Completely replaces the contents of a specific cell in a Jupyter notebook (.ipynb file) with new source. Jupyter notebooks are interactive documents that combine code, text, and visualizations, commonly used for data analysis and scientific computing. The notebook_path parameter must be an absolute path, not a relative path. The cell_number is 0-indexed. Use edit_mode=insert to add a new cell at the index specified by cell_number. Use edit_mode=delete to delete the cell at the index specified by cell_number.";
67
67
  readonly parameters = notebookSchema;
68
+ readonly strict = true;
68
69
  readonly concurrency = "exclusive";
69
70
 
70
71
  constructor(private readonly session: ToolSession) {}
@@ -19,7 +19,7 @@ export function resolvePlanPath(session: ToolSession, targetPath: string): strin
19
19
  export function enforcePlanModeWrite(
20
20
  session: ToolSession,
21
21
  targetPath: string,
22
- options?: { rename?: string; op?: "create" | "update" | "delete" },
22
+ options?: { move?: string; op?: "create" | "update" | "delete" },
23
23
  ): void {
24
24
  const state = session.getPlanModeState?.();
25
25
  if (!state?.enabled) return;
@@ -27,7 +27,7 @@ export function enforcePlanModeWrite(
27
27
  const resolvedTarget = resolvePlanPath(session, targetPath);
28
28
  const resolvedPlan = resolvePlanPath(session, state.planFilePath);
29
29
 
30
- if (options?.rename) {
30
+ if (options?.move) {
31
31
  throw new ToolError("Plan mode: renaming files is not allowed.");
32
32
  }
33
33
 
@@ -39,6 +39,7 @@ export class PollJobsTool implements AgentTool<typeof pollJobsSchema, PollJobsTo
39
39
  readonly label = "PollJobs";
40
40
  readonly description: string;
41
41
  readonly parameters = pollJobsSchema;
42
+ readonly strict = true;
42
43
 
43
44
  constructor(private readonly session: ToolSession) {
44
45
  this.description = renderPromptTemplate(pollJobsDescription);
@@ -148,6 +148,7 @@ export class PythonTool implements AgentTool<typeof pythonSchema> {
148
148
  readonly description: string;
149
149
  readonly parameters = pythonSchema;
150
150
  readonly concurrency = "exclusive";
151
+ readonly strict = true;
151
152
 
152
153
  readonly #proxyExecutor?: PythonProxyExecutor;
153
154
 
package/src/tools/read.ts CHANGED
@@ -558,6 +558,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
558
558
  readonly description: string;
559
559
  readonly parameters = readSchema;
560
560
  readonly nonAbortable = true;
561
+ readonly strict = true;
561
562
 
562
563
  readonly #autoResizeImages: boolean;
563
564
 
package/src/tools/ssh.ts CHANGED
@@ -122,6 +122,7 @@ export class SshTool implements AgentTool<typeof sshSchema, SSHToolDetails> {
122
122
  readonly label = "SSH";
123
123
  readonly parameters = sshSchema;
124
124
  readonly concurrency = "exclusive";
125
+ readonly strict = true;
125
126
 
126
127
  readonly #allowedHosts: Set<string>;
127
128
 
@@ -59,6 +59,7 @@ export class SubmitResultTool implements AgentTool<TObject, SubmitResultDetails>
59
59
  "Finish the task with structured JSON output. Call exactly once at the end of the task.\n\n" +
60
60
  "If you cannot complete the task, call with status='aborted' and an error message.";
61
61
  readonly parameters: TObject;
62
+ readonly strict = true;
62
63
 
63
64
  readonly #validate?: ValidateFunction;
64
65
  readonly #schemaError?: string;
@@ -289,6 +289,7 @@ export class TodoWriteTool implements AgentTool<typeof todoWriteSchema, TodoWrit
289
289
  readonly description: string;
290
290
  readonly parameters = todoWriteSchema;
291
291
  readonly concurrency = "exclusive";
292
+ readonly strict = true;
292
293
 
293
294
  constructor(private readonly session: ToolSession) {
294
295
  this.description = renderPromptTemplate(todoWriteDescription);
@@ -75,6 +75,7 @@ export class WriteTool implements AgentTool<typeof writeSchema, WriteToolDetails
75
75
  readonly description: string;
76
76
  readonly parameters = writeSchema;
77
77
  readonly nonAbortable = true;
78
+ readonly strict = true;
78
79
  readonly concurrency = "exclusive";
79
80
 
80
81
  readonly #writethrough: WritethroughCallback;
@@ -258,6 +258,7 @@ export class SearchTool implements AgentTool<typeof webSearchSchema, SearchRende
258
258
  readonly label = "Web Search";
259
259
  readonly description: string;
260
260
  readonly parameters = webSearchSchema;
261
+ readonly strict = true;
261
262
 
262
263
  constructor(_session: ToolSession) {
263
264
  this.description = renderPromptTemplate(webSearchDescription);