@oh-my-pi/pi-coding-agent 16.1.22 → 16.2.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 (276) hide show
  1. package/CHANGELOG.md +99 -1
  2. package/dist/cli.js +4387 -4164
  3. package/dist/types/advisor/__tests__/emission-guard.test.d.ts +1 -0
  4. package/dist/types/advisor/emission-guard.d.ts +73 -0
  5. package/dist/types/advisor/index.d.ts +1 -0
  6. package/dist/types/advisor/runtime.d.ts +7 -0
  7. package/dist/types/advisor/watchdog.d.ts +2 -0
  8. package/dist/types/cli/flag-tables.d.ts +1 -0
  9. package/dist/types/cli/gallery-fixtures/search.d.ts +1 -1
  10. package/dist/types/cli/gc-cli.d.ts +58 -0
  11. package/dist/types/collab/display-name.d.ts +3 -0
  12. package/dist/types/collab/host.d.ts +0 -2
  13. package/dist/types/commands/gc.d.ts +37 -0
  14. package/dist/types/commands/worktree.d.ts +0 -3
  15. package/dist/types/config/inline-tool-descriptors-mode.d.ts +13 -0
  16. package/dist/types/config/model-discovery.d.ts +6 -1
  17. package/dist/types/config/model-registry.d.ts +6 -2
  18. package/dist/types/config/model-resolver.d.ts +12 -0
  19. package/dist/types/config/models-config-schema.d.ts +29 -2
  20. package/dist/types/config/models-config.d.ts +22 -1
  21. package/dist/types/config/settings-schema.d.ts +145 -21
  22. package/dist/types/config/settings.d.ts +13 -0
  23. package/dist/types/dap/config.d.ts +1 -1
  24. package/dist/types/edit/hashline/filesystem.d.ts +4 -2
  25. package/dist/types/edit/renderer.d.ts +4 -0
  26. package/dist/types/extensibility/extensions/types.d.ts +17 -17
  27. package/dist/types/extensibility/hooks/types.d.ts +10 -10
  28. package/dist/types/extensibility/plugins/marketplace/types.d.ts +1 -0
  29. package/dist/types/internal-urls/__tests__/ssh-protocol.test.d.ts +1 -0
  30. package/dist/types/internal-urls/index.d.ts +1 -0
  31. package/dist/types/internal-urls/registry-helpers.d.ts +2 -0
  32. package/dist/types/internal-urls/router.d.ts +1 -1
  33. package/dist/types/internal-urls/ssh-protocol.d.ts +10 -0
  34. package/dist/types/internal-urls/types.d.ts +19 -2
  35. package/dist/types/irc/bus.d.ts +6 -0
  36. package/dist/types/mcp/transports/stdio.d.ts +25 -1
  37. package/dist/types/modes/components/__tests__/move-overlay.test.d.ts +1 -0
  38. package/dist/types/modes/components/custom-editor.d.ts +7 -0
  39. package/dist/types/modes/components/move-overlay.d.ts +23 -0
  40. package/dist/types/modes/components/plugin-selector.d.ts +2 -1
  41. package/dist/types/modes/components/queue-mode-selector.d.ts +2 -1
  42. package/dist/types/modes/components/select-list-mouse-routing.d.ts +2 -0
  43. package/dist/types/modes/components/settings-defs.d.ts +4 -1
  44. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  45. package/dist/types/modes/components/show-images-selector.d.ts +2 -1
  46. package/dist/types/modes/components/status-line/component.d.ts +2 -0
  47. package/dist/types/modes/components/status-line/types.d.ts +2 -0
  48. package/dist/types/modes/components/theme-selector.d.ts +2 -1
  49. package/dist/types/modes/components/thinking-selector.d.ts +2 -1
  50. package/dist/types/modes/controllers/command-controller.d.ts +10 -1
  51. package/dist/types/modes/controllers/streaming-reveal.d.ts +6 -0
  52. package/dist/types/modes/interactive-mode.d.ts +10 -1
  53. package/dist/types/modes/internal-url-autocomplete.d.ts +1 -1
  54. package/dist/types/modes/running-subagent-badge.d.ts +6 -0
  55. package/dist/types/modes/theme/mermaid-rendering.test.d.ts +1 -0
  56. package/dist/types/modes/theme/theme.d.ts +2 -1
  57. package/dist/types/modes/types.d.ts +9 -1
  58. package/dist/types/sdk.d.ts +2 -2
  59. package/dist/types/session/agent-session.d.ts +2 -1
  60. package/dist/types/session/session-listing.d.ts +10 -1
  61. package/dist/types/session/session-manager.d.ts +13 -0
  62. package/dist/types/slash-commands/builtin-registry.d.ts +1 -1
  63. package/dist/types/ssh/__tests__/connection-manager-args.test.d.ts +1 -0
  64. package/dist/types/ssh/__tests__/file-transfer-posix-guard.test.d.ts +1 -0
  65. package/dist/types/ssh/connection-manager.d.ts +2 -0
  66. package/dist/types/ssh/file-transfer.d.ts +79 -0
  67. package/dist/types/ssh/utils.d.ts +6 -0
  68. package/dist/types/system-prompt.d.ts +5 -0
  69. package/dist/types/task/executor.d.ts +16 -0
  70. package/dist/types/tiny/text.d.ts +1 -1
  71. package/dist/types/tools/builtin-names.d.ts +5 -1
  72. package/dist/types/tools/{find.d.ts → glob.d.ts} +15 -15
  73. package/dist/types/tools/{search.d.ts → grep.d.ts} +14 -14
  74. package/dist/types/tools/index.d.ts +3 -3
  75. package/dist/types/tools/path-utils.d.ts +29 -0
  76. package/dist/types/tools/plan-mode-guard.d.ts +7 -0
  77. package/dist/types/tools/read.d.ts +2 -2
  78. package/dist/types/tools/render-utils.d.ts +8 -0
  79. package/dist/types/tools/renderers.d.ts +11 -0
  80. package/dist/types/tools/ssh.d.ts +2 -0
  81. package/dist/types/tools/todo.d.ts +0 -16
  82. package/dist/types/tools/write.d.ts +2 -2
  83. package/dist/types/utils/active-repo-context.d.ts +8 -0
  84. package/dist/types/utils/image-resize.d.ts +1 -0
  85. package/dist/types/utils/markit-cache.d.ts +23 -0
  86. package/dist/types/utils/markit.d.ts +5 -1
  87. package/dist/types/utils/prompt-path.d.ts +1 -0
  88. package/dist/types/web/search/providers/duckduckgo.d.ts +14 -0
  89. package/dist/types/web/search/providers/firecrawl.d.ts +28 -0
  90. package/dist/types/web/search/providers/tinyfish.d.ts +29 -0
  91. package/dist/types/web/search/providers/xai.d.ts +13 -0
  92. package/dist/types/web/search/types.d.ts +18 -2
  93. package/package.json +30 -15
  94. package/scripts/bench-guard.ts +1 -1
  95. package/scripts/build-binary.ts +9 -9
  96. package/scripts/bundle-dist.ts +2 -2
  97. package/src/advisor/__tests__/advisor.test.ts +40 -4
  98. package/src/advisor/__tests__/emission-guard.test.ts +147 -0
  99. package/src/advisor/advise-tool.ts +1 -1
  100. package/src/advisor/emission-guard.ts +172 -0
  101. package/src/advisor/index.ts +1 -0
  102. package/src/advisor/runtime.ts +11 -0
  103. package/src/advisor/watchdog.ts +12 -1
  104. package/src/cli/args.ts +5 -2
  105. package/src/cli/auth-broker-cli.ts +17 -0
  106. package/src/cli/config-cli.ts +4 -0
  107. package/src/cli/flag-tables.ts +7 -4
  108. package/src/cli/gallery-cli.ts +14 -2
  109. package/src/cli/gallery-fixtures/edit.ts +60 -0
  110. package/src/cli/gallery-fixtures/fs.ts +17 -17
  111. package/src/cli/gallery-fixtures/search.ts +4 -4
  112. package/src/cli/gc-cli.ts +939 -0
  113. package/src/cli/usage-cli.ts +20 -1
  114. package/src/cli/web-search-cli.ts +1 -1
  115. package/src/cli-commands.ts +1 -0
  116. package/src/collab/display-name.ts +13 -0
  117. package/src/collab/guest.ts +5 -1
  118. package/src/collab/host.ts +2 -13
  119. package/src/commands/gc.ts +46 -0
  120. package/src/commands/worktree.ts +6 -0
  121. package/src/config/inline-tool-descriptors-mode.ts +27 -0
  122. package/src/config/model-discovery.ts +77 -8
  123. package/src/config/model-registry.ts +89 -11
  124. package/src/config/model-resolver.ts +39 -1
  125. package/src/config/models-config-schema.ts +41 -5
  126. package/src/config/models-config.ts +4 -1
  127. package/src/config/settings-schema.ts +130 -27
  128. package/src/config/settings.ts +216 -7
  129. package/src/cursor.ts +1 -1
  130. package/src/dap/config.ts +152 -8
  131. package/src/dap/session.ts +1 -1
  132. package/src/discovery/helpers.ts +3 -1
  133. package/src/edit/hashline/diff.ts +14 -3
  134. package/src/edit/hashline/execute.ts +42 -6
  135. package/src/edit/hashline/filesystem.ts +49 -8
  136. package/src/edit/index.ts +1 -0
  137. package/src/edit/modes/patch.ts +11 -1
  138. package/src/edit/renderer.ts +140 -13
  139. package/src/eval/__tests__/agent-bridge.test.ts +101 -0
  140. package/src/eval/__tests__/julia-prelude.test.ts +18 -0
  141. package/src/eval/agent-bridge.ts +26 -3
  142. package/src/eval/jl/runner.jl +7 -1
  143. package/src/eval/js/tool-bridge.ts +2 -2
  144. package/src/export/html/index.ts +1 -1
  145. package/src/export/html/template.js +3 -1
  146. package/src/export/html/tool-views.generated.js +20 -20
  147. package/src/extensibility/extensions/types.ts +22 -22
  148. package/src/extensibility/hooks/types.ts +11 -11
  149. package/src/extensibility/plugins/legacy-pi-bundled-keys.ts +10 -3
  150. package/src/extensibility/plugins/legacy-pi-bundled-registry.ts +31 -10
  151. package/src/extensibility/plugins/marketplace/manager.ts +22 -0
  152. package/src/extensibility/plugins/marketplace/types.ts +1 -0
  153. package/src/internal-urls/__tests__/ssh-protocol.test.ts +331 -0
  154. package/src/internal-urls/docs-index.generated.txt +2 -2
  155. package/src/internal-urls/docs-index.ts +2 -3
  156. package/src/internal-urls/index.ts +1 -0
  157. package/src/internal-urls/registry-helpers.ts +19 -4
  158. package/src/internal-urls/router.ts +5 -3
  159. package/src/internal-urls/ssh-protocol.ts +367 -0
  160. package/src/internal-urls/types.ts +19 -2
  161. package/src/irc/bus.ts +11 -3
  162. package/src/lsp/index.ts +8 -1
  163. package/src/mcp/oauth-discovery.ts +20 -20
  164. package/src/mcp/tool-bridge.ts +32 -2
  165. package/src/mcp/transports/stdio.test.ts +20 -3
  166. package/src/mcp/transports/stdio.ts +45 -14
  167. package/src/memories/index.ts +1 -1
  168. package/src/modes/acp/acp-event-mapper.ts +2 -2
  169. package/src/modes/components/__tests__/move-overlay.test.ts +166 -0
  170. package/src/modes/components/agent-hub.ts +3 -0
  171. package/src/modes/components/agent-transcript-viewer.ts +9 -7
  172. package/src/modes/components/custom-editor.ts +90 -5
  173. package/src/modes/components/move-overlay.ts +282 -0
  174. package/src/modes/components/plan-review-overlay.ts +35 -35
  175. package/src/modes/components/plugin-selector.ts +6 -1
  176. package/src/modes/components/queue-mode-selector.ts +6 -1
  177. package/src/modes/components/select-list-mouse-routing.ts +35 -0
  178. package/src/modes/components/session-selector.ts +11 -10
  179. package/src/modes/components/settings-defs.ts +14 -1
  180. package/src/modes/components/settings-selector.ts +196 -29
  181. package/src/modes/components/show-images-selector.ts +6 -1
  182. package/src/modes/components/status-line/component.ts +108 -28
  183. package/src/modes/components/status-line/segments.ts +5 -1
  184. package/src/modes/components/status-line/types.ts +2 -0
  185. package/src/modes/components/theme-selector.ts +6 -1
  186. package/src/modes/components/thinking-selector.ts +6 -1
  187. package/src/modes/components/tool-execution.ts +25 -9
  188. package/src/modes/components/tree-selector.ts +5 -5
  189. package/src/modes/controllers/command-controller.ts +140 -47
  190. package/src/modes/controllers/event-controller.ts +59 -3
  191. package/src/modes/controllers/input-controller.ts +70 -4
  192. package/src/modes/controllers/selector-controller.ts +15 -2
  193. package/src/modes/controllers/streaming-reveal.ts +17 -0
  194. package/src/modes/controllers/tool-args-reveal.ts +1 -1
  195. package/src/modes/interactive-mode.ts +142 -59
  196. package/src/modes/internal-url-autocomplete.ts +17 -2
  197. package/src/modes/prompt-action-autocomplete.ts +3 -1
  198. package/src/modes/running-subagent-badge.ts +13 -0
  199. package/src/modes/setup-wizard/scenes/glyph.ts +2 -13
  200. package/src/modes/setup-wizard/scenes/providers.ts +2 -1
  201. package/src/modes/setup-wizard/scenes/theme.ts +6 -12
  202. package/src/modes/setup-wizard/scenes/web-search.ts +8 -13
  203. package/src/modes/setup-wizard/wizard-overlay.ts +6 -5
  204. package/src/modes/theme/mermaid-rendering.test.ts +53 -0
  205. package/src/modes/theme/theme.ts +42 -15
  206. package/src/modes/types.ts +9 -1
  207. package/src/modes/utils/interactive-context-helpers.ts +1 -1
  208. package/src/priority.json +15 -0
  209. package/src/prompts/advisor/active-repo-watchdog.md +6 -0
  210. package/src/prompts/advisor/system.md +21 -7
  211. package/src/prompts/agents/designer.md +1 -1
  212. package/src/prompts/agents/explore.md +1 -1
  213. package/src/prompts/agents/librarian.md +2 -2
  214. package/src/prompts/agents/plan.md +2 -2
  215. package/src/prompts/agents/reviewer.md +1 -1
  216. package/src/prompts/agents/task.md +2 -2
  217. package/src/prompts/system/active-repo-context.md +4 -0
  218. package/src/prompts/system/gemini-tool-call-reminder.md +9 -0
  219. package/src/prompts/system/plan-mode-active.md +12 -3
  220. package/src/prompts/system/project-prompt.md +2 -2
  221. package/src/prompts/system/system-prompt.md +8 -6
  222. package/src/prompts/tools/bash.md +2 -2
  223. package/src/prompts/tools/checkpoint.md +1 -1
  224. package/src/prompts/tools/{find.md → glob.md} +1 -1
  225. package/src/prompts/tools/{search.md → grep.md} +3 -3
  226. package/src/prompts/tools/read.md +4 -2
  227. package/src/sdk.ts +98 -29
  228. package/src/session/agent-session.ts +828 -191
  229. package/src/session/session-history-format.ts +2 -2
  230. package/src/session/session-listing.ts +35 -2
  231. package/src/session/session-manager.ts +46 -0
  232. package/src/slash-commands/builtin-registry.ts +158 -22
  233. package/src/slash-commands/helpers/usage-report.ts +23 -2
  234. package/src/ssh/__tests__/connection-manager-args.test.ts +69 -0
  235. package/src/ssh/__tests__/file-transfer-posix-guard.test.ts +68 -0
  236. package/src/ssh/connection-manager.ts +12 -15
  237. package/src/ssh/file-transfer.ts +209 -0
  238. package/src/ssh/utils.ts +24 -0
  239. package/src/system-prompt.ts +60 -28
  240. package/src/task/executor.ts +96 -36
  241. package/src/task/index.ts +3 -3
  242. package/src/task/render.ts +14 -13
  243. package/src/task/worktree.ts +38 -1
  244. package/src/tiny/text.ts +49 -4
  245. package/src/tiny/worker.ts +3 -3
  246. package/src/tools/acp-bridge.ts +6 -1
  247. package/src/tools/bash.ts +2 -2
  248. package/src/tools/builtin-names.ts +26 -2
  249. package/src/tools/{find.ts → glob.ts} +48 -42
  250. package/src/tools/{search.ts → grep.ts} +311 -129
  251. package/src/tools/index.ts +13 -14
  252. package/src/tools/irc.ts +6 -2
  253. package/src/tools/path-utils.ts +64 -1
  254. package/src/tools/plan-mode-guard.ts +26 -13
  255. package/src/tools/read.ts +35 -6
  256. package/src/tools/render-utils.ts +14 -0
  257. package/src/tools/renderers.ts +15 -4
  258. package/src/tools/ssh.ts +17 -2
  259. package/src/tools/todo.ts +4 -26
  260. package/src/tools/write.ts +25 -9
  261. package/src/utils/active-repo-context.ts +143 -0
  262. package/src/utils/edit-mode.ts +19 -2
  263. package/src/utils/image-resize.ts +88 -7
  264. package/src/utils/lang-from-path.ts +3 -3
  265. package/src/utils/markit-cache.ts +166 -0
  266. package/src/utils/markit.ts +86 -18
  267. package/src/utils/prompt-path.ts +3 -0
  268. package/src/utils/shell-snapshot.ts +1 -1
  269. package/src/utils/title-generator.ts +1 -1
  270. package/src/web/search/provider.ts +54 -34
  271. package/src/web/search/providers/duckduckgo.ts +140 -0
  272. package/src/web/search/providers/firecrawl.ts +144 -0
  273. package/src/web/search/providers/tinyfish.ts +159 -0
  274. package/src/web/search/providers/xai.ts +292 -0
  275. package/src/web/search/providers/zai.ts +142 -56
  276. package/src/web/search/types.ts +6 -2
