@draht/coding-agent 2026.3.11-1 → 2026.3.25-1

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 (380) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +45 -30
  3. package/bin/draht-tools.cjs +187 -32
  4. package/dist/bun/cli.d.ts +3 -0
  5. package/dist/bun/cli.d.ts.map +1 -0
  6. package/dist/bun/cli.js +7 -0
  7. package/dist/bun/cli.js.map +1 -0
  8. package/dist/bun/register-bedrock.d.ts +2 -0
  9. package/dist/bun/register-bedrock.d.ts.map +1 -0
  10. package/dist/bun/register-bedrock.js +4 -0
  11. package/dist/bun/register-bedrock.js.map +1 -0
  12. package/dist/cli/args.d.ts +1 -0
  13. package/dist/cli/args.d.ts.map +1 -1
  14. package/dist/cli/args.js +11 -6
  15. package/dist/cli/args.js.map +1 -1
  16. package/dist/cli/file-processor.d.ts.map +1 -1
  17. package/dist/cli/file-processor.js +4 -0
  18. package/dist/cli/file-processor.js.map +1 -1
  19. package/dist/cli/initial-message.d.ts +18 -0
  20. package/dist/cli/initial-message.d.ts.map +1 -0
  21. package/dist/cli/initial-message.js +22 -0
  22. package/dist/cli/initial-message.js.map +1 -0
  23. package/dist/cli/session-picker.d.ts.map +1 -1
  24. package/dist/cli/session-picker.js +2 -1
  25. package/dist/cli/session-picker.js.map +1 -1
  26. package/dist/cli.d.ts.map +1 -1
  27. package/dist/cli.js +1 -3
  28. package/dist/cli.js.map +1 -1
  29. package/dist/config.d.ts.map +1 -1
  30. package/dist/config.js +2 -2
  31. package/dist/config.js.map +1 -1
  32. package/dist/core/agent-session.d.ts +38 -5
  33. package/dist/core/agent-session.d.ts.map +1 -1
  34. package/dist/core/agent-session.js +201 -73
  35. package/dist/core/agent-session.js.map +1 -1
  36. package/dist/core/bash-executor.d.ts +6 -7
  37. package/dist/core/bash-executor.d.ts.map +1 -1
  38. package/dist/core/bash-executor.js +8 -107
  39. package/dist/core/bash-executor.js.map +1 -1
  40. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  41. package/dist/core/compaction/branch-summarization.js +1 -0
  42. package/dist/core/compaction/branch-summarization.js.map +1 -1
  43. package/dist/core/compaction/compaction.d.ts.map +1 -1
  44. package/dist/core/compaction/compaction.js +2 -0
  45. package/dist/core/compaction/compaction.js.map +1 -1
  46. package/dist/core/exec.d.ts.map +1 -1
  47. package/dist/core/exec.js +7 -3
  48. package/dist/core/exec.js.map +1 -1
  49. package/dist/core/export-html/index.d.ts +2 -2
  50. package/dist/core/export-html/index.d.ts.map +1 -1
  51. package/dist/core/export-html/index.js +7 -6
  52. package/dist/core/export-html/index.js.map +1 -1
  53. package/dist/core/export-html/template.css +43 -13
  54. package/dist/core/export-html/template.html +1 -0
  55. package/dist/core/export-html/template.js +107 -0
  56. package/dist/core/export-html/tool-renderer.d.ts +2 -2
  57. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  58. package/dist/core/export-html/tool-renderer.js +41 -16
  59. package/dist/core/export-html/tool-renderer.js.map +1 -1
  60. package/dist/core/extensions/index.d.ts +4 -3
  61. package/dist/core/extensions/index.d.ts.map +1 -1
  62. package/dist/core/extensions/index.js +1 -1
  63. package/dist/core/extensions/index.js.map +1 -1
  64. package/dist/core/extensions/loader.d.ts.map +1 -1
  65. package/dist/core/extensions/loader.js +16 -6
  66. package/dist/core/extensions/loader.js.map +1 -1
  67. package/dist/core/extensions/runner.d.ts +9 -9
  68. package/dist/core/extensions/runner.d.ts.map +1 -1
  69. package/dist/core/extensions/runner.js +89 -71
  70. package/dist/core/extensions/runner.js.map +1 -1
  71. package/dist/core/extensions/types.d.ts +49 -13
  72. package/dist/core/extensions/types.d.ts.map +1 -1
  73. package/dist/core/extensions/types.js.map +1 -1
  74. package/dist/core/extensions/wrapper.d.ts +4 -11
  75. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  76. package/dist/core/extensions/wrapper.js +6 -86
  77. package/dist/core/extensions/wrapper.js.map +1 -1
  78. package/dist/core/footer-data-provider.d.ts +13 -1
  79. package/dist/core/footer-data-provider.d.ts.map +1 -1
  80. package/dist/core/footer-data-provider.js +155 -37
  81. package/dist/core/footer-data-provider.js.map +1 -1
  82. package/dist/core/index.d.ts +2 -1
  83. package/dist/core/index.d.ts.map +1 -1
  84. package/dist/core/index.js +2 -1
  85. package/dist/core/index.js.map +1 -1
  86. package/dist/core/keybindings.d.ts +270 -50
  87. package/dist/core/keybindings.d.ts.map +1 -1
  88. package/dist/core/keybindings.js +222 -134
  89. package/dist/core/keybindings.js.map +1 -1
  90. package/dist/core/model-registry.d.ts +1 -0
  91. package/dist/core/model-registry.d.ts.map +1 -1
  92. package/dist/core/model-registry.js +49 -23
  93. package/dist/core/model-registry.js.map +1 -1
  94. package/dist/core/model-resolver.d.ts +6 -0
  95. package/dist/core/model-resolver.d.ts.map +1 -1
  96. package/dist/core/model-resolver.js +41 -17
  97. package/dist/core/model-resolver.js.map +1 -1
  98. package/dist/core/output-guard.d.ts +6 -0
  99. package/dist/core/output-guard.d.ts.map +1 -0
  100. package/dist/core/output-guard.js +59 -0
  101. package/dist/core/output-guard.js.map +1 -0
  102. package/dist/core/package-manager.d.ts +22 -1
  103. package/dist/core/package-manager.d.ts.map +1 -1
  104. package/dist/core/package-manager.js +374 -54
  105. package/dist/core/package-manager.js.map +1 -1
  106. package/dist/core/prompt-templates.d.ts +2 -1
  107. package/dist/core/prompt-templates.d.ts.map +1 -1
  108. package/dist/core/prompt-templates.js +39 -39
  109. package/dist/core/prompt-templates.js.map +1 -1
  110. package/dist/core/resolve-config-value.d.ts.map +1 -1
  111. package/dist/core/resolve-config-value.js +43 -8
  112. package/dist/core/resolve-config-value.js.map +1 -1
  113. package/dist/core/resource-loader.d.ts +6 -7
  114. package/dist/core/resource-loader.d.ts.map +1 -1
  115. package/dist/core/resource-loader.js +141 -118
  116. package/dist/core/resource-loader.js.map +1 -1
  117. package/dist/core/sdk.d.ts +3 -3
  118. package/dist/core/sdk.d.ts.map +1 -1
  119. package/dist/core/sdk.js +4 -4
  120. package/dist/core/sdk.js.map +1 -1
  121. package/dist/core/session-manager.d.ts +6 -0
  122. package/dist/core/session-manager.d.ts.map +1 -1
  123. package/dist/core/session-manager.js +9 -10
  124. package/dist/core/session-manager.js.map +1 -1
  125. package/dist/core/settings-manager.d.ts +3 -0
  126. package/dist/core/settings-manager.d.ts.map +1 -1
  127. package/dist/core/settings-manager.js +8 -0
  128. package/dist/core/settings-manager.js.map +1 -1
  129. package/dist/core/skills.d.ts +5 -3
  130. package/dist/core/skills.d.ts.map +1 -1
  131. package/dist/core/skills.js +54 -9
  132. package/dist/core/skills.js.map +1 -1
  133. package/dist/core/slash-commands.d.ts +2 -3
  134. package/dist/core/slash-commands.d.ts.map +1 -1
  135. package/dist/core/slash-commands.js +3 -2
  136. package/dist/core/slash-commands.js.map +1 -1
  137. package/dist/core/source-info.d.ts +18 -0
  138. package/dist/core/source-info.d.ts.map +1 -0
  139. package/dist/core/source-info.js +19 -0
  140. package/dist/core/source-info.js.map +1 -0
  141. package/dist/core/system-prompt.d.ts.map +1 -1
  142. package/dist/core/system-prompt.js +17 -60
  143. package/dist/core/system-prompt.js.map +1 -1
  144. package/dist/core/tools/bash.d.ts +24 -6
  145. package/dist/core/tools/bash.d.ts.map +1 -1
  146. package/dist/core/tools/bash.js +210 -110
  147. package/dist/core/tools/bash.js.map +1 -1
  148. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  149. package/dist/core/tools/edit-diff.js +1 -0
  150. package/dist/core/tools/edit-diff.js.map +1 -1
  151. package/dist/core/tools/edit.d.ts +14 -2
  152. package/dist/core/tools/edit.d.ts.map +1 -1
  153. package/dist/core/tools/edit.js +95 -23
  154. package/dist/core/tools/edit.js.map +1 -1
  155. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  156. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  157. package/dist/core/tools/file-mutation-queue.js +37 -0
  158. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  159. package/dist/core/tools/find.d.ts +11 -4
  160. package/dist/core/tools/find.d.ts.map +1 -1
  161. package/dist/core/tools/find.js +82 -30
  162. package/dist/core/tools/find.js.map +1 -1
  163. package/dist/core/tools/grep.d.ts +15 -4
  164. package/dist/core/tools/grep.d.ts.map +1 -1
  165. package/dist/core/tools/grep.js +83 -29
  166. package/dist/core/tools/grep.js.map +1 -1
  167. package/dist/core/tools/index.d.ts +58 -19
  168. package/dist/core/tools/index.d.ts.map +1 -1
  169. package/dist/core/tools/index.js +51 -26
  170. package/dist/core/tools/index.js.map +1 -1
  171. package/dist/core/tools/ls.d.ts +9 -3
  172. package/dist/core/tools/ls.d.ts.map +1 -1
  173. package/dist/core/tools/ls.js +67 -13
  174. package/dist/core/tools/ls.js.map +1 -1
  175. package/dist/core/tools/read.d.ts +10 -3
  176. package/dist/core/tools/read.d.ts.map +1 -1
  177. package/dist/core/tools/read.js +110 -51
  178. package/dist/core/tools/read.js.map +1 -1
  179. package/dist/core/tools/render-utils.d.ts +21 -0
  180. package/dist/core/tools/render-utils.d.ts.map +1 -0
  181. package/dist/core/tools/render-utils.js +49 -0
  182. package/dist/core/tools/render-utils.js.map +1 -0
  183. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  184. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  185. package/dist/core/tools/tool-definition-wrapper.js +30 -0
  186. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  187. package/dist/core/tools/write.d.ts +9 -3
  188. package/dist/core/tools/write.d.ts.map +1 -1
  189. package/dist/core/tools/write.js +168 -30
  190. package/dist/core/tools/write.js.map +1 -1
  191. package/dist/gsd/domain.d.ts +5 -1
  192. package/dist/gsd/domain.d.ts.map +1 -1
  193. package/dist/gsd/domain.js +71 -1
  194. package/dist/gsd/domain.js.map +1 -1
  195. package/dist/gsd/git.d.ts.map +1 -1
  196. package/dist/gsd/git.js +18 -0
  197. package/dist/gsd/git.js.map +1 -1
  198. package/dist/gsd/index.d.ts +1 -0
  199. package/dist/gsd/index.d.ts.map +1 -1
  200. package/dist/gsd/index.js.map +1 -1
  201. package/dist/index.d.ts +5 -4
  202. package/dist/index.d.ts.map +1 -1
  203. package/dist/index.js +4 -3
  204. package/dist/index.js.map +1 -1
  205. package/dist/main.d.ts.map +1 -1
  206. package/dist/main.js +105 -226
  207. package/dist/main.js.map +1 -1
  208. package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
  209. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  210. package/dist/modes/interactive/components/bash-execution.js +22 -9
  211. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  212. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  213. package/dist/modes/interactive/components/bordered-loader.js +1 -1
  214. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  215. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  216. package/dist/modes/interactive/components/branch-summary-message.js +2 -2
  217. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  218. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  219. package/dist/modes/interactive/components/compaction-summary-message.js +2 -2
  220. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  221. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  222. package/dist/modes/interactive/components/config-selector.js +8 -8
  223. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  224. package/dist/modes/interactive/components/custom-editor.d.ts +3 -3
  225. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  226. package/dist/modes/interactive/components/custom-editor.js +6 -6
  227. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  228. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  229. package/dist/modes/interactive/components/extension-editor.js +9 -9
  230. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  231. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  232. package/dist/modes/interactive/components/extension-input.js +5 -5
  233. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  234. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  235. package/dist/modes/interactive/components/extension-selector.js +8 -8
  236. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  237. package/dist/modes/interactive/components/index.d.ts +1 -1
  238. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  239. package/dist/modes/interactive/components/index.js +1 -1
  240. package/dist/modes/interactive/components/index.js.map +1 -1
  241. package/dist/modes/interactive/components/keybinding-hints.d.ts +3 -36
  242. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  243. package/dist/modes/interactive/components/keybinding-hints.js +5 -44
  244. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  245. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  246. package/dist/modes/interactive/components/login-dialog.js +6 -6
  247. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  248. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  249. package/dist/modes/interactive/components/model-selector.js +13 -9
  250. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  251. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  252. package/dist/modes/interactive/components/oauth-selector.js +6 -6
  253. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  254. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  255. package/dist/modes/interactive/components/scoped-models-selector.js +4 -4
  256. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  257. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  258. package/dist/modes/interactive/components/session-selector.js +32 -35
  259. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  260. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  261. package/dist/modes/interactive/components/settings-selector.js +5 -1
  262. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  263. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  264. package/dist/modes/interactive/components/show-images-selector.js +5 -1
  265. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  266. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  267. package/dist/modes/interactive/components/skill-invocation-message.js +2 -2
  268. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  269. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  270. package/dist/modes/interactive/components/theme-selector.js +5 -1
  271. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  272. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  273. package/dist/modes/interactive/components/thinking-selector.js +5 -1
  274. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  275. package/dist/modes/interactive/components/tool-execution.d.ts +16 -34
  276. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  277. package/dist/modes/interactive/components/tool-execution.js +128 -636
  278. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  279. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/tree-selector.js +27 -16
  281. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  282. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  283. package/dist/modes/interactive/components/user-message-selector.js +6 -6
  284. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  285. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  286. package/dist/modes/interactive/components/user-message.js +2 -1
  287. package/dist/modes/interactive/components/user-message.js.map +1 -1
  288. package/dist/modes/interactive/interactive-mode.d.ts +7 -11
  289. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  290. package/dist/modes/interactive/interactive-mode.js +353 -212
  291. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  292. package/dist/modes/interactive/theme/theme.d.ts +3 -0
  293. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  294. package/dist/modes/interactive/theme/theme.js +63 -37
  295. package/dist/modes/interactive/theme/theme.js.map +1 -1
  296. package/dist/modes/print-mode.d.ts.map +1 -1
  297. package/dist/modes/print-mode.js +5 -11
  298. package/dist/modes/print-mode.js.map +1 -1
  299. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  300. package/dist/modes/rpc/rpc-mode.js +27 -17
  301. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  302. package/dist/modes/rpc/rpc-types.d.ts +3 -4
  303. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  304. package/dist/modes/rpc/rpc-types.js.map +1 -1
  305. package/dist/prompts/commands/execute-phase.md +2 -2
  306. package/dist/prompts/commands/fix.md +2 -2
  307. package/dist/prompts/commands/plan-phase.md +5 -1
  308. package/dist/prompts/commands/quick.md +5 -1
  309. package/dist/utils/changelog.d.ts +12 -0
  310. package/dist/utils/changelog.d.ts.map +1 -1
  311. package/dist/utils/changelog.js +25 -14
  312. package/dist/utils/changelog.js.map +1 -1
  313. package/dist/utils/child-process.d.ts +11 -0
  314. package/dist/utils/child-process.d.ts.map +1 -0
  315. package/dist/utils/child-process.js +78 -0
  316. package/dist/utils/child-process.js.map +1 -0
  317. package/dist/utils/clipboard-image.d.ts.map +1 -1
  318. package/dist/utils/clipboard-image.js +94 -11
  319. package/dist/utils/clipboard-image.js.map +1 -1
  320. package/dist/utils/clipboard-native.d.ts +1 -0
  321. package/dist/utils/clipboard-native.d.ts.map +1 -1
  322. package/dist/utils/clipboard-native.js.map +1 -1
  323. package/dist/utils/clipboard.d.ts +1 -1
  324. package/dist/utils/clipboard.d.ts.map +1 -1
  325. package/dist/utils/clipboard.js +27 -16
  326. package/dist/utils/clipboard.js.map +1 -1
  327. package/dist/utils/exif-orientation.d.ts +5 -0
  328. package/dist/utils/exif-orientation.d.ts.map +1 -0
  329. package/dist/utils/exif-orientation.js +158 -0
  330. package/dist/utils/exif-orientation.js.map +1 -0
  331. package/dist/utils/image-convert.d.ts.map +1 -1
  332. package/dist/utils/image-convert.js +5 -1
  333. package/dist/utils/image-convert.js.map +1 -1
  334. package/dist/utils/image-resize.d.ts +5 -5
  335. package/dist/utils/image-resize.d.ts.map +1 -1
  336. package/dist/utils/image-resize.js +51 -95
  337. package/dist/utils/image-resize.js.map +1 -1
  338. package/dist/utils/notify.d.ts +12 -0
  339. package/dist/utils/notify.d.ts.map +1 -0
  340. package/dist/utils/notify.js +41 -0
  341. package/dist/utils/notify.js.map +1 -0
  342. package/dist/utils/tools-manager.d.ts.map +1 -1
  343. package/dist/utils/tools-manager.js +5 -4
  344. package/dist/utils/tools-manager.js.map +1 -1
  345. package/docs/custom-provider.md +6 -2
  346. package/docs/extensions.md +108 -21
  347. package/docs/keybindings.md +103 -112
  348. package/docs/models.md +39 -1
  349. package/docs/packages.md +9 -0
  350. package/docs/providers.md +7 -0
  351. package/docs/rpc.md +15 -6
  352. package/docs/sdk.md +2 -2
  353. package/docs/settings.md +9 -0
  354. package/docs/terminal-setup.md +11 -0
  355. package/docs/tui.md +2 -2
  356. package/examples/extensions/README.md +2 -2
  357. package/examples/extensions/antigravity-image-gen.ts +9 -6
  358. package/examples/extensions/built-in-tool-renderer.ts +8 -8
  359. package/examples/extensions/commands.ts +3 -3
  360. package/examples/extensions/custom-provider-gitlab-duo/test.ts +2 -2
  361. package/examples/extensions/minimal-mode.ts +14 -14
  362. package/examples/extensions/notify.ts +9 -2
  363. package/examples/extensions/preset.ts +2 -3
  364. package/examples/extensions/question.ts +2 -2
  365. package/examples/extensions/questionnaire.ts +2 -2
  366. package/examples/extensions/sandbox/index.ts +2 -3
  367. package/examples/extensions/subagent/index.ts +30 -8
  368. package/examples/extensions/titlebar-spinner.ts +2 -2
  369. package/examples/extensions/todo.ts +2 -2
  370. package/examples/extensions/tool-override.ts +10 -9
  371. package/examples/extensions/truncated-tool.ts +8 -5
  372. package/examples/sdk/04-skills.ts +8 -2
  373. package/examples/sdk/08-prompt-templates.ts +8 -2
  374. package/examples/sdk/12-full-control.ts +0 -1
  375. package/examples/sdk/README.md +1 -1
  376. package/package.json +4 -4
  377. package/prompts/commands/execute-phase.md +2 -2
  378. package/prompts/commands/fix.md +2 -2
  379. package/prompts/commands/plan-phase.md +5 -1
  380. package/prompts/commands/quick.md +5 -1
