@quickcall/krew 0.1.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 (728) hide show
  1. package/CHANGELOG.md +4178 -0
  2. package/README.md +653 -0
  3. package/dist/bun/cli.d.ts +3 -0
  4. package/dist/bun/cli.d.ts.map +1 -0
  5. package/dist/bun/cli.js +9 -0
  6. package/dist/bun/cli.js.map +1 -0
  7. package/dist/bun/register-bedrock.d.ts +2 -0
  8. package/dist/bun/register-bedrock.d.ts.map +1 -0
  9. package/dist/bun/register-bedrock.js +4 -0
  10. package/dist/bun/register-bedrock.js.map +1 -0
  11. package/dist/bun/restore-sandbox-env.d.ts +13 -0
  12. package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
  13. package/dist/bun/restore-sandbox-env.js +32 -0
  14. package/dist/bun/restore-sandbox-env.js.map +1 -0
  15. package/dist/cli/args.d.ts +54 -0
  16. package/dist/cli/args.d.ts.map +1 -0
  17. package/dist/cli/args.js +346 -0
  18. package/dist/cli/args.js.map +1 -0
  19. package/dist/cli/config-selector.d.ts +14 -0
  20. package/dist/cli/config-selector.d.ts.map +1 -0
  21. package/dist/cli/config-selector.js +31 -0
  22. package/dist/cli/config-selector.js.map +1 -0
  23. package/dist/cli/file-processor.d.ts +15 -0
  24. package/dist/cli/file-processor.d.ts.map +1 -0
  25. package/dist/cli/file-processor.js +83 -0
  26. package/dist/cli/file-processor.js.map +1 -0
  27. package/dist/cli/initial-message.d.ts +18 -0
  28. package/dist/cli/initial-message.d.ts.map +1 -0
  29. package/dist/cli/initial-message.js +22 -0
  30. package/dist/cli/initial-message.js.map +1 -0
  31. package/dist/cli/list-models.d.ts +9 -0
  32. package/dist/cli/list-models.d.ts.map +1 -0
  33. package/dist/cli/list-models.js +98 -0
  34. package/dist/cli/list-models.js.map +1 -0
  35. package/dist/cli/session-picker.d.ts +9 -0
  36. package/dist/cli/session-picker.d.ts.map +1 -0
  37. package/dist/cli/session-picker.js +35 -0
  38. package/dist/cli/session-picker.js.map +1 -0
  39. package/dist/cli.d.ts +3 -0
  40. package/dist/cli.d.ts.map +1 -0
  41. package/dist/cli.js +20 -0
  42. package/dist/cli.js.map +1 -0
  43. package/dist/config.d.ts +92 -0
  44. package/dist/config.d.ts.map +1 -0
  45. package/dist/config.js +399 -0
  46. package/dist/config.js.map +1 -0
  47. package/dist/core/agent-session-runtime.d.ts +117 -0
  48. package/dist/core/agent-session-runtime.d.ts.map +1 -0
  49. package/dist/core/agent-session-runtime.js +304 -0
  50. package/dist/core/agent-session-runtime.js.map +1 -0
  51. package/dist/core/agent-session-services.d.ts +86 -0
  52. package/dist/core/agent-session-services.d.ts.map +1 -0
  53. package/dist/core/agent-session-services.js +129 -0
  54. package/dist/core/agent-session-services.js.map +1 -0
  55. package/dist/core/agent-session.d.ts +595 -0
  56. package/dist/core/agent-session.d.ts.map +1 -0
  57. package/dist/core/agent-session.js +2521 -0
  58. package/dist/core/agent-session.js.map +1 -0
  59. package/dist/core/auth-guidance.d.ts +5 -0
  60. package/dist/core/auth-guidance.d.ts.map +1 -0
  61. package/dist/core/auth-guidance.js +21 -0
  62. package/dist/core/auth-guidance.js.map +1 -0
  63. package/dist/core/auth-storage.d.ts +141 -0
  64. package/dist/core/auth-storage.d.ts.map +1 -0
  65. package/dist/core/auth-storage.js +441 -0
  66. package/dist/core/auth-storage.js.map +1 -0
  67. package/dist/core/bash-executor.d.ts +32 -0
  68. package/dist/core/bash-executor.d.ts.map +1 -0
  69. package/dist/core/bash-executor.js +111 -0
  70. package/dist/core/bash-executor.js.map +1 -0
  71. package/dist/core/compaction/branch-summarization.d.ts +88 -0
  72. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  73. package/dist/core/compaction/branch-summarization.js +243 -0
  74. package/dist/core/compaction/branch-summarization.js.map +1 -0
  75. package/dist/core/compaction/compaction.d.ts +121 -0
  76. package/dist/core/compaction/compaction.d.ts.map +1 -0
  77. package/dist/core/compaction/compaction.js +615 -0
  78. package/dist/core/compaction/compaction.js.map +1 -0
  79. package/dist/core/compaction/index.d.ts +7 -0
  80. package/dist/core/compaction/index.d.ts.map +1 -0
  81. package/dist/core/compaction/index.js +7 -0
  82. package/dist/core/compaction/index.js.map +1 -0
  83. package/dist/core/compaction/utils.d.ts +38 -0
  84. package/dist/core/compaction/utils.d.ts.map +1 -0
  85. package/dist/core/compaction/utils.js +153 -0
  86. package/dist/core/compaction/utils.js.map +1 -0
  87. package/dist/core/defaults.d.ts +3 -0
  88. package/dist/core/defaults.d.ts.map +1 -0
  89. package/dist/core/defaults.js +2 -0
  90. package/dist/core/defaults.js.map +1 -0
  91. package/dist/core/diagnostics.d.ts +15 -0
  92. package/dist/core/diagnostics.d.ts.map +1 -0
  93. package/dist/core/diagnostics.js +2 -0
  94. package/dist/core/diagnostics.js.map +1 -0
  95. package/dist/core/event-bus.d.ts +9 -0
  96. package/dist/core/event-bus.d.ts.map +1 -0
  97. package/dist/core/event-bus.js +25 -0
  98. package/dist/core/event-bus.js.map +1 -0
  99. package/dist/core/exec.d.ts +29 -0
  100. package/dist/core/exec.d.ts.map +1 -0
  101. package/dist/core/exec.js +75 -0
  102. package/dist/core/exec.js.map +1 -0
  103. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  104. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  105. package/dist/core/export-html/ansi-to-html.js +249 -0
  106. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  107. package/dist/core/export-html/index.d.ts +37 -0
  108. package/dist/core/export-html/index.d.ts.map +1 -0
  109. package/dist/core/export-html/index.js +224 -0
  110. package/dist/core/export-html/index.js.map +1 -0
  111. package/dist/core/export-html/template.css +1066 -0
  112. package/dist/core/export-html/template.html +55 -0
  113. package/dist/core/export-html/template.js +1834 -0
  114. package/dist/core/export-html/tool-renderer.d.ts +34 -0
  115. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  116. package/dist/core/export-html/tool-renderer.js +108 -0
  117. package/dist/core/export-html/tool-renderer.js.map +1 -0
  118. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  119. package/dist/core/export-html/vendor/marked.min.js +6 -0
  120. package/dist/core/extensions/index.d.ts +12 -0
  121. package/dist/core/extensions/index.d.ts.map +1 -0
  122. package/dist/core/extensions/index.js +9 -0
  123. package/dist/core/extensions/index.js.map +1 -0
  124. package/dist/core/extensions/loader.d.ts +24 -0
  125. package/dist/core/extensions/loader.d.ts.map +1 -0
  126. package/dist/core/extensions/loader.js +498 -0
  127. package/dist/core/extensions/loader.js.map +1 -0
  128. package/dist/core/extensions/runner.d.ts +159 -0
  129. package/dist/core/extensions/runner.d.ts.map +1 -0
  130. package/dist/core/extensions/runner.js +824 -0
  131. package/dist/core/extensions/runner.js.map +1 -0
  132. package/dist/core/extensions/types.d.ts +1173 -0
  133. package/dist/core/extensions/types.d.ts.map +1 -0
  134. package/dist/core/extensions/types.js +45 -0
  135. package/dist/core/extensions/types.js.map +1 -0
  136. package/dist/core/extensions/wrapper.d.ts +20 -0
  137. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  138. package/dist/core/extensions/wrapper.js +22 -0
  139. package/dist/core/extensions/wrapper.js.map +1 -0
  140. package/dist/core/footer-data-provider.d.ts +52 -0
  141. package/dist/core/footer-data-provider.d.ts.map +1 -0
  142. package/dist/core/footer-data-provider.js +310 -0
  143. package/dist/core/footer-data-provider.js.map +1 -0
  144. package/dist/core/index.d.ts +12 -0
  145. package/dist/core/index.d.ts.map +1 -0
  146. package/dist/core/index.js +12 -0
  147. package/dist/core/index.js.map +1 -0
  148. package/dist/core/keybindings.d.ts +353 -0
  149. package/dist/core/keybindings.d.ts.map +1 -0
  150. package/dist/core/keybindings.js +295 -0
  151. package/dist/core/keybindings.js.map +1 -0
  152. package/dist/core/messages.d.ts +77 -0
  153. package/dist/core/messages.d.ts.map +1 -0
  154. package/dist/core/messages.js +123 -0
  155. package/dist/core/messages.js.map +1 -0
  156. package/dist/core/model-registry.d.ts +150 -0
  157. package/dist/core/model-registry.d.ts.map +1 -0
  158. package/dist/core/model-registry.js +728 -0
  159. package/dist/core/model-registry.js.map +1 -0
  160. package/dist/core/model-resolver.d.ts +110 -0
  161. package/dist/core/model-resolver.d.ts.map +1 -0
  162. package/dist/core/model-resolver.js +495 -0
  163. package/dist/core/model-resolver.js.map +1 -0
  164. package/dist/core/output-guard.d.ts +6 -0
  165. package/dist/core/output-guard.d.ts.map +1 -0
  166. package/dist/core/output-guard.js +59 -0
  167. package/dist/core/output-guard.js.map +1 -0
  168. package/dist/core/package-manager.d.ts +198 -0
  169. package/dist/core/package-manager.d.ts.map +1 -0
  170. package/dist/core/package-manager.js +1975 -0
  171. package/dist/core/package-manager.js.map +1 -0
  172. package/dist/core/prompt-templates.d.ts +52 -0
  173. package/dist/core/prompt-templates.d.ts.map +1 -0
  174. package/dist/core/prompt-templates.js +250 -0
  175. package/dist/core/prompt-templates.js.map +1 -0
  176. package/dist/core/provider-display-names.d.ts +2 -0
  177. package/dist/core/provider-display-names.d.ts.map +1 -0
  178. package/dist/core/provider-display-names.js +33 -0
  179. package/dist/core/provider-display-names.js.map +1 -0
  180. package/dist/core/resolve-config-value.d.ts +23 -0
  181. package/dist/core/resolve-config-value.d.ts.map +1 -0
  182. package/dist/core/resolve-config-value.js +126 -0
  183. package/dist/core/resolve-config-value.js.map +1 -0
  184. package/dist/core/resource-loader.d.ts +194 -0
  185. package/dist/core/resource-loader.d.ts.map +1 -0
  186. package/dist/core/resource-loader.js +732 -0
  187. package/dist/core/resource-loader.js.map +1 -0
  188. package/dist/core/sdk.d.ts +107 -0
  189. package/dist/core/sdk.d.ts.map +1 -0
  190. package/dist/core/sdk.js +282 -0
  191. package/dist/core/sdk.js.map +1 -0
  192. package/dist/core/session-cwd.d.ts +19 -0
  193. package/dist/core/session-cwd.d.ts.map +1 -0
  194. package/dist/core/session-cwd.js +38 -0
  195. package/dist/core/session-cwd.js.map +1 -0
  196. package/dist/core/session-manager.d.ts +333 -0
  197. package/dist/core/session-manager.d.ts.map +1 -0
  198. package/dist/core/session-manager.js +1109 -0
  199. package/dist/core/session-manager.js.map +1 -0
  200. package/dist/core/settings-manager.d.ts +261 -0
  201. package/dist/core/settings-manager.d.ts.map +1 -0
  202. package/dist/core/settings-manager.js +782 -0
  203. package/dist/core/settings-manager.js.map +1 -0
  204. package/dist/core/skills.d.ts +60 -0
  205. package/dist/core/skills.d.ts.map +1 -0
  206. package/dist/core/skills.js +404 -0
  207. package/dist/core/skills.js.map +1 -0
  208. package/dist/core/slash-commands.d.ts +14 -0
  209. package/dist/core/slash-commands.d.ts.map +1 -0
  210. package/dist/core/slash-commands.js +25 -0
  211. package/dist/core/slash-commands.js.map +1 -0
  212. package/dist/core/source-info.d.ts +18 -0
  213. package/dist/core/source-info.d.ts.map +1 -0
  214. package/dist/core/source-info.js +19 -0
  215. package/dist/core/source-info.js.map +1 -0
  216. package/dist/core/system-prompt.d.ts +28 -0
  217. package/dist/core/system-prompt.d.ts.map +1 -0
  218. package/dist/core/system-prompt.js +119 -0
  219. package/dist/core/system-prompt.js.map +1 -0
  220. package/dist/core/telemetry-config.d.ts +19 -0
  221. package/dist/core/telemetry-config.d.ts.map +1 -0
  222. package/dist/core/telemetry-config.js +66 -0
  223. package/dist/core/telemetry-config.js.map +1 -0
  224. package/dist/core/telemetry-sync.d.ts +50 -0
  225. package/dist/core/telemetry-sync.d.ts.map +1 -0
  226. package/dist/core/telemetry-sync.js +580 -0
  227. package/dist/core/telemetry-sync.js.map +1 -0
  228. package/dist/core/telemetry.d.ts +3 -0
  229. package/dist/core/telemetry.d.ts.map +1 -0
  230. package/dist/core/telemetry.js +9 -0
  231. package/dist/core/telemetry.js.map +1 -0
  232. package/dist/core/timings.d.ts +8 -0
  233. package/dist/core/timings.d.ts.map +1 -0
  234. package/dist/core/timings.js +31 -0
  235. package/dist/core/timings.js.map +1 -0
  236. package/dist/core/tools/bash.d.ts +68 -0
  237. package/dist/core/tools/bash.d.ts.map +1 -0
  238. package/dist/core/tools/bash.js +335 -0
  239. package/dist/core/tools/bash.js.map +1 -0
  240. package/dist/core/tools/edit-diff.d.ts +85 -0
  241. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  242. package/dist/core/tools/edit-diff.js +338 -0
  243. package/dist/core/tools/edit-diff.js.map +1 -0
  244. package/dist/core/tools/edit.d.ts +49 -0
  245. package/dist/core/tools/edit.d.ts.map +1 -0
  246. package/dist/core/tools/edit.js +324 -0
  247. package/dist/core/tools/edit.js.map +1 -0
  248. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  249. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  250. package/dist/core/tools/file-mutation-queue.js +37 -0
  251. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  252. package/dist/core/tools/find.d.ts +35 -0
  253. package/dist/core/tools/find.d.ts.map +1 -0
  254. package/dist/core/tools/find.js +298 -0
  255. package/dist/core/tools/find.js.map +1 -0
  256. package/dist/core/tools/grep.d.ts +37 -0
  257. package/dist/core/tools/grep.d.ts.map +1 -0
  258. package/dist/core/tools/grep.js +304 -0
  259. package/dist/core/tools/grep.js.map +1 -0
  260. package/dist/core/tools/index.d.ts +40 -0
  261. package/dist/core/tools/index.d.ts.map +1 -0
  262. package/dist/core/tools/index.js +112 -0
  263. package/dist/core/tools/index.js.map +1 -0
  264. package/dist/core/tools/ls.d.ts +37 -0
  265. package/dist/core/tools/ls.d.ts.map +1 -0
  266. package/dist/core/tools/ls.js +169 -0
  267. package/dist/core/tools/ls.js.map +1 -0
  268. package/dist/core/tools/output-accumulator.d.ts +50 -0
  269. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  270. package/dist/core/tools/output-accumulator.js +178 -0
  271. package/dist/core/tools/output-accumulator.js.map +1 -0
  272. package/dist/core/tools/path-utils.d.ts +8 -0
  273. package/dist/core/tools/path-utils.d.ts.map +1 -0
  274. package/dist/core/tools/path-utils.js +81 -0
  275. package/dist/core/tools/path-utils.js.map +1 -0
  276. package/dist/core/tools/read.d.ts +35 -0
  277. package/dist/core/tools/read.d.ts.map +1 -0
  278. package/dist/core/tools/read.js +296 -0
  279. package/dist/core/tools/read.js.map +1 -0
  280. package/dist/core/tools/render-utils.d.ts +21 -0
  281. package/dist/core/tools/render-utils.d.ts.map +1 -0
  282. package/dist/core/tools/render-utils.js +49 -0
  283. package/dist/core/tools/render-utils.js.map +1 -0
  284. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  285. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  286. package/dist/core/tools/tool-definition-wrapper.js +34 -0
  287. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  288. package/dist/core/tools/truncate.d.ts +70 -0
  289. package/dist/core/tools/truncate.d.ts.map +1 -0
  290. package/dist/core/tools/truncate.js +205 -0
  291. package/dist/core/tools/truncate.js.map +1 -0
  292. package/dist/core/tools/write.d.ts +26 -0
  293. package/dist/core/tools/write.d.ts.map +1 -0
  294. package/dist/core/tools/write.js +213 -0
  295. package/dist/core/tools/write.js.map +1 -0
  296. package/dist/index.d.ts +29 -0
  297. package/dist/index.d.ts.map +1 -0
  298. package/dist/index.js +43 -0
  299. package/dist/index.js.map +1 -0
  300. package/dist/main.d.ts +12 -0
  301. package/dist/main.d.ts.map +1 -0
  302. package/dist/main.js +619 -0
  303. package/dist/main.js.map +1 -0
  304. package/dist/migrations.d.ts +33 -0
  305. package/dist/migrations.d.ts.map +1 -0
  306. package/dist/migrations.js +281 -0
  307. package/dist/migrations.js.map +1 -0
  308. package/dist/modes/index.d.ts +9 -0
  309. package/dist/modes/index.d.ts.map +1 -0
  310. package/dist/modes/index.js +8 -0
  311. package/dist/modes/index.js.map +1 -0
  312. package/dist/modes/interactive/assets/clankolas.png +0 -0
  313. package/dist/modes/interactive/components/armin.d.ts +34 -0
  314. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  315. package/dist/modes/interactive/components/armin.js +333 -0
  316. package/dist/modes/interactive/components/armin.js.map +1 -0
  317. package/dist/modes/interactive/components/assistant-message.d.ts +20 -0
  318. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  319. package/dist/modes/interactive/components/assistant-message.js +121 -0
  320. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  321. package/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  322. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  323. package/dist/modes/interactive/components/bash-execution.js +175 -0
  324. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  325. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  326. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  327. package/dist/modes/interactive/components/bordered-loader.js +54 -0
  328. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  329. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  330. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  331. package/dist/modes/interactive/components/branch-summary-message.js +44 -0
  332. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  333. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  334. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  335. package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
  336. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  337. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  338. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  339. package/dist/modes/interactive/components/config-selector.js +503 -0
  340. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  341. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  342. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  343. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  344. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  345. package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  346. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  347. package/dist/modes/interactive/components/custom-editor.js +70 -0
  348. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  349. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  350. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  351. package/dist/modes/interactive/components/custom-message.js +79 -0
  352. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  353. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  354. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  355. package/dist/modes/interactive/components/daxnuts.js +140 -0
  356. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  357. package/dist/modes/interactive/components/diff.d.ts +12 -0
  358. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  359. package/dist/modes/interactive/components/diff.js +133 -0
  360. package/dist/modes/interactive/components/diff.js.map +1 -0
  361. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  362. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  363. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  364. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  365. package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  366. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
  367. package/dist/modes/interactive/components/earendil-announcement.js +40 -0
  368. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
  369. package/dist/modes/interactive/components/extension-editor.d.ts +20 -0
  370. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  371. package/dist/modes/interactive/components/extension-editor.js +111 -0
  372. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  373. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  374. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  375. package/dist/modes/interactive/components/extension-input.js +61 -0
  376. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  377. package/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  378. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  379. package/dist/modes/interactive/components/extension-selector.js +83 -0
  380. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  381. package/dist/modes/interactive/components/footer.d.ts +27 -0
  382. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  383. package/dist/modes/interactive/components/footer.js +201 -0
  384. package/dist/modes/interactive/components/footer.js.map +1 -0
  385. package/dist/modes/interactive/components/index.d.ts +32 -0
  386. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  387. package/dist/modes/interactive/components/index.js +33 -0
  388. package/dist/modes/interactive/components/index.js.map +1 -0
  389. package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  390. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  391. package/dist/modes/interactive/components/keybinding-hints.js +36 -0
  392. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  393. package/dist/modes/interactive/components/login-dialog.d.ts +46 -0
  394. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  395. package/dist/modes/interactive/components/login-dialog.js +160 -0
  396. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  397. package/dist/modes/interactive/components/model-selector.d.ts +47 -0
  398. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  399. package/dist/modes/interactive/components/model-selector.js +278 -0
  400. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  401. package/dist/modes/interactive/components/oauth-selector.d.ts +31 -0
  402. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  403. package/dist/modes/interactive/components/oauth-selector.js +165 -0
  404. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  405. package/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  406. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  407. package/dist/modes/interactive/components/scoped-models-selector.js +290 -0
  408. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  409. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  410. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  411. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  412. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  413. package/dist/modes/interactive/components/session-selector.d.ts +96 -0
  414. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  415. package/dist/modes/interactive/components/session-selector.js +861 -0
  416. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  417. package/dist/modes/interactive/components/settings-selector.d.ts +67 -0
  418. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  419. package/dist/modes/interactive/components/settings-selector.js +375 -0
  420. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  421. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  422. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  423. package/dist/modes/interactive/components/show-images-selector.js +39 -0
  424. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  425. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  426. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  427. package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
  428. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  429. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  430. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  431. package/dist/modes/interactive/components/theme-selector.js +50 -0
  432. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  433. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  434. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  435. package/dist/modes/interactive/components/thinking-selector.js +51 -0
  436. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  437. package/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  438. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  439. package/dist/modes/interactive/components/tool-execution.js +295 -0
  440. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  441. package/dist/modes/interactive/components/tree-selector.d.ts +89 -0
  442. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  443. package/dist/modes/interactive/components/tree-selector.js +1093 -0
  444. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  445. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  446. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  447. package/dist/modes/interactive/components/user-message-selector.js +114 -0
  448. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  449. package/dist/modes/interactive/components/user-message.d.ts +10 -0
  450. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  451. package/dist/modes/interactive/components/user-message.js +29 -0
  452. package/dist/modes/interactive/components/user-message.js.map +1 -0
  453. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  454. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  455. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  456. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  457. package/dist/modes/interactive/interactive-mode.d.ts +369 -0
  458. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  459. package/dist/modes/interactive/interactive-mode.js +4615 -0
  460. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  461. package/dist/modes/interactive/theme/dark.json +85 -0
  462. package/dist/modes/interactive/theme/light.json +84 -0
  463. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  464. package/dist/modes/interactive/theme/theme.d.ts +81 -0
  465. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  466. package/dist/modes/interactive/theme/theme.js +973 -0
  467. package/dist/modes/interactive/theme/theme.js.map +1 -0
  468. package/dist/modes/print-mode.d.ts +28 -0
  469. package/dist/modes/print-mode.d.ts.map +1 -0
  470. package/dist/modes/print-mode.js +131 -0
  471. package/dist/modes/print-mode.js.map +1 -0
  472. package/dist/modes/rpc/jsonl.d.ts +17 -0
  473. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  474. package/dist/modes/rpc/jsonl.js +49 -0
  475. package/dist/modes/rpc/jsonl.js.map +1 -0
  476. package/dist/modes/rpc/rpc-client.d.ts +224 -0
  477. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  478. package/dist/modes/rpc/rpc-client.js +410 -0
  479. package/dist/modes/rpc/rpc-client.js.map +1 -0
  480. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  481. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  482. package/dist/modes/rpc/rpc-mode.js +601 -0
  483. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  484. package/dist/modes/rpc/rpc-types.d.ts +419 -0
  485. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  486. package/dist/modes/rpc/rpc-types.js +8 -0
  487. package/dist/modes/rpc/rpc-types.js.map +1 -0
  488. package/dist/package-manager-cli.d.ts +4 -0
  489. package/dist/package-manager-cli.d.ts.map +1 -0
  490. package/dist/package-manager-cli.js +460 -0
  491. package/dist/package-manager-cli.js.map +1 -0
  492. package/dist/utils/ansi.d.ts +2 -0
  493. package/dist/utils/ansi.d.ts.map +1 -0
  494. package/dist/utils/ansi.js +77 -0
  495. package/dist/utils/ansi.js.map +1 -0
  496. package/dist/utils/changelog.d.ts +21 -0
  497. package/dist/utils/changelog.d.ts.map +1 -0
  498. package/dist/utils/changelog.js +87 -0
  499. package/dist/utils/changelog.js.map +1 -0
  500. package/dist/utils/child-process.d.ts +12 -0
  501. package/dist/utils/child-process.d.ts.map +1 -0
  502. package/dist/utils/child-process.js +86 -0
  503. package/dist/utils/child-process.js.map +1 -0
  504. package/dist/utils/clipboard-image.d.ts +11 -0
  505. package/dist/utils/clipboard-image.d.ts.map +1 -0
  506. package/dist/utils/clipboard-image.js +245 -0
  507. package/dist/utils/clipboard-image.js.map +1 -0
  508. package/dist/utils/clipboard-native.d.ts +8 -0
  509. package/dist/utils/clipboard-native.d.ts.map +1 -0
  510. package/dist/utils/clipboard-native.js +14 -0
  511. package/dist/utils/clipboard-native.js.map +1 -0
  512. package/dist/utils/clipboard.d.ts +2 -0
  513. package/dist/utils/clipboard.d.ts.map +1 -0
  514. package/dist/utils/clipboard.js +117 -0
  515. package/dist/utils/clipboard.js.map +1 -0
  516. package/dist/utils/exif-orientation.d.ts +5 -0
  517. package/dist/utils/exif-orientation.d.ts.map +1 -0
  518. package/dist/utils/exif-orientation.js +158 -0
  519. package/dist/utils/exif-orientation.js.map +1 -0
  520. package/dist/utils/frontmatter.d.ts +8 -0
  521. package/dist/utils/frontmatter.d.ts.map +1 -0
  522. package/dist/utils/frontmatter.js +26 -0
  523. package/dist/utils/frontmatter.js.map +1 -0
  524. package/dist/utils/fs-watch.d.ts +5 -0
  525. package/dist/utils/fs-watch.d.ts.map +1 -0
  526. package/dist/utils/fs-watch.js +25 -0
  527. package/dist/utils/fs-watch.js.map +1 -0
  528. package/dist/utils/git.d.ts +26 -0
  529. package/dist/utils/git.d.ts.map +1 -0
  530. package/dist/utils/git.js +163 -0
  531. package/dist/utils/git.js.map +1 -0
  532. package/dist/utils/image-convert.d.ts +9 -0
  533. package/dist/utils/image-convert.d.ts.map +1 -0
  534. package/dist/utils/image-convert.js +39 -0
  535. package/dist/utils/image-convert.js.map +1 -0
  536. package/dist/utils/image-resize.d.ts +36 -0
  537. package/dist/utils/image-resize.d.ts.map +1 -0
  538. package/dist/utils/image-resize.js +137 -0
  539. package/dist/utils/image-resize.js.map +1 -0
  540. package/dist/utils/mime.d.ts +3 -0
  541. package/dist/utils/mime.d.ts.map +1 -0
  542. package/dist/utils/mime.js +69 -0
  543. package/dist/utils/mime.js.map +1 -0
  544. package/dist/utils/paths.d.ts +16 -0
  545. package/dist/utils/paths.d.ts.map +1 -0
  546. package/dist/utils/paths.js +50 -0
  547. package/dist/utils/paths.js.map +1 -0
  548. package/dist/utils/photon.d.ts +21 -0
  549. package/dist/utils/photon.d.ts.map +1 -0
  550. package/dist/utils/photon.js +121 -0
  551. package/dist/utils/photon.js.map +1 -0
  552. package/dist/utils/pi-user-agent.d.ts +2 -0
  553. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  554. package/dist/utils/pi-user-agent.js +5 -0
  555. package/dist/utils/pi-user-agent.js.map +1 -0
  556. package/dist/utils/shell.d.ts +30 -0
  557. package/dist/utils/shell.d.ts.map +1 -0
  558. package/dist/utils/shell.js +190 -0
  559. package/dist/utils/shell.js.map +1 -0
  560. package/dist/utils/sleep.d.ts +5 -0
  561. package/dist/utils/sleep.d.ts.map +1 -0
  562. package/dist/utils/sleep.js +17 -0
  563. package/dist/utils/sleep.js.map +1 -0
  564. package/dist/utils/tools-manager.d.ts +3 -0
  565. package/dist/utils/tools-manager.d.ts.map +1 -0
  566. package/dist/utils/tools-manager.js +325 -0
  567. package/dist/utils/tools-manager.js.map +1 -0
  568. package/dist/utils/uuid.d.ts +2 -0
  569. package/dist/utils/uuid.d.ts.map +1 -0
  570. package/dist/utils/uuid.js +40 -0
  571. package/dist/utils/uuid.js.map +1 -0
  572. package/dist/utils/version-check.d.ts +14 -0
  573. package/dist/utils/version-check.d.ts.map +1 -0
  574. package/dist/utils/version-check.js +77 -0
  575. package/dist/utils/version-check.js.map +1 -0
  576. package/docs/compaction.md +394 -0
  577. package/docs/custom-provider.md +646 -0
  578. package/docs/development.md +71 -0
  579. package/docs/docs.json +148 -0
  580. package/docs/extensions.md +2596 -0
  581. package/docs/images/doom-extension.png +0 -0
  582. package/docs/images/exy.png +0 -0
  583. package/docs/images/interactive-mode.png +0 -0
  584. package/docs/images/tree-view.png +0 -0
  585. package/docs/index.md +70 -0
  586. package/docs/json.md +82 -0
  587. package/docs/keybindings.md +197 -0
  588. package/docs/models.md +474 -0
  589. package/docs/packages.md +223 -0
  590. package/docs/prompt-templates.md +88 -0
  591. package/docs/providers.md +243 -0
  592. package/docs/quickstart.md +142 -0
  593. package/docs/rpc.md +1407 -0
  594. package/docs/sdk.md +1129 -0
  595. package/docs/session-format.md +412 -0
  596. package/docs/sessions.md +137 -0
  597. package/docs/settings.md +279 -0
  598. package/docs/shell-aliases.md +13 -0
  599. package/docs/skills.md +232 -0
  600. package/docs/terminal-setup.md +106 -0
  601. package/docs/termux.md +127 -0
  602. package/docs/themes.md +295 -0
  603. package/docs/tmux.md +61 -0
  604. package/docs/tui.md +918 -0
  605. package/docs/usage.md +277 -0
  606. package/docs/windows.md +17 -0
  607. package/examples/README.md +25 -0
  608. package/examples/extensions/README.md +208 -0
  609. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  610. package/examples/extensions/bash-spawn-hook.ts +30 -0
  611. package/examples/extensions/bookmark.ts +50 -0
  612. package/examples/extensions/border-status-editor.ts +150 -0
  613. package/examples/extensions/built-in-tool-renderer.ts +249 -0
  614. package/examples/extensions/claude-rules.ts +86 -0
  615. package/examples/extensions/commands.ts +72 -0
  616. package/examples/extensions/confirm-destructive.ts +59 -0
  617. package/examples/extensions/custom-compaction.ts +127 -0
  618. package/examples/extensions/custom-footer.ts +64 -0
  619. package/examples/extensions/custom-header.ts +73 -0
  620. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  621. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  622. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  623. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  624. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  625. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  626. package/examples/extensions/dirty-repo-guard.ts +56 -0
  627. package/examples/extensions/doom-overlay/README.md +46 -0
  628. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  629. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  630. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  631. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  632. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  633. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  634. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  635. package/examples/extensions/doom-overlay/index.ts +74 -0
  636. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  637. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  638. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  639. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  640. package/examples/extensions/dynamic-resources/index.ts +15 -0
  641. package/examples/extensions/dynamic-tools.ts +74 -0
  642. package/examples/extensions/event-bus.ts +43 -0
  643. package/examples/extensions/file-trigger.ts +41 -0
  644. package/examples/extensions/git-checkpoint.ts +53 -0
  645. package/examples/extensions/github-issue-autocomplete.ts +185 -0
  646. package/examples/extensions/handoff.ts +191 -0
  647. package/examples/extensions/hello.ts +26 -0
  648. package/examples/extensions/hidden-thinking-label.ts +53 -0
  649. package/examples/extensions/inline-bash.ts +94 -0
  650. package/examples/extensions/input-transform.ts +43 -0
  651. package/examples/extensions/interactive-shell.ts +196 -0
  652. package/examples/extensions/mac-system-theme.ts +47 -0
  653. package/examples/extensions/message-renderer.ts +59 -0
  654. package/examples/extensions/minimal-mode.ts +426 -0
  655. package/examples/extensions/modal-editor.ts +85 -0
  656. package/examples/extensions/model-status.ts +31 -0
  657. package/examples/extensions/notify.ts +55 -0
  658. package/examples/extensions/overlay-qa-tests.ts +1348 -0
  659. package/examples/extensions/overlay-test.ts +150 -0
  660. package/examples/extensions/permission-gate.ts +34 -0
  661. package/examples/extensions/pirate.ts +47 -0
  662. package/examples/extensions/plan-mode/README.md +65 -0
  663. package/examples/extensions/plan-mode/index.ts +340 -0
  664. package/examples/extensions/plan-mode/utils.ts +168 -0
  665. package/examples/extensions/preset.ts +430 -0
  666. package/examples/extensions/prompt-customizer.ts +97 -0
  667. package/examples/extensions/protected-paths.ts +30 -0
  668. package/examples/extensions/provider-payload.ts +18 -0
  669. package/examples/extensions/qna.ts +122 -0
  670. package/examples/extensions/question.ts +264 -0
  671. package/examples/extensions/questionnaire.ts +427 -0
  672. package/examples/extensions/rainbow-editor.ts +88 -0
  673. package/examples/extensions/reload-runtime.ts +37 -0
  674. package/examples/extensions/rpc-demo.ts +118 -0
  675. package/examples/extensions/sandbox/index.ts +321 -0
  676. package/examples/extensions/sandbox/package-lock.json +92 -0
  677. package/examples/extensions/sandbox/package.json +19 -0
  678. package/examples/extensions/send-user-message.ts +97 -0
  679. package/examples/extensions/session-name.ts +27 -0
  680. package/examples/extensions/shutdown-command.ts +63 -0
  681. package/examples/extensions/snake.ts +343 -0
  682. package/examples/extensions/space-invaders.ts +560 -0
  683. package/examples/extensions/ssh.ts +220 -0
  684. package/examples/extensions/status-line.ts +32 -0
  685. package/examples/extensions/structured-output.ts +65 -0
  686. package/examples/extensions/subagent/README.md +172 -0
  687. package/examples/extensions/subagent/agents/planner.md +37 -0
  688. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  689. package/examples/extensions/subagent/agents/scout.md +50 -0
  690. package/examples/extensions/subagent/agents/worker.md +24 -0
  691. package/examples/extensions/subagent/agents.ts +126 -0
  692. package/examples/extensions/subagent/index.ts +987 -0
  693. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  694. package/examples/extensions/subagent/prompts/implement.md +10 -0
  695. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  696. package/examples/extensions/summarize.ts +206 -0
  697. package/examples/extensions/system-prompt-header.ts +17 -0
  698. package/examples/extensions/telemetry.ts +49 -0
  699. package/examples/extensions/tic-tac-toe.ts +1008 -0
  700. package/examples/extensions/timed-confirm.ts +70 -0
  701. package/examples/extensions/titlebar-spinner.ts +58 -0
  702. package/examples/extensions/todo.ts +297 -0
  703. package/examples/extensions/tool-override.ts +144 -0
  704. package/examples/extensions/tools.ts +141 -0
  705. package/examples/extensions/trigger-compact.ts +50 -0
  706. package/examples/extensions/truncated-tool.ts +195 -0
  707. package/examples/extensions/widget-placement.ts +9 -0
  708. package/examples/extensions/with-deps/index.ts +32 -0
  709. package/examples/extensions/with-deps/package-lock.json +31 -0
  710. package/examples/extensions/with-deps/package.json +22 -0
  711. package/examples/extensions/working-indicator.ts +123 -0
  712. package/examples/extensions/working-message-test.ts +25 -0
  713. package/examples/rpc-extension-ui.ts +632 -0
  714. package/examples/sdk/01-minimal.ts +26 -0
  715. package/examples/sdk/02-custom-model.ts +53 -0
  716. package/examples/sdk/03-custom-prompt.ts +75 -0
  717. package/examples/sdk/04-skills.ts +55 -0
  718. package/examples/sdk/05-tools.ts +48 -0
  719. package/examples/sdk/06-extensions.ts +99 -0
  720. package/examples/sdk/07-context-files.ts +47 -0
  721. package/examples/sdk/08-prompt-templates.ts +51 -0
  722. package/examples/sdk/09-api-keys-and-oauth.ts +52 -0
  723. package/examples/sdk/10-settings.ts +53 -0
  724. package/examples/sdk/11-sessions.ts +52 -0
  725. package/examples/sdk/12-full-control.ts +77 -0
  726. package/examples/sdk/13-session-runtime.ts +67 -0
  727. package/examples/sdk/README.md +144 -0
  728. package/package.json +99 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/core/telemetry.ts"],"names":[],"mappings":"AAEA,SAAS,eAAe,CAAC,KAAyB,EAAW;IAC5D,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,OAAO,KAAK,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC;AAAA,CACxF;AAED,MAAM,UAAU,yBAAyB,CACxC,eAAgC,EAChC,YAAY,GAAuB,OAAO,CAAC,GAAG,CAAC,YAAY,EACjD;IACV,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,yBAAyB,EAAE,CAAC;AAAA,CAChH","sourcesContent":["import type { SettingsManager } from \"./settings-manager.js\";\n\nfunction isTruthyEnvFlag(value: string | undefined): boolean {\n\tif (!value) return false;\n\treturn value === \"1\" || value.toLowerCase() === \"true\" || value.toLowerCase() === \"yes\";\n}\n\nexport function isInstallTelemetryEnabled(\n\tsettingsManager: SettingsManager,\n\ttelemetryEnv: string | undefined = process.env.PI_TELEMETRY,\n): boolean {\n\treturn telemetryEnv !== undefined ? isTruthyEnvFlag(telemetryEnv) : settingsManager.getEnableInstallTelemetry();\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Central timing instrumentation for startup profiling.
