@oh-my-pi/pi-coding-agent 15.3.1 → 15.4.1

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 (200) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/dist/types/cli/auth-gateway-cli.d.ts +1 -1
  3. package/dist/types/cli/file-processor.d.ts +1 -1
  4. package/dist/types/config/settings-schema.d.ts +45 -3
  5. package/dist/types/config/settings.d.ts +1 -1
  6. package/dist/types/debug/raw-sse.d.ts +2 -0
  7. package/dist/types/edit/file-read-cache.d.ts +15 -4
  8. package/dist/types/edit/index.d.ts +3 -8
  9. package/dist/types/edit/renderer.d.ts +1 -2
  10. package/dist/types/eval/__tests__/shared-executors.test.d.ts +1 -0
  11. package/dist/types/eval/js/shared/local-module-loader.d.ts +16 -0
  12. package/dist/types/eval/js/shared/rewrite-imports.d.ts +4 -0
  13. package/dist/types/eval/js/shared/runtime.d.ts +14 -8
  14. package/dist/types/eval/py/executor.d.ts +1 -2
  15. package/dist/types/eval/py/kernel.d.ts +6 -0
  16. package/dist/types/eval/py/tool-bridge.d.ts +1 -5
  17. package/dist/types/eval/session-id.d.ts +3 -0
  18. package/dist/types/extensibility/extensions/types.d.ts +1 -3
  19. package/dist/types/hashline/anchors.d.ts +15 -9
  20. package/dist/types/hashline/constants.d.ts +0 -2
  21. package/dist/types/hashline/diff.d.ts +1 -2
  22. package/dist/types/hashline/executor.d.ts +52 -0
  23. package/dist/types/hashline/hash.d.ts +44 -93
  24. package/dist/types/hashline/index.d.ts +2 -1
  25. package/dist/types/hashline/input.d.ts +2 -9
  26. package/dist/types/hashline/recovery.d.ts +3 -9
  27. package/dist/types/hashline/tokenizer.d.ts +91 -0
  28. package/dist/types/hashline/types.d.ts +5 -7
  29. package/dist/types/modes/components/extensions/types.d.ts +0 -4
  30. package/dist/types/modes/types.d.ts +1 -0
  31. package/dist/types/modes/utils/ui-helpers.d.ts +1 -0
  32. package/dist/types/sdk.d.ts +2 -0
  33. package/dist/types/session/agent-session.d.ts +11 -15
  34. package/dist/types/session/agent-storage.d.ts +11 -10
  35. package/dist/types/slash-commands/acp-builtins.d.ts +3 -3
  36. package/dist/types/slash-commands/types.d.ts +0 -5
  37. package/dist/types/task/executor.d.ts +2 -0
  38. package/dist/types/task/types.d.ts +8 -0
  39. package/dist/types/tool-discovery/tool-index.d.ts +0 -50
  40. package/dist/types/tools/index.d.ts +2 -8
  41. package/dist/types/tools/match-line-format.d.ts +4 -4
  42. package/dist/types/tools/output-schema-validator.d.ts +64 -0
  43. package/dist/types/tools/review.d.ts +13 -0
  44. package/dist/types/tools/search-tool-bm25.d.ts +1 -1
  45. package/dist/types/tools/search.d.ts +4 -3
  46. package/dist/types/utils/edit-mode.d.ts +1 -1
  47. package/dist/types/web/kagi.d.ts +4 -2
  48. package/dist/types/web/parallel.d.ts +4 -3
  49. package/dist/types/web/scrapers/types.d.ts +2 -1
  50. package/dist/types/web/search/index.d.ts +12 -4
  51. package/dist/types/web/search/provider.d.ts +2 -1
  52. package/dist/types/web/search/providers/anthropic.d.ts +9 -4
  53. package/dist/types/web/search/providers/base.d.ts +34 -2
  54. package/dist/types/web/search/providers/brave.d.ts +8 -1
  55. package/dist/types/web/search/providers/codex.d.ts +13 -9
  56. package/dist/types/web/search/providers/exa.d.ts +10 -1
  57. package/dist/types/web/search/providers/gemini.d.ts +20 -23
  58. package/dist/types/web/search/providers/jina.d.ts +2 -1
  59. package/dist/types/web/search/providers/kagi.d.ts +4 -1
  60. package/dist/types/web/search/providers/kimi.d.ts +10 -1
  61. package/dist/types/web/search/providers/parallel.d.ts +3 -2
  62. package/dist/types/web/search/providers/perplexity.d.ts +5 -2
  63. package/dist/types/web/search/providers/searxng.d.ts +2 -1
  64. package/dist/types/web/search/providers/synthetic.d.ts +5 -8
  65. package/dist/types/web/search/providers/tavily.d.ts +11 -4
  66. package/dist/types/web/search/providers/utils.d.ts +8 -6
  67. package/dist/types/web/search/providers/zai.d.ts +12 -3
  68. package/package.json +7 -7
  69. package/src/cli/auth-gateway-cli.ts +71 -2
  70. package/src/cli/file-processor.ts +12 -2
  71. package/src/cli.ts +0 -8
  72. package/src/commands/auth-gateway.ts +2 -0
  73. package/src/commands/commit.ts +8 -8
  74. package/src/config/prompt-templates.ts +6 -6
  75. package/src/config/settings-schema.ts +47 -3
  76. package/src/config/settings.ts +5 -5
  77. package/src/debug/raw-sse.ts +68 -3
  78. package/src/edit/file-read-cache.ts +68 -25
  79. package/src/edit/index.ts +6 -37
  80. package/src/edit/renderer.ts +9 -47
  81. package/src/edit/streaming.ts +43 -56
  82. package/src/eval/__tests__/shared-executors.test.ts +520 -0
  83. package/src/eval/js/context-manager.ts +64 -53
  84. package/src/eval/js/shared/local-module-loader.ts +265 -0
  85. package/src/eval/js/shared/prelude.txt +4 -0
  86. package/src/eval/js/shared/rewrite-imports.ts +85 -0
  87. package/src/eval/js/shared/runtime.ts +129 -86
  88. package/src/eval/js/worker-core.ts +23 -38
  89. package/src/eval/py/executor.ts +155 -84
  90. package/src/eval/py/kernel.ts +10 -1
  91. package/src/eval/py/prelude.py +22 -24
  92. package/src/eval/py/runner.py +203 -85
  93. package/src/eval/py/tool-bridge.ts +17 -10
  94. package/src/eval/session-id.ts +8 -0
  95. package/src/exec/bash-executor.ts +27 -16
  96. package/src/extensibility/extensions/runner.ts +0 -1
  97. package/src/extensibility/extensions/types.ts +1 -3
  98. package/src/extensibility/plugins/marketplace/manager.ts +20 -1
  99. package/src/hashline/anchors.ts +56 -65
  100. package/src/hashline/apply.ts +29 -31
  101. package/src/hashline/constants.ts +0 -3
  102. package/src/hashline/diff-preview.ts +4 -5
  103. package/src/hashline/diff.ts +30 -4
  104. package/src/hashline/execute.ts +91 -26
  105. package/src/hashline/executor.ts +239 -0
  106. package/src/hashline/grammar.lark +12 -10
  107. package/src/hashline/hash.ts +69 -114
  108. package/src/hashline/index.ts +2 -1
  109. package/src/hashline/input.ts +48 -41
  110. package/src/hashline/prefixes.ts +21 -11
  111. package/src/hashline/recovery.ts +63 -71
  112. package/src/hashline/stream.ts +2 -2
  113. package/src/hashline/tokenizer.ts +467 -0
  114. package/src/hashline/types.ts +6 -8
  115. package/src/internal-urls/docs-index.generated.ts +9 -8
  116. package/src/lsp/config.ts +87 -22
  117. package/src/modes/components/extensions/types.ts +0 -5
  118. package/src/modes/components/session-observer-overlay.ts +11 -2
  119. package/src/modes/components/tree-selector.ts +10 -2
  120. package/src/modes/controllers/command-controller.ts +1 -3
  121. package/src/modes/controllers/extension-ui-controller.ts +10 -11
  122. package/src/modes/controllers/selector-controller.ts +5 -5
  123. package/src/modes/types.ts +4 -1
  124. package/src/modes/utils/ui-helpers.ts +4 -0
  125. package/src/prompts/agents/explore.md +1 -1
  126. package/src/prompts/tools/ast-edit.md +1 -1
  127. package/src/prompts/tools/ast-grep.md +1 -1
  128. package/src/prompts/tools/eval.md +1 -1
  129. package/src/prompts/tools/hashline.md +73 -94
  130. package/src/prompts/tools/read.md +4 -4
  131. package/src/prompts/tools/search.md +3 -3
  132. package/src/sdk.ts +21 -24
  133. package/src/session/agent-session.ts +59 -66
  134. package/src/session/agent-storage.ts +13 -14
  135. package/src/slash-commands/acp-builtins.ts +3 -3
  136. package/src/slash-commands/types.ts +0 -6
  137. package/src/task/executor.ts +55 -57
  138. package/src/task/index.ts +8 -4
  139. package/src/task/render.ts +53 -1
  140. package/src/task/types.ts +8 -0
  141. package/src/tool-discovery/tool-index.ts +0 -134
  142. package/src/tools/ast-edit.ts +36 -13
  143. package/src/tools/ast-grep.ts +45 -4
  144. package/src/tools/browser/tab-worker.ts +3 -2
  145. package/src/tools/eval.ts +2 -1
  146. package/src/tools/fetch.ts +23 -14
  147. package/src/tools/index.ts +2 -8
  148. package/src/tools/irc.ts +59 -5
  149. package/src/tools/jtd-to-json-schema.ts +5 -1
  150. package/src/tools/match-line-format.ts +5 -7
  151. package/src/tools/output-schema-validator.ts +132 -0
  152. package/src/tools/read.ts +142 -63
  153. package/src/tools/review.ts +23 -0
  154. package/src/tools/search-tool-bm25.ts +3 -30
  155. package/src/tools/search.ts +48 -16
  156. package/src/tools/write.ts +3 -3
  157. package/src/tools/yield.ts +32 -41
  158. package/src/utils/edit-mode.ts +1 -2
  159. package/src/utils/file-mentions.ts +2 -2
  160. package/src/web/kagi.ts +15 -6
  161. package/src/web/parallel.ts +9 -6
  162. package/src/web/scrapers/types.ts +7 -1
  163. package/src/web/scrapers/youtube.ts +13 -7
  164. package/src/web/search/index.ts +37 -11
  165. package/src/web/search/provider.ts +5 -3
  166. package/src/web/search/providers/anthropic.ts +30 -21
  167. package/src/web/search/providers/base.ts +35 -2
  168. package/src/web/search/providers/brave.ts +4 -4
  169. package/src/web/search/providers/codex.ts +118 -89
  170. package/src/web/search/providers/exa.ts +3 -2
  171. package/src/web/search/providers/gemini.ts +58 -155
  172. package/src/web/search/providers/jina.ts +4 -4
  173. package/src/web/search/providers/kagi.ts +17 -11
  174. package/src/web/search/providers/kimi.ts +29 -13
  175. package/src/web/search/providers/parallel.ts +171 -23
  176. package/src/web/search/providers/perplexity.ts +38 -37
  177. package/src/web/search/providers/searxng.ts +3 -1
  178. package/src/web/search/providers/synthetic.ts +16 -19
  179. package/src/web/search/providers/tavily.ts +23 -18
  180. package/src/web/search/providers/utils.ts +11 -17
  181. package/src/web/search/providers/zai.ts +16 -8
  182. package/dist/types/hashline/parser.d.ts +0 -7
  183. package/dist/types/mcp/discoverable-tool-metadata.d.ts +0 -7
  184. package/dist/types/tools/vim.d.ts +0 -58
  185. package/dist/types/vim/buffer.d.ts +0 -41
  186. package/dist/types/vim/commands.d.ts +0 -6
  187. package/dist/types/vim/engine.d.ts +0 -47
  188. package/dist/types/vim/parser.d.ts +0 -3
  189. package/dist/types/vim/render.d.ts +0 -25
  190. package/dist/types/vim/types.d.ts +0 -182
  191. package/src/hashline/parser.ts +0 -212
  192. package/src/mcp/discoverable-tool-metadata.ts +0 -24
  193. package/src/prompts/tools/vim.md +0 -98
  194. package/src/tools/vim.ts +0 -949
  195. package/src/vim/buffer.ts +0 -309
  196. package/src/vim/commands.ts +0 -382
  197. package/src/vim/engine.ts +0 -2409
  198. package/src/vim/parser.ts +0 -134
  199. package/src/vim/render.ts +0 -252
  200. package/src/vim/types.ts +0 -197
