@selesai/code 0.13.16 → 0.13.18

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 (467) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +2 -14
  3. package/dist/bun/cli.d.ts +3 -1
  4. package/dist/bun/cli.js +3 -9
  5. package/dist/bun/{register-bedrock.js → runtime-setup.js} +5 -0
  6. package/dist/bun/sandbox-env-setup.d.ts +1 -0
  7. package/dist/bun/sandbox-env-setup.js +3 -0
  8. package/dist/cli/auth-command.d.ts +23 -0
  9. package/dist/cli/auth-command.js +102 -0
  10. package/dist/cli/config-selector.js +2 -1
  11. package/dist/cli/setup.d.ts +1 -0
  12. package/dist/cli/setup.js +11 -0
  13. package/dist/cli.js +2 -14
  14. package/dist/config.d.ts +3 -2
  15. package/dist/config.js +9 -4
  16. package/dist/core/agent-session-runtime.js +15 -7
  17. package/dist/core/agent-session.d.ts +2 -6
  18. package/dist/core/agent-session.js +15 -4
  19. package/dist/core/compaction/branch-summarization.d.ts +1 -1
  20. package/dist/core/compaction/branch-summarization.js +2 -1
  21. package/dist/core/extensions/loader.js +3 -0
  22. package/dist/core/extensions/types.d.ts +16 -2
  23. package/dist/core/http-dispatcher.js +2 -0
  24. package/dist/core/keybindings.d.ts +5 -0
  25. package/dist/core/keybindings.js +4 -0
  26. package/dist/core/messages.d.ts +1 -1
  27. package/dist/core/model-config.d.ts +15 -0
  28. package/dist/core/model-config.js +3 -0
  29. package/dist/core/model-runtime.d.ts +1 -0
  30. package/dist/core/model-runtime.js +5 -2
  31. package/dist/core/provider-composer.js +8 -2
  32. package/dist/core/session-export.d.ts +3 -0
  33. package/dist/core/session-export.js +31 -0
  34. package/dist/core/session-manager.d.ts +3 -2
  35. package/dist/core/session-manager.js +40 -13
  36. package/dist/core/skills.d.ts +1 -1
  37. package/dist/core/skills.js +4 -2
  38. package/dist/core/system-prompt.js +10 -10
  39. package/dist/core/tools/bash.js +3 -117
  40. package/dist/core/tools/edit.d.ts +1 -12
  41. package/dist/core/tools/edit.js +5 -163
  42. package/dist/core/tools/find.js +4 -55
  43. package/dist/core/tools/grep.js +4 -60
  44. package/dist/core/tools/ls.js +4 -49
  45. package/dist/core/tools/read.d.ts +4 -0
  46. package/dist/core/tools/read.js +10 -122
  47. package/dist/core/tools/renderers/bash.d.ts +11 -0
  48. package/dist/core/tools/renderers/bash.js +129 -0
  49. package/dist/core/tools/renderers/edit.d.ts +22 -0
  50. package/dist/core/tools/renderers/edit.js +166 -0
  51. package/dist/core/tools/renderers/find.d.ts +9 -0
  52. package/dist/core/tools/renderers/find.js +63 -0
  53. package/dist/core/tools/renderers/grep.d.ts +9 -0
  54. package/dist/core/tools/renderers/grep.js +68 -0
  55. package/dist/core/tools/renderers/index.d.ts +27 -0
  56. package/dist/core/tools/renderers/index.js +46 -0
  57. package/dist/core/tools/renderers/ls.d.ts +9 -0
  58. package/dist/core/tools/renderers/ls.js +57 -0
  59. package/dist/core/tools/renderers/read.d.ts +10 -0
  60. package/dist/core/tools/renderers/read.js +128 -0
  61. package/dist/core/tools/renderers/write.d.ts +9 -0
  62. package/dist/core/tools/renderers/write.js +152 -0
  63. package/dist/core/tools/write.js +5 -146
  64. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +18 -0
  65. package/dist/extensions/pi-hermes-memory/README.md +16 -12
  66. package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +1 -1
  67. package/dist/extensions/pi-hermes-memory/package-lock.json +587 -62
  68. package/dist/extensions/pi-hermes-memory/package.json +4 -4
  69. package/dist/extensions/pi-hermes-memory/src/config.ts +32 -0
  70. package/dist/extensions/pi-hermes-memory/src/constants.ts +12 -2
  71. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +109 -51
  72. package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +9 -3
  73. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +257 -98
  74. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +9 -2
  75. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +5 -0
  76. package/dist/extensions/pi-hermes-memory/src/index.ts +22 -2
  77. package/dist/extensions/pi-hermes-memory/src/paths.ts +1 -1
  78. package/dist/extensions/pi-hermes-memory/src/store/db.ts +6 -0
  79. package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +58 -1
  80. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +60 -8
  81. package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +169 -7
  82. package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +7 -21
  83. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +134 -15
  84. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +4 -2
  85. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +24 -9
  86. package/dist/extensions/pi-hermes-memory/src/types.ts +11 -0
  87. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +42 -0
  88. package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +159 -3
  89. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +452 -0
  90. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +39 -0
  91. package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +91 -0
  92. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +29 -0
  93. package/dist/extensions/pi-hermes-memory/tests/store/fts-query.test.ts +116 -0
  94. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +163 -0
  95. package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +233 -0
  96. package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +12 -0
  97. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +175 -0
  98. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +2 -2
  99. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +22 -0
  100. package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +37 -1
  101. package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
  102. package/dist/extensions/pi-intercom/README.md +16 -2
  103. package/dist/extensions/pi-intercom/broker/spawn.test.ts +19 -2
  104. package/dist/extensions/pi-intercom/broker/spawn.ts +4 -4
  105. package/dist/extensions/pi-intercom/index.ts +1 -1
  106. package/dist/extensions/pi-intercom/intercom.integration.test.ts +121 -2
  107. package/dist/extensions/pi-intercom/package.json +1 -1
  108. package/dist/extensions/pi-intercom/project-agent.test.ts +1 -1
  109. package/dist/extensions/pi-intercom/project-agent.ts +1 -6
  110. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +7 -6
  111. package/dist/extensions/pi-rewind-hook/index.test.ts +7 -0
  112. package/dist/extensions/pi-subagents/.github/workflows/test.yml +36 -4
  113. package/dist/extensions/pi-subagents/CHANGELOG.md +120 -0
  114. package/dist/extensions/pi-subagents/README.md +3 -3
  115. package/dist/extensions/pi-subagents/agents/researcher.md +23 -13
  116. package/dist/extensions/pi-subagents/agents/reviewer.md +1 -1
  117. package/dist/extensions/pi-subagents/agents/scout.md +1 -1
  118. package/dist/extensions/pi-subagents/docs/agents.md +32 -16
  119. package/dist/extensions/pi-subagents/docs/configuration.md +41 -15
  120. package/dist/extensions/pi-subagents/docs/extension-api.md +109 -6
  121. package/dist/extensions/pi-subagents/docs/missions.md +2 -0
  122. package/dist/extensions/pi-subagents/docs/models.md +58 -1
  123. package/dist/extensions/pi-subagents/docs/observability.md +50 -12
  124. package/dist/extensions/pi-subagents/docs/tool-reference.md +17 -10
  125. package/dist/extensions/pi-subagents/docs/watchdog.md +1 -1
  126. package/dist/extensions/pi-subagents/docs/workflows.md +26 -9
  127. package/dist/extensions/pi-subagents/package-lock.json +747 -177
  128. package/dist/extensions/pi-subagents/package.json +6 -4
  129. package/dist/extensions/pi-subagents/runner-server-preload.mjs +13 -0
  130. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -1
  131. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
  132. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +21 -4
  133. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
  134. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +2 -0
  135. package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +63 -0
  136. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +61 -16
  137. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
  138. package/dist/extensions/pi-subagents/src/agents/agents.ts +8 -0
  139. package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +0 -1
  140. package/dist/extensions/pi-subagents/src/api/{pi-args.ts → child-tool-plan.ts} +1 -1
  141. package/dist/extensions/pi-subagents/src/api/preflight.ts +7 -4
  142. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -2
  143. package/dist/extensions/pi-subagents/src/api/workflow-resources.ts +6 -0
  144. package/dist/extensions/pi-subagents/src/extension/config.ts +4 -2
  145. package/dist/extensions/pi-subagents/src/extension/doctor.ts +2 -10
  146. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +9 -11
  147. package/dist/extensions/pi-subagents/src/extension/index.ts +99 -10
  148. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +13 -0
  149. package/dist/extensions/pi-subagents/src/extension/rpc.ts +7 -23
  150. package/dist/extensions/pi-subagents/src/extension/schemas.ts +11 -8
  151. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +25 -7
  152. package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +73 -0
  153. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +228 -136
  154. package/dist/extensions/pi-subagents/src/intercom/supervisor-ui.ts +244 -0
  155. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +37 -16
  156. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +18 -18
  157. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +51 -25
  158. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +46 -3
  159. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -3
  160. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +9 -0
  161. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +10 -12
  162. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -15
  163. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +40 -29
  164. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +8 -0
  165. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +79 -247
  166. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +88 -12
  167. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +6 -6
  168. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +24 -24
  169. package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +96 -0
  170. package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +642 -0
  171. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +75 -6
  172. package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +163 -0
  173. package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +86 -0
  174. package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +31 -0
  175. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +18 -4
  176. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -1
  177. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +597 -1092
  178. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +3 -0
  179. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +4 -0
  180. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +20 -17
  181. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +296 -394
  182. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +4 -0
  183. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +3 -1
  184. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +9 -5
  185. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +630 -283
  186. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +8 -5
  187. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +78 -98
  188. package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +3 -3
  189. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +16 -3
  190. package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
  191. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +47 -47
  192. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -2
  193. package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +174 -0
  194. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +14 -3
  195. package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +319 -0
  196. package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +25 -0
  197. package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +126 -0
  198. package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +373 -0
  199. package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +530 -0
  200. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +2 -2
  201. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +2 -1
  202. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +16 -0
  203. package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +11 -11
  204. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +30 -20
  205. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +5 -4
  206. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +84 -15
  207. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +88 -12
  208. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +37 -53
  209. package/dist/extensions/pi-subagents/src/runs/shared/nested-path.ts +1 -1
  210. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +18 -7
  211. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +57 -12
  212. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -4
  213. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +0 -11
  214. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +4 -1
  215. package/dist/extensions/pi-subagents/src/runs/shared/readonly-drain-observation.ts +42 -0
  216. package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +69 -0
  217. package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +307 -0
  218. package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +8 -21
  219. package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +3 -30
  220. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +17 -4
  221. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +2 -0
  222. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +99 -386
  223. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +18 -62
  224. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +0 -14
  225. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +31 -9
  226. package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +190 -0
  227. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +506 -226
  228. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +1 -1
  229. package/dist/extensions/pi-subagents/src/shared/jsonl-writer.ts +11 -0
  230. package/dist/extensions/pi-subagents/src/shared/model-response-aliases.ts +13 -0
  231. package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +0 -6
  232. package/dist/extensions/pi-subagents/src/shared/types.ts +145 -89
  233. package/dist/extensions/pi-subagents/src/shared/utils.ts +13 -6
  234. package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +2 -0
  235. package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +18 -13
  236. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +0 -6
  237. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +1 -1
  238. package/dist/extensions/pi-subagents/src/tui/fleet.ts +11 -6
  239. package/dist/extensions/pi-subagents/src/tui/render.ts +277 -46
  240. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +0 -1
  241. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +12 -12
  242. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
  243. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +116 -15
  244. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +15 -18
  245. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +57 -8
  246. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +19 -19
  247. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +3 -3
  248. package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +97 -22
  249. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +3 -0
  250. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +336 -21
  251. package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +1181 -0
  252. package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +2240 -0
  253. package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +2268 -0
  254. package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +1512 -0
  255. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +231 -16
  256. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +4 -18
  257. package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +95 -0
  258. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +9 -15
  259. package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +374 -0
  260. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -10
  261. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +18 -6
  262. package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +151 -0
  263. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +42 -1
  264. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +150 -25
  265. package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +354 -0
  266. package/dist/extensions/pi-subagents/test/integration/shared-cwd-terminal-evidence.test.ts +117 -0
  267. package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +3678 -0
  268. package/dist/extensions/pi-subagents/test/integration/{single-execution.test.ts → single-execution.part-2.test.ts} +500 -4207
  269. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -2
  270. package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +127 -0
  271. package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +365 -0
  272. package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +31 -0
  273. package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +74 -0
  274. package/dist/extensions/pi-subagents/test/smoke/pi085-extension.ts +16 -0
  275. package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +699 -0
  276. package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +418 -0
  277. package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +13 -0
  278. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +30 -76
  279. package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +84 -0
  280. package/dist/extensions/pi-subagents/test/support/result-publication-capacity-preload.mjs +70 -0
  281. package/dist/extensions/pi-subagents/test/support/runner-child-session-factory.ts +17 -0
  282. package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +390 -0
  283. package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +120 -0
  284. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +24 -3
  285. package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +87 -0
  286. package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +163 -0
  287. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -31
  288. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +78 -3
  289. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +2 -8
  290. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +1 -1
  291. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +73 -66
  292. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +51 -1
  293. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +49 -1
  294. package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +103 -0
  295. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +3 -3
  296. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +9 -8
  297. package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +10 -7
  298. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +48 -6
  299. package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +90 -0
  300. package/dist/extensions/pi-subagents/test/unit/{pi-args-permission-system.test.ts → child-tool-plan-permission-system.test.ts} +48 -86
  301. package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +33 -0
  302. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +18 -18
  303. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +9 -9
  304. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +8 -7
  305. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +225 -65
  306. package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +17 -22
  307. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +11 -1
  308. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +47 -3
  309. package/dist/extensions/pi-subagents/test/unit/foreign-workflow-steering.test.ts +74 -0
  310. package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +23 -29
  311. package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +96 -4
  312. package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +4 -4
  313. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +116 -55
  314. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +58 -1
  315. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +104 -3
  316. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
  317. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +31 -1
  318. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +102 -51
  319. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +196 -6
  320. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +181 -38
  321. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +62 -70
  322. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +58 -53
  323. package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +42 -0
  324. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +84 -0
  325. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +13 -5
  326. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +21 -5
  327. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +5 -4
  328. package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +2 -6
  329. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +28 -2
  330. package/dist/extensions/pi-subagents/test/unit/pi-web-session-liveness.test.ts +209 -0
  331. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +38 -1
  332. package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +43 -0
  333. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +24 -2
  334. package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +174 -0
  335. package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +94 -0
  336. package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +1329 -0
  337. package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +29 -80
  338. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +11 -8
  339. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +2 -2
  340. package/dist/extensions/pi-subagents/test/unit/retained-nested-route-tracker.test.ts +175 -0
  341. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +38 -12
  342. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +2 -5
  343. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +89 -1
  344. package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +2 -16
  345. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +27 -3
  346. package/dist/extensions/pi-subagents/test/unit/scheduled-supervisor-demand.test.ts +215 -0
  347. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +15 -11
  348. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +237 -1
  349. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -5
  350. package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +2 -2
  351. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +14 -1
  352. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +130 -739
  353. package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +682 -0
  354. package/dist/extensions/pi-subagents/test/unit/supervisor-ui.test.ts +137 -0
  355. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +1 -11
  356. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +23 -3
  357. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +8 -1
  358. package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +19 -1
  359. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +72 -4
  360. package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +17 -3
  361. package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +34 -0
  362. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +12 -2
  363. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +46 -6
  364. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +3 -3
  365. package/dist/extensions/pi-subagents/test/unit/workflow-resources.test.ts +133 -1
  366. package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +53 -2
  367. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +222 -14
  368. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +526 -85
  369. package/dist/extensions/pi-zentui/README.md +17 -0
  370. package/dist/extensions/pi-zentui/assets/screenshots/footer-status-hyperlink.png +0 -0
  371. package/dist/extensions/pi-zentui/docs/configuration.md +71 -2
  372. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +11 -0
  373. package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +14 -0
  374. package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +29 -13
  375. package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +5 -4
  376. package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +11 -0
  377. package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +11 -10
  378. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +77 -3
  379. package/dist/extensions/pi-zentui/extensions/zentui/presets.ts +77 -0
  380. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +103 -2
  381. package/dist/extensions/pi-zentui/extensions/zentui/working-line-extension-segments.ts +115 -0
  382. package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +87 -5
  383. package/dist/extensions/pi-zentui/package-lock.json +277 -517
  384. package/dist/extensions/pi-zentui/package.json +7 -4
  385. package/dist/extensions/pi-zentui/test/config-presets.test.ts +238 -0
  386. package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +24 -1
  387. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +570 -2
  388. package/dist/extensions/pi-zentui/test/extension-status.test.ts +90 -0
  389. package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +243 -0
  390. package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
  391. package/dist/extensions/pi-zentui/test/presets.test.ts +121 -0
  392. package/dist/extensions/pi-zentui/test/settings-command.test.ts +205 -1
  393. package/dist/extensions/pi-zentui/test/working-line-extension-segments.test.ts +139 -0
  394. package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +237 -3
  395. package/dist/extensions/pi-zentui/test/working-line.test.ts +94 -2
  396. package/dist/index.d.ts +1 -1
  397. package/dist/main.js +4 -1
  398. package/dist/modes/interactive/chat-viewport.d.ts +19 -0
  399. package/dist/modes/interactive/chat-viewport.js +27 -0
  400. package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
  401. package/dist/modes/interactive/components/assistant-message.js +30 -13
  402. package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
  403. package/dist/modes/interactive/components/custom-editor.js +39 -1
  404. package/dist/modes/interactive/components/first-time-setup.js +1 -1
  405. package/dist/modes/interactive/components/index.d.ts +1 -1
  406. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -0
  407. package/dist/modes/interactive/components/markdown-transform.js +18 -0
  408. package/dist/modes/interactive/components/model-selector.js +19 -17
  409. package/dist/modes/interactive/components/scoped-models-selector.js +21 -23
  410. package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
  411. package/dist/modes/interactive/components/settings-selector.js +128 -20
  412. package/dist/modes/interactive/components/settings-submenu.d.ts +71 -0
  413. package/dist/modes/interactive/components/settings-submenu.js +164 -0
  414. package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
  415. package/dist/modes/interactive/components/status-indicator.js +10 -3
  416. package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
  417. package/dist/modes/interactive/components/thinking-selector.js +75 -18
  418. package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
  419. package/dist/modes/interactive/components/tool-execution.js +35 -33
  420. package/dist/modes/interactive/components/trust-selector.js +2 -2
  421. package/dist/modes/interactive/interactive-mode.d.ts +13 -15
  422. package/dist/modes/interactive/interactive-mode.js +144 -80
  423. package/dist/modes/interactive/session-share.d.ts +15 -0
  424. package/dist/modes/interactive/session-share.js +183 -0
  425. package/dist/modes/interactive/theme/dark.json +2 -1
  426. package/dist/modes/interactive/theme/light.json +2 -1
  427. package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
  428. package/dist/modes/interactive/theme/theme-controller.js +5 -0
  429. package/dist/modes/interactive/theme/theme-json.d.ts +83 -0
  430. package/dist/modes/interactive/theme/theme-json.js +129 -0
  431. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  432. package/dist/modes/interactive/theme/theme.d.ts +14 -5
  433. package/dist/modes/interactive/theme/theme.js +18 -119
  434. package/dist/modes/interactive/tui-renderer.d.ts +20 -0
  435. package/dist/modes/interactive/tui-renderer.js +65 -0
  436. package/dist/utils/exif-orientation.js +2 -3
  437. package/dist/utils/management-http.d.ts +24 -0
  438. package/dist/utils/management-http.js +53 -0
  439. package/dist/utils/text.d.ts +7 -0
  440. package/dist/utils/text.js +8 -0
  441. package/dist/utils/tools-manager.d.ts +1 -0
  442. package/dist/utils/tools-manager.js +43 -21
  443. package/docs/docs.json +0 -4
  444. package/package.json +4 -4
  445. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +0 -415
  446. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +0 -1059
  447. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +0 -116
  448. package/dist/extensions/pi-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
  449. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +0 -224
  450. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +0 -6986
  451. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +0 -447
  452. package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +0 -185
  453. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +0 -311
  454. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +0 -84
  455. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +0 -202
  456. package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +0 -101
  457. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +0 -2347
  458. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +0 -104
  459. package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +0 -49
  460. package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
  461. package/dist/skills/imagegen-frontend-web/SKILL.md +0 -987
  462. package/dist/skills/implanger/SKILL.md +0 -70
  463. package/dist/skills/output/SKILL.md +0 -49
  464. package/dist/skills/planger/SKILL.md +0 -167
  465. package/dist/skills/workflow/SKILL.md +0 -95
  466. package/docs/workflows.md +0 -18
  467. /package/dist/bun/{register-bedrock.d.ts → runtime-setup.d.ts} +0 -0