package/dist/main.js CHANGED
@@ -10,14 +10,16 @@ import { createInterface } from "readline";
10
10
  import { parseArgs, printHelp } from "./cli/args.js";
11
11
  import { selectConfig } from "./cli/config-selector.js";
12
12
  import { processFileArguments } from "./cli/file-processor.js";
13
+ import { buildInitialMessage } from "./cli/initial-message.js";
13
14
  import { listModels } from "./cli/list-models.js";
14
15
  import { selectSession } from "./cli/session-picker.js";
15
16
  import { APP_NAME, getAgentDir, getModelsPath, VERSION } from "./config.js";
16
17
  import { AuthStorage } from "./core/auth-storage.js";
17
18
  import { exportFromFile } from "./core/export-html/index.js";
18
- import { KeybindingsManager } from "./core/keybindings.js";
19
+ import { migrateKeybindingsConfigFile } from "./core/keybindings.js";
19
20
  import { ModelRegistry } from "./core/model-registry.js";
20
21
  import { resolveCliModel, resolveModelScope } from "./core/model-resolver.js";
22
+ import { restoreStdout, takeOverStdout } from "./core/output-guard.js";
21
23
  import { DefaultPackageManager } from "./core/package-manager.js";
22
24
  import { DefaultResourceLoader } from "./core/resource-loader.js";