@@ -1,130 +1,109 @@
1
1
  Your patch language is a compact, line-anchored edit format.
2
2
 
3
- A patch contains one or more file sections. The first non-blank line of every edit section MUST be `§PATH`.
4
- Operations reference lines in the file by their line number and hash, called "Anchors", e.g. `5th`, `123ab`.
5
- You MUST copy them verbatim from the latest output for the file you're editing.
3
+ A patch contains one or more file sections. Each anchored section starts with `¶PATH#HASH`, copied verbatim from the latest `read`/`search` output. `HASH` is a 4-hex file hash; `¶PATH` without `#HASH` is allowed only for new-file / `BOF` / `EOF` boundary inserts.
6
4
 
7
- Purely textual format. The tool has NO awareness of language, indentation, brackets, fences, or table widths. You MUST emit valid syntax in replacements/insertions.
5
+ Operations reference lines by bare line number (`5`, `123`). Payload text is verbatim — NEVER escape unicode. The tool has NO awareness of language, indentation, brackets, fences, or table widths. Emit valid syntax in replacements/insertions.
8
6
 
9
7
  <ops>
10
- §PATH header: subsequent ops apply to PATH
11
- Each op line is ONE of:
12
- »ANCHOR insert lines AFTER the anchored line (or EOF); payload follows on subsequent lines
13
- «ANCHOR insert lines BEFORE the anchored line (or BOF); payload follows on subsequent lines
14
- A..B replace the inclusive range A..B with payload; delete the range if no payload follows
15
- A shorthand for A..A
8
+ PATH#HASH header: subsequent anchored ops apply to PATH at file hash HASH
9
+ ¶PATH unbound header: only BOF/EOF boundary inserts
10
+ LINE↑PAYLOAD insert ABOVE the anchored line (or BOF)
11
+ LINE↓PAYLOAD insert BELOW the anchored line (or EOF)
12
+ A-B:PAYLOAD replace the inclusive range A..B with PAYLOAD
13
+ A:PAYLOAD shorthand for A-A:PAYLOAD
14
+ A-B! delete the inclusive range A..B (payload forbidden)
15
+ A! shorthand for A-A!
16
16
  </ops>