@@ -1,18 +1,12 @@
1
- import { basename, dirname, isAbsolute, relative, resolve as resolvePath, sep } from "node:path";
2
- import { Text } from "@earendil-works/pi-tui";
3
1
  import { constants } from "fs";
4
2
  import { access as fsAccess, readFile as fsReadFile } from "fs/promises";
5
3
  import { Type } from "typebox";
6
- import { getReadmePath } from "../../config.js";
7
- import { keyHint, keyText } from "../../modes/interactive/components/keybinding-hints.js";
8
- import { getLanguageFromPath, highlightCode } from "../../modes/interactive/theme/theme.js";
9
4
  import { processImage } from "../../utils/image-process.js";
10
5
  import { detectSupportedImageMimeTypeFromFile } from "../../utils/mime.js";
11
- import { formatPathRelativeToCwdOrAbsolute } from "../../utils/paths.js";
12
6
  import { getExperimentalToolSampling } from "../experimental.js";
13
7
  import { captionImageWithModel } from "../vision-caption.js";
14
- import { resolveReadPathAsync, resolveToCwd } from "./path-utils.js";
15
- import { getTextOutput, renderToolPath, replaceTabs, str } from "./render-utils.js";
8
+ import { resolveReadPathAsync } from "./path-utils.js";
9
+ import { readRenderers } from "./renderers/read.js";
16
10
  import { wrapToolDefinition } from "./tool-definition-wrapper.js";