23
25
  import { createAgentSession } from "./core/sdk.js";
@@ -84,7 +86,7 @@ function printPackageCommandHelp(command) {
84
86
  Install a package and add it to settings.
85
87
 
86
88
  Options:
87
- -l, --local Install project-locally (.draht/settings.json)
89
+ -l, --local Install project-locally (.pi/settings.json)
88
90
 
89
91
  Examples:
90
92
  ${APP_NAME} install npm:@foo/bar
@@ -100,12 +102,14 @@ Examples:
100
102
  ${getPackageCommandUsage("remove")}
101
103
 
102
104
  Remove a package and its source from settings.
105
+ Alias: ${APP_NAME} uninstall <source> [-l]
103
106
 
104
107
  Options:
105
- -l, --local Remove from project settings (.draht/settings.json)
108
+ -l, --local Remove from project settings (.pi/settings.json)
106
109
 
107
- Example:
110
+ Examples:
108
111
  ${APP_NAME} remove npm:@foo/bar
112
+ ${APP_NAME} uninstall npm:@foo/bar
109
113
  `);
110
114
  return;
111
115
  case "update":
@@ -126,8 +130,15 @@ List installed packages from user and project settings.
126
130
  }
127
131
  }
128
132
  function parsePackageCommand(args) {
129
- const [command, ...rest] = args;
130
- if (command !== "install" && command !== "remove" && command !== "update" && command !== "list") {
133
+ const [rawCommand, ...rest] = args;
134
+ let command;
135
+ if (rawCommand === "uninstall") {
136
+ command = "remove";
137
+ }
138
+ else if (rawCommand === "install" || rawCommand === "remove" || rawCommand === "update" || rawCommand === "list") {
139
+ command = rawCommand;
140
+ }
141
+ if (!command) {
131
142
  return undefined;
132
143
  }
133
144
  let local = false;
@@ -261,23 +272,17 @@ async function handlePackageCommand(args) {
261
272
  return true;
262
273
  }
263
274
  }
264
- async function prepareInitialMessage(parsed, autoResizeImages) {
275
+ async function prepareInitialMessage(parsed, autoResizeImages, stdinContent) {
265
276
  if (parsed.fileArgs.length === 0) {
266
- return {};
277
+ return buildInitialMessage({ parsed, stdinContent });
267
278
  }
268
279
  const { text, images } = await processFileArguments(parsed.fileArgs, { autoResizeImages });
269
- let initialMessage;
270
- if (parsed.messages.length > 0) {
271
- initialMessage = text + parsed.messages[0];
272
- parsed.messages.shift();
273
- }
274
- else {
275
- initialMessage = text;
276
- }
277
- return {
278
- initialMessage,
279
- initialImages: images.length > 0 ? images : undefined,
280
- };
280
+ return buildInitialMessage({
281
+ parsed,
282
+ fileText: text,
283
+ fileImages: images,
284
+ stdinContent,
285
+ });
281
286
  }
282
287
  /**
283
288
  * Resolve a session argument to a file path.
@@ -340,6 +345,30 @@ async function callSessionDirectoryHook(extensions, cwd) {
340
345
  }
341
346
  return customSessionDir;
342
347
  }
348
+ function validateForkFlags(parsed) {
349
+ if (!parsed.fork)
350
+ return;
351
+ const conflictingFlags = [
352
+ parsed.session ? "--session" : undefined,
353
+ parsed.continue ? "--continue" : undefined,
354
+ parsed.resume ? "--resume" : undefined,
355
+ parsed.noSession ? "--no-session" : undefined,
356
+ ].filter((flag) => flag !== undefined);
357
+ if (conflictingFlags.length > 0) {
358
+ console.error(chalk.red(`Error: --fork cannot be combined with ${conflictingFlags.join(", ")}`));
359
+ process.exit(1);
360
+ }
361
+ }
362
+ function forkSessionOrExit(sourcePath, cwd, sessionDir) {
363
+ try {
364
+ return SessionManager.forkFrom(sourcePath, cwd, sessionDir);
365
+ }
366
+ catch (error) {
367
+ const message = error instanceof Error ? error.message : String(error);
368
+ console.error(chalk.red(`Error: ${message}`));
369
+ process.exit(1);
370
+ }
371
+ }
343
372
  async function createSessionManager(parsed, cwd, extensions) {
344
373
  if (parsed.noSession) {
345
374
  return SessionManager.inMemory();
@@ -349,6 +378,18 @@ async function createSessionManager(parsed, cwd, extensions) {
349
378
  if (!effectiveSessionDir) {
350
379
  effectiveSessionDir = await callSessionDirectoryHook(extensions, cwd);
351
380
  }
381
+ if (parsed.fork) {
382
+ const resolved = await resolveSessionPath(parsed.fork, cwd, effectiveSessionDir);
383
+ switch (resolved.type) {
384
+ case "path":
385
+ case "local":
386
+ case "global":
387
+ return forkSessionOrExit(resolved.path, cwd, effectiveSessionDir);
388
+ case "not_found":
389
+ console.error(chalk.red(`No session found matching '${resolved.arg}'`));
390
+ process.exit(1);
391
+ }
392
+ }
352
393
  if (parsed.session) {
353
394
  const resolved = await resolveSessionPath(parsed.session, cwd, effectiveSessionDir);
354
395
  switch (resolved.type) {
@@ -363,7 +404,7 @@ async function createSessionManager(parsed, cwd, extensions) {
363
404
  console.log(chalk.dim("Aborted."));
364
405
  process.exit(0);
365
406
  }
366
- return SessionManager.forkFrom(resolved.path, cwd, effectiveSessionDir);
407
+ return forkSessionOrExit(resolved.path, cwd, effectiveSessionDir);
367
408
  }
368
409
  case "not_found":
369
410
  console.error(chalk.red(`No session found matching '${resolved.arg}'`));
@@ -483,159 +524,11 @@ async function handleConfigCommand(args) {
483
524
  });
484
525
  process.exit(0);
485
526
  }
486
- async function handleLoginCommand(args) {
487
- if (args[0] !== "login" && args[0] !== "--login") {
488
- return false;
489
- }
490
- const { getOAuthProviders } = await import("@draht/ai/oauth");
491
- const authMod = await import("./core/auth-storage.js");
492
- const AuthStorageClass = authMod.AuthStorage;
493
- // open browser - use dynamic import, fallback to exec
494
- const openBrowser = async (url) => {
495
- try {
496
- const { exec } = await import("child_process");
497
- exec(`open "${url}" 2>/dev/null || xdg-open "${url}" 2>/dev/null`);
498
- }
499
- catch {
500
- /* ignore */
501
- }
502
- };
503
- const providers = getOAuthProviders();
504
- const requestedProvider = args[1]?.toLowerCase();
505
- // Map friendly names to provider IDs
506
- const PROVIDER_ALIASES = {
507
- anthropic: "anthropic",
508
- claude: "anthropic",
509
- google: "google-gemini-cli",
510
- gemini: "google-gemini-cli",
511
- openai: "openai-codex",
512
- codex: "openai-codex",
513
- copilot: "github-copilot",
514
- github: "github-copilot",
515
- antigravity: "google-antigravity",
516
- };
517
- if (requestedProvider === "--help" || requestedProvider === "-h" || requestedProvider === "help") {
518
- console.log(chalk.bold("\n🔌 draht login\n"));
519
- console.log("Authenticate with AI providers.\n");
520
- console.log("Usage:");
521
- console.log(" draht login Interactive provider selection");
522
- console.log(" draht login anthropic Login to Anthropic (Claude Pro/Max)");
523
- console.log(" draht login gemini Login to Google Gemini CLI");
524
- console.log(" draht login openai Login to OpenAI (ChatGPT/Codex)");
525
- console.log(" draht login copilot Login to GitHub Copilot");
526
- console.log(" draht login all Login to all providers\n");
527
- console.log("Aliases: claude, google, codex, github\n");
528
- process.exit(0);
529
- }
530
- if (requestedProvider && requestedProvider !== "all") {
531
- const providerId = PROVIDER_ALIASES[requestedProvider] ?? requestedProvider;
532
- const provider = providers.find((p) => p.id === providerId);
533
- if (!provider) {
534
- console.log(chalk.red(`Unknown provider: ${requestedProvider}`));
535
- console.log(`\nAvailable providers:`);
536
- for (const p of providers) {
537
- const aliases = Object.entries(PROVIDER_ALIASES)
538
- .filter(([_, v]) => v === p.id)
539
- .map(([k]) => k);
540
- console.log(` ${chalk.bold(p.name)} (${p.id}) — aliases: ${aliases.join(", ")}`);
541
- }
542
- process.exit(1);
543
- }
544
- await loginProvider(provider, openBrowser);
545
- process.exit(0);
546
- }
547
- // Interactive: show menu
548
- console.log(chalk.bold("\n🔌 Draht Login\n"));
549
- console.log("Select a provider to authenticate:\n");
550
- const providerList = providers.filter((p) => ["anthropic", "gemini-cli", "openai-codex", "github-copilot"].includes(p.id));
551
- for (let i = 0; i < providerList.length; i++) {
552
- const p = providerList[i];
553
- const as = AuthStorageClass.create();
554
- const hasCredentials = as.has(p.id);
555
- const status = hasCredentials ? chalk.green("✓ logged in") : chalk.dim("not connected");
556
- console.log(` ${chalk.bold(i + 1)}. ${p.name} ${status}`);
557
- }
558
- console.log(` ${chalk.bold("a")}. Login to all`);
559
- console.log(` ${chalk.bold("q")}. Cancel\n`);
560
- const rl = createInterface({ input: process.stdin, output: process.stdout });
561
- const answer = await new Promise((resolve) => {
562
- rl.question("Choice: ", (ans) => {
563
- rl.close();
564
- resolve(ans.trim());
565
- });
566
- });
567
- if (answer === "q" || answer === "") {
568
- process.exit(0);
569
- }
570
- if (answer === "a") {
571
- for (const p of providerList) {
572
- await loginProvider(p, openBrowser);
573
- }
574
- }
575
- else {
576
- const idx = parseInt(answer, 10) - 1;
577
- if (idx >= 0 && idx < providerList.length) {
578
- await loginProvider(providerList[idx], openBrowser);
579
- }
580
- else {
581
- console.log(chalk.red("Invalid choice"));
582
- }
583
- }
584
- process.exit(0);
585
- }
586
- async function loginProvider(provider, openBrowser) {
587
- const { AuthStorage } = await import("./core/auth-storage.js");
588
- const authStorage = AuthStorage.create();
589
- console.log(`\n${chalk.bold(`Logging in to ${provider.name}...`)}`);
590
- try {
591
- const credentials = await provider.login({
592
- onAuth: (info) => {
593
- console.log(`\n${chalk.blue("→")} Opening browser for authentication...`);
594
- if (info.instructions)
595
- console.log(chalk.dim(info.instructions));
596
- openBrowser(info.url).catch(() => {
597
- console.log(`\n${chalk.yellow("Could not open browser. Visit manually:")}`);
598
- console.log(chalk.underline(info.url));
599
- });
600
- },
601
- onPrompt: async (prompt) => {
602
- const { createInterface } = await import("readline");
603
- const rl = createInterface({ input: process.stdin, output: process.stdout });
604
- return new Promise((resolve) => {
605
- rl.question(`${prompt.message} `, (ans) => {
606
- rl.close();
607
- resolve(ans.trim());
608
- });
609
- });
610
- },
611
- onProgress: (message) => {
612
- console.log(chalk.dim(` ${message}`));
613
- },
614
- onManualCodeInput: provider.usesCallbackServer
615
- ? async () => {
616
- const { createInterface } = await import("readline");
617
- const rl = createInterface({ input: process.stdin, output: process.stdout });
618
- return new Promise((resolve) => {
619
- rl.question("Enter the authorization code: ", (ans) => {
620
- rl.close();
621
- resolve(ans.trim());
622
- });
623
- });
624
- }
625
- : undefined,
626
- });
627
- authStorage.set(provider.id, { type: "oauth", ...credentials });
628
- console.log(chalk.green(`✓ ${provider.name} — logged in successfully`));
629
- }
630
- catch (error) {
631
- console.log(chalk.red(`✗ ${provider.name} — login failed: ${error instanceof Error ? error.message : error}`));
632
- }
633
- }
634
527
  export async function main(args) {
635
- const offlineMode = args.includes("--offline") || isTruthyEnvFlag(process.env.DRAHT_OFFLINE);
528
+ const offlineMode = args.includes("--offline") || isTruthyEnvFlag(process.env.PI_OFFLINE);
636
529
  if (offlineMode) {
637
- process.env.DRAHT_OFFLINE = "1";
638
- process.env.DRAHT_SKIP_VERSION_CHECK = "1";
530
+ process.env.PI_OFFLINE = "1";
531
+ process.env.PI_SKIP_VERSION_CHECK = "1";
639
532
  }
640
533
  if (await handlePackageCommand(args)) {
641
534
  return;
@@ -643,13 +536,14 @@ export async function main(args) {
643
536
  if (await handleConfigCommand(args)) {
644
537
  return;
645
538
  }
646
- if (await handleLoginCommand(args)) {
647
- return;
539
+ // First pass: parse args to get --extension paths
540
+ const firstPass = parseArgs(args);
541
+ const shouldTakeOverStdout = firstPass.mode !== undefined || firstPass.print || !process.stdin.isTTY;
542
+ if (shouldTakeOverStdout) {
543
+ takeOverStdout();
648
544
  }
649
545
  // Run migrations (pass cwd for project-local migrations)
650
546
  const { migratedAuthProviders: migratedProviders, deprecationWarnings } = runMigrations(process.cwd());
651
- // First pass: parse args to get --extension paths
652
- const firstPass = parseArgs(args);
653
547
  // Early load extensions to discover their CLI flags
654
548
  const cwd = process.cwd();
655
549
  const agentDir = getAgentDir();
@@ -680,8 +574,14 @@ export async function main(args) {
680
574
  }
681
575
  // Apply pending provider registrations from extensions immediately
682
576
  // so they're available for model resolution before AgentSession is created
683
- for (const { name, config } of extensionsResult.runtime.pendingProviderRegistrations) {
684
- modelRegistry.registerProvider(name, config);
577
+ for (const { name, config, extensionPath } of extensionsResult.runtime.pendingProviderRegistrations) {
578
+ try {
579
+ modelRegistry.registerProvider(name, config);
580
+ }
581
+ catch (error) {
582
+ const message = error instanceof Error ? error.message : String(error);
583
+ console.error(chalk.red(`Extension "${extensionPath}" error: ${message}`));
584
+ }
685
585
  }
686
586
  extensionsResult.runtime.pendingProviderRegistrations = [];
687
587
  const extensionFlags = new Map();
@@ -709,26 +609,13 @@ export async function main(args) {
709
609
  await listModels(modelRegistry, searchPattern);
710
610
  process.exit(0);
711
611
  }
712
- // Experimental: List attachable sessions
713
- if (parsed.listSessions) {
714
- const { listSessions } = await import("./cli/list-sessions.js");
715
- await listSessions();
716
- process.exit(0);
717
- }
718
- // Experimental: Attach to existing session
719
- if (parsed.attach) {
720
- const { runAttachMode } = await import("./cli/attach-mode.js");
721
- await runAttachMode(parsed.attach);
722
- process.exit(0);
723
- }
724
612
  // Read piped stdin content (if any) - skip for RPC mode which uses stdin for JSON-RPC
613
+ let stdinContent;
725
614
  if (parsed.mode !== "rpc") {
726
- const stdinContent = await readPipedStdin();
615
+ stdinContent = await readPipedStdin();
727
616
  if (stdinContent !== undefined) {
728
617
  // Force print mode since interactive mode requires a TTY for keyboard input
729
618
  parsed.print = true;
730
- // Prepend stdin content to messages
731
- parsed.messages.unshift(stdinContent);
732
619
  }
733
620
  }
734
621
  if (parsed.export) {
@@ -745,12 +632,19 @@ export async function main(args) {
745
632
  console.log(`Exported to: ${result}`);
746
633
  process.exit(0);
747
634
  }
635
+ migrateKeybindingsConfigFile(agentDir);
748
636
  if (parsed.mode === "rpc" && parsed.fileArgs.length > 0) {
749
637
  console.error(chalk.red("Error: @file arguments are not supported in RPC mode"));
750
638
  process.exit(1);
751
639
  }
752
- const { initialMessage, initialImages } = await prepareInitialMessage(parsed, settingsManager.getImageAutoResize());
640
+ validateForkFlags(parsed);
641
+ const { initialMessage, initialImages } = await prepareInitialMessage(parsed, settingsManager.getImageAutoResize(), stdinContent);
753
642
  const isInteractive = !parsed.print && parsed.mode === undefined;
643
+ const startupBenchmark = isTruthyEnvFlag(process.env.PI_STARTUP_BENCHMARK);
644
+ if (startupBenchmark && !isInteractive) {
645
+ console.error(chalk.red("Error: PI_STARTUP_BENCHMARK only supports interactive mode"));
646
+ process.exit(1);
647
+ }
754
648
  const mode = parsed.mode || "text";
755
649
  initTheme(settingsManager.getTheme(), isInteractive);
756
650
  // Show deprecation warnings in interactive mode
@@ -766,8 +660,6 @@ export async function main(args) {
766
660
  let sessionManager = await createSessionManager(parsed, cwd, extensionsResult);
767
661
  // Handle --resume: show session picker
768
662
  if (parsed.resume) {
769
- // Initialize keybindings so session picker respects user config
770
- KeybindingsManager.create();
771
663
  // Compute effective session dir for resume (same logic as createSessionManager)
772
664
  const effectiveSessionDir = parsed.sessionDir || (await callSessionDirectoryHook(extensionsResult, cwd));
773
665
  const selectedPath = await selectSession((onProgress) => SessionManager.list(cwd, effectiveSessionDir, onProgress), SessionManager.listAll);
@@ -791,29 +683,6 @@ export async function main(args) {
791
683
  authStorage.setRuntimeApiKey(sessionOptions.model.provider, parsed.apiKey);
792
684
  }
793
685
  const { session, modelFallbackMessage } = await createAgentSession(sessionOptions);
794
- // Experimental: Make session attachable if --attachable flag is set
795
- let cleanupSocketServer = null;
796
- if (parsed.attachable) {
797
- const { makeSessionAttachable } = await import("./core/socket-server/index.js");
798
- cleanupSocketServer = await makeSessionAttachable({
799
- session,
800
- enabled: true,
801
- });
802
- }
803
- // Ensure socket server is cleaned up on exit
804
- const cleanup = async () => {
805
- if (cleanupSocketServer) {
806
- await cleanupSocketServer();
807
- }
808
- };
809
- process.on("SIGINT", cleanup);
810
- process.on("SIGTERM", cleanup);
811
- process.on("exit", () => {
812
- if (cleanupSocketServer) {
813
- // Synchronous cleanup attempt
814
- cleanupSocketServer().catch(() => { });
815
- }
816
- });
817
686
  if (!isInteractive && !session.model) {
818
687
  console.error(chalk.red("No models available."));
819
688
  console.error(chalk.yellow("\nSet an API key environment variable:"));
@@ -849,8 +718,7 @@ export async function main(args) {
849
718
  .join(", ");
850
719
  console.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray("(Ctrl+P to cycle)")}`));