17
17
 
18
+ <payload>
19
+ - The first payload line is whatever follows the sigil on the op line. Additional payload lines follow on the next lines and append after the first.
20
+ - An empty inline IS an empty first line. So bare `A↓` / `A↑` insert one blank line; bare `A:` / `A-B:` replace with one blank line. `A↓\nfoo` inserts blank-then-`foo`, NOT just `foo`.
21
+ - Payload ends at the next op, next `¶PATH`, envelope marker, or EOF. Blank lines immediately before a next op or `¶PATH` are dropped; blank lines between content lines are preserved.
22
+ </payload>
23
+
18
24
  <rules>
19
- - Payload text is verbatim NEVER escape unicode.
20
- - Payload ends at the next `»`, `«`, `≔`, `§`, envelope marker, or EOF.
21
- - `≔A..B` with no payload deletes the range. To keep a blank line, include one explicit empty payload line.
22
- - **Payload is only what's NEW relative to your range:**
23
- - `≔` replaces inside; NEVER include lines outside.
24
- - `»`/`«` adds at the anchor; NEVER repeat line A or neighbors.
25
- - Payload matching nearby content duplicates — drop it or widen.
26
- - **Pick a self-contained unit first.** Touching a multiline construct? Widen to the whole thing.
27
- - Then smallest op: add → `»`/`«`; delete/replace → `≔`.
25
+ - The sigil tells where content lands: `↑` above, `↓` below, `:` replaces, `!` deletes.
26
+ - **Payload is only what's NEW relative to your range.** `:` replaces inside; `↑`/`↓` add at anchor. NEVER repeat the anchor line or neighbors that duplicates them.
27
+ - **Pick a self-contained unit.** Touching a multiline construct (return, array, brace block, JSX element)? Widen the range to span it. Don't bisect.
28
+ - Smallest op wins: add with `↑`/`↓`; replace with `:`; delete with `!`.
29
+ - Anchors reference the file as last read. ONE patch, ONE coordinate space — later ops still use original line numbers.
28
30
  </rules>