@@ -16,7 +16,9 @@ You are a helpful assistant the team trusts with load-bearing changes, operating
16
16
  - Consider what code compiles to. NEVER allocate avoidably; no needless copies or computation.
17
17
  - You are not alone in this repo. Treat unexpected changes as the user's work and adapt.
18
18
  - In terminal prose and final chat, you MAY use LaTeX math (`$`, `$$`, `\text`, `\times`) and color (`\textcolor`, `\colorbox`, `\fcolorbox`).
19
+ {{#if renderMermaid}}
19
20
  - To show a diagram, you MAY emit a ` ```mermaid ` block — the terminal renders it as ASCII. Use it for genuine structure or flow, not trivia.
21
+ {{/if}}
20
22
 
21
23
  RUNTIME
22
24
  ==============
@@ -107,8 +109,8 @@ You MUST use the specialized tool over its shell equivalent:
107
109
  {{#has tools "edit"}}- Surgical edits → `{{toolRefs.edit}}`.{{/has}}
108
110
  {{#has tools "write"}}- Create or overwrite → `{{toolRefs.write}}`.{{/has}}
109
111
  {{#has tools "lsp"}}- Code intelligence → `{{toolRefs.lsp}}`.{{/has}}
110
- {{#has tools "search"}}- Regex search → `{{toolRefs.search}}`, not `grep`, `rg`, or `awk`.{{/has}}
111
- {{#has tools "find"}}- Globbing → `{{toolRefs.find}}`, not `ls **/*.ext` or `fd`.{{/has}}
112
+ {{#has tools "grep"}}- Regex search → `{{toolRefs.grep}}`, not `grep`, `rg`, or `awk`.{{/has}}
113
+ {{#has tools "glob"}}- Globbing → `{{toolRefs.glob}}`, not `ls **/*.ext` or `fd`.{{/has}}
112
114
  {{#has tools "eval"}}- Default for any compute: `{{toolRefs.eval}}` cells. Bash is the EXCEPTION — only single binary calls or short fact-computing pipelines (`wc -l`, `sort | uniq -c`, `diff`, checksums). The moment a command grows a loop, conditional, heredoc, `-e`/`-c` script, `$(…)` nesting, or >2 pipe stages, it's a program → `{{toolRefs.eval}}`. NEVER write multiline or inline-script bash.{{/has}}
113
115
  {{#has tools "bash"}}- `{{toolRefs.bash}}`: real binaries and short fact pipelines only. Commands shadowing the specialized tools above are blocked.{{/has}}
114
116
  {{#has tools "bash"}}- Litmus: one external-CLI call or short pipeline returning a count, frequency, set difference, or checksum → bash.{{#has tools "eval"}} Needs control flow, state, or fights shell quoting → `{{toolRefs.eval}}`.{{/has}} Merely moves, pages, or trims bytes a tool can fetch → use the tool.{{/has}}
@@ -122,8 +124,8 @@ You MUST use the specialized tool over its shell equivalent:
122
124
  # Exploration
123
125
  You NEVER open a file hoping. Hope is not a strategy.
124
126
  - You MUST load only what's necessary; AVOID reading files or sections you don't need.
125
- {{#has tools "search"}}- Use `{{toolRefs.search}}` to locate targets.{{/has}}
126
- {{#has tools "find"}}- Use `{{toolRefs.find}}` to map structure.{{/has}}
127
+ {{#has tools "grep"}}- Use `{{toolRefs.grep}}` to locate targets.{{/has}}
128
+ {{#has tools "glob"}}- Use `{{toolRefs.glob}}` to map structure.{{/has}}
127
129
  {{#has tools "read"}}- Use `{{toolRefs.read}}` with offset/limit instead of whole-file reads.{{/has}}
128
130
  {{#has tools "task"}}- Use `{{toolRefs.task}}` to map unknown code instead of reading file after file yourself.{{/has}}
129
131
 
@@ -139,7 +141,7 @@ You NEVER use search or manual edits for code intelligence when a language serve
139
141
  You SHOULD use syntax-aware tools before text hacks:
140
142
  {{#has tools "ast_grep"}}- `{{toolRefs.ast_grep}}` for structural discovery.{{/has}}
141
143
  {{#has tools "ast_edit"}}- `{{toolRefs.ast_edit}}` for codemods.{{/has}}
142
- - Use `search` only for plain-text lookup when structure is irrelevant.
144
+ - Use `grep` only for plain-text lookup when structure is irrelevant.
143
145
  {{/ifAny}}
144
146
 
145
147
  # Delegation
@@ -178,7 +180,7 @@ EXECUTION WORKFLOW
178
180
  - Fix problems at the source. Remove obsolete code—no leftover comments, aliases, or re-exports.
179
181
  - Prefer updating existing files over creating new ones.
180
182
  - Review changes from the user's perspective.
181
- {{#has tools "search"}}- Search instead of guessing.{{/has}}
183
+ {{#has tools "grep"}}- Grep instead of guessing.{{/has}}
182
184
  {{#has tools "ask"}}- Ask before destructive commands or deleting code you didn't write.{{else}}- Don't run destructive git commands or delete code you didn't write.{{/has}}
183
185
 
184
186
  # 5. Verify
@@ -29,8 +29,8 @@ Anything below → `eval` cell, not bash:
29
29
 
30
30
  <critical>
31
31
  - Bash invokes real binaries with simple args; it is NOT a scripting surface. Loops, conditionals, heredocs, inline interpreter scripts (`-e`/`-c`/`--eval`) when an eval runtime exists, several piped stages, or quote/JSON escaping mean you're writing a program → use `eval` cells: restartable, stateful, and free of shell-quoting traps.
32
- - NEVER shell out to search content or files: `grep/rg` → `search`.
33
- - NEVER use `ls` or `find` to list or locate files — `ls` → `read` (a directory path lists entries), `find` → the `find` tool (globbing). This is non-negotiable, even for a single quick listing.
32
+ - NEVER shell out to search content or files: `grep/rg` → `grep`.
33
+ - NEVER use `ls` or `find` to list or locate files — `ls` → `read` (a directory path lists entries), `find` → the `glob` tool (globbing). This is non-negotiable, even for a single quick listing.
34
34
  - Avoid head/tail/redirections: stderr already merged; long output auto-truncated, FULL capture kept at `artifact://<id>`.
35
35
  </critical>
36
36
 
@@ -1,6 +1,6 @@
1
1
  Creates a context checkpoint before exploratory work so you can later rewind and keep only a concise report.
2
2
 
3
- Use this when you need to investigate with many intermediate tool calls (read/search/find/lsp/etc.) and want to minimize context cost afterward.
3
+ Use this when you need to investigate with many intermediate tool calls (read/grep/glob/lsp/etc.) and want to minimize context cost afterward.
4
4
 
5
5
  Rules:
6
6
  - You MUST call `rewind` before yielding after starting a checkpoint.
@@ -1,4 +1,4 @@
1
- Finds files and directories via fast pattern matching, any codebase size.
1
+ Globs files and directories via fast pattern matching, any codebase size.
2
2
 
3
3
  <instruction>
4
4
  - `paths`: array of globs, files, or directories.
@@ -1,4 +1,4 @@
1
- Searches files using regex.
1
+ Greps files using regex.
2
2
 
3
3
  <instruction>
4
4
  - Rust regex (RE2-style) — no lookaround/backreferences; use line anchors or post-filters instead of (?!…)/(?<!…).
@@ -17,6 +17,6 @@ Searches files using regex.
17
17
  </output>
18
18
 
19
19
  <critical>
20
- - MUST use built-in `search` for any content search. NEVER shell out to `grep`, `rg`, `ripgrep`, `ag`, `ack`, `git grep`, `awk`, `sed`-for-search, or any CLI search via Bash — not even for one match or a quick check.
21
- - Open-ended search needing multiple rounds? MUST use the Task tool with the explore subagent, NOT chained `search` calls.
20
+ - MUST use built-in `grep` for any content search. NEVER shell out to `grep`, `rg`, `ripgrep`, `ag`, `ack`, `git grep`, `awk`, `sed`-for-search, or any CLI search via Bash — not even for one match or a quick check.
21
+ - Open-ended search needing multiple rounds? MUST use the Task tool with the explore subagent, NOT chained `grep` calls.
22
22
  </critical>
@@ -7,7 +7,7 @@ Read files, directories, archives, SQLite, images, documents, internal resources
7
7
 
8
8
  ## Parameters
9
9
 
10
- - `path` — required. Local path, internal URI (`skill://`, `agent://`, `artifact://`, `history://`, `memory://`, `rule://`, `local://`, `vault://`, `mcp://`, `omp://`, `issue://`, `pr://`), or URL. Append `:<sel>` for ranges/modes (e.g. `src/foo.ts:50-200`, `src/foo.ts:raw`, `db.sqlite:users:42`).
10
+ - `path` — required. Local path, internal URI (`skill://`, `agent://`, `artifact://`, `history://`, `memory://`, `rule://`, `local://`, `vault://`, `mcp://`, `omp://`, `issue://`, `pr://`, `ssh://`), or URL. Append `:<sel>` for ranges/modes (e.g. `src/foo.ts:50-200`, `src/foo.ts:raw`, `db.sqlite:users:42`).
11
11
 
12
12
  ## Selectors
13
13
 
@@ -25,7 +25,7 @@ Read files, directories, archives, SQLite, images, documents, internal resources
25
25
 
26
26
  - Directory → depth-limited dirent listing.
27
27
  {{#if IS_HL_MODE}}
28
- - File + selector → snapshot tag header + numbered lines: `[src/foo.ts#1A2B]` then `41:def alpha():`. Copy `[PATH#TAG]` for anchored edits; ops use bare line numbers. NEVER fabricate the tag.
28
+ - File + selector → filename-only snapshot header + numbered lines: `[foo.ts#1A2B]` then `41:def alpha():`. Copy `[FILENAME#TAG]` for anchored edits; ops use bare line numbers. NEVER fabricate the tag.
29
29
  {{else}}
30
30
  {{#if IS_LINE_NUMBER_MODE}}
31
31
  - File + selector → numbered lines: `41|def alpha():`.
@@ -69,6 +69,8 @@ For `.sqlite`, `.sqlite3`, `.db`, `.db3`:
69
69
 
70
70
  All URI schemes take the same line selectors. `artifact://<id>` recovers full output a bash/eval/tool result spilled or truncated. `history://<agentId>` = agent transcript; bare `history://` lists agents.
71
71
 
72
+ `ssh://host/<absolute-path>` reads a remote text file (UTF-8, ≤1 MiB) or lists a directory one level deep, on a pre-configured SSH host or `~/.ssh/config` alias; `ssh://host/` lists the remote root and bare `ssh://` lists the configured hosts. Files are also writable via `write` and searchable via `search`; a directory only lists (`search` refuses a directory, `write` refuses to overwrite one). A literal `:`, `?`, or `#` in the remote path must be percent-encoded (`%3A`/`%3F`/`%23`) — a trailing `:sel` is read as a line selector, and `?`/`#` start a URL query/fragment. Requires a POSIX login shell (`sh`/`bash`/`zsh`); a Windows host or a non-POSIX shell (fish, csh/tcsh) is rejected — use the `ssh` tool there.
73
+
72
74
  <critical>
73
75
  - Line ranges go in the selector: `path="src/foo.ts:50-200"`.
74
76
  - Summary footer names elided ranges? Re-issue ONLY those ranges. NEVER guess `..`/`…` content.
package/src/sdk.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  type AgentTelemetryConfig,
6
6
  type AgentTool,
7
7
  AppendOnlyContextManager,
8
+ filterProviderReplayMessages,
8
9
  type ThinkingLevel,
9
10
  } from "@oh-my-pi/pi-agent-core";
10
11
  import {
@@ -24,13 +25,14 @@ import { FALLBACK_DIALECT, preferredDialect } from "@oh-my-pi/pi-catalog/identit
24
25
  import type { Component } from "@oh-my-pi/pi-tui";
25
26
  import { $env, $flag, getAgentDir, getProjectDir, logger, postmortem, prompt, Snowflake } from "@oh-my-pi/pi-utils";
26
27
  import { INTENT_FIELD } from "@oh-my-pi/pi-wire";
27
- import { ADVISOR_READONLY_TOOL_NAMES, discoverWatchdogFiles } from "./advisor";
28
+ import { ADVISOR_READONLY_TOOL_NAMES, discoverWatchdogFiles, formatActiveRepoWatchdogPrompt } from "./advisor";
28
29
  import { type AsyncJob, AsyncJobManager } from "./async";
29
30
  import { AutoLearnController, buildAutoLearnInstructions } from "./autolearn/controller";
30
31
  import { loadCapability } from "./capability";
31
32
  import { type Rule, ruleCapability, setActiveRules } from "./capability/rule";
32
33
  import { bucketRules } from "./capability/rule-buckets";
33
34
  import { shouldEnableAppendOnlyContext } from "./config/append-only-context-mode";
35
+ import { shouldInlineToolDescriptors } from "./config/inline-tool-descriptors-mode";
34
36
  import { ModelRegistry } from "./config/model-registry";
35
37
  import {
36
38
  formatModelString,
@@ -42,7 +44,7 @@ import {
42
44
  resolveModelRoleValue,
43
45
  } from "./config/model-resolver";
44
46
  import { loadPromptTemplates as loadPromptTemplatesInternal, type PromptTemplate } from "./config/prompt-templates";
45
- import { Settings, type SkillsSettings } from "./config/settings";
47
+ import { Settings, type SkillsSettings, validateProviderMaxInFlightRequests } from "./config/settings";
46
48
  import { CursorExecHandlers } from "./cursor";
47
49
  import "./discovery";
48
50
  import { initializeWithSettings } from "./discovery";
@@ -158,8 +160,9 @@ import {
158
160
  discoverStartupLspServers,
159
161
  EditTool,
160
162
  EvalTool,
161
- FindTool,
162
163
  filterInitialToolsForDiscoveryAll,
164
+ GlobTool,
165
+ GrepTool,
163
166
  getSearchTools,
164
167
  HIDDEN_TOOLS,
165
168
  isImageProviderPreference,
@@ -170,7 +173,6 @@ import {
170
173
  ReadTool,
171
174
  ResolveTool,
172
175
  renderSearchToolBm25Description,
173
- SearchTool,
174
176
  SearchToolBm25Tool,
175
177
  setExcludedSearchProviders,
176
178
  setPreferredImageProvider,
@@ -181,11 +183,13 @@ import {
181
183
  WriteTool,
182
184
  warmupLspServers,
183
185
  } from "./tools";
186
+ import { normalizeToolName, normalizeToolNames } from "./tools/builtin-names";
184
187
  import { ToolContextStore } from "./tools/context";
185
188
  import { getImageGenTools } from "./tools/image-gen";
186
189
  import { wrapToolWithMetaNotice } from "./tools/output-meta";
187
190
  import { queueResolveHandler } from "./tools/resolve";
188
191
  import { ttsTool } from "./tools/tts";
192
+ import { resolveActiveRepoContext } from "./utils/active-repo-context";
189
193
  import { EventBus } from "./utils/event-bus";
190
194
  import { buildNamedToolChoice } from "./utils/tool-choice";
191
195
  import { buildWorkspaceTree, type WorkspaceTree } from "./workspace-tree";
@@ -606,12 +610,12 @@ export {
606
610
  createTools,
607
611
  EditTool,
608
612
  EvalTool,
609
- FindTool,
613
+ GlobTool,
614
+ GrepTool,
610
615
  HIDDEN_TOOLS,
611
616
  loadSshTool,
612
617
  ReadTool,
613
618
  ResolveTool,
614
- SearchTool,
615
619
  type ToolSession,
616
620
  WebSearchTool,
617
621
  WriteTool,
@@ -1143,6 +1147,15 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1143
1147
  ? Promise.resolve(options.contextFiles)
1144
1148
  : logger.time("discoverContextFiles", discoverContextFiles, cwd, agentDir);
1145
1149
  contextFilesPromise.catch(() => {});
1150
+ const activeRepoContextPromise = logger.time("resolveActiveRepoContext", async () => {
1151
+ try {
1152
+ return await resolveActiveRepoContext(cwd);
1153
+ } catch (err) {
1154
+ logger.debug("Failed to resolve active repo context", { err: String(err) });
1155
+ return null;
1156
+ }
1157
+ });
1158
+ activeRepoContextPromise.catch(() => {});
1146
1159
  const watchdogFilesPromise = logger.time("discoverWatchdogFiles", () => discoverWatchdogFiles(cwd, agentDir));
1147
1160
  watchdogFilesPromise.catch(() => {});
1148
1161
  const promptTemplatesPromise = options.promptTemplates
@@ -1223,7 +1236,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1223
1236
  const allowedModels = await logger.time("resolveAllowedModels", () =>
1224
1237
  resolveAllowedModels(modelRegistry, settings, modelMatchPreferences),
1225
1238
  );
1226
- const defaultRoleSpec = logger.time("resolveDefaultModelRole", () =>
1239
+ let defaultRoleSpec = logger.time("resolveDefaultModelRole", () =>
1227
1240
  resolveModelRoleValue(settings.getModelRole("default"), allowedModels, {
1228
1241
  settings,
1229
1242
  matchPreferences: modelMatchPreferences,
@@ -1390,10 +1403,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1390
1403
  }
1391
1404
  return result;
1392
1405
  };
1393
- const [contextFiles, resolvedWorkspaceTree, watchdogFiles] = await Promise.all([
1406
+ const [contextFiles, resolvedWorkspaceTree, watchdogFiles, activeRepoContext] = await Promise.all([
1394
1407
  contextFilesPromise,
1395
1408
  raceWithDeadline("buildWorkspaceTree", workspaceTreePromise),
1396
1409
  watchdogFilesPromise,
1410
+ activeRepoContextPromise,
1397
1411
  ]);
1398
1412
 
1399
1413
  let agent: Agent;
@@ -1489,9 +1503,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1489
1503
  hasUI: options.hasUI ?? false,
1490
1504
  enableLsp,
1491
1505
  get hasEditTool() {
1492
- const requestedToolNames = options.toolNames
1493
- ? [...new Set(options.toolNames.map(name => name.toLowerCase()))]
1494
- : undefined;
1506
+ const requestedToolNames = options.toolNames ? normalizeToolNames(options.toolNames) : undefined;
1495
1507
  return !requestedToolNames || requestedToolNames.includes("edit");
1496
1508
  },
1497
1509
  skipPythonPreflight: options.skipPythonPreflight,
@@ -1946,9 +1958,47 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1946
1958
  // Re-resolve the allowed set: extension factories above may have
1947
1959
  // registered providers/models that weren't visible at startup.
1948
1960
  const fallbackCandidates = await resolveAllowedModels(modelRegistry, settings, modelMatchPreferences);
1949
- const defaultModel = pickDefaultAvailableModel(fallbackCandidates.filter(hasModelAuth));
1950
- if (defaultModel) {
1951
- model = defaultModel;
1961
+
1962
+ // Retry the default-role lookup against the post-extension allowed
1963
+ // set. Extension factories register providers AFTER the early
1964
+ // `defaultRoleSpec` resolution, so a role pointing at an extension
1965
+ // model (e.g. an openai-compat plugin's `posthog/claude-opus-4-8`)
1966
+ // returned `undefined` there. Without this retry the next step's
1967
+ // `pickDefaultAvailableModel` happily replaces the user's configured
1968
+ // default with a bundled provider's default whenever a stray
1969
+ // `OPENAI_API_KEY`/`ANTHROPIC_API_KEY` is in the environment.
1970
+ // (issue #3569)
1971
+ if (!hasExplicitModel && !defaultRoleSpec.model) {
1972
+ const reResolvedRoleSpec = resolveModelRoleValue(settings.getModelRole("default"), fallbackCandidates, {
1973
+ settings,
1974
+ matchPreferences: modelMatchPreferences,
1975
+ modelRegistry,
1976
+ });
1977
+ if (reResolvedRoleSpec.model) {
1978
+ defaultRoleSpec = reResolvedRoleSpec;
1979
+ const resolvedDefaultModel = reResolvedRoleSpec.model;
1980
+ model = resolvedDefaultModel;
1981
+ modelFallbackMessage = undefined;
1982
+ // Recompute the thinking level against the now-real model.
1983
+ // `pickInitialThinkingLevel` closes over `defaultRoleSpec`,
1984
+ // so the role's explicit selector (e.g. `:max`) now applies.
1985
+ thinkingLevel = pickInitialThinkingLevel(resolvedDefaultModel);
1986
+ autoThinking = thinkingLevel === AUTO_THINKING;
1987
+ effectiveThinkingLevel = thinkingLevel === AUTO_THINKING ? undefined : thinkingLevel;
1988
+ effectiveThinkingLevel = logger.time("resolveThinkingLevelForModel", () =>
1989
+ autoThinking
1990
+ ? resolveProvisionalAutoLevel(resolvedDefaultModel)
1991
+ : resolveThinkingLevelForModel(resolvedDefaultModel, effectiveThinkingLevel),
1992
+ );
1993
+ preconnectModelHost(resolvedDefaultModel.baseUrl);
1994
+ }
1995
+ }
1996
+
1997
+ if (!model) {
1998
+ const defaultModel = pickDefaultAvailableModel(fallbackCandidates.filter(hasModelAuth));
1999
+ if (defaultModel) {
2000
+ model = defaultModel;
2001
+ }
1952
2002
  }
1953
2003
  if (model) {
1954
2004
  if (modelFallbackMessage) {
@@ -2119,7 +2169,14 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2119
2169
  emitEvent: event => cursorEventEmitter?.(event),
2120
2170
  });
2121
2171
 
2122
- const inlineToolDescriptors = settings.get("inlineToolDescriptors");
2172
+ // Resolve the inline-descriptors setting against the session-start model.
2173
+ // `auto` enforces the per-model policy (inline for Gemini, off otherwise);
2174
+ // like the rest of the prune machinery this is fixed for the session, so a
2175
+ // mid-session model switch keeps the start-time decision.
2176
+ const inlineToolDescriptors = shouldInlineToolDescriptors(
2177
+ settings.get("inlineToolDescriptors"),
2178
+ model ? (modelRegistry.getCanonicalId(model) ?? model.id) : undefined,
2179
+ );
2123
2180
  const eagerTasks = settings.get("task.eager") !== "default";
2124
2181
  const eagerTasksAlways = settings.get("task.eager") === "always";
2125
2182
  const intentField = $flag("PI_INTENT_TRACING", settings.get("tools.intentTracing")) ? INTENT_FIELD : undefined;
@@ -2221,6 +2278,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2221
2278
  memoryRootEnabled: memoryBackend.id === "local",
2222
2279
  model: settings.get("includeModelInPrompt") ? getActiveModelString() : undefined,
2223
2280
  personality: agentKind === "sub" ? "none" : settings.get("personality"),
2281
+ renderMermaid: settings.get("tui.renderMermaid"),
2282
+ activeRepoContext,
2224
2283
  });
2225
2284
 
2226
2285
  if (options.systemPrompt === undefined) {
@@ -2236,9 +2295,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2236
2295
  };
2237
2296
 
2238
2297
  const toolNamesFromRegistry = Array.from(toolRegistry.keys());
2239
- const explicitlyRequestedToolNames = options.toolNames
2240
- ? [...new Set(options.toolNames.map(name => name.toLowerCase()))]
2241
- : undefined;
2298
+ const explicitlyRequestedToolNames = options.toolNames ? normalizeToolNames(options.toolNames) : undefined;
2242
2299
  // When `requireYieldTool` is set, the subagent's prompts and idle-reminders demand a
2243
2300
  // `yield` call to terminate. The tool registry already includes `yield` (see
2244
2301
  // `createTools`), but an explicit `toolNames` list would otherwise drop it from the
@@ -2288,13 +2345,14 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2288
2345
  discoveryDefaultServers,
2289
2346
  )
2290
2347
  : [];
2348
+ const normalizeRenamedBuiltinToolName = normalizeToolName;
2291
2349
  let initialSelectedMCPToolNames: string[] = [];
2292
2350
  let defaultSelectedMCPToolNames: string[] = [];
2293
2351
  let initialToolNames = [...initialRequestedActiveToolNames];
2294
2352
  if (mcpDiscoveryEnabled) {
2295
- const restoredSelectedMCPToolNames = existingSession.selectedMCPToolNames.filter(name =>
2296
- toolRegistry.has(name),
2297
- );
2353
+ const restoredSelectedMCPToolNames = existingSession.selectedMCPToolNames
2354
+ .map(normalizeRenamedBuiltinToolName)
2355
+ .filter(name => toolRegistry.has(name));
2298
2356
  defaultSelectedMCPToolNames = [
2299
2357
  ...new Set([...discoveryDefaultServerToolNames, ...explicitlyRequestedMCPToolNames]),
2300
2358
  ];
@@ -2343,10 +2401,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2343
2401
  initialToolNames = filterInitialToolsForDiscoveryAll(initialToolNames, {
2344
2402
  loadModeOf: name => toolRegistry.get(name)?.loadMode,
2345
2403
  essentialNames: new Set(computeEssentialBuiltinNames(settings)),
2346
- explicitlyRequested: new Set(options.toolNames?.map(name => name.toLowerCase()) ?? []),
2404
+ explicitlyRequested: new Set(options.toolNames ? normalizeToolNames(options.toolNames) : []),
2347
2405
  // Back-compat: persisted activations live under selectedMCPToolNames today (built-in
2348
2406
  // activation persistence is a follow-up). MCP names won't collide with built-in names.
2349
- restored: new Set(existingSession.selectedMCPToolNames),
2407
+ restored: new Set(existingSession.selectedMCPToolNames.map(normalizeRenamedBuiltinToolName)),
2350
2408
  forceActive,
2351
2409
  });
2352
2410
  }
@@ -2410,9 +2468,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2410
2468
  });
2411
2469
  };
2412
2470
 
2413
- // Final convertToLlm: chain block-images filter with secret obfuscation
2471
+ // Final convertToLlm: live provider replay drops API-level refusal errors,
2472
+ // then applies secret obfuscation to the remaining outbound context.
2414
2473
  const convertToLlmFinal = (messages: AgentMessage[]): Message[] => {
2415
- const converted = convertToLlmWithBlockImages(messages);
2474
+ const converted = filterProviderReplayMessages(convertToLlmWithBlockImages(messages));
2416
2475
  if (!obfuscator?.hasSecrets()) return converted;
2417
2476
  return obfuscateMessages(obfuscator, converted);
2418
2477
  };
@@ -2480,6 +2539,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2480
2539
  disableReasoning: shouldDisableReasoning(effectiveThinkingLevel),
2481
2540
  tools: initialTools,
2482
2541
  },
2542
+ cwd,
2543
+ // Live cwd: `/move` updates SessionManager (and process cwd) without
2544
+ // reconstructing the Agent, so a static cwd would strand GitLab Duo Agent
2545
+ // namespace/project discovery on the original repo's git remote. Re-read it
2546
+ // per turn from the SessionManager.
2547
+ cwdResolver: () => sessionManager.getCwd(),
2483
2548
  convertToLlm: convertToLlmFinal,
2484
2549
  onPayload,
2485
2550
  onResponse,
@@ -2524,6 +2589,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2524
2589
  ...streamOptions,
2525
2590
  openrouterVariant: streamOptions?.openrouterVariant ?? openrouterVariant,
2526
2591
  antigravityEndpointMode: streamOptions?.antigravityEndpointMode ?? antigravityEndpointMode,
2592
+ maxInFlightRequests: validateProviderMaxInFlightRequests(
2593
+ streamOptions?.maxInFlightRequests ?? settings.get("providers.maxInFlightRequests"),
2594
+ ),
2527
2595
  loopGuard: {
2528
2596
  enabled: settings.get("model.loopGuard.enabled"),
2529
2597
  checkAssistantContent: settings.get("model.loopGuard.checkAssistantContent"),
@@ -2577,7 +2645,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2577
2645
  }
2578
2646
 
2579
2647
  // Hard-isolated read-only toolset for the advisor (built unconditionally so
2580
- // it can be toggled at runtime). Fresh ReadTool/SearchTool/FindTool bound to a
2648
+ // it can be toggled at runtime). Fresh ReadTool/GrepTool/GlobTool bound to a
2581
2649
  // DISTINCT ToolSession so the advisor's investigative reads never touch the
2582
2650
  // primary's snapshot, seen-lines, conflict, or summary caches (all keyed on
2583
2651
  // session identity). `cwd` stays dynamic; edit/yield capabilities are off.
@@ -2605,10 +2673,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2605
2673
  .filter((tool): tool is Tool => tool != null)
2606
2674
  .map(wrapToolWithMetaNotice);
2607
2675
 
2608
- let advisorWatchdogPrompt: string | undefined;
2609
- if (watchdogFiles && watchdogFiles.length > 0) {
2610
- advisorWatchdogPrompt = watchdogFiles.join("\n\n");
2676
+ const advisorWatchdogPrompts = [...watchdogFiles];
2677
+ if (activeRepoContext) {
2678
+ advisorWatchdogPrompts.push(formatActiveRepoWatchdogPrompt(activeRepoContext));
2611
2679
  }
2680
+ const advisorWatchdogPrompt = advisorWatchdogPrompts.length > 0 ? advisorWatchdogPrompts.join("\n\n") : undefined;
2612
2681
  // Owned only when this session created the manager; subagents receive a
2613
2682
  // parent's manager via `options.mcpManager` and MUST NOT disconnect it.
2614
2683
  const ownedMcpManager = options.mcpManager ? undefined : mcpManager;