17
11
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead } from "./truncate.js";
18
12
  const readSchema = Type.Object({
@@ -20,30 +14,15 @@ const readSchema = Type.Object({
20
14
  offset: Type.Optional(Type.Number({ description: "Line number to start reading from (1-indexed)" })),
21
15
  limit: Type.Optional(Type.Number({ description: "Maximum number of lines to read" })),
22
16
  });
23
- const COMPACT_RESOURCE_FILE_NAMES = new Set(["AGENTS.md", "AGENTS.MD", "CLAUDE.md", "CLAUDE.MD"]);
17
+ export const readToolSystemPromptContribution = {
18
+ snippet: "Read file contents",
19
+ guidelines: ["Use read to examine files instead of cat or sed."],
20
+ };
24
21
  const defaultReadOperations = {
25
22
  readFile: (path) => fsReadFile(path),
26
23
  access: (path) => fsAccess(path, constants.R_OK),
27
24
  detectImageMimeType: detectSupportedImageMimeTypeFromFile,
28
25
  };
29
- function formatReadLineRange(args, theme) {
30
- if (args?.offset === undefined && args?.limit === undefined)
31
- return "";
32
- const startLine = args.offset ?? 1;
33
- const endLine = args.limit !== undefined ? startLine + args.limit - 1 : "";
34
- return theme.fg("warning", `:${startLine}${endLine ? `-${endLine}` : ""}`);
35
- }
36
- function formatReadCall(args, theme, cwd) {
37
- const pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);
38
- return `${theme.fg("toolTitle", theme.bold("read"))} ${pathDisplay}${formatReadLineRange(args, theme)}`;
39
- }
40
- function trimTrailingEmptyLines(lines) {
41
- let end = lines.length;
42
- while (end > 0 && lines[end - 1] === "") {
43
- end--;
44
- }
45
- return lines.slice(0, end);
46
- }
47
26
  function getNonVisionImageNote(model) {
48
27
  if (!model || model.input.includes("image")) {
49
28
  return undefined;
@@ -80,85 +59,6 @@ export async function captionImage(image, captionModelId, ctx, signal) {
80
59
  signal,
81
60
  });
82
61
  }
83
- function toPosixPath(filePath) {
84
- return filePath.split(sep).join("/");
85
- }
86
- function getPiDocsClassification(absolutePath) {
87
- const packageRoot = dirname(getReadmePath());
88
- const relativePath = relative(resolvePath(packageRoot), resolvePath(absolutePath));
89
- if (relativePath === "" ||
90
- relativePath === ".." ||
91
- relativePath.startsWith(`..${sep}`) ||
92
- isAbsolute(relativePath)) {
93
- return undefined;
94
- }
95
- const label = toPosixPath(relativePath);
96
- if (label === "README.md" || label.startsWith("docs/") || label.startsWith("examples/")) {
97
- return { kind: "docs", label };
98
- }
99
- return undefined;
100
- }
101
- function getCompactReadClassification(args, cwd) {
102
- const rawPath = str(args?.file_path ?? args?.path);
103
- if (!rawPath)
104
- return undefined;
105
- const absolutePath = resolveToCwd(rawPath, cwd);
106
- const fileName = basename(absolutePath);
107
- if (fileName === "SKILL.md") {
108
- return { kind: "skill", label: basename(dirname(absolutePath)) || fileName };
109
- }
110
- const docsClassification = getPiDocsClassification(absolutePath);
111
- if (docsClassification)
112
- return docsClassification;
113
- if (COMPACT_RESOURCE_FILE_NAMES.has(fileName)) {
114
- return { kind: "resource", label: formatPathRelativeToCwdOrAbsolute(absolutePath, cwd) };
115
- }
116
- return undefined;
117
- }
118
- function formatCompactReadCall(classification, args, theme) {
119
- const expandHint = theme.fg("dim", ` (${keyText("app.tools.expand")} to expand)`);
120
- if (classification.kind === "skill") {
121
- return (theme.fg("customMessageLabel", `\x1b[1m[skill]\x1b[22m `) +
122
- theme.fg("customMessageText", classification.label) +
123
- formatReadLineRange(args, theme) +
124
- expandHint);
125
- }
126
- return (theme.fg("toolTitle", theme.bold(`read ${classification.kind}`)) +
127
- " " +
128
- theme.fg("accent", classification.label) +
129
- formatReadLineRange(args, theme) +
130
- expandHint);
131
- }
132
- function formatReadResult(args, result, options, theme, showImages, _cwd, isError) {
133
- if (!options.expanded && !isError) {
134
- return "";
135
- }
136
- const rawPath = str(args?.file_path ?? args?.path);
137
- const output = getTextOutput(result, showImages);
138
- const lang = !isError && rawPath ? getLanguageFromPath(rawPath) : undefined;
139
- const renderedLines = lang ? highlightCode(replaceTabs(output), lang) : output.split("\n");
140
- const lines = trimTrailingEmptyLines(renderedLines);
141
- const maxLines = options.expanded ? lines.length : 10;
142
- const displayLines = lines.slice(0, maxLines);
143
- const remaining = lines.length - maxLines;
144
- let text = `\n${displayLines.map((line) => (lang ? replaceTabs(line) : theme.fg("toolOutput", replaceTabs(line)))).join("\n")}`;
145
- if (remaining > 0) {
146
- text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
147
- }
148
- const truncation = result.details?.truncation;
149
- if (truncation?.truncated) {
150
- if (truncation.firstLineExceedsLimit) {
151
- text += `\n${theme.fg("warning", `[First line exceeds ${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit]`)}`;
152
- }
153
- else if (truncation.truncatedBy === "lines") {
154
- text += `\n${theme.fg("warning", `[Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines (${truncation.maxLines ?? DEFAULT_MAX_LINES} line limit)]`)}`;
155
- }
156
- else {
157
- text += `\n${theme.fg("warning", `[Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)]`)}`;
158
- }
159
- }
160
- return text;
161
- }
162
62
  export function createReadToolDefinition(cwd, options) {
163
63
  const autoResizeImages = options?.autoResizeImages ?? true;
164
64
  const imageCaptionModel = options?.imageCaptionModel;
@@ -167,8 +67,8 @@ export function createReadToolDefinition(cwd, options) {
167
67
  name: "read",
168
68
  label: "read",
169
69
  description: `Read the contents of a file. Supports text files and images (jpg, png, gif, webp, bmp). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,
170
- promptSnippet: "Read file contents",
171
- promptGuidelines: ["Use read to examine files instead of cat or sed."],
70
+ promptSnippet: readToolSystemPromptContribution.snippet,
71
+ promptGuidelines: [...readToolSystemPromptContribution.guidelines],
172
72
  parameters: readSchema,
173
73
  constrainedSampling: getExperimentalToolSampling(),
174
74
  async execute(_toolCallId, { path, offset, limit }, signal, _onUpdate, ctx) {
@@ -185,7 +85,7 @@ export function createReadToolDefinition(cwd, options) {
185
85
  signal?.addEventListener("abort", onAbort, { once: true });
186
86
  (async () => {
187
87
  try {
188
- const absolutePath = await resolveReadPathAsync(path, cwd);
88
+ const absolutePath = await resolveReadPathAsync(path, ctx?.cwd || cwd);
189
89
  if (aborted)
190
90
  return;
191
91
  // Check if file exists and is readable.
@@ -307,19 +207,7 @@ export function createReadToolDefinition(cwd, options) {
307
207
  })();
308
208
  });
309
209
  },
310
- renderCall(args, theme, context) {
311
- const text = context.lastComponent ?? new Text("", 0, 0);
312
- const classification = !context.expanded ? getCompactReadClassification(args, context.cwd) : undefined;
313
- text.setText(classification
314
- ? formatCompactReadCall(classification, args, theme)
315
- : formatReadCall(args, theme, context.cwd));
316
- return text;
317
- },
318
- renderResult(result, options, theme, context) {
319
- const text = context.lastComponent ?? new Text("", 0, 0);
320
- text.setText(formatReadResult(context.args, result, options, theme, context.showImages, context.cwd, context.isError));
321
- return text;
322
- },
210
+ ...readRenderers,
323
211
  };
324
212
  }
325
213
  export function createReadTool(cwd, options) {
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Presentation for the shell tools.
3
+ *
4
+ * Renderers live apart from the implementation so a process that only displays tool output does not
5
+ * load the execution path or its typebox parameter schema. `bash.ts` spreads these into the shell
6
+ * tool definition, so the tool's public shape is unchanged.
7
+ */
8
+ import type { ToolDefinition } from "../../extensions/types.ts";
9
+ export declare const BASH_UPDATE_THROTTLE_MS = 100;
10
+ /** Shell renderers are shared by bash and powershell, which differ only in the prompt they display. */
11
+ export declare function createShellRenderers(prompt: string): Pick<ToolDefinition<any, any>, "renderCall" | "renderResult">;
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Presentation for the shell tools.
3
+ *
4
+ * Renderers live apart from the implementation so a process that only displays tool output does not
5
+ * load the execution path or its typebox parameter schema. `bash.ts` spreads these into the shell
6
+ * tool definition, so the tool's public shape is unchanged.
7
+ */
8
+ import { Container, Text, truncateToWidth } from "@earendil-works/pi-tui";
9
+ import { keyHint } from "../../../modes/interactive/components/keybinding-hints.js";
10
+ import { truncateToVisualLines } from "../../../modes/interactive/components/visual-truncate.js";
11
+ import { theme } from "../../../modes/interactive/theme/theme.js";
12
+ import { getTextOutput, invalidArgText, str } from "../render-utils.js";
13
+ import { DEFAULT_MAX_BYTES, formatSize } from "../truncate.js";
14
+ const BASH_PREVIEW_LINES = 5;
15
+ export const BASH_UPDATE_THROTTLE_MS = 100;
16
+ class BashResultRenderComponent extends Container {
17
+ state = {
18
+ cachedWidth: undefined,
19
+ cachedLines: undefined,
20
+ cachedSkipped: undefined,
21
+ };
22
+ }
23
+ function formatDuration(ms) {
24
+ return `${(ms / 1000).toFixed(1)}s`;
25
+ }
26
+ function formatShellCall(args, prompt) {
27
+ const command = str(args?.command);
28
+ const timeout = args?.timeout;
29
+ const timeoutSuffix = timeout ? theme.fg("muted", ` (timeout ${timeout}s)`) : "";
30
+ const commandDisplay = command === null ? invalidArgText(theme) : command ? command : theme.fg("toolOutput", "...");
31
+ return theme.fg("toolTitle", theme.bold(`${prompt} ${commandDisplay}`)) + timeoutSuffix;
32
+ }
33
+ function rebuildBashResultRenderComponent(component, result, options, showImages, startedAt, endedAt) {
34
+ const state = component.state;
35
+ component.clear();
36
+ let output = getTextOutput(result, showImages).trim();
37
+ const truncation = result.details?.truncation;
38
+ const fullOutputPath = result.details?.fullOutputPath;
39
+ if (!options.isPartial && truncation?.truncated && fullOutputPath && output.endsWith("]")) {
40
+ const footerStart = output.lastIndexOf("\n\n[");
41
+ if (footerStart !== -1 && output.slice(footerStart).includes(fullOutputPath)) {
42
+ output = output.slice(0, footerStart).trimEnd();
43
+ }
44
+ }
45
+ if (output) {
46
+ const styledOutput = output
47
+ .split("\n")
48
+ .map((line) => theme.fg("toolOutput", line))
49
+ .join("\n");
50
+ if (options.expanded) {
51
+ component.addChild(new Text(`\n${styledOutput}`, 0, 0));
52
+ }
53
+ else {
54
+ component.addChild({
55
+ render: (width) => {
56
+ if (state.cachedLines === undefined || state.cachedWidth !== width) {
57
+ const preview = truncateToVisualLines(styledOutput, BASH_PREVIEW_LINES, width);
58
+ state.cachedLines = preview.visualLines;
59
+ state.cachedSkipped = preview.skippedCount;
60
+ state.cachedWidth = width;
61
+ }
62
+ if (state.cachedSkipped && state.cachedSkipped > 0) {
63
+ const hint = theme.fg("muted", `... (${state.cachedSkipped} earlier lines,`) +
64
+ ` ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
65
+ return ["", truncateToWidth(hint, width, "..."), ...(state.cachedLines ?? [])];
66
+ }
67
+ return ["", ...(state.cachedLines ?? [])];
68
+ },
69
+ invalidate: () => {
70
+ state.cachedWidth = undefined;
71
+ state.cachedLines = undefined;
72
+ state.cachedSkipped = undefined;
73
+ },
74
+ });
75
+ }
76
+ }
77
+ if (truncation?.truncated || fullOutputPath) {
78
+ const warnings = [];
79
+ if (fullOutputPath) {
80
+ warnings.push(`Full output: ${fullOutputPath}`);
81
+ }
82
+ if (truncation?.truncated) {
83
+ if (truncation.truncatedBy === "lines") {
84
+ warnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);
85
+ }
86
+ else {
87
+ warnings.push(`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`);
88
+ }
89
+ }
90
+ component.addChild(new Text(`\n${theme.fg("warning", `[${warnings.join(". ")}]`)}`, 0, 0));
91
+ }
92
+ if (startedAt !== undefined) {
93
+ const label = options.isPartial ? "Elapsed" : "Took";
94
+ const endTime = endedAt ?? Date.now();
95
+ component.addChild(new Text(`\n${theme.fg("muted", `${label} ${formatDuration(endTime - startedAt)}`)}`, 0, 0));
96
+ }
97
+ }
98
+ /** Shell renderers are shared by bash and powershell, which differ only in the prompt they display. */
99
+ export function createShellRenderers(prompt) {
100
+ return {
101
+ renderCall(args, _theme, context) {
102
+ const state = context.state;
103
+ if (context.executionStarted && state.startedAt === undefined) {
104
+ state.startedAt = Date.now();
105
+ state.endedAt = undefined;
106
+ }
107
+ const text = context.lastComponent ?? new Text("", 0, 0);
108
+ text.setText(formatShellCall(args, prompt));
109
+ return text;
110
+ },
111
+ renderResult(result, options, _theme, context) {
112
+ const state = context.state;
113
+ if (state.startedAt !== undefined && options.isPartial && !state.interval) {
114
+ state.interval = setInterval(() => context.invalidate(), 1000);
115
+ }
116
+ if (!options.isPartial || context.isError) {
117
+ state.endedAt ??= Date.now();
118
+ if (state.interval) {
119
+ clearInterval(state.interval);
120
+ state.interval = undefined;
121
+ }
122
+ }
123
+ const component = context.lastComponent ?? new BashResultRenderComponent();
124
+ rebuildBashResultRenderComponent(component, result, options, context.showImages, state.startedAt, state.endedAt);
125
+ component.invalidate();
126
+ return component;
127
+ },
128
+ };
129
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Presentation for the edit tool.
3
+ *
4
+ * Renderers live apart from the implementation so a process that only displays tool output does not
5
+ * load the execution path or its typebox parameter schema. `edit.ts` spreads these into its
6
+ * definition, so the tool's public shape is unchanged.
7
+ */
8
+ import { Box } from "@earendil-works/pi-tui";
9
+ import type { ToolDefinition } from "../../extensions/types.ts";
10
+ import { type EditDiffError, type EditDiffResult } from "../edit-diff.ts";
11
+ type EditPreview = EditDiffResult | EditDiffError;
12
+ export type EditRenderState = {
13
+ callComponent?: EditCallRenderComponent;
14
+ };
15
+ type EditCallRenderComponent = Box & {
16
+ preview?: EditPreview;
17
+ previewArgsKey?: string;
18
+ previewPending?: boolean;
19
+ settledError?: boolean;
20
+ };
21
+ export declare const editRenderers: Pick<ToolDefinition<any, any>, "renderCall" | "renderResult">;
22
+ export {};
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Presentation for the edit tool.
3
+ *
4
+ * Renderers live apart from the implementation so a process that only displays tool output does not
5
+ * load the execution path or its typebox parameter schema. `edit.ts` spreads these into its
6
+ * definition, so the tool's public shape is unchanged.
7
+ */
8
+ import { Box, Container, Spacer, Text } from "@earendil-works/pi-tui";
9
+ import { renderDiff } from "../../../modes/interactive/components/diff.js";
10
+ import { computeEditsDiff } from "../edit-diff.js";
11
+ import { renderToolPath, str } from "../render-utils.js";
12
+ function createEditCallRenderComponent() {
13
+ return Object.assign(new Box(1, 1, (text) => text), {
14
+ preview: undefined,
15
+ previewArgsKey: undefined,
16
+ previewPending: false,
17
+ settledError: false,
18
+ });
19
+ }
20
+ function getEditCallRenderComponent(state, lastComponent) {
21
+ if (lastComponent instanceof Box) {
22
+ const component = lastComponent;
23
+ state.callComponent = component;
24
+ return component;
25
+ }
26
+ if (state.callComponent) {
27
+ return state.callComponent;
28
+ }
29
+ const component = createEditCallRenderComponent();
30
+ state.callComponent = component;
31
+ return component;
32
+ }
33
+ function getRenderablePreviewInput(args) {
34
+ if (!args) {
35
+ return null;
36
+ }
37
+ const path = typeof args.path === "string" ? args.path : typeof args.file_path === "string" ? args.file_path : null;
38
+ if (!path) {
39
+ return null;
40
+ }
41
+ if (Array.isArray(args.edits) &&
42
+ args.edits.length > 0 &&
43
+ args.edits.every((edit) => typeof edit?.oldText === "string" && typeof edit?.newText === "string")) {
44
+ return { path, edits: args.edits };
45
+ }
46
+ if (typeof args.oldText === "string" && typeof args.newText === "string") {
47
+ return { path, edits: [{ oldText: args.oldText, newText: args.newText }] };
48
+ }
49
+ return null;
50
+ }
51
+ function formatEditCall(args, theme, cwd) {
52
+ const pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);
53
+ return `${theme.fg("toolTitle", theme.bold("edit"))} ${pathDisplay}`;
54
+ }
55
+ function formatEditResult(args, preview, result, theme, isError) {
56
+ const rawPath = str(args?.file_path ?? args?.path);
57
+ const previewDiff = preview && !("error" in preview) ? preview.diff : undefined;
58
+ const previewError = preview && "error" in preview ? preview.error : undefined;
59
+ if (isError) {
60
+ const errorText = result.content
61
+ .filter((c) => c.type === "text")
62
+ .map((c) => c.text || "")
63
+ .join("\n");
64
+ if (!errorText || errorText === previewError) {
65
+ return undefined;
66
+ }
67
+ return theme.fg("error", errorText);
68
+ }
69
+ const resultDiff = result.details?.diff;
70
+ if (resultDiff && resultDiff !== previewDiff) {
71
+ return renderDiff(resultDiff, { filePath: rawPath ?? undefined });
72
+ }
73
+ return undefined;
74
+ }
75
+ function getEditHeaderBg(preview, settledError, theme) {
76
+ if (preview) {
77
+ if ("error" in preview) {
78
+ return (text) => theme.bg("toolErrorBg", text);
79
+ }
80
+ return (text) => theme.bg("toolSuccessBg", text);
81
+ }
82
+ if (settledError) {
83
+ return (text) => theme.bg("toolErrorBg", text);
84
+ }
85
+ return (text) => theme.bg("toolPendingBg", text);
86
+ }
87
+ function buildEditCallComponent(component, args, theme, cwd) {
88
+ component.setBgFn(getEditHeaderBg(component.preview, component.settledError, theme));
89
+ component.clear();
90
+ component.addChild(new Text(formatEditCall(args, theme, cwd), 0, 0));
91
+ if (!component.preview) {
92
+ return component;
93
+ }
94
+ const body = "error" in component.preview ? theme.fg("error", component.preview.error) : renderDiff(component.preview.diff);
95
+ component.addChild(new Spacer(1));
96
+ component.addChild(new Text(body, 0, 0));
97
+ return component;
98
+ }
99
+ function setEditPreview(component, preview, argsKey) {
100
+ const current = component.preview;
101
+ const changed = current === undefined ||
102
+ ("error" in current && "error" in preview
103
+ ? current.error !== preview.error
104
+ : "error" in current !== "error" in preview) ||
105
+ (!("error" in current) &&
106
+ !("error" in preview) &&
107
+ (current.diff !== preview.diff || current.firstChangedLine !== preview.firstChangedLine));
108
+ component.preview = preview;
109
+ component.previewArgsKey = argsKey;
110
+ component.previewPending = false;
111
+ return changed;
112
+ }
113
+ export const editRenderers = {
114
+ renderCall(args, theme, context) {
115
+ const component = getEditCallRenderComponent(context.state, context.lastComponent);
116
+ const previewInput = getRenderablePreviewInput(args);
117
+ const argsKey = previewInput ? JSON.stringify({ path: previewInput.path, edits: previewInput.edits }) : undefined;
118
+ if (component.previewArgsKey !== argsKey) {
119
+ component.preview = undefined;
120
+ component.previewArgsKey = argsKey;
121
+ component.previewPending = false;
122
+ component.settledError = false;
123
+ }
124
+ if (context.argsComplete && previewInput && !component.preview && !component.previewPending) {
125
+ component.previewPending = true;
126
+ const requestKey = argsKey;
127
+ void computeEditsDiff(previewInput.path, previewInput.edits, context.cwd).then((preview) => {
128
+ if (component.previewArgsKey === requestKey) {
129
+ setEditPreview(component, preview, requestKey);
130
+ context.invalidate();
131
+ }
132
+ });
133
+ }
134
+ return buildEditCallComponent(component, args, theme, context.cwd);
135
+ },
136
+ renderResult(result, _options, theme, context) {
137
+ const callComponent = context.state.callComponent;
138
+ const previewInput = getRenderablePreviewInput(context.args);
139
+ const argsKey = previewInput ? JSON.stringify({ path: previewInput.path, edits: previewInput.edits }) : undefined;
140
+ const typedResult = result;
141
+ const resultDiff = !context.isError ? typedResult.details?.diff : undefined;
142
+ let changed = false;
143
+ if (callComponent) {
144
+ if (typeof resultDiff === "string") {
145
+ changed =
146
+ setEditPreview(callComponent, { diff: resultDiff, firstChangedLine: typedResult.details?.firstChangedLine }, argsKey) || changed;
147
+ }
148
+ if (callComponent.settledError !== context.isError) {
149
+ callComponent.settledError = context.isError;
150
+ changed = true;
151
+ }
152
+ if (changed) {
153
+ buildEditCallComponent(callComponent, context.args, theme, context.cwd);
154
+ }
155
+ }
156
+ const output = formatEditResult(context.args, callComponent?.preview, typedResult, theme, context.isError);
157
+ const component = context.lastComponent ?? new Container();
158
+ component.clear();
159
+ if (!output) {
160
+ return component;
161
+ }
162
+ component.addChild(new Spacer(1));
163
+ component.addChild(new Text(output, 1, 0));
164
+ return component;
165
+ },
166
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Presentation for the find tool.
3
+ *
4
+ * Renderers live apart from the implementation so a process that only displays tool output does not
5
+ * load the execution path or its typebox parameter schema. `find.ts` spreads these into its
6
+ * definition, so the tool's public shape is unchanged.
7
+ */
8
+ import type { ToolDefinition } from "../../extensions/types.ts";
9
+ export declare const findRenderers: Pick<ToolDefinition<any, any>, "renderCall" | "renderResult">;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Presentation for the find tool.
3
+ *
4
+ * Renderers live apart from the implementation so a process that only displays tool output does not
5
+ * load the execution path or its typebox parameter schema. `find.ts` spreads these into its
6
+ * definition, so the tool's public shape is unchanged.
7
+ */
8
+ import { Text } from "@earendil-works/pi-tui";
9
+ import { keyHint } from "../../../modes/interactive/components/keybinding-hints.js";
10
+ import { getTextOutput, invalidArgText, shortenPath, str } from "../render-utils.js";
11
+ import { DEFAULT_MAX_BYTES, formatSize } from "../truncate.js";
12
+ function formatFindCall(args, theme) {
13
+ const pattern = str(args?.pattern);
14
+ const rawPath = str(args?.path);
15
+ const path = rawPath !== null ? shortenPath(rawPath || ".") : null;
16
+ const limit = args?.limit;
17
+ const invalidArg = invalidArgText(theme);
18
+ let text = theme.fg("toolTitle", theme.bold("find")) +
19
+ " " +
20
+ (pattern === null ? invalidArg : theme.fg("accent", pattern || "")) +
21
+ theme.fg("toolOutput", ` in ${path === null ? invalidArg : path}`);
22
+ if (limit !== undefined) {
23
+ text += theme.fg("toolOutput", ` (limit ${limit})`);
24
+ }
25
+ return text;
26
+ }
27
+ function formatFindResult(result, options, theme, showImages) {
28
+ const output = getTextOutput(result, showImages).trim();
29
+ let text = "";
30
+ if (output) {
31
+ const lines = output.split("\n");
32
+ const maxLines = options.expanded ? lines.length : 20;
33
+ const displayLines = lines.slice(0, maxLines);
34
+ const remaining = lines.length - maxLines;
35
+ text += `\n${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
36
+ if (remaining > 0) {
37
+ text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
38
+ }
39
+ }
40
+ const resultLimit = result.details?.resultLimitReached;
41
+ const truncation = result.details?.truncation;
42
+ if (resultLimit || truncation?.truncated) {
43
+ const warnings = [];
44
+ if (resultLimit)
45
+ warnings.push(`${resultLimit} results limit`);
46
+ if (truncation?.truncated)
47
+ warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
48
+ text += `\n${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
49
+ }
50
+ return text;
51
+ }
52
+ export const findRenderers = {
53
+ renderCall(args, theme, context) {
54
+ const text = context.lastComponent ?? new Text("", 0, 0);
55
+ text.setText(formatFindCall(args, theme));
56
+ return text;
57
+ },
58
+ renderResult(result, options, theme, context) {
59
+ const text = context.lastComponent ?? new Text("", 0, 0);
60
+ text.setText(formatFindResult(result, options, theme, context.showImages));
61
+ return text;
62
+ },
63
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Presentation for the grep tool.
3
+ *
4
+ * Renderers live apart from the implementation so a process that only displays tool output does not
5
+ * load the execution path or its typebox parameter schema. `grep.ts` spreads these into its
6
+ * definition, so the tool's public shape is unchanged.
7
+ */
8
+ import type { ToolDefinition } from "../../extensions/types.ts";
9
+ export declare const grepRenderers: Pick<ToolDefinition<any, any>, "renderCall" | "renderResult">;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Presentation for the grep tool.
3
+ *
4
+ * Renderers live apart from the implementation so a process that only displays tool output does not
5
+ * load the execution path or its typebox parameter schema. `grep.ts` spreads these into its
6
+ * definition, so the tool's public shape is unchanged.
7
+ */
8
+ import { Text } from "@earendil-works/pi-tui";
9
+ import { keyHint } from "../../../modes/interactive/components/keybinding-hints.js";
10
+ import { getTextOutput, invalidArgText, shortenPath, str } from "../render-utils.js";
11
+ import { DEFAULT_MAX_BYTES, formatSize } from "../truncate.js";
12
+ function formatGrepCall(args, theme) {
13
+ const pattern = str(args?.pattern);
14
+ const rawPath = str(args?.path);
15
+ const path = rawPath !== null ? shortenPath(rawPath || ".") : null;
16
+ const glob = str(args?.glob);
17
+ const limit = args?.limit;
18
+ const invalidArg = invalidArgText(theme);
19
+ let text = theme.fg("toolTitle", theme.bold("grep")) +
20
+ " " +
21
+ (pattern === null ? invalidArg : theme.fg("accent", `/${pattern || ""}/`)) +
22
+ theme.fg("toolOutput", ` in ${path === null ? invalidArg : path}`);
23
+ if (glob)
24
+ text += theme.fg("toolOutput", ` (${glob})`);
25
+ if (limit !== undefined)
26
+ text += theme.fg("toolOutput", ` limit ${limit}`);
27
+ return text;
28
+ }
29
+ function formatGrepResult(result, options, theme, showImages) {
30
+ const output = getTextOutput(result, showImages).trim();
31
+ let text = "";
32
+ if (output) {
33
+ const lines = output.split("\n");
34
+ const maxLines = options.expanded ? lines.length : 15;
35
+ const displayLines = lines.slice(0, maxLines);
36
+ const remaining = lines.length - maxLines;
37
+ text += `\n${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
38
+ if (remaining > 0) {
39
+ text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
40
+ }
41
+ }
42
+ const matchLimit = result.details?.matchLimitReached;
43
+ const truncation = result.details?.truncation;
44
+ const linesTruncated = result.details?.linesTruncated;
45
+ if (matchLimit || truncation?.truncated || linesTruncated) {
46
+ const warnings = [];
47
+ if (matchLimit)
48
+ warnings.push(`${matchLimit} matches limit`);
49
+ if (truncation?.truncated)
50
+ warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
51
+ if (linesTruncated)
52
+ warnings.push("some lines truncated");
53
+ text += `\n${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
54
+ }
55
+ return text;
56
+ }
57
+ export const grepRenderers = {
58
+ renderCall(args, theme, context) {
59
+ const text = context.lastComponent ?? new Text("", 0, 0);
60
+ text.setText(formatGrepCall(args, theme));
61
+ return text;
62
+ },
63
+ renderResult(result, options, theme, context) {
64
+ const text = context.lastComponent ?? new Text("", 0, 0);
65
+ text.setText(formatGrepResult(result, options, theme, context.showImages));
66
+ return text;
67
+ },
68
+ };