@draht/coding-agent 2026.3.2-2

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 (639) hide show
  1. package/CHANGELOG.md +2866 -0
  2. package/README.md +566 -0
  3. package/bin/draht-tools.cjs +912 -0
  4. package/dist/cli/args.d.ts +48 -0
  5. package/dist/cli/args.d.ts.map +1 -0
  6. package/dist/cli/args.js +298 -0
  7. package/dist/cli/args.js.map +1 -0
  8. package/dist/cli/config-selector.d.ts +14 -0
  9. package/dist/cli/config-selector.d.ts.map +1 -0
  10. package/dist/cli/config-selector.js +31 -0
  11. package/dist/cli/config-selector.js.map +1 -0
  12. package/dist/cli/file-processor.d.ts +15 -0
  13. package/dist/cli/file-processor.d.ts.map +1 -0
  14. package/dist/cli/file-processor.js +79 -0
  15. package/dist/cli/file-processor.js.map +1 -0
  16. package/dist/cli/list-models.d.ts +9 -0
  17. package/dist/cli/list-models.d.ts.map +1 -0
  18. package/dist/cli/list-models.js +92 -0
  19. package/dist/cli/list-models.js.map +1 -0
  20. package/dist/cli/session-picker.d.ts +9 -0
  21. package/dist/cli/session-picker.d.ts.map +1 -0
  22. package/dist/cli/session-picker.js +34 -0
  23. package/dist/cli/session-picker.js.map +1 -0
  24. package/dist/cli.d.ts +3 -0
  25. package/dist/cli.d.ts.map +1 -0
  26. package/dist/cli.js +11 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/config.d.ts +85 -0
  29. package/dist/config.d.ts.map +1 -0
  30. package/dist/config.js +235 -0
  31. package/dist/config.js.map +1 -0
  32. package/dist/core/agent-session.d.ts +571 -0
  33. package/dist/core/agent-session.d.ts.map +1 -0
  34. package/dist/core/agent-session.js +2343 -0
  35. package/dist/core/agent-session.js.map +1 -0
  36. package/dist/core/auth-storage.d.ts +129 -0
  37. package/dist/core/auth-storage.d.ts.map +1 -0
  38. package/dist/core/auth-storage.js +394 -0
  39. package/dist/core/auth-storage.js.map +1 -0
  40. package/dist/core/bash-executor.d.ts +47 -0
  41. package/dist/core/bash-executor.d.ts.map +1 -0
  42. package/dist/core/bash-executor.js +212 -0
  43. package/dist/core/bash-executor.js.map +1 -0
  44. package/dist/core/compaction/branch-summarization.d.ts +86 -0
  45. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  46. package/dist/core/compaction/branch-summarization.js +242 -0
  47. package/dist/core/compaction/branch-summarization.js.map +1 -0
  48. package/dist/core/compaction/compaction.d.ts +121 -0
  49. package/dist/core/compaction/compaction.d.ts.map +1 -0
  50. package/dist/core/compaction/compaction.js +607 -0
  51. package/dist/core/compaction/compaction.js.map +1 -0
  52. package/dist/core/compaction/index.d.ts +7 -0
  53. package/dist/core/compaction/index.d.ts.map +1 -0
  54. package/dist/core/compaction/index.js +7 -0
  55. package/dist/core/compaction/index.js.map +1 -0
  56. package/dist/core/compaction/utils.d.ts +35 -0
  57. package/dist/core/compaction/utils.d.ts.map +1 -0
  58. package/dist/core/compaction/utils.js +138 -0
  59. package/dist/core/compaction/utils.js.map +1 -0
  60. package/dist/core/defaults.d.ts +3 -0
  61. package/dist/core/defaults.d.ts.map +1 -0
  62. package/dist/core/defaults.js +2 -0
  63. package/dist/core/defaults.js.map +1 -0
  64. package/dist/core/diagnostics.d.ts +15 -0
  65. package/dist/core/diagnostics.d.ts.map +1 -0
  66. package/dist/core/diagnostics.js +2 -0
  67. package/dist/core/diagnostics.js.map +1 -0
  68. package/dist/core/event-bus.d.ts +9 -0
  69. package/dist/core/event-bus.d.ts.map +1 -0
  70. package/dist/core/event-bus.js +25 -0
  71. package/dist/core/event-bus.js.map +1 -0
  72. package/dist/core/exec.d.ts +29 -0
  73. package/dist/core/exec.d.ts.map +1 -0
  74. package/dist/core/exec.js +71 -0
  75. package/dist/core/exec.js.map +1 -0
  76. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  77. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  78. package/dist/core/export-html/ansi-to-html.js +249 -0
  79. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  80. package/dist/core/export-html/index.d.ts +34 -0
  81. package/dist/core/export-html/index.d.ts.map +1 -0
  82. package/dist/core/export-html/index.js +222 -0
  83. package/dist/core/export-html/index.js.map +1 -0
  84. package/dist/core/export-html/template.css +971 -0
  85. package/dist/core/export-html/template.html +54 -0
  86. package/dist/core/export-html/template.js +1586 -0
  87. package/dist/core/export-html/tool-renderer.d.ts +35 -0
  88. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  89. package/dist/core/export-html/tool-renderer.js +57 -0
  90. package/dist/core/export-html/tool-renderer.js.map +1 -0
  91. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  92. package/dist/core/export-html/vendor/marked.min.js +6 -0
  93. package/dist/core/extensions/index.d.ts +11 -0
  94. package/dist/core/extensions/index.d.ts.map +1 -0
  95. package/dist/core/extensions/index.js +9 -0
  96. package/dist/core/extensions/index.js.map +1 -0
  97. package/dist/core/extensions/loader.d.ts +25 -0
  98. package/dist/core/extensions/loader.d.ts.map +1 -0
  99. package/dist/core/extensions/loader.js +415 -0
  100. package/dist/core/extensions/loader.js.map +1 -0
  101. package/dist/core/extensions/runner.d.ts +146 -0
  102. package/dist/core/extensions/runner.d.ts.map +1 -0
  103. package/dist/core/extensions/runner.js +645 -0
  104. package/dist/core/extensions/runner.js.map +1 -0
  105. package/dist/core/extensions/types.d.ts +1011 -0
  106. package/dist/core/extensions/types.d.ts.map +1 -0
  107. package/dist/core/extensions/types.js +35 -0
  108. package/dist/core/extensions/types.js.map +1 -0
  109. package/dist/core/extensions/wrapper.d.ts +27 -0
  110. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  111. package/dist/core/extensions/wrapper.js +102 -0
  112. package/dist/core/extensions/wrapper.js.map +1 -0
  113. package/dist/core/footer-data-provider.d.ts +32 -0
  114. package/dist/core/footer-data-provider.d.ts.map +1 -0
  115. package/dist/core/footer-data-provider.js +134 -0
  116. package/dist/core/footer-data-provider.js.map +1 -0
  117. package/dist/core/index.d.ts +9 -0
  118. package/dist/core/index.d.ts.map +1 -0
  119. package/dist/core/index.js +9 -0
  120. package/dist/core/index.js.map +1 -0
  121. package/dist/core/keybindings.d.ts +55 -0
  122. package/dist/core/keybindings.d.ts.map +1 -0
  123. package/dist/core/keybindings.js +153 -0
  124. package/dist/core/keybindings.js.map +1 -0
  125. package/dist/core/messages.d.ts +77 -0
  126. package/dist/core/messages.d.ts.map +1 -0
  127. package/dist/core/messages.js +123 -0
  128. package/dist/core/messages.js.map +1 -0
  129. package/dist/core/model-registry.d.ts +112 -0
  130. package/dist/core/model-registry.d.ts.map +1 -0
  131. package/dist/core/model-registry.js +534 -0
  132. package/dist/core/model-registry.js.map +1 -0
  133. package/dist/core/model-resolver.d.ts +104 -0
  134. package/dist/core/model-resolver.d.ts.map +1 -0
  135. package/dist/core/model-resolver.js +432 -0
  136. package/dist/core/model-resolver.js.map +1 -0
  137. package/dist/core/package-manager.d.ts +151 -0
  138. package/dist/core/package-manager.d.ts.map +1 -0
  139. package/dist/core/package-manager.js +1447 -0
  140. package/dist/core/package-manager.js.map +1 -0
  141. package/dist/core/prompt-templates.d.ts +50 -0
  142. package/dist/core/prompt-templates.d.ts.map +1 -0
  143. package/dist/core/prompt-templates.js +268 -0
  144. package/dist/core/prompt-templates.js.map +1 -0
  145. package/dist/core/resolve-config-value.d.ts +17 -0
  146. package/dist/core/resolve-config-value.d.ts.map +1 -0
  147. package/dist/core/resolve-config-value.js +59 -0
  148. package/dist/core/resolve-config-value.js.map +1 -0
  149. package/dist/core/resource-loader.d.ts +184 -0
  150. package/dist/core/resource-loader.d.ts.map +1 -0
  151. package/dist/core/resource-loader.js +670 -0
  152. package/dist/core/resource-loader.js.map +1 -0
  153. package/dist/core/sdk.d.ts +90 -0
  154. package/dist/core/sdk.d.ts.map +1 -0
  155. package/dist/core/sdk.js +235 -0
  156. package/dist/core/sdk.js.map +1 -0
  157. package/dist/core/session-manager.d.ts +323 -0
  158. package/dist/core/session-manager.d.ts.map +1 -0
  159. package/dist/core/session-manager.js +1098 -0
  160. package/dist/core/session-manager.js.map +1 -0
  161. package/dist/core/settings-manager.d.ts +225 -0
  162. package/dist/core/settings-manager.d.ts.map +1 -0
  163. package/dist/core/settings-manager.js +653 -0
  164. package/dist/core/settings-manager.js.map +1 -0
  165. package/dist/core/skills.d.ts +58 -0
  166. package/dist/core/skills.d.ts.map +1 -0
  167. package/dist/core/skills.js +364 -0
  168. package/dist/core/skills.js.map +1 -0
  169. package/dist/core/slash-commands.d.ts +15 -0
  170. package/dist/core/slash-commands.d.ts.map +1 -0
  171. package/dist/core/slash-commands.js +22 -0
  172. package/dist/core/slash-commands.js.map +1 -0
  173. package/dist/core/system-prompt.d.ts +24 -0
  174. package/dist/core/system-prompt.d.ts.map +1 -0
  175. package/dist/core/system-prompt.js +137 -0
  176. package/dist/core/system-prompt.js.map +1 -0
  177. package/dist/core/timings.d.ts +7 -0
  178. package/dist/core/timings.d.ts.map +1 -0
  179. package/dist/core/timings.js +25 -0
  180. package/dist/core/timings.js.map +1 -0
  181. package/dist/core/tools/bash.d.ts +55 -0
  182. package/dist/core/tools/bash.d.ts.map +1 -0
  183. package/dist/core/tools/bash.js +242 -0
  184. package/dist/core/tools/bash.js.map +1 -0
  185. package/dist/core/tools/edit-diff.d.ts +63 -0
  186. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  187. package/dist/core/tools/edit-diff.js +243 -0
  188. package/dist/core/tools/edit-diff.js.map +1 -0
  189. package/dist/core/tools/edit.d.ts +39 -0
  190. package/dist/core/tools/edit.d.ts.map +1 -0
  191. package/dist/core/tools/edit.js +146 -0
  192. package/dist/core/tools/edit.js.map +1 -0
  193. package/dist/core/tools/find.d.ts +39 -0
  194. package/dist/core/tools/find.d.ts.map +1 -0
  195. package/dist/core/tools/find.js +206 -0
  196. package/dist/core/tools/find.js.map +1 -0
  197. package/dist/core/tools/grep.d.ts +45 -0
  198. package/dist/core/tools/grep.d.ts.map +1 -0
  199. package/dist/core/tools/grep.js +239 -0
  200. package/dist/core/tools/grep.js.map +1 -0
  201. package/dist/core/tools/index.d.ts +73 -0
  202. package/dist/core/tools/index.d.ts.map +1 -0
  203. package/dist/core/tools/index.js +61 -0
  204. package/dist/core/tools/index.js.map +1 -0
  205. package/dist/core/tools/ls.d.ts +40 -0
  206. package/dist/core/tools/ls.d.ts.map +1 -0
  207. package/dist/core/tools/ls.js +118 -0
  208. package/dist/core/tools/ls.js.map +1 -0
  209. package/dist/core/tools/path-utils.d.ts +8 -0
  210. package/dist/core/tools/path-utils.d.ts.map +1 -0
  211. package/dist/core/tools/path-utils.js +81 -0
  212. package/dist/core/tools/path-utils.js.map +1 -0
  213. package/dist/core/tools/read.d.ts +39 -0
  214. package/dist/core/tools/read.d.ts.map +1 -0
  215. package/dist/core/tools/read.js +166 -0
  216. package/dist/core/tools/read.js.map +1 -0
  217. package/dist/core/tools/truncate.d.ts +70 -0
  218. package/dist/core/tools/truncate.d.ts.map +1 -0
  219. package/dist/core/tools/truncate.js +205 -0
  220. package/dist/core/tools/truncate.js.map +1 -0
  221. package/dist/core/tools/write.d.ts +29 -0
  222. package/dist/core/tools/write.d.ts.map +1 -0
  223. package/dist/core/tools/write.js +78 -0
  224. package/dist/core/tools/write.js.map +1 -0
  225. package/dist/extensions/gsd-commands.ts +338 -0
  226. package/dist/extensions/subagent.ts +312 -0
  227. package/dist/hooks/gsd/draht-post-phase.js +133 -0
  228. package/dist/hooks/gsd/draht-post-task.js +132 -0
  229. package/dist/hooks/gsd/draht-pre-execute.js +146 -0
  230. package/dist/hooks/gsd/draht-quality-gate.js +210 -0
  231. package/dist/index.d.ts +27 -0
  232. package/dist/index.d.ts.map +1 -0
  233. package/dist/index.js +42 -0
  234. package/dist/index.js.map +1 -0
  235. package/dist/main.d.ts +8 -0
  236. package/dist/main.d.ts.map +1 -0
  237. package/dist/main.js +812 -0
  238. package/dist/main.js.map +1 -0
  239. package/dist/migrations.d.ts +33 -0
  240. package/dist/migrations.d.ts.map +1 -0
  241. package/dist/migrations.js +261 -0
  242. package/dist/migrations.js.map +1 -0
  243. package/dist/modes/index.d.ts +9 -0
  244. package/dist/modes/index.d.ts.map +1 -0
  245. package/dist/modes/index.js +8 -0
  246. package/dist/modes/index.js.map +1 -0
  247. package/dist/modes/interactive/components/armin.d.ts +34 -0
  248. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  249. package/dist/modes/interactive/components/armin.js +333 -0
  250. package/dist/modes/interactive/components/armin.js.map +1 -0
  251. package/dist/modes/interactive/components/assistant-message.d.ts +16 -0
  252. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  253. package/dist/modes/interactive/components/assistant-message.js +96 -0
  254. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  255. package/dist/modes/interactive/components/bash-execution.d.ts +35 -0
  256. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  257. package/dist/modes/interactive/components/bash-execution.js +162 -0
  258. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  259. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  260. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  261. package/dist/modes/interactive/components/bordered-loader.js +51 -0
  262. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  263. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  264. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  265. package/dist/modes/interactive/components/branch-summary-message.js +44 -0
  266. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  267. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  268. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  269. package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
  270. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  271. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  272. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  273. package/dist/modes/interactive/components/config-selector.js +479 -0
  274. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  275. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  276. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  277. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  278. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  279. package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  280. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  281. package/dist/modes/interactive/components/custom-editor.js +70 -0
  282. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  283. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  284. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  285. package/dist/modes/interactive/components/custom-message.js +79 -0
  286. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  287. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  288. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  289. package/dist/modes/interactive/components/daxnuts.js +140 -0
  290. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  291. package/dist/modes/interactive/components/diff.d.ts +12 -0
  292. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  293. package/dist/modes/interactive/components/diff.js +133 -0
  294. package/dist/modes/interactive/components/diff.js.map +1 -0
  295. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  296. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  297. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  298. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  299. package/dist/modes/interactive/components/extension-editor.d.ts +17 -0
  300. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  301. package/dist/modes/interactive/components/extension-editor.js +102 -0
  302. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  303. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  304. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  305. package/dist/modes/interactive/components/extension-input.js +61 -0
  306. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  307. package/dist/modes/interactive/components/extension-selector.d.ts +24 -0
  308. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  309. package/dist/modes/interactive/components/extension-selector.js +78 -0
  310. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  311. package/dist/modes/interactive/components/footer.d.ts +26 -0
  312. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  313. package/dist/modes/interactive/components/footer.js +213 -0
  314. package/dist/modes/interactive/components/footer.js.map +1 -0
  315. package/dist/modes/interactive/components/index.d.ts +32 -0
  316. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  317. package/dist/modes/interactive/components/index.js +33 -0
  318. package/dist/modes/interactive/components/index.js.map +1 -0
  319. package/dist/modes/interactive/components/keybinding-hints.d.ts +41 -0
  320. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  321. package/dist/modes/interactive/components/keybinding-hints.js +61 -0
  322. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  323. package/dist/modes/interactive/components/login-dialog.d.ts +42 -0
  324. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  325. package/dist/modes/interactive/components/login-dialog.js +145 -0
  326. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  327. package/dist/modes/interactive/components/model-selector.d.ts +47 -0
  328. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  329. package/dist/modes/interactive/components/model-selector.js +271 -0
  330. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  331. package/dist/modes/interactive/components/oauth-selector.d.ts +19 -0
  332. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  333. package/dist/modes/interactive/components/oauth-selector.js +97 -0
  334. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  335. package/dist/modes/interactive/components/scoped-models-selector.d.ts +49 -0
  336. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  337. package/dist/modes/interactive/components/scoped-models-selector.js +275 -0
  338. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  339. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  340. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  341. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  342. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  343. package/dist/modes/interactive/components/session-selector.d.ts +95 -0
  344. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  345. package/dist/modes/interactive/components/session-selector.js +851 -0
  346. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  347. package/dist/modes/interactive/components/settings-selector.d.ts +56 -0
  348. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  349. package/dist/modes/interactive/components/settings-selector.js +287 -0
  350. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  351. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  352. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  353. package/dist/modes/interactive/components/show-images-selector.js +35 -0
  354. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  355. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  356. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  357. package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
  358. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  359. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  360. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  361. package/dist/modes/interactive/components/theme-selector.js +46 -0
  362. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  363. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  364. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  365. package/dist/modes/interactive/components/thinking-selector.js +47 -0
  366. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  367. package/dist/modes/interactive/components/tool-execution.d.ts +75 -0
  368. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  369. package/dist/modes/interactive/components/tool-execution.js +752 -0
  370. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  371. package/dist/modes/interactive/components/tree-selector.d.ts +68 -0
  372. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  373. package/dist/modes/interactive/components/tree-selector.js +934 -0
  374. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  375. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  376. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  377. package/dist/modes/interactive/components/user-message-selector.js +113 -0
  378. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  379. package/dist/modes/interactive/components/user-message.d.ts +8 -0
  380. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  381. package/dist/modes/interactive/components/user-message.js +16 -0
  382. package/dist/modes/interactive/components/user-message.js.map +1 -0
  383. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  384. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  385. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  386. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  387. package/dist/modes/interactive/interactive-mode.d.ts +315 -0
  388. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  389. package/dist/modes/interactive/interactive-mode.js +3719 -0
  390. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  391. package/dist/modes/interactive/theme/dark.json +85 -0
  392. package/dist/modes/interactive/theme/light.json +84 -0
  393. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  394. package/dist/modes/interactive/theme/theme.d.ts +78 -0
  395. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  396. package/dist/modes/interactive/theme/theme.js +944 -0
  397. package/dist/modes/interactive/theme/theme.js.map +1 -0
  398. package/dist/modes/print-mode.d.ts +28 -0
  399. package/dist/modes/print-mode.d.ts.map +1 -0
  400. package/dist/modes/print-mode.js +101 -0
  401. package/dist/modes/print-mode.js.map +1 -0
  402. package/dist/modes/rpc/rpc-client.d.ts +217 -0
  403. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  404. package/dist/modes/rpc/rpc-client.js +405 -0
  405. package/dist/modes/rpc/rpc-client.js.map +1 -0
  406. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  407. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  408. package/dist/modes/rpc/rpc-mode.js +511 -0
  409. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  410. package/dist/modes/rpc/rpc-types.d.ts +409 -0
  411. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  412. package/dist/modes/rpc/rpc-types.js +8 -0
  413. package/dist/modes/rpc/rpc-types.js.map +1 -0
  414. package/dist/prompts/agents/build.md +44 -0
  415. package/dist/prompts/agents/plan.md +39 -0
  416. package/dist/prompts/agents/verify.md +33 -0
  417. package/dist/prompts/commands/atomic-commit.md +39 -0
  418. package/dist/prompts/commands/discuss-phase.md +25 -0
  419. package/dist/prompts/commands/execute-phase.md +59 -0
  420. package/dist/prompts/commands/map-codebase.md +32 -0
  421. package/dist/prompts/commands/new-project.md +40 -0
  422. package/dist/prompts/commands/pause-work.md +12 -0
  423. package/dist/prompts/commands/plan-phase.md +61 -0
  424. package/dist/prompts/commands/progress.md +12 -0
  425. package/dist/prompts/commands/quick.md +19 -0
  426. package/dist/prompts/commands/resume-work.md +13 -0
  427. package/dist/prompts/commands/verify-work.md +27 -0
  428. package/dist/utils/changelog.d.ts +21 -0
  429. package/dist/utils/changelog.d.ts.map +1 -0
  430. package/dist/utils/changelog.js +87 -0
  431. package/dist/utils/changelog.js.map +1 -0
  432. package/dist/utils/clipboard-image.d.ts +11 -0
  433. package/dist/utils/clipboard-image.d.ts.map +1 -0
  434. package/dist/utils/clipboard-image.js +162 -0
  435. package/dist/utils/clipboard-image.js.map +1 -0
  436. package/dist/utils/clipboard-native.d.ts +7 -0
  437. package/dist/utils/clipboard-native.d.ts.map +1 -0
  438. package/dist/utils/clipboard-native.js +14 -0
  439. package/dist/utils/clipboard-native.js.map +1 -0
  440. package/dist/utils/clipboard.d.ts +2 -0
  441. package/dist/utils/clipboard.d.ts.map +1 -0
  442. package/dist/utils/clipboard.js +67 -0
  443. package/dist/utils/clipboard.js.map +1 -0
  444. package/dist/utils/frontmatter.d.ts +8 -0
  445. package/dist/utils/frontmatter.d.ts.map +1 -0
  446. package/dist/utils/frontmatter.js +26 -0
  447. package/dist/utils/frontmatter.js.map +1 -0
  448. package/dist/utils/git.d.ts +26 -0
  449. package/dist/utils/git.d.ts.map +1 -0
  450. package/dist/utils/git.js +163 -0
  451. package/dist/utils/git.js.map +1 -0
  452. package/dist/utils/image-convert.d.ts +9 -0
  453. package/dist/utils/image-convert.d.ts.map +1 -0
  454. package/dist/utils/image-convert.js +35 -0
  455. package/dist/utils/image-convert.js.map +1 -0
  456. package/dist/utils/image-resize.d.ts +36 -0
  457. package/dist/utils/image-resize.d.ts.map +1 -0
  458. package/dist/utils/image-resize.js +181 -0
  459. package/dist/utils/image-resize.js.map +1 -0
  460. package/dist/utils/mime.d.ts +2 -0
  461. package/dist/utils/mime.d.ts.map +1 -0
  462. package/dist/utils/mime.js +26 -0
  463. package/dist/utils/mime.js.map +1 -0
  464. package/dist/utils/photon.d.ts +21 -0
  465. package/dist/utils/photon.d.ts.map +1 -0
  466. package/dist/utils/photon.js +121 -0
  467. package/dist/utils/photon.js.map +1 -0
  468. package/dist/utils/shell.d.ts +26 -0
  469. package/dist/utils/shell.d.ts.map +1 -0
  470. package/dist/utils/shell.js +186 -0
  471. package/dist/utils/shell.js.map +1 -0
  472. package/dist/utils/sleep.d.ts +5 -0
  473. package/dist/utils/sleep.d.ts.map +1 -0
  474. package/dist/utils/sleep.js +17 -0
  475. package/dist/utils/sleep.js.map +1 -0
  476. package/dist/utils/tools-manager.d.ts +3 -0
  477. package/dist/utils/tools-manager.d.ts.map +1 -0
  478. package/dist/utils/tools-manager.js +251 -0
  479. package/dist/utils/tools-manager.js.map +1 -0
  480. package/docs/compaction.md +390 -0
  481. package/docs/custom-provider.md +580 -0
  482. package/docs/development.md +69 -0
  483. package/docs/extensions.md +1952 -0
  484. package/docs/images/doom-extension.png +0 -0
  485. package/docs/images/exy.png +0 -0
  486. package/docs/images/interactive-mode.png +0 -0
  487. package/docs/images/tree-view.png +0 -0
  488. package/docs/json.md +79 -0
  489. package/docs/keybindings.md +174 -0
  490. package/docs/models.md +293 -0
  491. package/docs/packages.md +209 -0
  492. package/docs/prompt-templates.md +67 -0
  493. package/docs/providers.md +186 -0
  494. package/docs/rpc.md +1317 -0
  495. package/docs/sdk.md +968 -0
  496. package/docs/session.md +412 -0
  497. package/docs/settings.md +223 -0
  498. package/docs/shell-aliases.md +13 -0
  499. package/docs/skills.md +231 -0
  500. package/docs/terminal-setup.md +70 -0
  501. package/docs/termux.md +127 -0
  502. package/docs/themes.md +295 -0
  503. package/docs/tree.md +219 -0
  504. package/docs/tui.md +887 -0
  505. package/docs/windows.md +17 -0
  506. package/examples/README.md +25 -0
  507. package/examples/extensions/README.md +204 -0
  508. package/examples/extensions/antigravity-image-gen.ts +413 -0
  509. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  510. package/examples/extensions/bash-spawn-hook.ts +30 -0
  511. package/examples/extensions/bookmark.ts +50 -0
  512. package/examples/extensions/built-in-tool-renderer.ts +246 -0
  513. package/examples/extensions/claude-rules.ts +86 -0
  514. package/examples/extensions/commands.ts +72 -0
  515. package/examples/extensions/confirm-destructive.ts +59 -0
  516. package/examples/extensions/custom-compaction.ts +114 -0
  517. package/examples/extensions/custom-footer.ts +64 -0
  518. package/examples/extensions/custom-header.ts +73 -0
  519. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  520. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  521. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  522. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  523. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  524. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  525. package/examples/extensions/custom-provider-qwen-cli/index.ts +345 -0
  526. package/examples/extensions/custom-provider-qwen-cli/package.json +16 -0
  527. package/examples/extensions/dirty-repo-guard.ts +56 -0
  528. package/examples/extensions/doom-overlay/README.md +46 -0
  529. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  530. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  531. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  532. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  533. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  534. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  535. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  536. package/examples/extensions/doom-overlay/index.ts +74 -0
  537. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  538. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  539. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  540. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  541. package/examples/extensions/dynamic-resources/index.ts +15 -0
  542. package/examples/extensions/event-bus.ts +43 -0
  543. package/examples/extensions/file-trigger.ts +41 -0
  544. package/examples/extensions/git-checkpoint.ts +53 -0
  545. package/examples/extensions/handoff.ts +150 -0
  546. package/examples/extensions/hello.ts +25 -0
  547. package/examples/extensions/inline-bash.ts +94 -0
  548. package/examples/extensions/input-transform.ts +43 -0
  549. package/examples/extensions/interactive-shell.ts +196 -0
  550. package/examples/extensions/mac-system-theme.ts +47 -0
  551. package/examples/extensions/message-renderer.ts +59 -0
  552. package/examples/extensions/minimal-mode.ts +426 -0
  553. package/examples/extensions/modal-editor.ts +85 -0
  554. package/examples/extensions/model-status.ts +31 -0
  555. package/examples/extensions/notify.ts +55 -0
  556. package/examples/extensions/overlay-qa-tests.ts +881 -0
  557. package/examples/extensions/overlay-test.ts +150 -0
  558. package/examples/extensions/permission-gate.ts +34 -0
  559. package/examples/extensions/pirate.ts +47 -0
  560. package/examples/extensions/plan-mode/README.md +65 -0
  561. package/examples/extensions/plan-mode/index.ts +340 -0
  562. package/examples/extensions/plan-mode/utils.ts +168 -0
  563. package/examples/extensions/preset.ts +398 -0
  564. package/examples/extensions/protected-paths.ts +30 -0
  565. package/examples/extensions/qna.ts +119 -0
  566. package/examples/extensions/question.ts +264 -0
  567. package/examples/extensions/questionnaire.ts +427 -0
  568. package/examples/extensions/rainbow-editor.ts +88 -0
  569. package/examples/extensions/reload-runtime.ts +37 -0
  570. package/examples/extensions/rpc-demo.ts +124 -0
  571. package/examples/extensions/sandbox/index.ts +318 -0
  572. package/examples/extensions/sandbox/package-lock.json +92 -0
  573. package/examples/extensions/sandbox/package.json +19 -0
  574. package/examples/extensions/send-user-message.ts +97 -0
  575. package/examples/extensions/session-name.ts +27 -0
  576. package/examples/extensions/shutdown-command.ts +63 -0
  577. package/examples/extensions/snake.ts +343 -0
  578. package/examples/extensions/space-invaders.ts +560 -0
  579. package/examples/extensions/ssh.ts +220 -0
  580. package/examples/extensions/sst-resource-manager.ts +203 -0
  581. package/examples/extensions/status-line.ts +40 -0
  582. package/examples/extensions/subagent/README.md +172 -0
  583. package/examples/extensions/subagent/agents/planner.md +37 -0
  584. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  585. package/examples/extensions/subagent/agents/scout.md +50 -0
  586. package/examples/extensions/subagent/agents/worker.md +24 -0
  587. package/examples/extensions/subagent/agents.ts +126 -0
  588. package/examples/extensions/subagent/index.ts +964 -0
  589. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  590. package/examples/extensions/subagent/prompts/implement.md +10 -0
  591. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  592. package/examples/extensions/summarize.ts +195 -0
  593. package/examples/extensions/system-prompt-header.ts +17 -0
  594. package/examples/extensions/timed-confirm.ts +70 -0
  595. package/examples/extensions/titlebar-spinner.ts +58 -0
  596. package/examples/extensions/todo.ts +299 -0
  597. package/examples/extensions/tool-override.ts +143 -0
  598. package/examples/extensions/tools.ts +146 -0
  599. package/examples/extensions/trigger-compact.ts +40 -0
  600. package/examples/extensions/truncated-tool.ts +192 -0
  601. package/examples/extensions/widget-placement.ts +17 -0
  602. package/examples/extensions/with-deps/index.ts +36 -0
  603. package/examples/extensions/with-deps/package-lock.json +31 -0
  604. package/examples/extensions/with-deps/package.json +22 -0
  605. package/examples/rpc-extension-ui.ts +632 -0
  606. package/examples/sdk/01-minimal.ts +22 -0
  607. package/examples/sdk/02-custom-model.ts +49 -0
  608. package/examples/sdk/03-custom-prompt.ts +55 -0
  609. package/examples/sdk/04-skills.ts +46 -0
  610. package/examples/sdk/05-tools.ts +56 -0
  611. package/examples/sdk/06-extensions.ts +88 -0
  612. package/examples/sdk/07-context-files.ts +40 -0
  613. package/examples/sdk/08-prompt-templates.ts +42 -0
  614. package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
  615. package/examples/sdk/10-settings.ts +51 -0
  616. package/examples/sdk/11-sessions.ts +48 -0
  617. package/examples/sdk/12-full-control.ts +82 -0
  618. package/examples/sdk/README.md +144 -0
  619. package/extensions/gsd-commands.ts +338 -0
  620. package/extensions/subagent.ts +312 -0
  621. package/hooks/gsd/draht-post-phase.js +133 -0
  622. package/hooks/gsd/draht-post-task.js +132 -0
  623. package/hooks/gsd/draht-pre-execute.js +146 -0
  624. package/hooks/gsd/draht-quality-gate.js +210 -0
  625. package/package.json +105 -0
  626. package/prompts/agents/build.md +44 -0
  627. package/prompts/agents/plan.md +39 -0
  628. package/prompts/agents/verify.md +33 -0
  629. package/prompts/commands/atomic-commit.md +39 -0
  630. package/prompts/commands/discuss-phase.md +25 -0
  631. package/prompts/commands/execute-phase.md +59 -0
  632. package/prompts/commands/map-codebase.md +32 -0
  633. package/prompts/commands/new-project.md +40 -0
  634. package/prompts/commands/pause-work.md +12 -0
  635. package/prompts/commands/plan-phase.md +61 -0
  636. package/prompts/commands/progress.md +12 -0
  637. package/prompts/commands/quick.md +19 -0
  638. package/prompts/commands/resume-work.md +13 -0
  639. package/prompts/commands/verify-work.md +27 -0