29
31
 
30
- <brace-shapes>
31
- When braces bound your edit, you SHOULD prefer these shapes:
32
- - **Whole block**: range spans `{` through matching `}`.
33
- - **Signature only**: one-line `≔` on the opener; body untouched.
34
- - **Insert inside**: anchor on `{` or last interior line; NEVER repeat the braces.
35
- - **End on `}`**: only when that `}` is part of the change. Otherwise extend or stop earlier.
36
- </brace-shapes>
37
-
38
32
  <common-failures>
39
33
  - **NEVER replay past your range.** Stop before B+1; extend B if it must go.
40
- - **NEVER duplicate chunks inside one payload.** Caught re-emitting? Rewrite.
41
- - **Anchor only inside the visible region.** B+1 truncated? Re-`read` first.
42
- - **You SHOULD prefer the narrowest self-contained edit.** Narrow range beats wide range.
43
- - **Anchors reference the file as last read.** NEVER shift for prior ops.
44
- - **One `»`/`«` op per block, NOT per line.** N lines = ONE op, N payloads. Collapse adjacent ops.
45
- - **NEVER fabricate anchor hashes.** Missing? Re-`read`.
34
+ - **NEVER duplicate chunks inside one payload.**
35
+ - **Read lines look like replace ops.** `84:content` already means "make line 84 equal to content" — don't echo a context line before it.
36
+ - **NEVER fabricate file hashes.** Missing? Re-`read`.
37
+ - **`A!` deletes silently.** Deleting a line that closes/opens a block (`}`, `} else {`, `})`, `*/`) breaks structure with no parse error.
46
38
  </common-failures>