851
720
  }
852
- printTimings();
853
- const mode = new InteractiveMode(session, {
721
+ const interactiveMode = new InteractiveMode(session, {
854
722
  migratedProviders,
855
723
  modelFallbackMessage,
856
724
  initialMessage,
@@ -858,7 +726,20 @@ export async function main(args) {
858
726
  initialMessages: parsed.messages,
859
727
  verbose: parsed.verbose,
860
728
  });
861
- await mode.run();
729
+ if (startupBenchmark) {
730
+ await interactiveMode.init();
731
+ interactiveMode.stop();
732
+ stopThemeWatcher();
733
+ if (process.stdout.writableLength > 0) {
734
+ await new Promise((resolve) => process.stdout.once("drain", resolve));
735
+ }
736
+ if (process.stderr.writableLength > 0) {
737
+ await new Promise((resolve) => process.stderr.once("drain", resolve));
738
+ }
739
+ return;
740
+ }
741
+ printTimings();
742
+ await interactiveMode.run();
862
743
  }
863
744
  else {
864
745
  await runPrintMode(session, {
@@ -868,10 +749,8 @@ export async function main(args) {
868
749
  initialImages,
869
750
  });
870
751
  stopThemeWatcher();
871
- if (process.stdout.writableLength > 0) {
872
- await new Promise((resolve) => process.stdout.once("drain", resolve));
873
- }
874
- process.exit(0);
752
+ restoreStdout();
753
+ return;
875
754
  }
876
755
  }
877
756
  //# sourceMappingURL=main.js.map