@oh-my-pi/pi-coding-agent 8.1.0 → 8.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 (402) hide show
  1. package/CHANGELOG.md +21 -1
  2. package/docs/session.md +111 -46
  3. package/examples/custom-tools/hello/index.ts +1 -1
  4. package/examples/custom-tools/todo/index.ts +3 -4
  5. package/examples/extensions/api-demo.ts +0 -1
  6. package/examples/extensions/chalk-logger.ts +2 -3
  7. package/examples/extensions/hello.ts +0 -1
  8. package/examples/extensions/pirate.ts +0 -1
  9. package/examples/extensions/plan-mode.ts +15 -16
  10. package/examples/extensions/todo.ts +3 -4
  11. package/examples/extensions/tools.ts +1 -2
  12. package/examples/extensions/with-deps/index.ts +0 -1
  13. package/examples/hooks/auto-commit-on-exit.ts +1 -2
  14. package/examples/hooks/confirm-destructive.ts +0 -1
  15. package/examples/hooks/custom-compaction.ts +1 -2
  16. package/examples/hooks/dirty-repo-guard.ts +0 -1
  17. package/examples/hooks/file-trigger.ts +3 -4
  18. package/examples/hooks/git-checkpoint.ts +0 -1
  19. package/examples/hooks/handoff.ts +3 -4
  20. package/examples/hooks/permission-gate.ts +1 -2
  21. package/examples/hooks/protected-paths.ts +1 -2
  22. package/examples/hooks/qna.ts +2 -3
  23. package/examples/hooks/snake.ts +4 -5
  24. package/examples/hooks/status-line.ts +0 -1
  25. package/examples/sdk/01-minimal.ts +2 -3
  26. package/examples/sdk/02-custom-model.ts +2 -3
  27. package/examples/sdk/03-custom-prompt.ts +3 -4
  28. package/examples/sdk/04-skills.ts +2 -3
  29. package/examples/sdk/06-extensions.ts +1 -2
  30. package/examples/sdk/06-hooks.ts +6 -7
  31. package/examples/sdk/07-context-files.ts +0 -1
  32. package/examples/sdk/08-prompt-templates.ts +0 -1
  33. package/examples/sdk/08-slash-commands.ts +0 -1
  34. package/examples/sdk/09-api-keys-and-oauth.ts +0 -1
  35. package/examples/sdk/10-settings.ts +0 -1
  36. package/examples/sdk/11-sessions.ts +0 -1
  37. package/package.json +51 -23
  38. package/scripts/format-prompts.ts +0 -1
  39. package/src/capability/context-file.ts +2 -3
  40. package/src/capability/extension-module.ts +2 -3
  41. package/src/capability/extension.ts +2 -3
  42. package/src/capability/fs.ts +20 -21
  43. package/src/capability/hook.ts +2 -3
  44. package/src/capability/index.ts +15 -16
  45. package/src/capability/instruction.ts +2 -3
  46. package/src/capability/mcp.ts +2 -3
  47. package/src/capability/prompt.ts +2 -3
  48. package/src/capability/rule.ts +2 -3
  49. package/src/capability/settings.ts +1 -2
  50. package/src/capability/skill.ts +2 -3
  51. package/src/capability/slash-command.ts +2 -3
  52. package/src/capability/ssh.ts +2 -3
  53. package/src/capability/system-prompt.ts +2 -3
  54. package/src/capability/tool.ts +2 -3
  55. package/src/cli/args.ts +5 -6
  56. package/src/cli/config-cli.ts +6 -7
  57. package/src/cli/file-processor.ts +19 -17
  58. package/src/cli/jupyter-cli.ts +105 -0
  59. package/src/cli/list-models.ts +10 -11
  60. package/src/cli/plugin-cli.ts +20 -21
  61. package/src/cli/session-picker.ts +2 -3
  62. package/src/cli/setup-cli.ts +2 -3
  63. package/src/cli/stats-cli.ts +2 -3
  64. package/src/cli/update-cli.ts +25 -22
  65. package/src/commit/agentic/agent.ts +21 -23
  66. package/src/commit/agentic/fallback.ts +9 -9
  67. package/src/commit/agentic/index.ts +30 -38
  68. package/src/commit/agentic/state.ts +1 -6
  69. package/src/commit/agentic/tools/analyze-file.ts +15 -15
  70. package/src/commit/agentic/tools/git-file-diff.ts +3 -3
  71. package/src/commit/agentic/tools/git-hunk.ts +7 -7
  72. package/src/commit/agentic/tools/git-overview.ts +5 -5
  73. package/src/commit/agentic/tools/index.ts +14 -14
  74. package/src/commit/agentic/tools/propose-changelog.ts +6 -6
  75. package/src/commit/agentic/tools/propose-commit.ts +8 -8
  76. package/src/commit/agentic/tools/recent-commits.ts +2 -2
  77. package/src/commit/agentic/tools/split-commit.ts +19 -23
  78. package/src/commit/agentic/topo-sort.ts +1 -1
  79. package/src/commit/agentic/trivial.ts +3 -3
  80. package/src/commit/agentic/validation.ts +12 -12
  81. package/src/commit/analysis/conventional.ts +7 -11
  82. package/src/commit/analysis/index.ts +4 -4
  83. package/src/commit/analysis/scope.ts +4 -4
  84. package/src/commit/analysis/summary.ts +7 -9
  85. package/src/commit/analysis/validation.ts +1 -1
  86. package/src/commit/changelog/detect.ts +6 -6
  87. package/src/commit/changelog/generate.ts +7 -9
  88. package/src/commit/changelog/index.ts +13 -13
  89. package/src/commit/changelog/parse.ts +2 -2
  90. package/src/commit/cli.ts +1 -1
  91. package/src/commit/git/diff.ts +3 -3
  92. package/src/commit/git/index.ts +19 -24
  93. package/src/commit/index.ts +1 -1
  94. package/src/commit/map-reduce/index.ts +9 -9
  95. package/src/commit/map-reduce/map-phase.ts +19 -34
  96. package/src/commit/map-reduce/reduce-phase.ts +9 -11
  97. package/src/commit/message.ts +2 -2
  98. package/src/commit/model-selection.ts +3 -7
  99. package/src/commit/pipeline.ts +20 -22
  100. package/src/commit/utils/exclusions.ts +3 -3
  101. package/src/config/file-lock.ts +17 -7
  102. package/src/config/keybindings.ts +6 -8
  103. package/src/config/model-registry.ts +55 -37
  104. package/src/config/model-resolver.ts +18 -19
  105. package/src/config/prompt-templates.ts +11 -11
  106. package/src/config/settings-manager.ts +50 -34
  107. package/src/config.ts +60 -62
  108. package/src/cursor.ts +11 -9
  109. package/src/discovery/agents-md.ts +11 -12
  110. package/src/discovery/builtin.ts +68 -73
  111. package/src/discovery/claude.ts +41 -42
  112. package/src/discovery/cline.ts +11 -12
  113. package/src/discovery/codex.ts +52 -53
  114. package/src/discovery/cursor.ts +9 -10
  115. package/src/discovery/gemini.ts +17 -22
  116. package/src/discovery/github.ts +13 -14
  117. package/src/discovery/helpers.ts +35 -34
  118. package/src/discovery/index.ts +16 -18
  119. package/src/discovery/mcp-json.ts +8 -9
  120. package/src/discovery/ssh.ts +8 -9
  121. package/src/discovery/vscode.ts +4 -5
  122. package/src/discovery/windsurf.ts +6 -7
  123. package/src/exa/company.ts +1 -2
  124. package/src/exa/index.ts +2 -3
  125. package/src/exa/linkedin.ts +1 -2
  126. package/src/exa/mcp-client.ts +14 -16
  127. package/src/exa/render.ts +10 -11
  128. package/src/exa/researcher.ts +1 -2
  129. package/src/exa/search.ts +1 -2
  130. package/src/exa/types.ts +0 -1
  131. package/src/exa/websets.ts +1 -2
  132. package/src/exec/bash-executor.ts +3 -4
  133. package/src/exec/exec.ts +0 -1
  134. package/src/export/custom-share.ts +5 -6
  135. package/src/export/html/index.ts +24 -21
  136. package/src/export/ttsr.ts +2 -3
  137. package/src/extensibility/custom-commands/bundled/review/index.ts +7 -8
  138. package/src/extensibility/custom-commands/loader.ts +17 -14
  139. package/src/extensibility/custom-commands/types.ts +1 -2
  140. package/src/extensibility/custom-tools/loader.ts +10 -11
  141. package/src/extensibility/custom-tools/types.ts +6 -7
  142. package/src/extensibility/custom-tools/wrapper.ts +2 -3
  143. package/src/extensibility/extensions/loader.ts +75 -53
  144. package/src/extensibility/extensions/runner.ts +11 -12
  145. package/src/extensibility/extensions/types.ts +19 -26
  146. package/src/extensibility/extensions/wrapper.ts +3 -4
  147. package/src/extensibility/hooks/index.ts +1 -1
  148. package/src/extensibility/hooks/loader.ts +8 -9
  149. package/src/extensibility/hooks/runner.ts +7 -8
  150. package/src/extensibility/hooks/tool-wrapper.ts +0 -1
  151. package/src/extensibility/hooks/types.ts +10 -17
  152. package/src/extensibility/plugins/doctor.ts +3 -3
  153. package/src/extensibility/plugins/installer.ts +27 -27
  154. package/src/extensibility/plugins/loader.ts +59 -56
  155. package/src/extensibility/plugins/manager.ts +211 -171
  156. package/src/extensibility/plugins/parser.ts +1 -1
  157. package/src/extensibility/plugins/paths.ts +8 -8
  158. package/src/extensibility/skills.ts +63 -60
  159. package/src/extensibility/slash-commands.ts +10 -10
  160. package/src/index.ts +46 -46
  161. package/src/internal-urls/agent-protocol.ts +21 -11
  162. package/src/internal-urls/artifact-protocol.ts +17 -13
  163. package/src/internal-urls/router.ts +1 -2
  164. package/src/internal-urls/rule-protocol.ts +3 -4
  165. package/src/internal-urls/skill-protocol.ts +3 -4
  166. package/src/ipy/executor.ts +14 -10
  167. package/src/ipy/gateway-coordinator.ts +79 -90
  168. package/src/ipy/kernel.ts +32 -30
  169. package/src/ipy/modules.ts +13 -13
  170. package/src/lsp/client.ts +21 -10
  171. package/src/lsp/clients/biome-client.ts +1 -2
  172. package/src/lsp/clients/index.ts +3 -3
  173. package/src/lsp/clients/lsp-linter-client.ts +4 -5
  174. package/src/lsp/config.ts +15 -15
  175. package/src/lsp/edits.ts +4 -5
  176. package/src/lsp/index.ts +43 -44
  177. package/src/lsp/lspmux.ts +8 -8
  178. package/src/lsp/render.ts +10 -16
  179. package/src/lsp/utils.ts +3 -3
  180. package/src/main.ts +55 -34
  181. package/src/mcp/client.ts +2 -3
  182. package/src/mcp/config.ts +5 -6
  183. package/src/mcp/json-rpc.ts +0 -1
  184. package/src/mcp/loader.ts +3 -4
  185. package/src/mcp/manager.ts +17 -18
  186. package/src/mcp/tool-bridge.ts +4 -9
  187. package/src/mcp/tool-cache.ts +2 -3
  188. package/src/mcp/transports/http.ts +2 -4
  189. package/src/mcp/transports/stdio.ts +1 -2
  190. package/src/migrations.ts +60 -49
  191. package/src/modes/components/armin.ts +4 -5
  192. package/src/modes/components/assistant-message.ts +6 -6
  193. package/src/modes/components/bash-execution.ts +7 -8
  194. package/src/modes/components/bordered-loader.ts +3 -3
  195. package/src/modes/components/branch-summary-message.ts +3 -3
  196. package/src/modes/components/compaction-summary-message.ts +3 -3
  197. package/src/modes/components/countdown-timer.ts +0 -1
  198. package/src/modes/components/custom-message.ts +5 -5
  199. package/src/modes/components/diff.ts +1 -1
  200. package/src/modes/components/dynamic-border.ts +2 -2
  201. package/src/modes/components/extensions/extension-dashboard.ts +6 -7
  202. package/src/modes/components/extensions/extension-list.ts +2 -3
  203. package/src/modes/components/extensions/inspector-panel.ts +3 -4
  204. package/src/modes/components/extensions/state-manager.ts +25 -26
  205. package/src/modes/components/extensions/types.ts +1 -2
  206. package/src/modes/components/footer.ts +47 -43
  207. package/src/modes/components/history-search.ts +2 -2
  208. package/src/modes/components/hook-editor.ts +3 -4
  209. package/src/modes/components/hook-input.ts +2 -3
  210. package/src/modes/components/hook-message.ts +5 -5
  211. package/src/modes/components/hook-selector.ts +2 -3
  212. package/src/modes/components/keybinding-hints.ts +2 -3
  213. package/src/modes/components/login-dialog.ts +2 -2
  214. package/src/modes/components/model-selector.ts +12 -12
  215. package/src/modes/components/oauth-selector.ts +2 -2
  216. package/src/modes/components/plugin-settings.ts +20 -20
  217. package/src/modes/components/python-execution.ts +7 -8
  218. package/src/modes/components/queue-mode-selector.ts +3 -3
  219. package/src/modes/components/read-tool-group.ts +2 -2
  220. package/src/modes/components/session-selector.ts +4 -4
  221. package/src/modes/components/settings-defs.ts +77 -69
  222. package/src/modes/components/settings-selector.ts +16 -16
  223. package/src/modes/components/show-images-selector.ts +2 -2
  224. package/src/modes/components/status-line/segments.ts +4 -4
  225. package/src/modes/components/status-line/separators.ts +1 -1
  226. package/src/modes/components/status-line/types.ts +2 -2
  227. package/src/modes/components/status-line-segment-editor.ts +7 -8
  228. package/src/modes/components/status-line.ts +12 -12
  229. package/src/modes/components/theme-selector.ts +8 -7
  230. package/src/modes/components/thinking-selector.ts +4 -4
  231. package/src/modes/components/todo-display.ts +2 -2
  232. package/src/modes/components/todo-reminder.ts +4 -4
  233. package/src/modes/components/tool-execution.ts +11 -16
  234. package/src/modes/components/tree-selector.ts +11 -11
  235. package/src/modes/components/ttsr-notification.ts +5 -5
  236. package/src/modes/components/user-message-selector.ts +1 -1
  237. package/src/modes/components/user-message.ts +1 -1
  238. package/src/modes/components/visual-truncate.ts +0 -1
  239. package/src/modes/components/welcome.ts +4 -4
  240. package/src/modes/controllers/command-controller.ts +46 -47
  241. package/src/modes/controllers/event-controller.ts +16 -20
  242. package/src/modes/controllers/extension-ui-controller.ts +40 -46
  243. package/src/modes/controllers/input-controller.ts +17 -18
  244. package/src/modes/controllers/selector-controller.ts +103 -91
  245. package/src/modes/index.ts +3 -3
  246. package/src/modes/interactive-mode.ts +27 -29
  247. package/src/modes/print-mode.ts +12 -13
  248. package/src/modes/rpc/rpc-client.ts +7 -8
  249. package/src/modes/rpc/rpc-mode.ts +24 -25
  250. package/src/modes/rpc/rpc-types.ts +3 -4
  251. package/src/modes/theme/mermaid-cache.ts +2 -2
  252. package/src/modes/theme/theme.ts +128 -53
  253. package/src/modes/types.ts +10 -10
  254. package/src/modes/utils/ui-helpers.ts +17 -17
  255. package/src/patch/applicator.ts +18 -19
  256. package/src/patch/diff.ts +1 -2
  257. package/src/patch/fuzzy.ts +1 -2
  258. package/src/patch/index.ts +10 -11
  259. package/src/patch/normalize.ts +4 -4
  260. package/src/patch/normative.ts +1 -2
  261. package/src/patch/parser.ts +8 -9
  262. package/src/patch/shared.ts +12 -13
  263. package/src/sdk.ts +60 -63
  264. package/src/session/agent-session.ts +83 -84
  265. package/src/session/agent-storage.ts +11 -11
  266. package/src/session/artifacts.ts +8 -9
  267. package/src/session/auth-storage.ts +25 -29
  268. package/src/session/compaction/branch-summarization.ts +7 -10
  269. package/src/session/compaction/compaction.ts +8 -19
  270. package/src/session/compaction/utils.ts +6 -9
  271. package/src/session/history-storage.ts +10 -10
  272. package/src/session/messages.ts +4 -5
  273. package/src/session/session-manager.ts +76 -65
  274. package/src/session/session-storage.ts +57 -69
  275. package/src/session/storage-migration.ts +2 -3
  276. package/src/session/streaming-output.ts +2 -2
  277. package/src/ssh/connection-manager.ts +43 -50
  278. package/src/ssh/ssh-executor.ts +2 -2
  279. package/src/ssh/sshfs-mount.ts +11 -18
  280. package/src/system-prompt.ts +27 -34
  281. package/src/task/agents.ts +45 -30
  282. package/src/task/commands.ts +6 -7
  283. package/src/task/discovery.ts +39 -76
  284. package/src/task/executor.ts +14 -15
  285. package/src/task/index.ts +33 -36
  286. package/src/task/output-manager.ts +3 -4
  287. package/src/task/parallel.ts +0 -1
  288. package/src/task/render.ts +19 -20
  289. package/src/task/subprocess-tool-registry.ts +1 -2
  290. package/src/task/worker-protocol.ts +3 -3
  291. package/src/task/worker.ts +32 -38
  292. package/src/task/worktree.ts +19 -19
  293. package/src/tools/ask.ts +8 -9
  294. package/src/tools/bash-interceptor.ts +1 -5
  295. package/src/tools/bash.ts +19 -18
  296. package/src/tools/calculator.ts +12 -12
  297. package/src/tools/complete.ts +3 -4
  298. package/src/tools/context.ts +2 -2
  299. package/src/tools/fetch.ts +23 -26
  300. package/src/tools/find.ts +15 -16
  301. package/src/tools/gemini-image.ts +14 -14
  302. package/src/tools/grep.ts +27 -27
  303. package/src/tools/index.ts +78 -56
  304. package/src/tools/list-limit.ts +1 -1
  305. package/src/tools/ls.ts +7 -7
  306. package/src/tools/notebook.ts +5 -5
  307. package/src/tools/output-meta.ts +3 -4
  308. package/src/tools/output-utils.ts +1 -1
  309. package/src/tools/path-utils.ts +5 -5
  310. package/src/tools/python.ts +36 -37
  311. package/src/tools/read.ts +23 -23
  312. package/src/tools/render-utils.ts +8 -9
  313. package/src/tools/renderers.ts +6 -7
  314. package/src/tools/review.ts +8 -11
  315. package/src/tools/ssh.ts +31 -30
  316. package/src/tools/todo-write.ts +13 -13
  317. package/src/tools/tool-errors.ts +3 -3
  318. package/src/tools/tool-result.ts +3 -8
  319. package/src/tools/write.ts +11 -16
  320. package/src/tui/code-cell.ts +3 -9
  321. package/src/tui/file-list.ts +3 -4
  322. package/src/tui/output-block.ts +1 -2
  323. package/src/tui/status-line.ts +2 -3
  324. package/src/tui/tree-list.ts +2 -3
  325. package/src/tui/types.ts +1 -2
  326. package/src/tui/utils.ts +2 -3
  327. package/src/utils/changelog.ts +9 -10
  328. package/src/utils/clipboard.ts +11 -11
  329. package/src/utils/file-mentions.ts +4 -10
  330. package/src/utils/frontmatter.ts +6 -3
  331. package/src/utils/fuzzy.ts +2 -2
  332. package/src/utils/image-convert.ts +1 -1
  333. package/src/utils/image-resize.ts +1 -1
  334. package/src/utils/mime.ts +2 -2
  335. package/src/utils/shell-snapshot.ts +11 -13
  336. package/src/utils/shell.ts +4 -5
  337. package/src/utils/title-generator.ts +8 -9
  338. package/src/utils/tools-manager.ts +23 -23
  339. package/src/vendor/photon/index.js +1099 -1059
  340. package/src/vendor/photon/photon_rs_bg.wasm +0 -0
  341. package/src/web/scrapers/artifacthub.ts +1 -1
  342. package/src/web/scrapers/arxiv.ts +2 -2
  343. package/src/web/scrapers/bluesky.ts +2 -2
  344. package/src/web/scrapers/cheatsh.ts +1 -1
  345. package/src/web/scrapers/chocolatey.ts +2 -2
  346. package/src/web/scrapers/choosealicense.ts +5 -5
  347. package/src/web/scrapers/cisa-kev.ts +1 -1
  348. package/src/web/scrapers/crossref.ts +2 -2
  349. package/src/web/scrapers/devto.ts +3 -3
  350. package/src/web/scrapers/discogs.ts +3 -4
  351. package/src/web/scrapers/discourse.ts +1 -1
  352. package/src/web/scrapers/dockerhub.ts +1 -1
  353. package/src/web/scrapers/fdroid.ts +2 -2
  354. package/src/web/scrapers/firefox-addons.ts +3 -3
  355. package/src/web/scrapers/flathub.ts +1 -1
  356. package/src/web/scrapers/github.ts +3 -3
  357. package/src/web/scrapers/gitlab.ts +4 -4
  358. package/src/web/scrapers/hackernews.ts +2 -2
  359. package/src/web/scrapers/huggingface.ts +1 -1
  360. package/src/web/scrapers/iacr.ts +2 -2
  361. package/src/web/scrapers/index.ts +0 -1
  362. package/src/web/scrapers/jetbrains-marketplace.ts +1 -1
  363. package/src/web/scrapers/lemmy.ts +2 -2
  364. package/src/web/scrapers/maven.ts +2 -2
  365. package/src/web/scrapers/mdn.ts +2 -4
  366. package/src/web/scrapers/metacpan.ts +2 -2
  367. package/src/web/scrapers/musicbrainz.ts +1 -2
  368. package/src/web/scrapers/npm.ts +1 -1
  369. package/src/web/scrapers/nuget.ts +2 -2
  370. package/src/web/scrapers/nvd.ts +3 -3
  371. package/src/web/scrapers/ollama.ts +7 -9
  372. package/src/web/scrapers/opencorporates.ts +2 -2
  373. package/src/web/scrapers/openlibrary.ts +6 -6
  374. package/src/web/scrapers/orcid.ts +0 -1
  375. package/src/web/scrapers/osv.ts +2 -2
  376. package/src/web/scrapers/packagist.ts +1 -1
  377. package/src/web/scrapers/pubmed.ts +1 -2
  378. package/src/web/scrapers/rawg.ts +2 -2
  379. package/src/web/scrapers/readthedocs.ts +1 -2
  380. package/src/web/scrapers/repology.ts +2 -2
  381. package/src/web/scrapers/rfc.ts +1 -1
  382. package/src/web/scrapers/searchcode.ts +2 -2
  383. package/src/web/scrapers/semantic-scholar.ts +1 -1
  384. package/src/web/scrapers/snapcraft.ts +2 -2
  385. package/src/web/scrapers/sourcegraph.ts +1 -1
  386. package/src/web/scrapers/spdx.ts +3 -3
  387. package/src/web/scrapers/spotify.ts +0 -1
  388. package/src/web/scrapers/twitter.ts +1 -1
  389. package/src/web/scrapers/types.ts +1 -2
  390. package/src/web/scrapers/utils.ts +5 -5
  391. package/src/web/scrapers/wikidata.ts +3 -3
  392. package/src/web/scrapers/youtube.ts +9 -14
  393. package/src/web/search/auth.ts +4 -9
  394. package/src/web/search/index.ts +11 -21
  395. package/src/web/search/providers/anthropic.ts +3 -9
  396. package/src/web/search/providers/exa.ts +6 -10
  397. package/src/web/search/providers/perplexity.ts +5 -5
  398. package/src/web/search/render.ts +16 -18
  399. package/scripts/generate-wasm-b64.ts +0 -24
  400. package/src/commit/map-reduce/.map-phase.ts.kate-swp +0 -0
  401. package/src/task/.executor.ts.kate-swp +0 -0
  402. package/src/vendor/photon/photon_rs_bg.wasm.b64.js +0 -1