@@ -0,0 +1,220 @@
1
+ /**
2
+ * SSH Remote Execution Example
3
+ *
4
+ * Demonstrates delegating tool operations to a remote machine via SSH.
5
+ * When --ssh is provided, read/write/edit/bash run on the remote.
6
+ *
7
+ * Usage:
8
+ * pi -e ./ssh.ts --ssh user@host
9
+ * pi -e ./ssh.ts --ssh user@host:/remote/path
10
+ *
11
+ * Requirements:
12
+ * - SSH key-based auth (no password prompts)
13
+ * - bash on remote
14
+ */
15
+
16
+ import { spawn } from "node:child_process";
17
+ import type { ExtensionAPI } from "@draht/coding-agent";
18
+ import {
19
+ type BashOperations,
20
+ createBashTool,
21
+ createEditTool,
22
+ createReadTool,
23
+ createWriteTool,
24
+ type EditOperations,
25
+ type ReadOperations,
26
+ type WriteOperations,
27
+ } from "@draht/coding-agent";
28
+
29
+ function sshExec(remote: string, command: string): Promise<Buffer> {
30
+ return new Promise((resolve, reject) => {
31
+ const child = spawn("ssh", [remote, command], { stdio: ["ignore", "pipe", "pipe"] });
32
+ const chunks: Buffer[] = [];
33
+ const errChunks: Buffer[] = [];
34
+ child.stdout.on("data", (data) => chunks.push(data));
35
+ child.stderr.on("data", (data) => errChunks.push(data));
36
+ child.on("error", reject);
37
+ child.on("close", (code) => {
38
+ if (code !== 0) {
39
+ reject(new Error(`SSH failed (${code}): ${Buffer.concat(errChunks).toString()}`));
40
+ } else {
41
+ resolve(Buffer.concat(chunks));
42
+ }
43
+ });
44
+ });
45
+ }
46
+
47
+ function createRemoteReadOps(remote: string, remoteCwd: string, localCwd: string): ReadOperations {
48
+ const toRemote = (p: string) => p.replace(localCwd, remoteCwd);
49
+ return {
50
+ readFile: (p) => sshExec(remote, `cat ${JSON.stringify(toRemote(p))}`),
51
+ access: (p) => sshExec(remote, `test -r ${JSON.stringify(toRemote(p))}`).then(() => {}),
52
+ detectImageMimeType: async (p) => {
53
+ try {
54
+ const r = await sshExec(remote, `file --mime-type -b ${JSON.stringify(toRemote(p))}`);
55
+ const m = r.toString().trim();
56
+ return ["image/jpeg", "image/png", "image/gif", "image/webp"].includes(m) ? m : null;
57
+ } catch {
58
+ return null;
59
+ }
60
+ },
61
+ };
62
+ }
63
+
64
+ function createRemoteWriteOps(remote: string, remoteCwd: string, localCwd: string): WriteOperations {
65
+ const toRemote = (p: string) => p.replace(localCwd, remoteCwd);
66
+ return {
67
+ writeFile: async (p, content) => {
68
+ const b64 = Buffer.from(content).toString("base64");
69
+ await sshExec(remote, `echo ${JSON.stringify(b64)} | base64 -d > ${JSON.stringify(toRemote(p))}`);
70
+ },
71
+ mkdir: (dir) => sshExec(remote, `mkdir -p ${JSON.stringify(toRemote(dir))}`).then(() => {}),
72
+ };
73
+ }
74
+
75
+ function createRemoteEditOps(remote: string, remoteCwd: string, localCwd: string): EditOperations {
76
+ const r = createRemoteReadOps(remote, remoteCwd, localCwd);
77
+ const w = createRemoteWriteOps(remote, remoteCwd, localCwd);
78
+ return { readFile: r.readFile, access: r.access, writeFile: w.writeFile };
79
+ }
80
+
81
+ function createRemoteBashOps(remote: string, remoteCwd: string, localCwd: string): BashOperations {
82
+ const toRemote = (p: string) => p.replace(localCwd, remoteCwd);
83
+ return {
84
+ exec: (command, cwd, { onData, signal, timeout }) =>
85
+ new Promise((resolve, reject) => {
86
+ const cmd = `cd ${JSON.stringify(toRemote(cwd))} && ${command}`;
87
+ const child = spawn("ssh", [remote, cmd], { stdio: ["ignore", "pipe", "pipe"] });
88
+ let timedOut = false;
89
+ const timer = timeout
90
+ ? setTimeout(() => {
91
+ timedOut = true;
92
+ child.kill();
93
+ }, timeout * 1000)
94
+ : undefined;
95
+ child.stdout.on("data", onData);
96
+ child.stderr.on("data", onData);
97
+ child.on("error", (e) => {
98
+ if (timer) clearTimeout(timer);
99
+ reject(e);
100
+ });
101
+ const onAbort = () => child.kill();
102
+ signal?.addEventListener("abort", onAbort, { once: true });
103
+ child.on("close", (code) => {
104
+ if (timer) clearTimeout(timer);
105
+ signal?.removeEventListener("abort", onAbort);
106
+ if (signal?.aborted) reject(new Error("aborted"));
107
+ else if (timedOut) reject(new Error(`timeout:${timeout}`));
108
+ else resolve({ exitCode: code });
109
+ });
110
+ }),
111
+ };
112
+ }
113
+
114
+ export default function (pi: ExtensionAPI) {
115
+ pi.registerFlag("ssh", { description: "SSH remote: user@host or user@host:/path", type: "string" });
116
+
117
+ const localCwd = process.cwd();
118
+ const localRead = createReadTool(localCwd);
119
+ const localWrite = createWriteTool(localCwd);
120
+ const localEdit = createEditTool(localCwd);
121
+ const localBash = createBashTool(localCwd);
122
+
123
+ // Resolved lazily on session_start (CLI flags not available during factory)
124
+ let resolvedSsh: { remote: string; remoteCwd: string } | null = null;
125
+
126
+ const getSsh = () => resolvedSsh;
127
+
128
+ pi.registerTool({
129
+ ...localRead,
130
+ async execute(id, params, signal, onUpdate, _ctx) {
131
+ const ssh = getSsh();
132
+ if (ssh) {
133
+ const tool = createReadTool(localCwd, {
134
+ operations: createRemoteReadOps(ssh.remote, ssh.remoteCwd, localCwd),
135
+ });
136
+ return tool.execute(id, params, signal, onUpdate);
137
+ }
138
+ return localRead.execute(id, params, signal, onUpdate);
139
+ },
140
+ });
141
+
142
+ pi.registerTool({
143
+ ...localWrite,
144
+ async execute(id, params, signal, onUpdate, _ctx) {
145
+ const ssh = getSsh();
146
+ if (ssh) {
147
+ const tool = createWriteTool(localCwd, {
148
+ operations: createRemoteWriteOps(ssh.remote, ssh.remoteCwd, localCwd),
149
+ });
150
+ return tool.execute(id, params, signal, onUpdate);
151
+ }
152
+ return localWrite.execute(id, params, signal, onUpdate);
153
+ },
154
+ });
155
+
156
+ pi.registerTool({
157
+ ...localEdit,
158
+ async execute(id, params, signal, onUpdate, _ctx) {
159
+ const ssh = getSsh();
160
+ if (ssh) {
161
+ const tool = createEditTool(localCwd, {
162
+ operations: createRemoteEditOps(ssh.remote, ssh.remoteCwd, localCwd),
163
+ });
164
+ return tool.execute(id, params, signal, onUpdate);
165
+ }
166
+ return localEdit.execute(id, params, signal, onUpdate);
167
+ },
168
+ });
169
+
170
+ pi.registerTool({
171
+ ...localBash,
172
+ async execute(id, params, signal, onUpdate, _ctx) {
173
+ const ssh = getSsh();
174
+ if (ssh) {
175
+ const tool = createBashTool(localCwd, {
176
+ operations: createRemoteBashOps(ssh.remote, ssh.remoteCwd, localCwd),
177
+ });
178
+ return tool.execute(id, params, signal, onUpdate);
179
+ }
180
+ return localBash.execute(id, params, signal, onUpdate);
181
+ },
182
+ });
183
+
184
+ pi.on("session_start", async (_event, ctx) => {
185
+ // Resolve SSH config now that CLI flags are available
186
+ const arg = pi.getFlag("ssh") as string | undefined;
187
+ if (arg) {
188
+ if (arg.includes(":")) {
189
+ const [remote, path] = arg.split(":");
190
+ resolvedSsh = { remote, remoteCwd: path };
191
+ } else {
192
+ // No path given, evaluate pwd on remote
193
+ const remote = arg;
194
+ const pwd = (await sshExec(remote, "pwd")).toString().trim();
195
+ resolvedSsh = { remote, remoteCwd: pwd };
196
+ }
197
+ ctx.ui.setStatus("ssh", ctx.ui.theme.fg("accent", `SSH: ${resolvedSsh.remote}:${resolvedSsh.remoteCwd}`));
198
+ ctx.ui.notify(`SSH mode: ${resolvedSsh.remote}:${resolvedSsh.remoteCwd}`, "info");
199
+ }
200
+ });
201
+
202
+ // Handle user ! commands via SSH
203
+ pi.on("user_bash", (_event) => {
204
+ const ssh = getSsh();
205
+ if (!ssh) return; // No SSH, use local execution
206
+ return { operations: createRemoteBashOps(ssh.remote, ssh.remoteCwd, localCwd) };
207
+ });
208
+
209
+ // Replace local cwd with remote cwd in system prompt
210
+ pi.on("before_agent_start", async (event) => {
211
+ const ssh = getSsh();
212
+ if (ssh) {
213
+ const modified = event.systemPrompt.replace(
214
+ `Current working directory: ${localCwd}`,
215
+ `Current working directory: ${ssh.remoteCwd} (via SSH: ${ssh.remote})`,
216
+ );
217
+ return { systemPrompt: modified };
218
+ }
219
+ });
220
+ }
@@ -0,0 +1,203 @@
1
+ /**
2
+ * SST Resource Manager Extension
3
+ *
4
+ * Provides tools for querying SST v4 resource definitions and stack state
5
+ * from within the coding agent. Reads local .sst/ metadata and sst.config.ts
6
+ * — never triggers deployments.
7
+ *
8
+ * Tools:
9
+ * - sst_status: Show current SST stack status from local metadata
10
+ * - sst_resources: Parse and list resources defined in sst.config.ts
11
+ */
12
+
13
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
14
+ import { join, resolve } from "node:path";
15
+ import type { ExtensionAPI, ExtensionContext } from "@draht/coding-agent";
16
+ import { Type } from "@sinclair/typebox";
17
+
18
+ /** Find the nearest directory containing sst.config.ts, walking up from cwd */
19
+ function findSstRoot(cwd: string): string | undefined {
20
+ let dir = resolve(cwd);
21
+ while (dir !== "/") {
22
+ if (existsSync(join(dir, "sst.config.ts"))) return dir;
23
+ dir = resolve(dir, "..");
24
+ }
25
+ return undefined;
26
+ }
27
+
28
+ /** Parse resource definitions from sst.config.ts using regex (no eval) */
29
+ function parseResources(configPath: string): Array<{ type: string; name: string; line: number }> {
30
+ const content = readFileSync(configPath, "utf-8");
31
+ const resources: Array<{ type: string; name: string; line: number }> = [];
32
+ const lines = content.split("\n");
33
+
34
+ const resourcePattern = /new\s+sst\.aws\.(\w+)\(\s*["']([^"']+)["']/;
35
+ for (let i = 0; i < lines.length; i++) {
36
+ const match = lines[i].match(resourcePattern);
37
+ if (match) {
38
+ resources.push({ type: match[1], name: match[2], line: i + 1 });
39
+ }
40
+ }
41
+
42
+ const routePattern = /\.route\(\s*["']([^"']+)["']/;
43
+ for (let i = 0; i < lines.length; i++) {
44
+ const match = lines[i].match(routePattern);
45
+ if (match) {
46
+ resources.push({ type: "Route", name: match[1], line: i + 1 });
47
+ }
48
+ }
49
+
50
+ return resources;
51
+ }
52
+
53
+ /** Read .sst/ metadata if it exists */
54
+ function readSstMetadata(sstRoot: string): Record<string, unknown> | undefined {
55
+ const metaDir = join(sstRoot, ".sst");
56
+ if (!existsSync(metaDir)) return undefined;
57
+
58
+ const result: Record<string, unknown> = {};
59
+
60
+ const stageFile = join(metaDir, "stage");
61
+ if (existsSync(stageFile)) {
62
+ result.stage = readFileSync(stageFile, "utf-8").trim();
63
+ }
64
+
65
+ try {
66
+ const entries = readdirSync(metaDir);
67
+ result.files = entries;
68
+ result.lastModified = entries.reduce(
69
+ (latest, entry) => {
70
+ try {
71
+ const stat = statSync(join(metaDir, entry));
72
+ return stat.mtimeMs > (latest ?? 0) ? stat.mtimeMs : latest;
73
+ } catch {
74
+ return latest;
75
+ }
76
+ },
77
+ undefined as number | undefined,
78
+ );
79
+ } catch {
80
+ // ignore
81
+ }
82
+
83
+ return result;
84
+ }
85
+
86
+ export default function (pi: ExtensionAPI) {
87
+ pi.registerTool({
88
+ name: "sst_status",
89
+ label: "SST Status",
90
+ description:
91
+ "Show the current SST stack status from local .sst/ metadata. " +
92
+ "Reports stage, last activity, and whether the project has been initialized. " +
93
+ "Does NOT deploy or connect to AWS.",
94
+ parameters: Type.Object({}),
95
+
96
+ async execute(_toolCallId, _params, _signal, _onUpdate, ctx: ExtensionContext) {
97
+ const sstRoot = findSstRoot(ctx.cwd);
98
+
99
+ if (!sstRoot) {
100
+ return {
101
+ content: [
102
+ {
103
+ type: "text" as const,
104
+ text: "No sst.config.ts found in current directory or any parent. This project may not use SST.",
105
+ },
106
+ ],
107
+ details: undefined,
108
+ };
109
+ }
110
+
111
+ const configPath = join(sstRoot, "sst.config.ts");
112
+ const metadata = readSstMetadata(sstRoot);
113
+ const hasConfig = existsSync(configPath);
114
+ const hasSstDir = existsSync(join(sstRoot, ".sst"));
115
+
116
+ const lines: string[] = [];
117
+ lines.push(`SST Project Root: ${sstRoot}`);
118
+ lines.push(`Config: ${hasConfig ? "sst.config.ts found" : "MISSING"}`);
119
+ lines.push(
120
+ `Initialized: ${hasSstDir ? "yes (.sst/ exists)" : "no (.sst/ not found — run sst dev to initialize)"}`,
121
+ );
122
+
123
+ if (metadata) {
124
+ if (metadata.stage) lines.push(`Stage: ${metadata.stage}`);
125
+ if (metadata.lastModified) {
126
+ lines.push(`Last Activity: ${new Date(metadata.lastModified as number).toISOString()}`);
127
+ }
128
+ if (metadata.files) {
129
+ lines.push(`Metadata Files: ${(metadata.files as string[]).join(", ")}`);
130
+ }
131
+ }
132
+
133
+ return {
134
+ content: [{ type: "text" as const, text: lines.join("\n") }],
135
+ details: undefined,
136
+ };
137
+ },
138
+ });
139
+
140
+ pi.registerTool({
141
+ name: "sst_resources",
142
+ label: "SST Resources",
143
+ description:
144
+ "Parse and list all SST resources defined in sst.config.ts. " +
145
+ "Shows resource types (Dynamo, ApiGatewayV2, etc.), names, and line numbers. " +
146
+ "Reads the config file statically — does NOT deploy or query AWS.",
147
+ parameters: Type.Object({}),
148
+
149
+ async execute(_toolCallId, _params, _signal, _onUpdate, ctx: ExtensionContext) {
150
+ const sstRoot = findSstRoot(ctx.cwd);
151
+
152
+ if (!sstRoot) {
153
+ return {
154
+ content: [
155
+ {
156
+ type: "text" as const,
157
+ text: "No sst.config.ts found in current directory or any parent.",
158
+ },
159
+ ],
160
+ details: undefined,
161
+ };
162
+ }
163
+
164
+ const configPath = join(sstRoot, "sst.config.ts");
165
+ const resources = parseResources(configPath);
166
+
167
+ if (resources.length === 0) {
168
+ return {
169
+ content: [
170
+ {
171
+ type: "text" as const,
172
+ text: "No SST resources found in sst.config.ts. The file may use a non-standard pattern.",
173
+ },
174
+ ],
175
+ details: undefined,
176
+ };
177
+ }
178
+
179
+ const lines = [`SST Resources in ${configPath}:`, ""];
180
+ const byType = new Map<string, typeof resources>();
181
+ for (const r of resources) {
182
+ const list = byType.get(r.type) ?? [];
183
+ list.push(r);
184
+ byType.set(r.type, list);
185
+ }
186
+
187
+ for (const [type, items] of byType) {
188
+ lines.push(`${type}:`);
189
+ for (const item of items) {
190
+ lines.push(` - ${item.name} (line ${item.line})`);
191
+ }
192
+ }
193
+
194
+ lines.push("");
195
+ lines.push(`Total: ${resources.length} resources`);
196
+
197
+ return {
198
+ content: [{ type: "text" as const, text: lines.join("\n") }],
199
+ details: undefined,
200
+ };
201
+ },
202
+ });
203
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Status Line Extension
3
+ *
4
+ * Demonstrates ctx.ui.setStatus() for displaying persistent status text in the footer.
5
+ * Shows turn progress with themed colors.
6
+ */
7
+
8
+ import type { ExtensionAPI } from "@draht/coding-agent";
9
+
10
+ export default function (pi: ExtensionAPI) {
11
+ let turnCount = 0;
12
+
13
+ pi.on("session_start", async (_event, ctx) => {
14
+ const theme = ctx.ui.theme;
15
+ ctx.ui.setStatus("status-demo", theme.fg("dim", "Ready"));
16
+ });
17
+
18
+ pi.on("turn_start", async (_event, ctx) => {
19
+ turnCount++;
20
+ const theme = ctx.ui.theme;
21
+ const spinner = theme.fg("accent", "●");
22
+ const text = theme.fg("dim", ` Turn ${turnCount}...`);
23
+ ctx.ui.setStatus("status-demo", spinner + text);
24
+ });
25
+
26
+ pi.on("turn_end", async (_event, ctx) => {
27
+ const theme = ctx.ui.theme;
28
+ const check = theme.fg("success", "✓");
29
+ const text = theme.fg("dim", ` Turn ${turnCount} complete`);
30
+ ctx.ui.setStatus("status-demo", check + text);
31
+ });
32
+
33
+ pi.on("session_switch", async (event, ctx) => {
34
+ if (event.reason === "new") {
35
+ turnCount = 0;
36
+ const theme = ctx.ui.theme;
37
+ ctx.ui.setStatus("status-demo", theme.fg("dim", "Ready"));
38
+ }
39
+ });
40
+ }
@@ -0,0 +1,172 @@
1
+ # Subagent Example
2
+
3
+ Delegate tasks to specialized subagents with isolated context windows.
4
+
5
+ ## Features
6
+
7
+ - **Isolated context**: Each subagent runs in a separate `pi` process
8
+ - **Streaming output**: See tool calls and progress as they happen
9
+ - **Parallel streaming**: All parallel tasks stream updates simultaneously
10
+ - **Markdown rendering**: Final output rendered with proper formatting (expanded view)
11
+ - **Usage tracking**: Shows turns, tokens, cost, and context usage per agent
12
+ - **Abort support**: Ctrl+C propagates to kill subagent processes
13
+
14
+ ## Structure
15
+
16
+ ```
17
+ subagent/
18
+ ├── README.md # This file
19
+ ├── index.ts # The extension (entry point)
20
+ ├── agents.ts # Agent discovery logic
21
+ ├── agents/ # Sample agent definitions
22
+ │ ├── scout.md # Fast recon, returns compressed context
23
+ │ ├── planner.md # Creates implementation plans
24
+ │ ├── reviewer.md # Code review
25
+ │ └── worker.md # General-purpose (full capabilities)
26
+ └── prompts/ # Workflow presets (prompt templates)
27
+ ├── implement.md # scout -> planner -> worker
28
+ ├── scout-and-plan.md # scout -> planner (no implementation)
29
+ └── implement-and-review.md # worker -> reviewer -> worker
30
+ ```
31
+
32
+ ## Installation
33
+
34
+ From the repository root, symlink the files:
35
+
36
+ ```bash
37
+ # Symlink the extension (must be in a subdirectory with index.ts)
38
+ mkdir -p ~/.pi/agent/extensions/subagent
39
+ ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/index.ts" ~/.pi/agent/extensions/subagent/index.ts
40
+ ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/agents.ts" ~/.pi/agent/extensions/subagent/agents.ts
41
+
42
+ # Symlink agents
43
+ mkdir -p ~/.pi/agent/agents
44
+ for f in packages/coding-agent/examples/extensions/subagent/agents/*.md; do
45
+ ln -sf "$(pwd)/$f" ~/.pi/agent/agents/$(basename "$f")
46
+ done
47
+
48
+ # Symlink workflow prompts
49
+ mkdir -p ~/.pi/agent/prompts
50
+ for f in packages/coding-agent/examples/extensions/subagent/prompts/*.md; do
51
+ ln -sf "$(pwd)/$f" ~/.pi/agent/prompts/$(basename "$f")
52
+ done
53
+ ```
54
+
55
+ ## Security Model
56
+
57
+ This tool executes a separate `pi` subprocess with a delegated system prompt and tool/model configuration.
58
+
59
+ **Project-local agents** (`.pi/agents/*.md`) are repo-controlled prompts that can instruct the model to read files, run bash commands, etc.
60
+
61
+ **Default behavior:** Only loads **user-level agents** from `~/.pi/agent/agents`.
62
+
63
+ To enable project-local agents, pass `agentScope: "both"` (or `"project"`). Only do this for repositories you trust.
64
+
65
+ When running interactively, the tool prompts for confirmation before running project-local agents. Set `confirmProjectAgents: false` to disable.
66
+
67
+ ## Usage
68
+
69
+ ### Single agent
70
+ ```
71
+ Use scout to find all authentication code
72
+ ```
73
+
74
+ ### Parallel execution
75
+ ```
76
+ Run 2 scouts in parallel: one to find models, one to find providers
77
+ ```
78
+
79
+ ### Chained workflow
80
+ ```
81
+ Use a chain: first have scout find the read tool, then have planner suggest improvements
82
+ ```
83
+
84
+ ### Workflow prompts
85
+ ```
86
+ /implement add Redis caching to the session store
87
+ /scout-and-plan refactor auth to support OAuth
88
+ /implement-and-review add input validation to API endpoints
89
+ ```
90
+
91
+ ## Tool Modes
92
+
93
+ | Mode | Parameter | Description |
94
+ |------|-----------|-------------|
95
+ | Single | `{ agent, task }` | One agent, one task |
96
+ | Parallel | `{ tasks: [...] }` | Multiple agents run concurrently (max 8, 4 concurrent) |
97
+ | Chain | `{ chain: [...] }` | Sequential with `{previous}` placeholder |
98
+
99
+ ## Output Display
100
+
101
+ **Collapsed view** (default):
102
+ - Status icon (✓/✗/⏳) and agent name
103
+ - Last 5-10 items (tool calls and text)
104
+ - Usage stats: `3 turns ↑input ↓output RcacheRead WcacheWrite $cost ctx:contextTokens model`
105
+
106
+ **Expanded view** (Ctrl+O):
107
+ - Full task text
108
+ - All tool calls with formatted arguments
109
+ - Final output rendered as Markdown
110
+ - Per-task usage (for chain/parallel)
111
+
112
+ **Parallel mode streaming**:
113
+ - Shows all tasks with live status (⏳ running, ✓ done, ✗ failed)
114
+ - Updates as each task makes progress
115
+ - Shows "2/3 done, 1 running" status
116
+
117
+ **Tool call formatting** (mimics built-in tools):
118
+ - `$ command` for bash
119
+ - `read ~/path:1-10` for read
120
+ - `grep /pattern/ in ~/path` for grep
121
+ - etc.
122
+
123
+ ## Agent Definitions
124
+
125
+ Agents are markdown files with YAML frontmatter:
126
+
127
+ ```markdown
128
+ ---
129
+ name: my-agent
130
+ description: What this agent does
131
+ tools: read, grep, find, ls
132
+ model: claude-haiku-4-5
133
+ ---
134
+
135
+ System prompt for the agent goes here.
136
+ ```
137
+
138
+ **Locations:**
139
+ - `~/.pi/agent/agents/*.md` - User-level (always loaded)
140
+ - `.pi/agents/*.md` - Project-level (only with `agentScope: "project"` or `"both"`)
141
+
142
+ Project agents override user agents with the same name when `agentScope: "both"`.
143
+
144
+ ## Sample Agents
145
+
146
+ | Agent | Purpose | Model | Tools |
147
+ |-------|---------|-------|-------|
148
+ | `scout` | Fast codebase recon | Haiku | read, grep, find, ls, bash |
149
+ | `planner` | Implementation plans | Sonnet | read, grep, find, ls |
150
+ | `reviewer` | Code review | Sonnet | read, grep, find, ls, bash |
151
+ | `worker` | General-purpose | Sonnet | (all default) |
152
+
153
+ ## Workflow Prompts
154
+
155
+ | Prompt | Flow |
156
+ |--------|------|
157
+ | `/implement <query>` | scout → planner → worker |
158
+ | `/scout-and-plan <query>` | scout → planner |
159
+ | `/implement-and-review <query>` | worker → reviewer → worker |
160
+
161
+ ## Error Handling
162
+
163
+ - **Exit code != 0**: Tool returns error with stderr/output
164
+ - **stopReason "error"**: LLM error propagated with error message
165
+ - **stopReason "aborted"**: User abort (Ctrl+C) kills subprocess, throws error
166
+ - **Chain mode**: Stops at first failing step, reports which step failed
167
+
168
+ ## Limitations
169
+
170
+ - Output truncated to last 10 items in collapsed view (expand to see all)
171
+ - Agents discovered fresh on each invocation (allows editing mid-session)
172
+ - Parallel mode limited to 8 tasks, 4 concurrent
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: planner
3
+ description: Creates implementation plans from context and requirements
4
+ tools: read, grep, find, ls
5
+ model: claude-sonnet-4-5
6
+ ---
7
+
8
+ You are a planning specialist. You receive context (from a scout) and requirements, then produce a clear implementation plan.
9
+
10
+ You must NOT make any changes. Only read, analyze, and plan.
11
+
12
+ Input format you'll receive:
13
+ - Context/findings from a scout agent
14
+ - Original query or requirements
15
+
16
+ Output format:
17
+
18
+ ## Goal
19
+ One sentence summary of what needs to be done.
20
+
21
+ ## Plan
22
+ Numbered steps, each small and actionable:
23
+ 1. Step one - specific file/function to modify
24
+ 2. Step two - what to add/change
25
+ 3. ...
26
+
27
+ ## Files to Modify
28
+ - `path/to/file.ts` - what changes
29
+ - `path/to/other.ts` - what changes
30
+
31
+ ## New Files (if any)
32
+ - `path/to/new.ts` - purpose
33
+
34
+ ## Risks
35
+ Anything to watch out for.
36
+
37
+ Keep the plan concrete. The worker agent will execute it verbatim.