47
39
 
48
40
  <case file="mod.ts">
49
- {{hline 1 "const TITLE = \"Mr\";"}}
50
- {{hline 2 "export function greet(name) {"}}
51
- {{hline 3 "\treturn ["}}
52
- {{hline 4 "\t\tTITLE,"}}
53
- {{hline 5 "\t\tname?.trim() || \"guest\","}}
54
- {{hline 6 "\t].join(\" \");"}}
41
+ ¶mod.ts#1a2b
42
+ {{hline 1 'const TITLE = "Mr";'}}
43
+ {{hline 2 'export function greet(name) {'}}
44
+ {{hline 3 ' return ['}}
45
+ {{hline 4 ' TITLE,'}}
46
+ {{hline 5 ' name?.trim() || "guest",'}}
47
+ {{hline 6 ' ].join(" ");'}}
55
48
  {{hline 7 "}"}}
56
49
  </case>
57
50
 
58
51
  <examples>
59
- # Replace one line (the payload must re-emit the original indentation)
60
- §mod.ts
61
- {{hrefr 1}}
62
- const TITLE = "Mrs";
63
-
64
- # Replace a full multiline statement (widen to a self-contained boundary)
65
- §mod.ts
66
- ≔{{hrefr 3}}..{{hrefr 6}}
67
- return [
52
+ # Replace one line (inline payload preserves original indentation)
53
+ mod.ts#1a2b
54
+ {{hrefr 1}}:const TITLE = "Mrs";
55
+
56
+ # Replace a multiline statement — first line inline, rest below
57
+ ¶mod.ts#1a2b
58
+ {{hrefr 3}}-{{hrefr 6}}: return [
68
59
  "Mrs",
69
60
  name?.trim() || "guest",
70
61
  ].join(" ");
71
62
 
72
- # Insert AFTER/BEFORE a line
73
- §mod.ts
74
- »{{hrefr 4}}
75
- "Dr",
76
- «{{hrefr 5}}
77
- "Dr",
78
-
79
- # Append to file
80
- §mod.ts
81
- »EOF
82
- export const done = true;
83
-
84
- # Delete a line
85
- §mod.ts
86
- ≔{{hrefr 5}}
87
-
88
- # Blank a line (replace with LF: the empty payload is the blank line before `»EOF`)
89
- §mod.ts
90
- ≔{{hrefr 5}}
91
-
92
- »EOF
93
- export const done = true;
63
+ # Insert ABOVE / BELOW a line
64
+ mod.ts#1a2b
65
+ {{hrefr 4}}↓ "Dr",
66
+ {{hrefr 5}}↑ "Dr",
67
+
68
+ # Delete one line / blank a line / insert a blank line
69
+ ¶mod.ts#1a2b
70
+ {{hrefr 5}}!
71
+ {{hrefr 6}}:
72
+ {{hrefr 7}}↑
73
+
74
+ # Create a file / append to one (hash optional for boundary-only inserts)
75
+ ¶new.ts
76
+ BOF↓export const done = true;
77
+ ¶mod.ts
78
+ EOF↓export const done = true;
79
+
80
+ # Multi-file patch
81
+ ¶src/a.ts#1a2b
82
+ 12:const enabled = true;
83
+ ¶src/b.ts#3c4d
84
+ 20!
94
85
  </examples>
95
86
 
96
87
  <anti-pattern>
97
88
  # WRONG — replaces 2 lines just to add one.
98
- §mod.ts
99
- {{hrefr 1}}..{{hrefr 2}}
100
- const TITLE = "Mr";
89
+ mod.ts#1a2b
90
+ {{hrefr 1}}-{{hrefr 2}}:const TITLE = "Mr";
101
91
  const DEBUG = false;
102
92
  export function greet(name) {
103
- # RIGHT — same effect, one-line insert
104
- §mod.ts
105
- »{{hrefr 1}}
106
- const DEBUG = false;
107
93
 
108
- # WRONGreplace from the middle of a larger statement (error-prone)
109
- §mod.ts
110
- {{hrefr 4}}..{{hrefr 5}}
111
- "Dr",
94
+ # RIGHTone-line insert
95
+ mod.ts#1a2b
96
+ {{hrefr 1}}↓const DEBUG = false;
97
+
98
+ # WRONG — bisects a multiline statement
99
+ ¶mod.ts#1a2b
100
+ {{hrefr 4}}-{{hrefr 5}}: "Dr",
112
101
  name?.trim() || "guest",
102
+
113
103
  # RIGHT — widen to the full statement
114
- §mod.ts
115
- {{hrefr 3}}..{{hrefr 6}}
116
- return [
104
+ mod.ts#1a2b
105
+ {{hrefr 3}}-{{hrefr 6}}: return [
117
106
  "Dr",
118
107
  name?.trim() || "guest",
119
108
  ].join(" ");
120
109
  </anti-pattern>
121
-
122
- <critical>
123
- - Copy anchors verbatim (line number + 2-char hash); NEVER include the `|TEXT` body.
124
- - NEVER write unified diff syntax. Headers are `§PATH`; ops are `»`/`«`/`≔`.
125
- - `≔A..B` deletes the range when no payload follows. To keep a blank line, include one explicit empty payload line.
126
- - `≔A..B` with payload writes exactly that payload. Edge line matches just outside? Widen, or it duplicates.
127
- - Multiple ops are cheap. SHOULD prefer two narrow ops over one wide `≔`.
128
- - Before `≔A..B`, mentally delete A..B. Splits an unclosed bracket/brace/string from above, or orphans a closer inside? You're bisecting a construct.
129
- - NEVER use this tool to reformat code (indentation, whitespace, line wrapping, style). Run the project's formatter instead.
130
- </critical>
@@ -28,17 +28,17 @@ Append `:<sel>` to `path`. The bare path falls back to the default mode.
28
28
 
29
29
  - Reading a directory path returns a depth-limited dirent listing.
30
30
  {{#if IS_HL_MODE}}
31
- - Reading a file with an explicit selector returns lines prefixed with `line+hash` anchors: `41th|def alpha():`. The 2-char hash is a content fingerprint that `edit` / `apply_patch` consume — copy it verbatim, NEVER fabricate. The pipe character after the hash is a separator, not part of the file content.
31
+ - Reading a file with an explicit selector emits a file-hash header and numbered lines: `¶src/foo.ts#1a2b` then `41:def alpha():`. Copy the `¶PATH#HASH` header for anchored edits; ops use bare line numbers. NEVER fabricate the hash.
32
32
  {{else}}
33
33
  {{#if IS_LINE_NUMBER_MODE}}
34
34
  - Reading a file with an explicit selector returns lines prefixed with line numbers: `41|def alpha():`.
35
35
  {{/if}}
36
36
  {{/if}}
37
- - Parseable code without a selector returns a **structural summary**: declarations kept, large bodies collapsed to `..` (merged brace pair) or `…` (standalone). Summarized output ends with a footer of the form:
37
+ - Parseable code without a selector returns a **structural summary**: declarations kept, large bodies collapsed to `..` (merged brace pair) or `…` (standalone). Summarized output ends with a footer demonstrating the multi-range selector you can use to recover the elided bodies, e.g.:
38
38
 
39
- `[NN lines across MM elided regions; read <path>:raw or a line range like <path>:1-9999 for verbatim content]`
39
+ `[NN lines elided; re-read needed ranges, e.g. <path>:5-16,40-80]`
40
40
 
41
- If the elided body is what you actually need, re-issue the **exact selector the footer names**. NEVER guess what's inside `..` / `…` — those markers carry no content.
41
+ Re-issue **only the relevant range(s)** using the multi-range selector (e.g. `<path>:5-16,120-200`). NEVER guess what's inside `..` / `…` — those markers carry no content. NEVER re-read the whole file or use `:raw` when targeted ranges suffice.
42
42
 
43
43
  # Documents & Notebooks
44
44
 
@@ -2,14 +2,14 @@ Searches files using powerful regex matching.
2
2
 
3
3
  <instruction>
4
4
  - Supports Rust regex syntax (RE2-style — no lookaround or backreferences). Use line anchors or post-filters instead of (?!…)/(?<!…)
5
- - `paths` is required and accepts an array of files, directories, globs, or internal URLs
6
- - `paths` is an array; do not embed commas or spaces inside a single entry. Pass `["src", "tests"]` not `["src,tests"]`.
5
+ - `paths` is required and accepts either one string or an array of files, directories, globs, or internal URLs
6
+ - For multiple targets, pass an array with one target per element. Do not comma-join targets inside one string: pass `["src", "tests"]`, not `"src,tests"` or `["src,tests"]`.
7
7
  - Cross-line patterns are detected from literal `\n` or escaped `\\n` in `pattern`
8
8
  </instruction>
9
9
 
10
10
  <output>
11
11
  {{#if IS_HL_MODE}}
12
- - Text output is anchor-prefixed: `*5th|content` (match) or ` 9x}|content` (context, leading space). The 2-char suffix is a content fingerprint. The `|` before content is a separator, not part of the file content.
12
+ - Text output emits a file-hash header per matched file plus numbered lines: `¶src/login.ts#3c4d`, `*42:if (user.id) {` (match), ` 43:return user;` (context). Copy the header for anchored edits; ops use bare line numbers.
13
13
  {{else}}
14
14
  {{#if IS_LINE_NUMBER_MODE}}
15
15
  - Text output is line-number-prefixed
package/src/sdk.ts CHANGED
@@ -51,6 +51,7 @@ import "./discovery";
51
51
  import { resolveConfigValue } from "./config/resolve-config-value";
52
52
  import { initializeWithSettings } from "./discovery";
53
53
  import { disposeAllKernelSessions, disposeKernelSessionsByOwner } from "./eval/py/executor";
54
+ import { defaultEvalSessionId } from "./eval/session-id";
54
55
  import { TtsrManager } from "./export/ttsr";
55
56
  import {
56
57
  type CustomCommandsLoadResult,
@@ -84,11 +85,7 @@ import type { HindsightSessionState } from "./hindsight/state";
84
85
  import { LocalProtocolHandler, type LocalProtocolOptions } from "./internal-urls";
85
86
  import { LSP_STARTUP_EVENT_CHANNEL, type LspStartupEvent } from "./lsp/startup-events";
86
87
  import { discoverAndLoadMCPTools, MCPManager, type MCPToolsLoadResult } from "./mcp";
87
- import {
88
- collectDiscoverableMCPTools,
89
- formatDiscoverableMCPToolServerSummary,
90
- selectDiscoverableMCPToolNamesByServer,
91
- } from "./mcp/discoverable-tool-metadata";
88
+
92
89
  import { resolveMemoryBackend } from "./memory-backend";
93
90
  import asyncResultTemplate from "./prompts/tools/async-result.md" with { type: "text" };
94
91
  import { AgentRegistry, MAIN_AGENT_ID } from "./registry/agent-registry";
@@ -117,6 +114,9 @@ import { parseThinkingLevel, resolveThinkingLevelForModel, toReasoningEffort } f
117
114
  import {
118
115
  collectDiscoverableTools,
119
116
  type DiscoverableTool,
117
+ filterBySource,
118
+ formatDiscoverableToolServerSummary,
119
+ selectDiscoverableToolNamesByServer,
120
120
  summarizeDiscoverableTools,
121
121
  } from "./tool-discovery/tool-index";
122
122
  import {
@@ -318,6 +318,8 @@ export interface CreateAgentSessionOptions {
318
318
  agentRegistry?: AgentRegistry;
319
319
  /** Parent task ID prefix for nested artifact naming (e.g., "6-Extensions") */
320
320
  parentTaskPrefix?: string;
321
+ /** Inherited eval executor session id for subagents sharing parent eval state. */
322
+ parentEvalSessionId?: string;
321
323
 
322
324
  /** Session manager. Default: session stored under the configured agentDir sessions root */
323
325
  sessionManager?: SessionManager;
@@ -1177,6 +1179,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1177
1179
  taskDepth: options.taskDepth ?? 0,
1178
1180
  getSessionFile: () => sessionManager.getSessionFile() ?? null,
1179
1181
  getEvalKernelOwnerId: () => evalKernelOwnerId,
1182
+ getEvalSessionId: () =>
1183
+ session?.getEvalSessionId() ?? options.parentEvalSessionId ?? defaultEvalSessionId(toolSession),
1180
1184
  assertEvalExecutionAllowed: () => session?.assertEvalExecutionAllowed(),
1181
1185
  trackEvalExecution: (execution, abortController) =>
1182
1186
  session ? session.trackEvalExecution(execution, abortController) : execution,
@@ -1196,8 +1200,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1196
1200
  getTodoPhases: () => session.getTodoPhases(),
1197
1201
  setTodoPhases: phases => session.setTodoPhases(phases),
1198
1202
  isMCPDiscoveryEnabled: () => session.isMCPDiscoveryEnabled(),
1199
- getDiscoverableMCPTools: () => session.getDiscoverableMCPTools(),
1200
- getDiscoverableMCPSearchIndex: () => session.getDiscoverableMCPSearchIndex(),
1201
1203
  getSelectedMCPToolNames: () => session.getSelectedMCPToolNames(),
1202
1204
  activateDiscoveredMCPTools: toolNames => session.activateDiscoveredMCPTools(toolNames),
1203
1205
  // Generic tool discovery (unified — covers built-in + MCP + extension)
@@ -1581,7 +1583,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1581
1583
  tools: Map<string, AgentTool>,
1582
1584
  ): Promise<BuildSystemPromptResult> => {
1583
1585
  toolContextStore.setToolNames(toolNames);
1584
- const discoverableMCPTools = mcpDiscoveryEnabled ? collectDiscoverableMCPTools(tools.values()) : [];
1586
+ const discoverableMCPTools: DiscoverableTool[] = mcpDiscoveryEnabled
1587
+ ? filterBySource(collectDiscoverableTools(tools.values()), "mcp")
1588
+ : [];
1585
1589
  const activeToolNames = new Set(toolNames);
1586
1590
  const discoverableBuiltinTools: DiscoverableTool[] =
1587
1591
  effectiveDiscoveryMode === "all"
@@ -1592,18 +1596,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1592
1596
  { source: "builtin" },
1593
1597
  )
1594
1598
  : [];
1595
- const discoverableToolsForDesc: DiscoverableTool[] = [
1596
- ...discoverableBuiltinTools,
1597
- ...discoverableMCPTools.map(t => ({
1598
- name: t.name,
1599
- label: t.label,
1600
- summary: t.description,
1601
- source: "mcp" as const,
1602
- serverName: t.serverName,
1603
- mcpToolName: t.mcpToolName,
1604
- schemaKeys: t.schemaKeys,
1605
- })),
1606
- ];
1599
+ const discoverableToolsForDesc: DiscoverableTool[] = [...discoverableBuiltinTools, ...discoverableMCPTools];
1607
1600
  const discoverableToolSummary = summarizeDiscoverableTools(discoverableToolsForDesc);
1608
1601
  const hasDiscoverableTools =
1609
1602
  mcpDiscoveryEnabled && toolNames.includes("search_tool_bm25") && discoverableToolsForDesc.length > 0;
@@ -1647,7 +1640,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1647
1640
  repeatToolDescriptions,
1648
1641
  intentField,
1649
1642
  mcpDiscoveryMode: hasDiscoverableTools,
1650
- mcpDiscoveryServerSummaries: discoverableToolSummary.servers.map(formatDiscoverableMCPToolServerSummary),
1643
+ mcpDiscoveryServerSummaries: discoverableToolSummary.servers.map(formatDiscoverableToolServerSummary),
1651
1644
  eagerTasks,
1652
1645
  secretsEnabled,
1653
1646
  workspaceTree: workspaceTreePromise,
@@ -1693,8 +1686,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1693
1686
  (settings.get("mcp.discoveryDefaultServers") ?? []).map(serverName => serverName.trim()).filter(Boolean),
1694
1687
  );
1695
1688
  const discoveryDefaultServerToolNames = mcpDiscoveryEnabled
1696
- ? selectDiscoverableMCPToolNamesByServer(
1697
- collectDiscoverableMCPTools(toolRegistry.values()),
1689
+ ? selectDiscoverableToolNamesByServer(
1690
+ filterBySource(collectDiscoverableTools(toolRegistry.values()), "mcp"),
1698
1691
  discoveryDefaultServers,
1699
1692
  )
1700
1693
  : [];
@@ -1893,7 +1886,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1893
1886
  streamSimple(streamModel, context, {
1894
1887
  ...streamOptions,
1895
1888
  onAuthError: async (provider, oldKey, error) => {
1896
- await modelRegistry.authStorage.invalidateCredentialMatching(provider, oldKey, streamOptions?.signal);
1889
+ await modelRegistry.authStorage.invalidateCredentialMatching(provider, oldKey, {
1890
+ signal: streamOptions?.signal,
1891
+ sessionId: agent.sessionId,
1892
+ });
1897
1893
  logger.debug("Retrying provider request after credential invalidation", {
1898
1894
  provider,
1899
1895
  error: error instanceof Error ? error.message : String(error),
@@ -1991,6 +1987,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1991
1987
  agentId: resolvedAgentId,
1992
1988
  agentRegistry,
1993
1989
  providerSessionId: options.providerSessionId,
1990
+ parentEvalSessionId: options.parentEvalSessionId,
1994
1991
  });
1995
1992
  hasSession = true;
1996
1993
  if (asyncJobManager) {