@@ -11,13 +11,11 @@
11
11
  *
12
12
  * Agent files use markdown with YAML frontmatter.
13
13
  */
14
-
15
- import * as fs from "node:fs";
14
+ import * as fs from "node:fs/promises";
16
15
  import * as path from "node:path";
17
- import { findAllNearestProjectConfigDirs, getConfigDirs } from "@oh-my-pi/pi-coding-agent/config";
18
- import { parseAgentFields } from "@oh-my-pi/pi-coding-agent/discovery/helpers";
19
- import { parseFrontmatter } from "@oh-my-pi/pi-coding-agent/utils/frontmatter";
20
- import { loadBundledAgents } from "./agents";
16
+ import { logger } from "@oh-my-pi/pi-utils";
17
+ import { findAllNearestProjectConfigDirs, getConfigDirs } from "../config";
18
+ import { loadBundledAgents, parseAgent } from "./agents";
21
19
  import type { AgentDefinition, AgentSource } from "./types";
22
20
 
23
21
  /** Result of agent discovery */
@@ -29,55 +27,23 @@ export interface DiscoveryResult {
29
27
  /**
30
28
  * Load agents from a directory.
31
29
  */
32
- function loadAgentsFromDir(dir: string, source: AgentSource): AgentDefinition[] {
33
- const agents: AgentDefinition[] = [];
34
-
35
- if (!fs.existsSync(dir)) {
36
- return agents;
37
- }
38
-
39
- let entries: fs.Dirent[];
40
- try {
41
- entries = fs.readdirSync(dir, { withFileTypes: true });
42
- } catch {
43
- return agents;
44
- }
45
-
46
- for (const entry of entries) {
47
- if (!entry.name.endsWith(".md")) continue;
48
-
49
- const filePath = path.resolve(dir, entry.name);
50
-
51
- // Handle both regular files and symlinks
52
- try {
53
- if (!fs.statSync(filePath).isFile()) continue;
54
- } catch {
55
- continue;
56
- }
57
-
58
- let content: string;
59
- try {
60
- content = fs.readFileSync(filePath, "utf-8");
61
- } catch {
62
- continue;
63
- }
64
-
65
- const { frontmatter, body } = parseFrontmatter(content, { source: filePath });
66
- const fields = parseAgentFields(frontmatter);
67
-
68
- if (!fields) {
69
- continue;
70
- }
71
-
72
- agents.push({
73
- ...fields,
74
- systemPrompt: body,
75
- source,
76
- filePath,
30
+ async function loadAgentsFromDir(dir: string, source: AgentSource): Promise<AgentDefinition[]> {
31
+ const entries = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
32
+ const files = entries
33
+ .filter(entry => (entry.isFile() || entry.isSymbolicLink()) && entry.name.endsWith(".md"))
34
+ .sort((a, b) => a.name.localeCompare(b.name))
35
+ .map(file => {
36
+ const filePath = path.join(dir, file.name);
37
+ return fs
38
+ .readFile(filePath, "utf-8")
39
+ .then(content => parseAgent(filePath, content, source, "warn"))
40
+ .catch(error => {
41
+ logger.warn("Failed to read agent file", { filePath, error });
42
+ return null;
43
+ });
77
44
  });
78
- }
79
45
 
80
- return agents;
46
+ return (await Promise.all(files)).filter(Boolean) as AgentDefinition[];
81
47
  }
82
48
 
83
49
  /**
@@ -89,62 +55,59 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentDefinition[]
89
55
  */
90
56
  export async function discoverAgents(cwd: string): Promise<DiscoveryResult> {
91
57
  const resolvedCwd = path.resolve(cwd);
92
- const agentSources = Array.from(new Set(getConfigDirs("", { project: false }).map((entry) => entry.source)));
58
+ const agentSources = Array.from(new Set(getConfigDirs("", { project: false }).map(entry => entry.source)));
93
59
 
94
60
  // Get user directories (priority order: .omp, .pi, .claude, ...)
95
61
  const userDirs = getConfigDirs("agents", { project: false })
96
- .filter((entry) => agentSources.includes(entry.source))
97
- .map((entry) => ({
62
+ .filter(entry => agentSources.includes(entry.source))
63
+ .map(entry => ({
98
64
  ...entry,
99
65
  path: path.resolve(entry.path),
100
66
  }));
101
67
 
102
68
  // Get project directories by walking up from cwd (priority order)
103
69
  const projectDirs = (await findAllNearestProjectConfigDirs("agents", resolvedCwd))
104
- .filter((entry) => agentSources.includes(entry.source))
105
- .map((entry) => ({
70
+ .filter(entry => agentSources.includes(entry.source))
71
+ .map(entry => ({
106
72
  ...entry,
107
73
  path: path.resolve(entry.path),
108
74
  }));
109
75
 
110
76
  const orderedSources = agentSources.filter(
111
- (source) =>
112
- userDirs.some((entry) => entry.source === source) || projectDirs.some((entry) => entry.source === source),
77
+ source => userDirs.some(entry => entry.source === source) || projectDirs.some(entry => entry.source === source),
113
78
  );
114
79
 
115
80
  const orderedDirs: Array<{ dir: string; source: AgentSource }> = [];
116
81
  for (const source of orderedSources) {
117
- const project = projectDirs.find((entry) => entry.source === source);
82
+ const project = projectDirs.find(entry => entry.source === source);
118
83
  if (project) orderedDirs.push({ dir: project.path, source: "project" });
119
- const user = userDirs.find((entry) => entry.source === source);
84
+ const user = userDirs.find(entry => entry.source === source);
120
85
  if (user) orderedDirs.push({ dir: user.path, source: "user" });
121
86
  }
122
87
 
123
- const agents: AgentDefinition[] = [];
124
88
  const seen = new Set<string>();
125
-
126
- for (const { dir, source } of orderedDirs) {
127
- for (const agent of loadAgentsFromDir(dir, source)) {
128
- if (seen.has(agent.name)) continue;
129
- agents.push(agent);
89
+ const loadedAgents = (await Promise.all(orderedDirs.map(({ dir, source }) => loadAgentsFromDir(dir, source))))
90
+ .flat()
91
+ .filter(agent => {
92
+ if (seen.has(agent.name)) return false;
130
93
  seen.add(agent.name);
131
- }
132
- }
94
+ return true;
95
+ });
133
96
 
134
- for (const agent of loadBundledAgents()) {
135
- if (seen.has(agent.name)) continue;
136
- agents.push(agent);
97
+ const bundledAgents = loadBundledAgents().filter(agent => {
98
+ if (seen.has(agent.name)) return false;
137
99
  seen.add(agent.name);
138
- }
100
+ return true;
101
+ });
139
102
 
140
103
  const projectAgentsDir = projectDirs.length > 0 ? projectDirs[0].path : null;
141
104
 
142
- return { agents, projectAgentsDir };
105
+ return { agents: [...loadedAgents, ...bundledAgents], projectAgentsDir };
143
106
  }
144
107
 
145
108
  /**
146
109
  * Get an agent by name from discovered agents.
147
110
  */
148
111
  export function getAgent(agents: AgentDefinition[], name: string): AgentDefinition | undefined {
149
- return agents.find((a) => a.name === name);
112
+ return agents.find(a => a.name === name);
150
113
  }
@@ -3,20 +3,19 @@
3
3
  *
4
4
  * Runs each subagent in a Bun Worker and forwards AgentEvents for progress tracking.
5
5
  */
6
-
7
6
  import path from "node:path";
8
7
  import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
9
- import type { ModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry";
10
- import { formatModelString, parseModelPattern } from "@oh-my-pi/pi-coding-agent/config/model-resolver";
11
- import { checkPythonKernelAvailability } from "@oh-my-pi/pi-coding-agent/ipy/kernel";
12
- import { LspTool } from "@oh-my-pi/pi-coding-agent/lsp";
13
- import type { LspParams } from "@oh-my-pi/pi-coding-agent/lsp/types";
14
- import { callTool } from "@oh-my-pi/pi-coding-agent/mcp/client";
15
- import type { MCPManager } from "@oh-my-pi/pi-coding-agent/mcp/manager";
16
- import type { AuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage";
17
- import { PythonTool, type PythonToolParams } from "@oh-my-pi/pi-coding-agent/tools/python";
18
- import type { EventBus } from "@oh-my-pi/pi-coding-agent/utils/event-bus";
19
8
  import type { ToolSession } from "..";
9
+ import type { ModelRegistry } from "../config/model-registry";
10
+ import { formatModelString, parseModelPattern } from "../config/model-resolver";
11
+ import { checkPythonKernelAvailability } from "../ipy/kernel";
12
+ import { LspTool } from "../lsp";
13
+ import type { LspParams } from "../lsp/types";
14
+ import { callTool } from "../mcp/client";
15
+ import type { MCPManager } from "../mcp/manager";
16
+ import type { AuthStorage } from "../session/auth-storage";
17
+ import { PythonTool, type PythonToolParams } from "../tools/python";
18
+ import type { EventBus } from "../utils/event-bus";
20
19
  import { subprocessToolRegistry } from "./subprocess-tool-registry";
21
20
  import {
22
21
  type AgentDefinition,
@@ -171,7 +170,7 @@ function getUsageTokens(usage: unknown): number {
171
170
  * falling back to empty strings if not.
172
171
  */
173
172
  function extractMCPToolMetadata(mcpManager: MCPManager): MCPToolMetadata[] {
174
- return mcpManager.getTools().map((tool) => {
173
+ return mcpManager.getTools().map(tool => {
175
174
  // MCPTool and DeferredMCPTool have these properties
176
175
  const mcpTool = tool as { mcpToolName?: string; mcpServerName?: string };
177
176
  return {
@@ -264,7 +263,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
264
263
 
265
264
  const pythonToolMode = options.settingsManager?.getPythonToolMode?.() ?? "ipy-only";
266
265
  if (toolNames?.includes("exec")) {
267
- const expanded = toolNames.filter((name) => name !== "exec");
266
+ const expanded = toolNames.filter(name => name !== "exec");
268
267
  if (pythonToolMode === "bash-only") {
269
268
  expanded.push("bash");
270
269
  } else if (pythonToolMode === "ipy-only") {
@@ -706,11 +705,11 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
706
705
  message: string;
707
706
  }
708
707
 
709
- const done = await new Promise<Extract<SubagentWorkerResponse, { type: "done" }>>((resolve) => {
708
+ const done = await new Promise<Extract<SubagentWorkerResponse, { type: "done" }>>(resolve => {
710
709
  const cleanup = () => {
711
710
  listenerController.abort();
712
711
  };
713
- finalize = (message) => {
712
+ finalize = message => {
714
713
  if (resolved) return;
715
714
  resolved = true;
716
715
  cleanup();
package/src/task/index.ts CHANGED
@@ -12,22 +12,23 @@
12
12
  * - Progress tracking via JSON events
13
13
  * - Session artifacts for debugging
14
14
  */
15
-
16
- import { mkdir, rm, stat } from "node:fs/promises";
17
- import { tmpdir } from "node:os";
15
+ import * as fs from "node:fs/promises";
16
+ import * as os from "node:os";
18
17
  import path from "node:path";
19
18
  import type { AgentTool, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
20
19
  import type { Usage } from "@oh-my-pi/pi-ai";
21
- import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
22
- import type { Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
23
- import taskDescriptionTemplate from "@oh-my-pi/pi-coding-agent/prompts/tools/task.md" with { type: "text" };
24
- import { AgentOutputManager } from "@oh-my-pi/pi-coding-agent/task/output-manager";
25
- import { formatDuration } from "@oh-my-pi/pi-coding-agent/tools/render-utils";
26
20
  import { $ } from "bun";
27
21
  import { nanoid } from "nanoid";
28
22
  import type { ToolSession } from "..";
23
+ import { renderPromptTemplate } from "../config/prompt-templates";
24
+ import type { Theme } from "../modes/theme/theme";
25
+ import taskDescriptionTemplate from "../prompts/tools/task.md" with { type: "text" };
26
+ import { formatDuration } from "../tools/render-utils";
27
+ // Import review tools for side effects (registers subagent tool handlers)
28
+ import "../tools/review";
29
29
  import { discoverAgents, getAgent } from "./discovery";
30
30
  import { runSubprocess } from "./executor";
31
+ import { AgentOutputManager } from "./output-manager";
31
32
  import { mapWithConcurrencyLimit } from "./parallel";
32
33
  import { renderCall, renderResult } from "./render";
33
34
  import { renderTemplate } from "./template";
@@ -49,9 +50,6 @@ import {
49
50
  getRepoRoot,
50
51
  } from "./worktree";
51
52
 
52
- // Import review tools for side effects (registers subagent tool handlers)
53
- import "../tools/review";
54
-
55
53
  /** Format byte count for display */
56
54
  function formatBytes(bytes: number): string {
57
55
  if (bytes < 1024) return `${bytes}B`;
@@ -174,7 +172,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
174
172
  // Validate agent exists
175
173
  const agent = getAgent(agents, agentName);
176
174
  if (!agent) {
177
- const available = agents.map((a) => a.name).join(", ") || "none";
175
+ const available = agents.map(a => a.name).join(", ") || "none";
178
176
  return {
179
177
  content: [
180
178
  {
@@ -268,7 +266,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
268
266
  problems.push(`Missing task ids at indexes: ${missingTaskIndexes.join(", ")}`);
269
267
  }
270
268
  if (duplicateIds.length > 0) {
271
- const details = duplicateIds.map((entry) => `${entry.id} (indexes ${entry.indexes.join(", ")})`).join("; ");
269
+ const details = duplicateIds.map(entry => `${entry.id} (indexes ${entry.indexes.join(", ")})`).join("; ");
272
270
  problems.push(`Duplicate task ids detected (case-insensitive): ${details}`);
273
271
  }
274
272
  return {
@@ -308,9 +306,8 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
308
306
  // Derive artifacts directory
309
307
  const sessionFile = this.session.getSessionFile();
310
308
  const artifactsDir = sessionFile ? sessionFile.slice(0, -6) : null;
311
- const tempArtifactsDir = artifactsDir ? null : path.join(tmpdir(), `omp-task-${nanoid()}`);
309
+ const tempArtifactsDir = artifactsDir ? null : path.join(os.tmpdir(), `omp-task-${nanoid()}`);
312
310
  const effectiveArtifactsDir = artifactsDir || tempArtifactsDir!;
313
- await mkdir(effectiveArtifactsDir, { recursive: true });
314
311
 
315
312
  // Initialize progress tracking
316
313
  const progressMap = new Map<number, AgentProgress>();
@@ -349,7 +346,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
349
346
 
350
347
  // Check spawn restrictions from parent
351
348
  const parentSpawns = this.session.getSessionSpawns() ?? "*";
352
- const allowedSpawns = parentSpawns.split(",").map((s) => s.trim());
349
+ const allowedSpawns = parentSpawns.split(",").map(s => s.trim());
353
350
  const isSpawnAllowed = (): boolean => {
354
351
  if (parentSpawns === "") return false; // Empty = deny all
355
352
  if (parentSpawns === "*") return true; // Wildcard = allow all
@@ -372,11 +369,11 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
372
369
  // Allocate unique IDs across the session to prevent artifact collisions
373
370
  const outputManager =
374
371
  this.session.agentOutputManager ?? new AgentOutputManager(this.session.getArtifactsDir ?? (() => null));
375
- const uniqueIds = await outputManager.allocateBatch(tasks.map((t) => t.id));
372
+ const uniqueIds = await outputManager.allocateBatch(tasks.map(t => t.id));
376
373
  const tasksWithUniqueIds = tasks.map((t, i) => ({ ...t, id: uniqueIds[i] }));
377
374
 
378
375
  // Build full prompts with context prepended
379
- const tasksWithContext = tasksWithUniqueIds.map((t) => renderTemplate(context, t));
376
+ const tasksWithContext = tasksWithUniqueIds.map(t => renderTemplate(context, t));
380
377
 
381
378
  // Initialize progress for all tasks
382
379
  for (let i = 0; i < tasksWithContext.length; i++) {
@@ -419,7 +416,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
419
416
  enableLsp: false,
420
417
  signal,
421
418
  eventBus: undefined,
422
- onProgress: (progress) => {
419
+ onProgress: progress => {
423
420
  progressMap.set(index, {
424
421
  ...structuredClone(progress),
425
422
  args: tasksWithContext[index]?.args,
@@ -459,7 +456,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
459
456
  enableLsp: false,
460
457
  signal,
461
458
  eventBus: undefined,
462
- onProgress: (progress) => {
459
+ onProgress: progress => {
463
460
  progressMap.set(index, {
464
461
  ...structuredClone(progress),
465
462
  args: tasksWithContext[index]?.args,
@@ -565,29 +562,29 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
565
562
  let patchApplySummary = "";
566
563
  let patchesApplied: boolean | null = null;
567
564
  if (isIsolated) {
568
- const patchesInOrder = results.map((result) => result.patchPath).filter(Boolean) as string[];
569
- const missingPatch = results.some((result) => !result.patchPath);
565
+ const patchesInOrder = results.map(result => result.patchPath).filter(Boolean) as string[];
566
+ const missingPatch = results.some(result => !result.patchPath);
570
567
  if (!repoRoot || missingPatch) {
571
568
  patchesApplied = false;
572
569
  } else {
573
570
  const patchStats = await Promise.all(
574
- patchesInOrder.map(async (patchPath) => ({
571
+ patchesInOrder.map(async patchPath => ({
575
572
  patchPath,
576
- size: (await stat(patchPath)).size,
573
+ size: (await fs.stat(patchPath)).size,
577
574
  })),
578
575
  );
579
- const nonEmptyPatches = patchStats.filter((patch) => patch.size > 0).map((patch) => patch.patchPath);
576
+ const nonEmptyPatches = patchStats.filter(patch => patch.size > 0).map(patch => patch.patchPath);
580
577
  if (nonEmptyPatches.length === 0) {
581
578
  patchesApplied = true;
582
579
  } else {
583
580
  const patchTexts = await Promise.all(
584
- nonEmptyPatches.map(async (patchPath) => Bun.file(patchPath).text()),
581
+ nonEmptyPatches.map(async patchPath => Bun.file(patchPath).text()),
585
582
  );
586
- const combinedPatch = patchTexts.map((text) => (text.endsWith("\n") ? text : `${text}\n`)).join("");
583
+ const combinedPatch = patchTexts.map(text => (text.endsWith("\n") ? text : `${text}\n`)).join("");
587
584
  if (!combinedPatch.trim()) {
588
585
  patchesApplied = true;
589
586
  } else {
590
- const combinedPatchPath = path.join(tmpdir(), `omp-task-combined-${nanoid()}.patch`);
587
+ const combinedPatchPath = path.join(os.tmpdir(), `omp-task-combined-${nanoid()}.patch`);
591
588
  try {
592
589
  await Bun.write(combinedPatchPath, combinedPatch);
593
590
  const checkResult = await $`git apply --check --binary ${combinedPatchPath}`
@@ -604,7 +601,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
604
601
  patchesApplied = applyResult.exitCode === 0;
605
602
  }
606
603
  } finally {
607
- await rm(combinedPatchPath, { force: true });
604
+ await fs.rm(combinedPatchPath, { force: true });
608
605
  }
609
606
  }
610
607
  }
@@ -617,18 +614,18 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
617
614
  "<system-notification>Patches were not applied and must be handled manually.</system-notification>";
618
615
  const patchList =
619
616
  patchPaths.length > 0
620
- ? `\n\nPatch artifacts:\n${patchPaths.map((patch) => `- ${patch}`).join("\n")}`
617
+ ? `\n\nPatch artifacts:\n${patchPaths.map(patch => `- ${patch}`).join("\n")}`
621
618
  : "";
622
619
  patchApplySummary = `\n\n${notification}${patchList}`;
623
620
  }
624
621
  }
625
622
 
626
623
  // Build final output - match plugin format
627
- const successCount = results.filter((r) => r.exitCode === 0).length;
628
- const cancelledCount = results.filter((r) => r.aborted).length;
624
+ const successCount = results.filter(r => r.exitCode === 0).length;
625
+ const cancelledCount = results.filter(r => r.aborted).length;
629
626
  const totalDuration = Date.now() - startTime;
630
627
 
631
- const summaries = results.map((r) => {
628
+ const summaries = results.map(r => {
632
629
  const status = r.aborted ? "cancelled" : r.exitCode === 0 ? "completed" : `failed (exit ${r.exitCode})`;
633
630
  const output = r.output.trim() || r.stderr.trim() || "(no output)";
634
631
  const preview = output.split("\n").slice(0, 5).join("\n");
@@ -638,10 +635,10 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
638
635
  return `[${r.agent}] ${status}${meta} ${r.id}\n${preview}`;
639
636
  });
640
637
 
641
- const outputIds = results.filter((r) => !r.aborted || r.output.trim()).map((r) => r.id);
638
+ const outputIds = results.filter(r => !r.aborted || r.output.trim()).map(r => r.id);
642
639
  const outputHint =
643
640
  outputIds.length > 0
644
- ? `\n\nUse read with agent:// for full logs: ${outputIds.map((id) => `agent://${id}`).join(", ")}`
641
+ ? `\n\nUse read with agent:// for full logs: ${outputIds.map(id => `agent://${id}`).join(", ")}`
645
642
  : "";
646
643
  const schemaNote = schemaOverridden
647
644
  ? `\n\nNote: Agent '${agentName}' has a fixed output schema; your 'output' parameter was ignored.\nRequired schema: ${JSON.stringify(agent.output)}`
@@ -655,7 +652,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
655
652
  const shouldCleanupTempArtifacts =
656
653
  tempArtifactsDir && (!isIsolated || patchesApplied === true || patchesApplied === null);
657
654
  if (shouldCleanupTempArtifacts) {
658
- await rm(tempArtifactsDir, { recursive: true, force: true });
655
+ await fs.rm(tempArtifactsDir, { recursive: true, force: true });
659
656
  }
660
657
 
661
658
  return {
@@ -6,8 +6,7 @@
6
6
  *
7
7
  * This enables reliable agent:// URL resolution and prevents artifact collisions.
8
8
  */
9
-
10
- import { readdir } from "node:fs/promises";
9
+ import * as fs from "node:fs/promises";
11
10
 
12
11
  /**
13
12
  * Manages agent output ID allocation to ensure uniqueness.
@@ -37,7 +36,7 @@ export class AgentOutputManager {
37
36
 
38
37
  let files: string[];
39
38
  try {
40
- files = await readdir(dir);
39
+ files = await fs.readdir(dir);
41
40
  } catch {
42
41
  return; // Directory doesn't exist yet
43
42
  }
@@ -73,7 +72,7 @@ export class AgentOutputManager {
73
72
  */
74
73
  async allocateBatch(ids: string[]): Promise<string[]> {
75
74
  await this.#ensureInitialized();
76
- return ids.map((id) => `${this.#nextId++}-${id}`);
75
+ return ids.map(id => `${this.#nextId++}-${id}`);
77
76
  }
78
77
 
79
78
  /**
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Parallel execution with concurrency control.
3
3
  */
4
-
5
4
  import { MAX_CONCURRENCY } from "./types";
6
5
 
7
6
  /** Result of parallel execution */
@@ -4,10 +4,11 @@
4
4
  * Provides renderCall and renderResult functions for displaying
5
5
  * task execution in the terminal UI.
6
6
  */
7
-
8
7
  import path from "node:path";
9
- import type { RenderResultOptions } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
10
- import type { Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
8
+ import type { Component } from "@oh-my-pi/pi-tui";
9
+ import { Container, Text } from "@oh-my-pi/pi-tui";
10
+ import type { RenderResultOptions } from "../extensibility/custom-tools/types";
11
+ import type { Theme } from "../modes/theme/theme";
11
12
  import {
12
13
  formatBadge,
13
14
  formatDuration,
@@ -15,17 +16,15 @@ import {
15
16
  formatStatusIcon,
16
17
  formatTokens,
17
18
  truncate,
18
- } from "@oh-my-pi/pi-coding-agent/tools/render-utils";
19
+ } from "../tools/render-utils";
19
20
  import {
20
21
  type FindingPriority,
21
22
  getPriorityInfo,
22
23
  PRIORITY_LABELS,
23
24
  type ReportFindingDetails,
24
25
  type SubmitReviewDetails,
25
- } from "@oh-my-pi/pi-coding-agent/tools/review";
26
- import { renderStatusLine } from "@oh-my-pi/pi-coding-agent/tui";
27
- import type { Component } from "@oh-my-pi/pi-tui";
28
- import { Container, Text } from "@oh-my-pi/pi-tui";
26
+ } from "../tools/review";
27
+ import { renderStatusLine } from "../tui";
29
28
  import { subprocessToolRegistry } from "./subprocess-tool-registry";
30
29
  import type { AgentProgress, SingleResult, TaskParams, TaskToolDetails } from "./types";
31
30
 
@@ -79,7 +78,7 @@ function formatJsonScalar(value: unknown, theme: Theme): string {
79
78
  }
80
79
 
81
80
  function buildTreePrefix(ancestors: boolean[], theme: Theme): string {
82
- return ancestors.map((hasNext) => (hasNext ? `${theme.tree.vertical} ` : " ")).join("");
81
+ return ancestors.map(hasNext => (hasNext ? `${theme.tree.vertical} ` : " ")).join("");
83
82
  }
84
83
 
85
84
  function renderJsonTreeLines(
@@ -295,7 +294,7 @@ function formatArgsInline(args: Record<string, string>, theme: Theme): string {
295
294
 
296
295
  /** Convert snake_case or kebab-case to Title Case */
297
296
  function humanizeKey(key: string): string {
298
- return key.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
297
+ return key.replace(/[-_]/g, " ").replace(/\b\w/g, c => c.toUpperCase());
299
298
  }
300
299
 
301
300
  function formatScalarInline(value: unknown, maxLen: number, theme: Theme): string {
@@ -512,8 +511,8 @@ function renderAgentProgress(
512
511
  const completeData = progress.extractedToolData.complete as Array<{ data: unknown }> | undefined;
513
512
  const reportFindingData = progress.extractedToolData.report_finding as ReportFindingDetails[] | undefined;
514
513
  const reviewData = completeData
515
- ?.map((c) => c.data as SubmitReviewDetails)
516
- .filter((d) => d && typeof d === "object" && "overall_correctness" in d);
514
+ ?.map(c => c.data as SubmitReviewDetails)
515
+ .filter(d => d && typeof d === "object" && "overall_correctness" in d);
517
516
  if (reviewData && reviewData.length > 0) {
518
517
  const summary = reviewData[reviewData.length - 1];
519
518
  const findings = reportFindingData ?? [];
@@ -697,8 +696,8 @@ function renderAgentResult(result: SingleResult, isLast: boolean, expanded: bool
697
696
 
698
697
  // Extract review verdict from complete tool's data field if it matches SubmitReviewDetails
699
698
  const reviewData = completeData
700
- ?.map((c) => c.data as SubmitReviewDetails)
701
- .filter((d) => d && typeof d === "object" && "overall_correctness" in d);
699
+ ?.map(c => c.data as SubmitReviewDetails)
700
+ .filter(d => d && typeof d === "object" && "overall_correctness" in d);
702
701
  const submitReviewData = reviewData && reviewData.length > 0 ? reviewData : undefined;
703
702
 
704
703
  if (submitReviewData && submitReviewData.length > 0) {
@@ -775,12 +774,12 @@ export function renderResult(
775
774
  theme: Theme,
776
775
  ): Component {
777
776
  const { expanded, isPartial, spinnerFrame } = options;
778
- const fallbackText = result.content.find((c) => c.type === "text")?.text ?? "";
777
+ const fallbackText = result.content.find(c => c.type === "text")?.text ?? "";
779
778
  const details = result.details;
780
779
 
781
780
  if (!details) {
782
781
  // Fallback to simple text
783
- const text = result.content.find((c) => c.type === "text")?.text || "";
782
+ const text = result.content.find(c => c.type === "text")?.text || "";
784
783
  return new Text(theme.fg("dim", truncate(text, 100, theme.format.ellipsis)), 0, 0);
785
784
  }
786
785
 
@@ -800,8 +799,8 @@ export function renderResult(
800
799
  });
801
800
 
802
801
  // Summary line
803
- const abortedCount = details.results.filter((r) => r.aborted).length;
804
- const successCount = details.results.filter((r) => !r.aborted && r.exitCode === 0).length;
802
+ const abortedCount = details.results.filter(r => r.aborted).length;
803
+ const successCount = details.results.filter(r => !r.aborted && r.exitCode === 0).length;
805
804
  const failCount = details.results.length - successCount - abortedCount;
806
805
  let summary = `${theme.fg("dim", "Total:")} `;
807
806
  if (abortedCount > 0) {
@@ -829,7 +828,7 @@ export function renderResult(
829
828
  if (fallbackText.trim()) {
830
829
  const summaryLines = fallbackText.split("\n");
831
830
  const markerIndex = summaryLines.findIndex(
832
- (line) => line.includes("<system-notification>") || line.startsWith("Applied patches:"),
831
+ line => line.includes("<system-notification>") || line.startsWith("Applied patches:"),
833
832
  );
834
833
  if (markerIndex >= 0) {
835
834
  const extra = summaryLines.slice(markerIndex);
@@ -840,7 +839,7 @@ export function renderResult(
840
839
  }
841
840
  }
842
841
 
843
- const indented = lines.map((line) => (line.length > 0 ? ` ${line}` : ""));
842
+ const indented = lines.map(line => (line.length > 0 ? ` ${line}` : ""));
844
843
  return new Text(indented.join("\n"), 0, 0);
845
844
  }
846
845
 
@@ -6,9 +6,8 @@
6
6
  * - Trigger subprocess termination on completion
7
7
  * - Provide custom rendering for realtime/final display
8
8
  */
9
-
10
- import type { Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
11
9
  import type { Component } from "@oh-my-pi/pi-tui";
10
+ import type { Theme } from "../modes/theme/theme";
12
11
 
13
12
  /** Event from subprocess tool execution (parsed from JSONL) */
14
13
  export interface SubprocessToolEvent {
@@ -1,7 +1,7 @@
1
1
  import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
- import type { SerializedModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry";
3
- import type { Settings } from "@oh-my-pi/pi-coding-agent/config/settings-manager";
4
- import type { SerializedAuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage";
2
+ import type { SerializedModelRegistry } from "../config/model-registry";
3
+ import type { Settings } from "../config/settings-manager";
4
+ import type { SerializedAuthStorage } from "../session/auth-storage";
5
5
 
6
6
  /**
7
7
  * MCP tool metadata passed from parent to worker for proxy tool creation.