3
+ * Enable with PI_TIMING=1 environment variable.
4
+ */
5
+ export declare function resetTimings(): void;
6
+ export declare function time(label: string): void;
7
+ export declare function printTimings(): void;
8
+ //# sourceMappingURL=timings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timings.d.ts","sourceRoot":"","sources":["../../src/core/timings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,wBAAgB,YAAY,IAAI,IAAI,CAInC;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAKxC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAQnC","sourcesContent":["/**\n * Central timing instrumentation for startup profiling.\n * Enable with PI_TIMING=1 environment variable.\n */\n\nconst ENABLED = process.env.PI_TIMING === \"1\";\nconst timings: Array<{ label: string; ms: number }> = [];\nlet lastTime = Date.now();\n\nexport function resetTimings(): void {\n\tif (!ENABLED) return;\n\ttimings.length = 0;\n\tlastTime = Date.now();\n}\n\nexport function time(label: string): void {\n\tif (!ENABLED) return;\n\tconst now = Date.now();\n\ttimings.push({ label, ms: now - lastTime });\n\tlastTime = now;\n}\n\nexport function printTimings(): void {\n\tif (!ENABLED || timings.length === 0) return;\n\tconsole.error(\"\\n--- Startup Timings ---\");\n\tfor (const t of timings) {\n\t\tconsole.error(` ${t.label}: ${t.ms}ms`);\n\t}\n\tconsole.error(` TOTAL: ${timings.reduce((a, b) => a + b.ms, 0)}ms`);\n\tconsole.error(\"------------------------\\n\");\n}\n"]}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Central timing instrumentation for startup profiling.
3
+ * Enable with PI_TIMING=1 environment variable.
4
+ */
5
+ const ENABLED = process.env.PI_TIMING === "1";
6
+ const timings = [];
7
+ let lastTime = Date.now();
8
+ export function resetTimings() {
9
+ if (!ENABLED)
10
+ return;
11
+ timings.length = 0;
12
+ lastTime = Date.now();
13
+ }
14
+ export function time(label) {
15
+ if (!ENABLED)
16
+ return;
17
+ const now = Date.now();
18
+ timings.push({ label, ms: now - lastTime });
19
+ lastTime = now;
20
+ }
21
+ export function printTimings() {
22
+ if (!ENABLED || timings.length === 0)
23
+ return;
24
+ console.error("\n--- Startup Timings ---");
25
+ for (const t of timings) {
26
+ console.error(` ${t.label}: ${t.ms}ms`);
27
+ }
28
+ console.error(` TOTAL: ${timings.reduce((a, b) => a + b.ms, 0)}ms`);
29
+ console.error("------------------------\n");
30
+ }
31
+ //# sourceMappingURL=timings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timings.js","sourceRoot":"","sources":["../../src/core/timings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC;AAC9C,MAAM,OAAO,GAAyC,EAAE,CAAC;AACzD,IAAI,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAE1B,MAAM,UAAU,YAAY,GAAS;IACpC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IACnB,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAAA,CACtB;AAED,MAAM,UAAU,IAAI,CAAC,KAAa,EAAQ;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,GAAG,QAAQ,EAAE,CAAC,CAAC;IAC5C,QAAQ,GAAG,GAAG,CAAC;AAAA,CACf;AAED,MAAM,UAAU,YAAY,GAAS;IACpC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC7C,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,YAAY,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACrE,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;AAAA,CAC5C","sourcesContent":["/**\n * Central timing instrumentation for startup profiling.\n * Enable with PI_TIMING=1 environment variable.\n */\n\nconst ENABLED = process.env.PI_TIMING === \"1\";\nconst timings: Array<{ label: string; ms: number }> = [];\nlet lastTime = Date.now();\n\nexport function resetTimings(): void {\n\tif (!ENABLED) return;\n\ttimings.length = 0;\n\tlastTime = Date.now();\n}\n\nexport function time(label: string): void {\n\tif (!ENABLED) return;\n\tconst now = Date.now();\n\ttimings.push({ label, ms: now - lastTime });\n\tlastTime = now;\n}\n\nexport function printTimings(): void {\n\tif (!ENABLED || timings.length === 0) return;\n\tconsole.error(\"\\n--- Startup Timings ---\");\n\tfor (const t of timings) {\n\t\tconsole.error(` ${t.label}: ${t.ms}ms`);\n\t}\n\tconsole.error(` TOTAL: ${timings.reduce((a, b) => a + b.ms, 0)}ms`);\n\tconsole.error(\"------------------------\\n\");\n}\n"]}
@@ -0,0 +1,68 @@
1
+ import type { AgentTool } from "@earendil-works/pi-agent-core";
2
+ import { type Static, Type } from "typebox";
3
+ import type { ToolDefinition } from "../extensions/types.js";
4
+ import { type TruncationResult } from "./truncate.js";
5
+ declare const bashSchema: Type.TObject<{
6
+ command: Type.TString;
7
+ timeout: Type.TOptional<Type.TNumber>;
8
+ }>;
9
+ export type BashToolInput = Static<typeof bashSchema>;
10
+ export interface BashToolDetails {
11
+ truncation?: TruncationResult;
12
+ fullOutputPath?: string;
13
+ }
14
+ /**
15
+ * Pluggable operations for the bash tool.
16
+ * Override these to delegate command execution to remote systems (for example SSH).
17
+ */
18
+ export interface BashOperations {
19
+ /**
20
+ * Execute a command and stream output.
21
+ * @param command The command to execute
22
+ * @param cwd Working directory
23
+ * @param options Execution options
24
+ * @returns Promise resolving to exit code (null if killed)
25
+ */
26
+ exec: (command: string, cwd: string, options: {
27
+ onData: (data: Buffer) => void;
28
+ signal?: AbortSignal;
29
+ timeout?: number;
30
+ env?: NodeJS.ProcessEnv;
31
+ }) => Promise<{
32
+ exitCode: number | null;
33
+ }>;
34
+ }
35
+ /**
36
+ * Create bash operations using pi's built-in local shell execution backend.
37
+ *
38
+ * This is useful for extensions that intercept user_bash and still want pi's
39
+ * standard local shell behavior while wrapping or rewriting commands.
40
+ */
41
+ export declare function createLocalBashOperations(options?: {
42
+ shellPath?: string;
43
+ }): BashOperations;
44
+ export interface BashSpawnContext {
45
+ command: string;
46
+ cwd: string;
47
+ env: NodeJS.ProcessEnv;
48
+ }
49
+ export type BashSpawnHook = (context: BashSpawnContext) => BashSpawnContext;
50
+ export interface BashToolOptions {
51
+ /** Custom operations for command execution. Default: local shell */
52
+ operations?: BashOperations;
53
+ /** Command prefix prepended to every command (for example shell setup commands) */
54
+ commandPrefix?: string;
55
+ /** Optional explicit shell path from settings */
56
+ shellPath?: string;
57
+ /** Hook to adjust command, cwd, or env before execution */
58
+ spawnHook?: BashSpawnHook;
59
+ }
60
+ type BashRenderState = {
61
+ startedAt: number | undefined;
62
+ endedAt: number | undefined;
63
+ interval: NodeJS.Timeout | undefined;
64
+ };
65
+ export declare function createBashToolDefinition(cwd: string, options?: BashToolOptions): ToolDefinition<typeof bashSchema, BashToolDetails | undefined, BashRenderState>;
66
+ export declare function createBashTool(cwd: string, options?: BashToolOptions): AgentTool<typeof bashSchema>;
67
+ export {};
68
+ //# sourceMappingURL=bash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/core/tools/bash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAG/D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAY5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAItF,OAAO,EAAoD,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAExG,QAAA,MAAM,UAAU;;;EAGd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;;;OAMG;IACH,IAAI,EAAE,CACL,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;QACR,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QAC/B,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;KACxB,KACG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CAC1C;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CA8D1F;AAED,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,gBAAgB,CAAC;AAO5E,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,aAAa,CAAC;CAC1B;AAKD,KAAK,eAAe,GAAG;IACtB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC;CACrC,CAAC;AAwGF,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,EAAE,eAAe,CAAC,CAyKjF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG","sourcesContent":["import { existsSync } from \"node:fs\";\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { Container, Text, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { spawn } from \"child_process\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.js\";\nimport { truncateToVisualLines } from \"../../modes/interactive/components/visual-truncate.js\";\nimport { theme } from \"../../modes/interactive/theme/theme.js\";\nimport { waitForChildProcess } from \"../../utils/child-process.js\";\nimport {\n\tgetShellConfig,\n\tgetShellEnv,\n\tkillProcessTree,\n\ttrackDetachedChildPid,\n\tuntrackDetachedChildPid,\n} from \"../../utils/shell.js\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.js\";\nimport { OutputAccumulator } from \"./output-accumulator.js\";\nimport { getTextOutput, invalidArgText, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, type TruncationResult } from \"./truncate.js\";\n\nconst bashSchema = Type.Object({\n\tcommand: Type.String({ description: \"Bash command to execute\" }),\n\ttimeout: Type.Optional(Type.Number({ description: \"Timeout in seconds (optional, no default timeout)\" })),\n});\n\nexport type BashToolInput = Static<typeof bashSchema>;\n\nexport interface BashToolDetails {\n\ttruncation?: TruncationResult;\n\tfullOutputPath?: string;\n}\n\n/**\n * Pluggable operations for the bash tool.\n * Override these to delegate command execution to remote systems (for example SSH).\n */\nexport interface BashOperations {\n\t/**\n\t * Execute a command and stream output.\n\t * @param command The command to execute\n\t * @param cwd Working directory\n\t * @param options Execution options\n\t * @returns Promise resolving to exit code (null if killed)\n\t */\n\texec: (\n\t\tcommand: string,\n\t\tcwd: string,\n\t\toptions: {\n\t\t\tonData: (data: Buffer) => void;\n\t\t\tsignal?: AbortSignal;\n\t\t\ttimeout?: number;\n\t\t\tenv?: NodeJS.ProcessEnv;\n\t\t},\n\t) => Promise<{ exitCode: number | null }>;\n}\n\n/**\n * Create bash operations using pi's built-in local shell execution backend.\n *\n * This is useful for extensions that intercept user_bash and still want pi's\n * standard local shell behavior while wrapping or rewriting commands.\n */\nexport function createLocalBashOperations(options?: { shellPath?: string }): BashOperations {\n\treturn {\n\t\texec: (command, cwd, { onData, signal, timeout, env }) => {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tconst { shell, args } = getShellConfig(options?.shellPath);\n\t\t\t\tif (!existsSync(cwd)) {\n\t\t\t\t\treject(new Error(`Working directory does not exist: ${cwd}\\nCannot execute bash commands.`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst child = spawn(shell, [...args, command], {\n\t\t\t\t\tcwd,\n\t\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\t\tenv: env ?? getShellEnv(),\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t});\n\t\t\t\tif (child.pid) trackDetachedChildPid(child.pid);\n\t\t\t\tlet timedOut = false;\n\t\t\t\tlet timeoutHandle: NodeJS.Timeout | undefined;\n\t\t\t\t// Set timeout if provided.\n\t\t\t\tif (timeout !== undefined && timeout > 0) {\n\t\t\t\t\ttimeoutHandle = setTimeout(() => {\n\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\tif (child.pid) killProcessTree(child.pid);\n\t\t\t\t\t}, timeout * 1000);\n\t\t\t\t}\n\t\t\t\t// Stream stdout and stderr.\n\t\t\t\tchild.stdout?.on(\"data\", onData);\n\t\t\t\tchild.stderr?.on(\"data\", onData);\n\t\t\t\t// Handle abort signal by killing the entire process tree.\n\t\t\t\tconst onAbort = () => {\n\t\t\t\t\tif (child.pid) killProcessTree(child.pid);\n\t\t\t\t};\n\t\t\t\tif (signal) {\n\t\t\t\t\tif (signal.aborted) onAbort();\n\t\t\t\t\telse signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t}\n\t\t\t\t// Handle shell spawn errors and wait for the process to terminate without hanging\n\t\t\t\t// on inherited stdio handles held by detached descendants.\n\t\t\t\twaitForChildProcess(child)\n\t\t\t\t\t.then((code) => {\n\t\t\t\t\t\tif (child.pid) untrackDetachedChildPid(child.pid);\n\t\t\t\t\t\tif (timeoutHandle) clearTimeout(timeoutHandle);\n\t\t\t\t\t\tif (signal) signal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\treject(new Error(\"aborted\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (timedOut) {\n\t\t\t\t\t\t\treject(new Error(`timeout:${timeout}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresolve({ exitCode: code });\n\t\t\t\t\t})\n\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\tif (child.pid) untrackDetachedChildPid(child.pid);\n\t\t\t\t\t\tif (timeoutHandle) clearTimeout(timeoutHandle);\n\t\t\t\t\t\tif (signal) signal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t});\n\t\t\t});\n\t\t},\n\t};\n}\n\nexport interface BashSpawnContext {\n\tcommand: string;\n\tcwd: string;\n\tenv: NodeJS.ProcessEnv;\n}\n\nexport type BashSpawnHook = (context: BashSpawnContext) => BashSpawnContext;\n\nfunction resolveSpawnContext(command: string, cwd: string, spawnHook?: BashSpawnHook): BashSpawnContext {\n\tconst baseContext: BashSpawnContext = { command, cwd, env: { ...getShellEnv() } };\n\treturn spawnHook ? spawnHook(baseContext) : baseContext;\n}\n\nexport interface BashToolOptions {\n\t/** Custom operations for command execution. Default: local shell */\n\toperations?: BashOperations;\n\t/** Command prefix prepended to every command (for example shell setup commands) */\n\tcommandPrefix?: string;\n\t/** Optional explicit shell path from settings */\n\tshellPath?: string;\n\t/** Hook to adjust command, cwd, or env before execution */\n\tspawnHook?: BashSpawnHook;\n}\n\nconst BASH_PREVIEW_LINES = 5;\nconst BASH_UPDATE_THROTTLE_MS = 100;\n\ntype BashRenderState = {\n\tstartedAt: number | undefined;\n\tendedAt: number | undefined;\n\tinterval: NodeJS.Timeout | undefined;\n};\n\ntype BashResultRenderState = {\n\tcachedWidth: number | undefined;\n\tcachedLines: string[] | undefined;\n\tcachedSkipped: number | undefined;\n};\n\nclass BashResultRenderComponent extends Container {\n\tstate: BashResultRenderState = {\n\t\tcachedWidth: undefined,\n\t\tcachedLines: undefined,\n\t\tcachedSkipped: undefined,\n\t};\n}\n\nfunction formatDuration(ms: number): string {\n\treturn `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction formatBashCall(args: { command?: string; timeout?: number } | undefined): string {\n\tconst command = str(args?.command);\n\tconst timeout = args?.timeout as number | undefined;\n\tconst timeoutSuffix = timeout ? theme.fg(\"muted\", ` (timeout ${timeout}s)`) : \"\";\n\tconst commandDisplay = command === null ? invalidArgText(theme) : command ? command : theme.fg(\"toolOutput\", \"...\");\n\treturn theme.fg(\"toolTitle\", theme.bold(`$ ${commandDisplay}`)) + timeoutSuffix;\n}\n\nfunction rebuildBashResultRenderComponent(\n\tcomponent: BashResultRenderComponent,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: BashToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\tshowImages: boolean,\n\tstartedAt: number | undefined,\n\tendedAt: number | undefined,\n): void {\n\tconst state = component.state;\n\tcomponent.clear();\n\n\tconst output = getTextOutput(result as any, showImages).trim();\n\n\tif (output) {\n\t\tconst styledOutput = output\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => theme.fg(\"toolOutput\", line))\n\t\t\t.join(\"\\n\");\n\n\t\tif (options.expanded) {\n\t\t\tcomponent.addChild(new Text(`\\n${styledOutput}`, 0, 0));\n\t\t} else {\n\t\t\tcomponent.addChild({\n\t\t\t\trender: (width: number) => {\n\t\t\t\t\tif (state.cachedLines === undefined || state.cachedWidth !== width) {\n\t\t\t\t\t\tconst preview = truncateToVisualLines(styledOutput, BASH_PREVIEW_LINES, width);\n\t\t\t\t\t\tstate.cachedLines = preview.visualLines;\n\t\t\t\t\t\tstate.cachedSkipped = preview.skippedCount;\n\t\t\t\t\t\tstate.cachedWidth = width;\n\t\t\t\t\t}\n\t\t\t\t\tif (state.cachedSkipped && state.cachedSkipped > 0) {\n\t\t\t\t\t\tconst hint =\n\t\t\t\t\t\t\ttheme.fg(\"muted\", `... (${state.cachedSkipped} earlier lines,`) +\n\t\t\t\t\t\t\t` ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t\t\t\t\treturn [\"\", truncateToWidth(hint, width, \"...\"), ...(state.cachedLines ?? [])];\n\t\t\t\t\t}\n\t\t\t\t\treturn [\"\", ...(state.cachedLines ?? [])];\n\t\t\t\t},\n\t\t\t\tinvalidate: () => {\n\t\t\t\t\tstate.cachedWidth = undefined;\n\t\t\t\t\tstate.cachedLines = undefined;\n\t\t\t\t\tstate.cachedSkipped = undefined;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tconst truncation = result.details?.truncation;\n\tconst fullOutputPath = result.details?.fullOutputPath;\n\tif (truncation?.truncated || fullOutputPath) {\n\t\tconst warnings: string[] = [];\n\t\tif (fullOutputPath) {\n\t\t\twarnings.push(`Full output: ${fullOutputPath}`);\n\t\t}\n\t\tif (truncation?.truncated) {\n\t\t\tif (truncation.truncatedBy === \"lines\") {\n\t\t\t\twarnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);\n\t\t\t} else {\n\t\t\t\twarnings.push(\n\t\t\t\t\t`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tcomponent.addChild(new Text(`\\n${theme.fg(\"warning\", `[${warnings.join(\". \")}]`)}`, 0, 0));\n\t}\n\n\tif (startedAt !== undefined) {\n\t\tconst label = options.isPartial ? \"Elapsed\" : \"Took\";\n\t\tconst endTime = endedAt ?? Date.now();\n\t\tcomponent.addChild(new Text(`\\n${theme.fg(\"muted\", `${label} ${formatDuration(endTime - startedAt)}`)}`, 0, 0));\n\t}\n}\n\nexport function createBashToolDefinition(\n\tcwd: string,\n\toptions?: BashToolOptions,\n): ToolDefinition<typeof bashSchema, BashToolDetails | undefined, BashRenderState> {\n\tconst ops = options?.operations ?? createLocalBashOperations({ shellPath: options?.shellPath });\n\tconst commandPrefix = options?.commandPrefix;\n\tconst spawnHook = options?.spawnHook;\n\treturn {\n\t\tname: \"bash\",\n\t\tlabel: \"bash\",\n\t\tdescription: `Execute a bash command in the current working directory. Returns stdout and stderr. Output is truncated to last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file. Optionally provide a timeout in seconds.`,\n\t\tpromptSnippet: \"Execute bash commands (ls, grep, find, etc.)\",\n\t\tparameters: bashSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ command, timeout }: { command: string; timeout?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t\tonUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\tconst resolvedCommand = commandPrefix ? `${commandPrefix}\\n${command}` : command;\n\t\t\tconst spawnContext = resolveSpawnContext(resolvedCommand, cwd, spawnHook);\n\t\t\tconst output = new OutputAccumulator({ tempFilePrefix: \"pi-bash\" });\n\t\t\tlet updateTimer: NodeJS.Timeout | undefined;\n\t\t\tlet updateDirty = false;\n\t\t\tlet lastUpdateAt = 0;\n\n\t\t\tconst emitOutputUpdate = () => {\n\t\t\t\tif (!onUpdate || !updateDirty) return;\n\t\t\t\tupdateDirty = false;\n\t\t\t\tlastUpdateAt = Date.now();\n\t\t\t\tconst snapshot = output.snapshot({ persistIfTruncated: true });\n\t\t\t\tonUpdate({\n\t\t\t\t\tcontent: [{ type: \"text\", text: snapshot.content || \"\" }],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\ttruncation: snapshot.truncation.truncated ? snapshot.truncation : undefined,\n\t\t\t\t\t\tfullOutputPath: snapshot.fullOutputPath,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t};\n\n\t\t\tconst clearUpdateTimer = () => {\n\t\t\t\tif (updateTimer) {\n\t\t\t\t\tclearTimeout(updateTimer);\n\t\t\t\t\tupdateTimer = undefined;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst scheduleOutputUpdate = () => {\n\t\t\t\tif (!onUpdate) return;\n\t\t\t\tupdateDirty = true;\n\t\t\t\tconst delay = BASH_UPDATE_THROTTLE_MS - (Date.now() - lastUpdateAt);\n\t\t\t\tif (delay <= 0) {\n\t\t\t\t\tclearUpdateTimer();\n\t\t\t\t\temitOutputUpdate();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tupdateTimer ??= setTimeout(() => {\n\t\t\t\t\tupdateTimer = undefined;\n\t\t\t\t\temitOutputUpdate();\n\t\t\t\t}, delay);\n\t\t\t};\n\n\t\t\tif (onUpdate) {\n\t\t\t\tonUpdate({ content: [], details: undefined });\n\t\t\t}\n\n\t\t\tconst handleData = (data: Buffer) => {\n\t\t\t\toutput.append(data);\n\t\t\t\tscheduleOutputUpdate();\n\t\t\t};\n\n\t\t\tconst finishOutput = async () => {\n\t\t\t\toutput.finish();\n\t\t\t\tclearUpdateTimer();\n\t\t\t\temitOutputUpdate();\n\t\t\t\tconst snapshot = output.snapshot({ persistIfTruncated: true });\n\t\t\t\tawait output.closeTempFile();\n\t\t\t\treturn snapshot;\n\t\t\t};\n\n\t\t\tconst formatOutput = (snapshot: Awaited<ReturnType<typeof finishOutput>>, emptyText = \"(no output)\") => {\n\t\t\t\tconst truncation = snapshot.truncation;\n\t\t\t\tlet text = snapshot.content || emptyText;\n\t\t\t\tlet details: BashToolDetails | undefined;\n\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\tdetails = { truncation, fullOutputPath: snapshot.fullOutputPath };\n\t\t\t\t\tconst startLine = truncation.totalLines - truncation.outputLines + 1;\n\t\t\t\t\tconst endLine = truncation.totalLines;\n\t\t\t\t\tif (truncation.lastLinePartial) {\n\t\t\t\t\t\tconst lastLineSize = formatSize(output.getLastLineBytes());\n\t\t\t\t\t\ttext += `\\n\\n[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine} (line is ${lastLineSize}). Full output: ${snapshot.fullOutputPath}]`;\n\t\t\t\t\t} else if (truncation.truncatedBy === \"lines\") {\n\t\t\t\t\t\ttext += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines}. Full output: ${snapshot.fullOutputPath}]`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttext += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Full output: ${snapshot.fullOutputPath}]`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn { text, details };\n\t\t\t};\n\n\t\t\tconst appendStatus = (text: string, status: string) => `${text ? `${text}\\n\\n` : \"\"}${status}`;\n\n\t\t\ttry {\n\t\t\t\tlet exitCode: number | null;\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await ops.exec(spawnContext.command, spawnContext.cwd, {\n\t\t\t\t\t\tonData: handleData,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\tenv: spawnContext.env,\n\t\t\t\t\t});\n\t\t\t\t\texitCode = result.exitCode;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst snapshot = await finishOutput();\n\t\t\t\t\tconst { text } = formatOutput(snapshot, \"\");\n\t\t\t\t\tif (err instanceof Error && err.message === \"aborted\") {\n\t\t\t\t\t\tthrow new Error(appendStatus(text, \"Command aborted\"));\n\t\t\t\t\t}\n\t\t\t\t\tif (err instanceof Error && err.message.startsWith(\"timeout:\")) {\n\t\t\t\t\t\tconst timeoutSecs = err.message.split(\":\")[1];\n\t\t\t\t\t\tthrow new Error(appendStatus(text, `Command timed out after ${timeoutSecs} seconds`));\n\t\t\t\t\t}\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\n\t\t\t\tconst snapshot = await finishOutput();\n\t\t\t\tconst { text: outputText, details } = formatOutput(snapshot);\n\t\t\t\tif (exitCode !== 0 && exitCode !== null) {\n\t\t\t\t\tthrow new Error(appendStatus(outputText, `Command exited with code ${exitCode}`));\n\t\t\t\t}\n\t\t\t\treturn { content: [{ type: \"text\", text: outputText }], details };\n\t\t\t} finally {\n\t\t\t\tclearUpdateTimer();\n\t\t\t}\n\t\t},\n\t\trenderCall(args, _theme, context) {\n\t\t\tconst state = context.state;\n\t\t\tif (context.executionStarted && state.startedAt === undefined) {\n\t\t\t\tstate.startedAt = Date.now();\n\t\t\t\tstate.endedAt = undefined;\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatBashCall(args));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, _theme, context) {\n\t\t\tconst state = context.state;\n\t\t\tif (state.startedAt !== undefined && options.isPartial && !state.interval) {\n\t\t\t\tstate.interval = setInterval(() => context.invalidate(), 1000);\n\t\t\t}\n\t\t\tif (!options.isPartial || context.isError) {\n\t\t\t\tstate.endedAt ??= Date.now();\n\t\t\t\tif (state.interval) {\n\t\t\t\t\tclearInterval(state.interval);\n\t\t\t\t\tstate.interval = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst component =\n\t\t\t\t(context.lastComponent as BashResultRenderComponent | undefined) ?? new BashResultRenderComponent();\n\t\t\trebuildBashResultRenderComponent(\n\t\t\t\tcomponent,\n\t\t\t\tresult as any,\n\t\t\t\toptions,\n\t\t\t\tcontext.showImages,\n\t\t\t\tstate.startedAt,\n\t\t\t\tstate.endedAt,\n\t\t\t);\n\t\t\tcomponent.invalidate();\n\t\t\treturn component;\n\t\t},\n\t};\n}\n\nexport function createBashTool(cwd: string, options?: BashToolOptions): AgentTool<typeof bashSchema> {\n\treturn wrapToolDefinition(createBashToolDefinition(cwd, options));\n}\n"]}
@@ -0,0 +1,335 @@
1
+ import { existsSync } from "node:fs";
2
+ import { Container, Text, truncateToWidth } from "@earendil-works/pi-tui";
3
+ import { spawn } from "child_process";
4
+ import { Type } from "typebox";
5
+ import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
6
+ import { truncateToVisualLines } from "../../modes/interactive/components/visual-truncate.js";
7
+ import { theme } from "../../modes/interactive/theme/theme.js";
8
+ import { waitForChildProcess } from "../../utils/child-process.js";
9
+ import { getShellConfig, getShellEnv, killProcessTree, trackDetachedChildPid, untrackDetachedChildPid, } from "../../utils/shell.js";
10
+ import { OutputAccumulator } from "./output-accumulator.js";
11
+ import { getTextOutput, invalidArgText, str } from "./render-utils.js";
12
+ import { wrapToolDefinition } from "./tool-definition-wrapper.js";
13
+ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize } from "./truncate.js";
14
+ const bashSchema = Type.Object({
15
+ command: Type.String({ description: "Bash command to execute" }),
16
+ timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (optional, no default timeout)" })),
17
+ });
18
+ /**
19
+ * Create bash operations using pi's built-in local shell execution backend.
20
+ *
21
+ * This is useful for extensions that intercept user_bash and still want pi's
22
+ * standard local shell behavior while wrapping or rewriting commands.
23
+ */
24
+ export function createLocalBashOperations(options) {
25
+ return {
26
+ exec: (command, cwd, { onData, signal, timeout, env }) => {
27
+ return new Promise((resolve, reject) => {
28
+ const { shell, args } = getShellConfig(options?.shellPath);
29
+ if (!existsSync(cwd)) {
30
+ reject(new Error(`Working directory does not exist: ${cwd}\nCannot execute bash commands.`));
31
+ return;
32
+ }
33
+ const child = spawn(shell, [...args, command], {
34
+ cwd,
35
+ detached: process.platform !== "win32",
36
+ env: env ?? getShellEnv(),
37
+ stdio: ["ignore", "pipe", "pipe"],
38
+ });
39
+ if (child.pid)
40
+ trackDetachedChildPid(child.pid);
41
+ let timedOut = false;
42
+ let timeoutHandle;
43
+ // Set timeout if provided.
44
+ if (timeout !== undefined && timeout > 0) {
45
+ timeoutHandle = setTimeout(() => {
46
+ timedOut = true;
47
+ if (child.pid)
48
+ killProcessTree(child.pid);
49
+ }, timeout * 1000);
50
+ }
51
+ // Stream stdout and stderr.
52
+ child.stdout?.on("data", onData);
53
+ child.stderr?.on("data", onData);
54
+ // Handle abort signal by killing the entire process tree.
55
+ const onAbort = () => {
56
+ if (child.pid)
57
+ killProcessTree(child.pid);
58
+ };
59
+ if (signal) {
60
+ if (signal.aborted)
61
+ onAbort();
62
+ else
63
+ signal.addEventListener("abort", onAbort, { once: true });
64
+ }
65
+ // Handle shell spawn errors and wait for the process to terminate without hanging
66
+ // on inherited stdio handles held by detached descendants.
67
+ waitForChildProcess(child)
68
+ .then((code) => {
69
+ if (child.pid)
70
+ untrackDetachedChildPid(child.pid);
71
+ if (timeoutHandle)
72
+ clearTimeout(timeoutHandle);
73
+ if (signal)
74
+ signal.removeEventListener("abort", onAbort);
75
+ if (signal?.aborted) {
76
+ reject(new Error("aborted"));
77
+ return;
78
+ }
79
+ if (timedOut) {
80
+ reject(new Error(`timeout:${timeout}`));
81
+ return;
82
+ }
83
+ resolve({ exitCode: code });
84
+ })
85
+ .catch((err) => {
86
+ if (child.pid)
87
+ untrackDetachedChildPid(child.pid);
88
+ if (timeoutHandle)
89
+ clearTimeout(timeoutHandle);
90
+ if (signal)
91
+ signal.removeEventListener("abort", onAbort);
92
+ reject(err);
93
+ });
94
+ });
95
+ },
96
+ };
97
+ }
98
+ function resolveSpawnContext(command, cwd, spawnHook) {
99
+ const baseContext = { command, cwd, env: { ...getShellEnv() } };
100
+ return spawnHook ? spawnHook(baseContext) : baseContext;
101
+ }
102
+ const BASH_PREVIEW_LINES = 5;
103
+ const BASH_UPDATE_THROTTLE_MS = 100;
104
+ class BashResultRenderComponent extends Container {
105
+ state = {
106
+ cachedWidth: undefined,
107
+ cachedLines: undefined,
108
+ cachedSkipped: undefined,
109
+ };
110
+ }
111
+ function formatDuration(ms) {
112
+ return `${(ms / 1000).toFixed(1)}s`;
113
+ }
114
+ function formatBashCall(args) {
115
+ const command = str(args?.command);
116
+ const timeout = args?.timeout;
117
+ const timeoutSuffix = timeout ? theme.fg("muted", ` (timeout ${timeout}s)`) : "";
118
+ const commandDisplay = command === null ? invalidArgText(theme) : command ? command : theme.fg("toolOutput", "...");
119
+ return theme.fg("toolTitle", theme.bold(`$ ${commandDisplay}`)) + timeoutSuffix;
120
+ }
121
+ function rebuildBashResultRenderComponent(component, result, options, showImages, startedAt, endedAt) {
122
+ const state = component.state;
123
+ component.clear();
124
+ const output = getTextOutput(result, showImages).trim();
125
+ if (output) {
126
+ const styledOutput = output
127
+ .split("\n")
128
+ .map((line) => theme.fg("toolOutput", line))
129
+ .join("\n");
130
+ if (options.expanded) {
131
+ component.addChild(new Text(`\n${styledOutput}`, 0, 0));
132
+ }
133
+ else {
134
+ component.addChild({
135
+ render: (width) => {
136
+ if (state.cachedLines === undefined || state.cachedWidth !== width) {
137
+ const preview = truncateToVisualLines(styledOutput, BASH_PREVIEW_LINES, width);
138
+ state.cachedLines = preview.visualLines;
139
+ state.cachedSkipped = preview.skippedCount;
140
+ state.cachedWidth = width;
141
+ }
142
+ if (state.cachedSkipped && state.cachedSkipped > 0) {
143
+ const hint = theme.fg("muted", `... (${state.cachedSkipped} earlier lines,`) +
144
+ ` ${keyHint("app.tools.expand", "to expand")})`;
145
+ return ["", truncateToWidth(hint, width, "..."), ...(state.cachedLines ?? [])];
146
+ }
147
+ return ["", ...(state.cachedLines ?? [])];
148
+ },
149
+ invalidate: () => {
150
+ state.cachedWidth = undefined;
151
+ state.cachedLines = undefined;
152
+ state.cachedSkipped = undefined;
153
+ },
154
+ });
155
+ }
156
+ }
157
+ const truncation = result.details?.truncation;
158
+ const fullOutputPath = result.details?.fullOutputPath;
159
+ if (truncation?.truncated || fullOutputPath) {
160
+ const warnings = [];
161
+ if (fullOutputPath) {
162
+ warnings.push(`Full output: ${fullOutputPath}`);
163
+ }
164
+ if (truncation?.truncated) {
165
+ if (truncation.truncatedBy === "lines") {
166
+ warnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);
167
+ }
168
+ else {
169
+ warnings.push(`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`);
170
+ }
171
+ }
172
+ component.addChild(new Text(`\n${theme.fg("warning", `[${warnings.join(". ")}]`)}`, 0, 0));
173
+ }
174
+ if (startedAt !== undefined) {
175
+ const label = options.isPartial ? "Elapsed" : "Took";
176
+ const endTime = endedAt ?? Date.now();
177
+ component.addChild(new Text(`\n${theme.fg("muted", `${label} ${formatDuration(endTime - startedAt)}`)}`, 0, 0));
178
+ }
179
+ }
180
+ export function createBashToolDefinition(cwd, options) {
181
+ const ops = options?.operations ?? createLocalBashOperations({ shellPath: options?.shellPath });
182
+ const commandPrefix = options?.commandPrefix;
183
+ const spawnHook = options?.spawnHook;
184
+ return {
185
+ name: "bash",
186
+ label: "bash",
187
+ description: `Execute a bash command in the current working directory. Returns stdout and stderr. Output is truncated to last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file. Optionally provide a timeout in seconds.`,
188
+ promptSnippet: "Execute bash commands (ls, grep, find, etc.)",
189
+ parameters: bashSchema,
190
+ async execute(_toolCallId, { command, timeout }, signal, onUpdate, _ctx) {
191
+ const resolvedCommand = commandPrefix ? `${commandPrefix}\n${command}` : command;
192
+ const spawnContext = resolveSpawnContext(resolvedCommand, cwd, spawnHook);
193
+ const output = new OutputAccumulator({ tempFilePrefix: "pi-bash" });
194
+ let updateTimer;
195
+ let updateDirty = false;
196
+ let lastUpdateAt = 0;
197
+ const emitOutputUpdate = () => {
198
+ if (!onUpdate || !updateDirty)
199
+ return;
200
+ updateDirty = false;
201
+ lastUpdateAt = Date.now();
202
+ const snapshot = output.snapshot({ persistIfTruncated: true });
203
+ onUpdate({
204
+ content: [{ type: "text", text: snapshot.content || "" }],
205
+ details: {
206
+ truncation: snapshot.truncation.truncated ? snapshot.truncation : undefined,
207
+ fullOutputPath: snapshot.fullOutputPath,
208
+ },
209
+ });
210
+ };
211
+ const clearUpdateTimer = () => {
212
+ if (updateTimer) {
213
+ clearTimeout(updateTimer);
214
+ updateTimer = undefined;
215
+ }
216
+ };
217
+ const scheduleOutputUpdate = () => {
218
+ if (!onUpdate)
219
+ return;
220
+ updateDirty = true;
221
+ const delay = BASH_UPDATE_THROTTLE_MS - (Date.now() - lastUpdateAt);
222
+ if (delay <= 0) {
223
+ clearUpdateTimer();
224
+ emitOutputUpdate();
225
+ return;
226
+ }
227
+ updateTimer ??= setTimeout(() => {
228
+ updateTimer = undefined;
229
+ emitOutputUpdate();
230
+ }, delay);
231
+ };
232
+ if (onUpdate) {
233
+ onUpdate({ content: [], details: undefined });
234
+ }
235
+ const handleData = (data) => {
236
+ output.append(data);
237
+ scheduleOutputUpdate();
238
+ };
239
+ const finishOutput = async () => {
240
+ output.finish();
241
+ clearUpdateTimer();
242
+ emitOutputUpdate();
243
+ const snapshot = output.snapshot({ persistIfTruncated: true });
244
+ await output.closeTempFile();
245
+ return snapshot;
246
+ };
247
+ const formatOutput = (snapshot, emptyText = "(no output)") => {
248
+ const truncation = snapshot.truncation;
249
+ let text = snapshot.content || emptyText;
250
+ let details;
251
+ if (truncation.truncated) {
252
+ details = { truncation, fullOutputPath: snapshot.fullOutputPath };
253
+ const startLine = truncation.totalLines - truncation.outputLines + 1;
254
+ const endLine = truncation.totalLines;
255
+ if (truncation.lastLinePartial) {
256
+ const lastLineSize = formatSize(output.getLastLineBytes());
257
+ text += `\n\n[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine} (line is ${lastLineSize}). Full output: ${snapshot.fullOutputPath}]`;
258
+ }
259
+ else if (truncation.truncatedBy === "lines") {
260
+ text += `\n\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines}. Full output: ${snapshot.fullOutputPath}]`;
261
+ }
262
+ else {
263
+ text += `\n\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Full output: ${snapshot.fullOutputPath}]`;
264
+ }
265
+ }
266
+ return { text, details };
267
+ };
268
+ const appendStatus = (text, status) => `${text ? `${text}\n\n` : ""}${status}`;
269
+ try {
270
+ let exitCode;
271
+ try {
272
+ const result = await ops.exec(spawnContext.command, spawnContext.cwd, {
273
+ onData: handleData,
274
+ signal,
275
+ timeout,
276
+ env: spawnContext.env,
277
+ });
278
+ exitCode = result.exitCode;
279
+ }
280
+ catch (err) {
281
+ const snapshot = await finishOutput();
282
+ const { text } = formatOutput(snapshot, "");
283
+ if (err instanceof Error && err.message === "aborted") {
284
+ throw new Error(appendStatus(text, "Command aborted"));
285
+ }
286
+ if (err instanceof Error && err.message.startsWith("timeout:")) {
287
+ const timeoutSecs = err.message.split(":")[1];
288
+ throw new Error(appendStatus(text, `Command timed out after ${timeoutSecs} seconds`));
289
+ }
290
+ throw err;
291
+ }
292
+ const snapshot = await finishOutput();
293
+ const { text: outputText, details } = formatOutput(snapshot);
294
+ if (exitCode !== 0 && exitCode !== null) {
295
+ throw new Error(appendStatus(outputText, `Command exited with code ${exitCode}`));
296
+ }
297
+ return { content: [{ type: "text", text: outputText }], details };
298
+ }
299
+ finally {
300
+ clearUpdateTimer();
301
+ }
302
+ },
303
+ renderCall(args, _theme, context) {
304
+ const state = context.state;
305
+ if (context.executionStarted && state.startedAt === undefined) {
306
+ state.startedAt = Date.now();
307
+ state.endedAt = undefined;
308
+ }
309
+ const text = context.lastComponent ?? new Text("", 0, 0);
310
+ text.setText(formatBashCall(args));
311
+ return text;
312
+ },
313
+ renderResult(result, options, _theme, context) {
314
+ const state = context.state;
315
+ if (state.startedAt !== undefined && options.isPartial && !state.interval) {
316
+ state.interval = setInterval(() => context.invalidate(), 1000);
317
+ }
318
+ if (!options.isPartial || context.isError) {
319
+ state.endedAt ??= Date.now();
320
+ if (state.interval) {
321
+ clearInterval(state.interval);
322
+ state.interval = undefined;
323
+ }
324
+ }
325
+ const component = context.lastComponent ?? new BashResultRenderComponent();
326
+ rebuildBashResultRenderComponent(component, result, options, context.showImages, state.startedAt, state.endedAt);
327
+ component.invalidate();
328
+ return component;
329
+ },
330
+ };
331
+ }
332
+ export function createBashTool(cwd, options) {
333
+ return wrapToolDefinition(createBashToolDefinition(cwd, options));
334
+ }
335
+ //# sourceMappingURL=bash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../src/core/tools/bash.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { Container, Text, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { spawn } from \"child_process\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.js\";\nimport { truncateToVisualLines } from \"../../modes/interactive/components/visual-truncate.js\";\nimport { theme } from \"../../modes/interactive/theme/theme.js\";\nimport { waitForChildProcess } from \"../../utils/child-process.js\";\nimport {\n\tgetShellConfig,\n\tgetShellEnv,\n\tkillProcessTree,\n\ttrackDetachedChildPid,\n\tuntrackDetachedChildPid,\n} from \"../../utils/shell.js\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.js\";\nimport { OutputAccumulator } from \"./output-accumulator.js\";\nimport { getTextOutput, invalidArgText, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, type TruncationResult } from \"./truncate.js\";\n\nconst bashSchema = Type.Object({\n\tcommand: Type.String({ description: \"Bash command to execute\" }),\n\ttimeout: Type.Optional(Type.Number({ description: \"Timeout in seconds (optional, no default timeout)\" })),\n});\n\nexport type BashToolInput = Static<typeof bashSchema>;\n\nexport interface BashToolDetails {\n\ttruncation?: TruncationResult;\n\tfullOutputPath?: string;\n}\n\n/**\n * Pluggable operations for the bash tool.\n * Override these to delegate command execution to remote systems (for example SSH).\n */\nexport interface BashOperations {\n\t/**\n\t * Execute a command and stream output.\n\t * @param command The command to execute\n\t * @param cwd Working directory\n\t * @param options Execution options\n\t * @returns Promise resolving to exit code (null if killed)\n\t */\n\texec: (\n\t\tcommand: string,\n\t\tcwd: string,\n\t\toptions: {\n\t\t\tonData: (data: Buffer) => void;\n\t\t\tsignal?: AbortSignal;\n\t\t\ttimeout?: number;\n\t\t\tenv?: NodeJS.ProcessEnv;\n\t\t},\n\t) => Promise<{ exitCode: number | null }>;\n}\n\n/**\n * Create bash operations using pi's built-in local shell execution backend.\n *\n * This is useful for extensions that intercept user_bash and still want pi's\n * standard local shell behavior while wrapping or rewriting commands.\n */\nexport function createLocalBashOperations(options?: { shellPath?: string }): BashOperations {\n\treturn {\n\t\texec: (command, cwd, { onData, signal, timeout, env }) => {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tconst { shell, args } = getShellConfig(options?.shellPath);\n\t\t\t\tif (!existsSync(cwd)) {\n\t\t\t\t\treject(new Error(`Working directory does not exist: ${cwd}\\nCannot execute bash commands.`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst child = spawn(shell, [...args, command], {\n\t\t\t\t\tcwd,\n\t\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\t\tenv: env ?? getShellEnv(),\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t});\n\t\t\t\tif (child.pid) trackDetachedChildPid(child.pid);\n\t\t\t\tlet timedOut = false;\n\t\t\t\tlet timeoutHandle: NodeJS.Timeout | undefined;\n\t\t\t\t// Set timeout if provided.\n\t\t\t\tif (timeout !== undefined && timeout > 0) {\n\t\t\t\t\ttimeoutHandle = setTimeout(() => {\n\t\t\t\t\t\ttimedOut = true;\n\t\t\t\t\t\tif (child.pid) killProcessTree(child.pid);\n\t\t\t\t\t}, timeout * 1000);\n\t\t\t\t}\n\t\t\t\t// Stream stdout and stderr.\n\t\t\t\tchild.stdout?.on(\"data\", onData);\n\t\t\t\tchild.stderr?.on(\"data\", onData);\n\t\t\t\t// Handle abort signal by killing the entire process tree.\n\t\t\t\tconst onAbort = () => {\n\t\t\t\t\tif (child.pid) killProcessTree(child.pid);\n\t\t\t\t};\n\t\t\t\tif (signal) {\n\t\t\t\t\tif (signal.aborted) onAbort();\n\t\t\t\t\telse signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t}\n\t\t\t\t// Handle shell spawn errors and wait for the process to terminate without hanging\n\t\t\t\t// on inherited stdio handles held by detached descendants.\n\t\t\t\twaitForChildProcess(child)\n\t\t\t\t\t.then((code) => {\n\t\t\t\t\t\tif (child.pid) untrackDetachedChildPid(child.pid);\n\t\t\t\t\t\tif (timeoutHandle) clearTimeout(timeoutHandle);\n\t\t\t\t\t\tif (signal) signal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\treject(new Error(\"aborted\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (timedOut) {\n\t\t\t\t\t\t\treject(new Error(`timeout:${timeout}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresolve({ exitCode: code });\n\t\t\t\t\t})\n\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\tif (child.pid) untrackDetachedChildPid(child.pid);\n\t\t\t\t\t\tif (timeoutHandle) clearTimeout(timeoutHandle);\n\t\t\t\t\t\tif (signal) signal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t});\n\t\t\t});\n\t\t},\n\t};\n}\n\nexport interface BashSpawnContext {\n\tcommand: string;\n\tcwd: string;\n\tenv: NodeJS.ProcessEnv;\n}\n\nexport type BashSpawnHook = (context: BashSpawnContext) => BashSpawnContext;\n\nfunction resolveSpawnContext(command: string, cwd: string, spawnHook?: BashSpawnHook): BashSpawnContext {\n\tconst baseContext: BashSpawnContext = { command, cwd, env: { ...getShellEnv() } };\n\treturn spawnHook ? spawnHook(baseContext) : baseContext;\n}\n\nexport interface BashToolOptions {\n\t/** Custom operations for command execution. Default: local shell */\n\toperations?: BashOperations;\n\t/** Command prefix prepended to every command (for example shell setup commands) */\n\tcommandPrefix?: string;\n\t/** Optional explicit shell path from settings */\n\tshellPath?: string;\n\t/** Hook to adjust command, cwd, or env before execution */\n\tspawnHook?: BashSpawnHook;\n}\n\nconst BASH_PREVIEW_LINES = 5;\nconst BASH_UPDATE_THROTTLE_MS = 100;\n\ntype BashRenderState = {\n\tstartedAt: number | undefined;\n\tendedAt: number | undefined;\n\tinterval: NodeJS.Timeout | undefined;\n};\n\ntype BashResultRenderState = {\n\tcachedWidth: number | undefined;\n\tcachedLines: string[] | undefined;\n\tcachedSkipped: number | undefined;\n};\n\nclass BashResultRenderComponent extends Container {\n\tstate: BashResultRenderState = {\n\t\tcachedWidth: undefined,\n\t\tcachedLines: undefined,\n\t\tcachedSkipped: undefined,\n\t};\n}\n\nfunction formatDuration(ms: number): string {\n\treturn `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction formatBashCall(args: { command?: string; timeout?: number } | undefined): string {\n\tconst command = str(args?.command);\n\tconst timeout = args?.timeout as number | undefined;\n\tconst timeoutSuffix = timeout ? theme.fg(\"muted\", ` (timeout ${timeout}s)`) : \"\";\n\tconst commandDisplay = command === null ? invalidArgText(theme) : command ? command : theme.fg(\"toolOutput\", \"...\");\n\treturn theme.fg(\"toolTitle\", theme.bold(`$ ${commandDisplay}`)) + timeoutSuffix;\n}\n\nfunction rebuildBashResultRenderComponent(\n\tcomponent: BashResultRenderComponent,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: BashToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\tshowImages: boolean,\n\tstartedAt: number | undefined,\n\tendedAt: number | undefined,\n): void {\n\tconst state = component.state;\n\tcomponent.clear();\n\n\tconst output = getTextOutput(result as any, showImages).trim();\n\n\tif (output) {\n\t\tconst styledOutput = output\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => theme.fg(\"toolOutput\", line))\n\t\t\t.join(\"\\n\");\n\n\t\tif (options.expanded) {\n\t\t\tcomponent.addChild(new Text(`\\n${styledOutput}`, 0, 0));\n\t\t} else {\n\t\t\tcomponent.addChild({\n\t\t\t\trender: (width: number) => {\n\t\t\t\t\tif (state.cachedLines === undefined || state.cachedWidth !== width) {\n\t\t\t\t\t\tconst preview = truncateToVisualLines(styledOutput, BASH_PREVIEW_LINES, width);\n\t\t\t\t\t\tstate.cachedLines = preview.visualLines;\n\t\t\t\t\t\tstate.cachedSkipped = preview.skippedCount;\n\t\t\t\t\t\tstate.cachedWidth = width;\n\t\t\t\t\t}\n\t\t\t\t\tif (state.cachedSkipped && state.cachedSkipped > 0) {\n\t\t\t\t\t\tconst hint =\n\t\t\t\t\t\t\ttheme.fg(\"muted\", `... (${state.cachedSkipped} earlier lines,`) +\n\t\t\t\t\t\t\t` ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t\t\t\t\treturn [\"\", truncateToWidth(hint, width, \"...\"), ...(state.cachedLines ?? [])];\n\t\t\t\t\t}\n\t\t\t\t\treturn [\"\", ...(state.cachedLines ?? [])];\n\t\t\t\t},\n\t\t\t\tinvalidate: () => {\n\t\t\t\t\tstate.cachedWidth = undefined;\n\t\t\t\t\tstate.cachedLines = undefined;\n\t\t\t\t\tstate.cachedSkipped = undefined;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tconst truncation = result.details?.truncation;\n\tconst fullOutputPath = result.details?.fullOutputPath;\n\tif (truncation?.truncated || fullOutputPath) {\n\t\tconst warnings: string[] = [];\n\t\tif (fullOutputPath) {\n\t\t\twarnings.push(`Full output: ${fullOutputPath}`);\n\t\t}\n\t\tif (truncation?.truncated) {\n\t\t\tif (truncation.truncatedBy === \"lines\") {\n\t\t\t\twarnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);\n\t\t\t} else {\n\t\t\t\twarnings.push(\n\t\t\t\t\t`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tcomponent.addChild(new Text(`\\n${theme.fg(\"warning\", `[${warnings.join(\". \")}]`)}`, 0, 0));\n\t}\n\n\tif (startedAt !== undefined) {\n\t\tconst label = options.isPartial ? \"Elapsed\" : \"Took\";\n\t\tconst endTime = endedAt ?? Date.now();\n\t\tcomponent.addChild(new Text(`\\n${theme.fg(\"muted\", `${label} ${formatDuration(endTime - startedAt)}`)}`, 0, 0));\n\t}\n}\n\nexport function createBashToolDefinition(\n\tcwd: string,\n\toptions?: BashToolOptions,\n): ToolDefinition<typeof bashSchema, BashToolDetails | undefined, BashRenderState> {\n\tconst ops = options?.operations ?? createLocalBashOperations({ shellPath: options?.shellPath });\n\tconst commandPrefix = options?.commandPrefix;\n\tconst spawnHook = options?.spawnHook;\n\treturn {\n\t\tname: \"bash\",\n\t\tlabel: \"bash\",\n\t\tdescription: `Execute a bash command in the current working directory. Returns stdout and stderr. Output is truncated to last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file. Optionally provide a timeout in seconds.`,\n\t\tpromptSnippet: \"Execute bash commands (ls, grep, find, etc.)\",\n\t\tparameters: bashSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ command, timeout }: { command: string; timeout?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t\tonUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\tconst resolvedCommand = commandPrefix ? `${commandPrefix}\\n${command}` : command;\n\t\t\tconst spawnContext = resolveSpawnContext(resolvedCommand, cwd, spawnHook);\n\t\t\tconst output = new OutputAccumulator({ tempFilePrefix: \"pi-bash\" });\n\t\t\tlet updateTimer: NodeJS.Timeout | undefined;\n\t\t\tlet updateDirty = false;\n\t\t\tlet lastUpdateAt = 0;\n\n\t\t\tconst emitOutputUpdate = () => {\n\t\t\t\tif (!onUpdate || !updateDirty) return;\n\t\t\t\tupdateDirty = false;\n\t\t\t\tlastUpdateAt = Date.now();\n\t\t\t\tconst snapshot = output.snapshot({ persistIfTruncated: true });\n\t\t\t\tonUpdate({\n\t\t\t\t\tcontent: [{ type: \"text\", text: snapshot.content || \"\" }],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\ttruncation: snapshot.truncation.truncated ? snapshot.truncation : undefined,\n\t\t\t\t\t\tfullOutputPath: snapshot.fullOutputPath,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t};\n\n\t\t\tconst clearUpdateTimer = () => {\n\t\t\t\tif (updateTimer) {\n\t\t\t\t\tclearTimeout(updateTimer);\n\t\t\t\t\tupdateTimer = undefined;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst scheduleOutputUpdate = () => {\n\t\t\t\tif (!onUpdate) return;\n\t\t\t\tupdateDirty = true;\n\t\t\t\tconst delay = BASH_UPDATE_THROTTLE_MS - (Date.now() - lastUpdateAt);\n\t\t\t\tif (delay <= 0) {\n\t\t\t\t\tclearUpdateTimer();\n\t\t\t\t\temitOutputUpdate();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tupdateTimer ??= setTimeout(() => {\n\t\t\t\t\tupdateTimer = undefined;\n\t\t\t\t\temitOutputUpdate();\n\t\t\t\t}, delay);\n\t\t\t};\n\n\t\t\tif (onUpdate) {\n\t\t\t\tonUpdate({ content: [], details: undefined });\n\t\t\t}\n\n\t\t\tconst handleData = (data: Buffer) => {\n\t\t\t\toutput.append(data);\n\t\t\t\tscheduleOutputUpdate();\n\t\t\t};\n\n\t\t\tconst finishOutput = async () => {\n\t\t\t\toutput.finish();\n\t\t\t\tclearUpdateTimer();\n\t\t\t\temitOutputUpdate();\n\t\t\t\tconst snapshot = output.snapshot({ persistIfTruncated: true });\n\t\t\t\tawait output.closeTempFile();\n\t\t\t\treturn snapshot;\n\t\t\t};\n\n\t\t\tconst formatOutput = (snapshot: Awaited<ReturnType<typeof finishOutput>>, emptyText = \"(no output)\") => {\n\t\t\t\tconst truncation = snapshot.truncation;\n\t\t\t\tlet text = snapshot.content || emptyText;\n\t\t\t\tlet details: BashToolDetails | undefined;\n\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\tdetails = { truncation, fullOutputPath: snapshot.fullOutputPath };\n\t\t\t\t\tconst startLine = truncation.totalLines - truncation.outputLines + 1;\n\t\t\t\t\tconst endLine = truncation.totalLines;\n\t\t\t\t\tif (truncation.lastLinePartial) {\n\t\t\t\t\t\tconst lastLineSize = formatSize(output.getLastLineBytes());\n\t\t\t\t\t\ttext += `\\n\\n[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine} (line is ${lastLineSize}). Full output: ${snapshot.fullOutputPath}]`;\n\t\t\t\t\t} else if (truncation.truncatedBy === \"lines\") {\n\t\t\t\t\t\ttext += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines}. Full output: ${snapshot.fullOutputPath}]`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttext += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Full output: ${snapshot.fullOutputPath}]`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn { text, details };\n\t\t\t};\n\n\t\t\tconst appendStatus = (text: string, status: string) => `${text ? `${text}\\n\\n` : \"\"}${status}`;\n\n\t\t\ttry {\n\t\t\t\tlet exitCode: number | null;\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await ops.exec(spawnContext.command, spawnContext.cwd, {\n\t\t\t\t\t\tonData: handleData,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\ttimeout,\n\t\t\t\t\t\tenv: spawnContext.env,\n\t\t\t\t\t});\n\t\t\t\t\texitCode = result.exitCode;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst snapshot = await finishOutput();\n\t\t\t\t\tconst { text } = formatOutput(snapshot, \"\");\n\t\t\t\t\tif (err instanceof Error && err.message === \"aborted\") {\n\t\t\t\t\t\tthrow new Error(appendStatus(text, \"Command aborted\"));\n\t\t\t\t\t}\n\t\t\t\t\tif (err instanceof Error && err.message.startsWith(\"timeout:\")) {\n\t\t\t\t\t\tconst timeoutSecs = err.message.split(\":\")[1];\n\t\t\t\t\t\tthrow new Error(appendStatus(text, `Command timed out after ${timeoutSecs} seconds`));\n\t\t\t\t\t}\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\n\t\t\t\tconst snapshot = await finishOutput();\n\t\t\t\tconst { text: outputText, details } = formatOutput(snapshot);\n\t\t\t\tif (exitCode !== 0 && exitCode !== null) {\n\t\t\t\t\tthrow new Error(appendStatus(outputText, `Command exited with code ${exitCode}`));\n\t\t\t\t}\n\t\t\t\treturn { content: [{ type: \"text\", text: outputText }], details };\n\t\t\t} finally {\n\t\t\t\tclearUpdateTimer();\n\t\t\t}\n\t\t},\n\t\trenderCall(args, _theme, context) {\n\t\t\tconst state = context.state;\n\t\t\tif (context.executionStarted && state.startedAt === undefined) {\n\t\t\t\tstate.startedAt = Date.now();\n\t\t\t\tstate.endedAt = undefined;\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatBashCall(args));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, _theme, context) {\n\t\t\tconst state = context.state;\n\t\t\tif (state.startedAt !== undefined && options.isPartial && !state.interval) {\n\t\t\t\tstate.interval = setInterval(() => context.invalidate(), 1000);\n\t\t\t}\n\t\t\tif (!options.isPartial || context.isError) {\n\t\t\t\tstate.endedAt ??= Date.now();\n\t\t\t\tif (state.interval) {\n\t\t\t\t\tclearInterval(state.interval);\n\t\t\t\t\tstate.interval = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst component =\n\t\t\t\t(context.lastComponent as BashResultRenderComponent | undefined) ?? new BashResultRenderComponent();\n\t\t\trebuildBashResultRenderComponent(\n\t\t\t\tcomponent,\n\t\t\t\tresult as any,\n\t\t\t\toptions,\n\t\t\t\tcontext.showImages,\n\t\t\t\tstate.startedAt,\n\t\t\t\tstate.endedAt,\n\t\t\t);\n\t\t\tcomponent.invalidate();\n\t\t\treturn component;\n\t\t},\n\t};\n}\n\nexport function createBashTool(cwd: string, options?: BashToolOptions): AgentTool<typeof bashSchema> {\n\treturn wrapToolDefinition(createBashToolDefinition(cwd, options));\n}\n"]}