@draht/coding-agent 2026.3.6 → 2026.3.14

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 (177) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +6 -2
  3. package/bin/draht-tools.cjs +187 -32
  4. package/dist/cli/args.d.ts +6 -0
  5. package/dist/cli/args.d.ts.map +1 -1
  6. package/dist/cli/args.js +24 -0
  7. package/dist/cli/args.js.map +1 -1
  8. package/dist/cli/attach-mode.d.ts +13 -0
  9. package/dist/cli/attach-mode.d.ts.map +1 -0
  10. package/dist/cli/attach-mode.js +97 -0
  11. package/dist/cli/attach-mode.js.map +1 -0
  12. package/dist/cli/list-sessions.d.ts +8 -0
  13. package/dist/cli/list-sessions.d.ts.map +1 -0
  14. package/dist/cli/list-sessions.js +52 -0
  15. package/dist/cli/list-sessions.js.map +1 -0
  16. package/dist/config.d.ts.map +1 -1
  17. package/dist/config.js +2 -2
  18. package/dist/config.js.map +1 -1
  19. package/dist/core/agent-session.d.ts +1 -0
  20. package/dist/core/agent-session.d.ts.map +1 -1
  21. package/dist/core/agent-session.js +50 -17
  22. package/dist/core/agent-session.js.map +1 -1
  23. package/dist/core/auth-storage.d.ts +2 -1
  24. package/dist/core/auth-storage.d.ts.map +1 -1
  25. package/dist/core/auth-storage.js +25 -1
  26. package/dist/core/auth-storage.js.map +1 -1
  27. package/dist/core/compaction/utils.d.ts +3 -0
  28. package/dist/core/compaction/utils.d.ts.map +1 -1
  29. package/dist/core/compaction/utils.js +16 -1
  30. package/dist/core/compaction/utils.js.map +1 -1
  31. package/dist/core/export-html/index.d.ts +5 -2
  32. package/dist/core/export-html/index.d.ts.map +1 -1
  33. package/dist/core/export-html/index.js +4 -3
  34. package/dist/core/export-html/index.js.map +1 -1
  35. package/dist/core/export-html/template.js +11 -14
  36. package/dist/core/export-html/tool-renderer.d.ts +5 -2
  37. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  38. package/dist/core/export-html/tool-renderer.js +12 -5
  39. package/dist/core/export-html/tool-renderer.js.map +1 -1
  40. package/dist/core/extensions/index.d.ts +1 -1
  41. package/dist/core/extensions/index.d.ts.map +1 -1
  42. package/dist/core/extensions/index.js.map +1 -1
  43. package/dist/core/extensions/loader.d.ts.map +1 -1
  44. package/dist/core/extensions/loader.js +6 -6
  45. package/dist/core/extensions/loader.js.map +1 -1
  46. package/dist/core/extensions/runner.d.ts +3 -2
  47. package/dist/core/extensions/runner.d.ts.map +1 -1
  48. package/dist/core/extensions/runner.js +32 -0
  49. package/dist/core/extensions/runner.js.map +1 -1
  50. package/dist/core/extensions/types.d.ts +21 -2
  51. package/dist/core/extensions/types.d.ts.map +1 -1
  52. package/dist/core/extensions/types.js.map +1 -1
  53. package/dist/core/model-resolver.d.ts.map +1 -1
  54. package/dist/core/model-resolver.js +2 -2
  55. package/dist/core/model-resolver.js.map +1 -1
  56. package/dist/core/package-manager.d.ts.map +1 -1
  57. package/dist/core/package-manager.js +2 -2
  58. package/dist/core/package-manager.js.map +1 -1
  59. package/dist/core/resource-loader.d.ts.map +1 -1
  60. package/dist/core/resource-loader.js +1 -1
  61. package/dist/core/resource-loader.js.map +1 -1
  62. package/dist/core/sdk.d.ts.map +1 -1
  63. package/dist/core/sdk.js +7 -0
  64. package/dist/core/sdk.js.map +1 -1
  65. package/dist/core/settings-manager.d.ts +4 -0
  66. package/dist/core/settings-manager.d.ts.map +1 -1
  67. package/dist/core/settings-manager.js +36 -2
  68. package/dist/core/settings-manager.js.map +1 -1
  69. package/dist/core/socket-server/discovery.d.ts +19 -0
  70. package/dist/core/socket-server/discovery.d.ts.map +1 -0
  71. package/dist/core/socket-server/discovery.js +91 -0
  72. package/dist/core/socket-server/discovery.js.map +1 -0
  73. package/dist/core/socket-server/index.d.ts +13 -0
  74. package/dist/core/socket-server/index.d.ts.map +1 -0
  75. package/dist/core/socket-server/index.js +11 -0
  76. package/dist/core/socket-server/index.js.map +1 -0
  77. package/dist/core/socket-server/session-integration.d.ts +17 -0
  78. package/dist/core/socket-server/session-integration.d.ts.map +1 -0
  79. package/dist/core/socket-server/session-integration.js +77 -0
  80. package/dist/core/socket-server/session-integration.js.map +1 -0
  81. package/dist/core/socket-server/socket-client.d.ts +65 -0
  82. package/dist/core/socket-server/socket-client.d.ts.map +1 -0
  83. package/dist/core/socket-server/socket-client.js +197 -0
  84. package/dist/core/socket-server/socket-client.js.map +1 -0
  85. package/dist/core/socket-server/socket-server.d.ts +60 -0
  86. package/dist/core/socket-server/socket-server.d.ts.map +1 -0
  87. package/dist/core/socket-server/socket-server.js +273 -0
  88. package/dist/core/socket-server/socket-server.js.map +1 -0
  89. package/dist/core/socket-server/types.d.ts +81 -0
  90. package/dist/core/socket-server/types.d.ts.map +1 -0
  91. package/dist/core/socket-server/types.js +8 -0
  92. package/dist/core/socket-server/types.js.map +1 -0
  93. package/dist/gsd/domain.d.ts +5 -1
  94. package/dist/gsd/domain.d.ts.map +1 -1
  95. package/dist/gsd/domain.js +71 -1
  96. package/dist/gsd/domain.js.map +1 -1
  97. package/dist/gsd/git.d.ts.map +1 -1
  98. package/dist/gsd/git.js +18 -0
  99. package/dist/gsd/git.js.map +1 -1
  100. package/dist/gsd/index.d.ts +1 -0
  101. package/dist/gsd/index.d.ts.map +1 -1
  102. package/dist/gsd/index.js.map +1 -1
  103. package/dist/index.d.ts +1 -1
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js.map +1 -1
  106. package/dist/main.d.ts.map +1 -1
  107. package/dist/main.js +76 -11
  108. package/dist/main.js.map +1 -1
  109. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  110. package/dist/modes/interactive/components/extension-editor.js +1 -0
  111. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  112. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  113. package/dist/modes/interactive/components/footer.js +8 -23
  114. package/dist/modes/interactive/components/footer.js.map +1 -1
  115. package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  116. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  117. package/dist/modes/interactive/components/settings-selector.js +10 -0
  118. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  119. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  120. package/dist/modes/interactive/components/tool-execution.js +14 -4
  121. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  122. package/dist/modes/interactive/components/tree-selector.d.ts +21 -2
  123. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  124. package/dist/modes/interactive/components/tree-selector.js +115 -9
  125. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  126. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  127. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  128. package/dist/modes/interactive/interactive-mode.js +66 -5
  129. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  130. package/dist/modes/rpc/jsonl.d.ts +17 -0
  131. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  132. package/dist/modes/rpc/jsonl.js +49 -0
  133. package/dist/modes/rpc/jsonl.js.map +1 -0
  134. package/dist/modes/rpc/rpc-client.d.ts +1 -1
  135. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  136. package/dist/modes/rpc/rpc-client.js +7 -11
  137. package/dist/modes/rpc/rpc-client.js.map +1 -1
  138. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  139. package/dist/modes/rpc/rpc-mode.js +9 -11
  140. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  141. package/dist/prompts/commands/execute-phase.md +2 -2
  142. package/dist/prompts/commands/fix.md +2 -2
  143. package/dist/prompts/commands/plan-phase.md +5 -1
  144. package/dist/prompts/commands/quick.md +5 -1
  145. package/dist/utils/changelog.d.ts +12 -0
  146. package/dist/utils/changelog.d.ts.map +1 -1
  147. package/dist/utils/changelog.js +25 -14
  148. package/dist/utils/changelog.js.map +1 -1
  149. package/dist/utils/notify.d.ts +12 -0
  150. package/dist/utils/notify.d.ts.map +1 -0
  151. package/dist/utils/notify.js +41 -0
  152. package/dist/utils/notify.js.map +1 -0
  153. package/docs/compaction.md +2 -0
  154. package/docs/custom-provider.md +11 -7
  155. package/docs/extensions.md +55 -3
  156. package/docs/keybindings.md +9 -1
  157. package/docs/models.md +5 -1
  158. package/docs/rpc.md +40 -3
  159. package/docs/session.md +2 -2
  160. package/docs/settings.md +1 -0
  161. package/docs/terminal-setup.md +28 -3
  162. package/docs/tmux.md +61 -0
  163. package/docs/tree.md +9 -0
  164. package/examples/extensions/antigravity-image-gen.ts +5 -4
  165. package/examples/extensions/custom-provider-gitlab-duo/test.ts +2 -2
  166. package/examples/extensions/notify.ts +9 -2
  167. package/examples/extensions/overlay-qa-tests.ts +468 -1
  168. package/examples/extensions/preset.ts +2 -3
  169. package/examples/extensions/provider-payload.ts +14 -0
  170. package/examples/extensions/sandbox/index.ts +2 -3
  171. package/examples/extensions/tool-override.ts +2 -3
  172. package/examples/extensions/with-deps/index.ts +1 -5
  173. package/package.json +7 -5
  174. package/prompts/commands/execute-phase.md +2 -2
  175. package/prompts/commands/fix.md +2 -2
  176. package/prompts/commands/plan-phase.md +5 -1
  177. package/prompts/commands/quick.md +5 -1
@@ -19,6 +19,7 @@ import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
19
19
  import { getChangelogPath, getNewEntries, parseChangelog } from "../../utils/changelog.js";
20
20
  import { copyToClipboard } from "../../utils/clipboard.js";
21
21
  import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
22
+ import { sendTerminalNotification } from "../../utils/notify.js";
22
23
  import { ensureTool } from "../../utils/tools-manager.js";
23
24
  import { ArminComponent } from "./components/armin.js";
24
25
  import { AssistantMessageComponent } from "./components/assistant-message.js";
@@ -360,6 +361,12 @@ export class InteractiveMode {
360
361
  this.showNewVersionNotification(newVersion);
361
362
  }
362
363
  });
364
+ // Check tmux keyboard setup asynchronously
365
+ this.checkTmuxKeyboardSetup().then((warning) => {
366
+ if (warning) {
367
+ this.showWarning(warning);
368
+ }
369
+ });
363
370
  // Show startup warnings
364
371
  const { migratedProviders, modelFallbackMessage, initialMessage, initialImages, initialMessages } = this.options;
365
372
  if (migratedProviders && migratedProviders.length > 0) {
@@ -428,6 +435,44 @@ export class InteractiveMode {
428
435
  return undefined;
429
436
  }
430
437
  }
438
+ async checkTmuxKeyboardSetup() {
439
+ if (!process.env.TMUX)
440
+ return undefined;
441
+ const runTmuxShow = (option) => {
442
+ return new Promise((resolve) => {
443
+ const proc = spawn("tmux", ["show", "-gv", option], {
444
+ stdio: ["ignore", "pipe", "ignore"],
445
+ });
446
+ let stdout = "";
447
+ const timer = setTimeout(() => {
448
+ proc.kill();
449
+ resolve(undefined);
450
+ }, 2000);
451
+ proc.stdout?.on("data", (data) => {
452
+ stdout += data.toString();
453
+ });
454
+ proc.on("error", () => {
455
+ clearTimeout(timer);
456
+ resolve(undefined);
457
+ });
458
+ proc.on("close", (code) => {
459
+ clearTimeout(timer);
460
+ resolve(code === 0 ? stdout.trim() : undefined);
461
+ });
462
+ });
463
+ };
464
+ const [extendedKeys, extendedKeysFormat] = await Promise.all([
465
+ runTmuxShow("extended-keys"),
466
+ runTmuxShow("extended-keys-format"),
467
+ ]);
468
+ if (extendedKeys !== "on" && extendedKeys !== "always") {
469
+ return "tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.";
470
+ }
471
+ if (extendedKeysFormat === "xterm") {
472
+ return "tmux extended-keys-format is xterm. Pi works best with csi-u. Add `set -g extended-keys-format csi-u` to ~/.tmux.conf and restart tmux.";
473
+ }
474
+ return undefined;
475
+ }
431
476
  /**
432
477
  * Get changelog entries to display on startup.
433
478
  * Only shows new entries since last seen version, skips for resumed sessions.
@@ -1289,10 +1334,18 @@ export class InteractiveMode {
1289
1334
  // Use duck typing since instanceof fails across jiti module boundaries
1290
1335
  const customEditor = newEditor;
1291
1336
  if ("actionHandlers" in customEditor && customEditor.actionHandlers instanceof Map) {
1292
- customEditor.onEscape = () => this.defaultEditor.onEscape?.();
1293
- customEditor.onCtrlD = () => this.defaultEditor.onCtrlD?.();
1294
- customEditor.onPasteImage = () => this.defaultEditor.onPasteImage?.();
1295
- customEditor.onExtensionShortcut = (data) => this.defaultEditor.onExtensionShortcut?.(data);
1337
+ if (!customEditor.onEscape) {
1338
+ customEditor.onEscape = () => this.defaultEditor.onEscape?.();
1339
+ }
1340
+ if (!customEditor.onCtrlD) {
1341
+ customEditor.onCtrlD = () => this.defaultEditor.onCtrlD?.();
1342
+ }
1343
+ if (!customEditor.onPasteImage) {
1344
+ customEditor.onPasteImage = () => this.defaultEditor.onPasteImage?.();
1345
+ }
1346
+ if (!customEditor.onExtensionShortcut) {
1347
+ customEditor.onExtensionShortcut = (data) => this.defaultEditor.onExtensionShortcut?.(data);
1348
+ }
1296
1349
  // Copy action handlers (clear, suspend, model switching, etc.)
1297
1350
  for (const [action, handler] of this.defaultEditor.actionHandlers) {
1298
1351
  customEditor.actionHandlers.set(action, handler);
@@ -1823,6 +1876,7 @@ export class InteractiveMode {
1823
1876
  }
1824
1877
  this.pendingTools.clear();
1825
1878
  await this.checkShutdownRequested();
1879
+ sendTerminalNotification(APP_NAME, "Ready for input");
1826
1880
  this.ui.requestRender();
1827
1881
  break;
1828
1882
  case "auto_compaction_start": {
@@ -2294,6 +2348,7 @@ export class InteractiveMode {
2294
2348
  // Spawn editor synchronously with inherited stdio for interactive editing
2295
2349
  const result = spawnSync(editor, [...editorArgs, tmpFile], {
2296
2350
  stdio: "inherit",
2351
+ shell: process.platform === "win32",
2297
2352
  });
2298
2353
  // On successful exit (status 0), replace editor content
2299
2354
  if (result.status === 0) {
@@ -2547,6 +2602,7 @@ export class InteractiveMode {
2547
2602
  hideThinkingBlock: this.hideThinkingBlock,
2548
2603
  collapseChangelog: this.settingsManager.getCollapseChangelog(),
2549
2604
  doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
2605
+ treeFilterMode: this.settingsManager.getTreeFilterMode(),
2550
2606
  showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
2551
2607
  editorPaddingX: this.settingsManager.getEditorPaddingX(),
2552
2608
  autocompleteMaxVisible: this.settingsManager.getAutocompleteMaxVisible(),
@@ -2625,6 +2681,9 @@ export class InteractiveMode {
2625
2681
  onDoubleEscapeActionChange: (action) => {
2626
2682
  this.settingsManager.setDoubleEscapeAction(action);
2627
2683
  },
2684
+ onTreeFilterModeChange: (mode) => {
2685
+ this.settingsManager.setTreeFilterMode(mode);
2686
+ },
2628
2687
  onShowHardwareCursorChange: (enabled) => {
2629
2688
  this.settingsManager.setShowHardwareCursor(enabled);
2630
2689
  this.ui.setShowHardwareCursor(enabled);
@@ -2878,6 +2937,7 @@ export class InteractiveMode {
2878
2937
  showTreeSelector(initialSelectedId) {
2879
2938
  const tree = this.sessionManager.getTree();
2880
2939
  const realLeafId = this.sessionManager.getLeafId();
2940
+ const initialFilterMode = this.settingsManager.getTreeFilterMode();
2881
2941
  if (tree.length === 0) {
2882
2942
  this.showStatus("No entries in session");
2883
2943
  return;
@@ -2971,7 +3031,7 @@ export class InteractiveMode {
2971
3031
  }, (entryId, label) => {
2972
3032
  this.sessionManager.appendLabelChange(entryId, label);
2973
3033
  this.ui.requestRender();
2974
- }, initialSelectedId);
3034
+ }, initialSelectedId, initialFilterMode);
2975
3035
  return { component: selector, focus: selector };
2976
3036
  });
2977
3037
  }
@@ -3526,6 +3586,7 @@ export class InteractiveMode {
3526
3586
  // New session via session (emits extension session events)
3527
3587
  await this.session.newSession();
3528
3588
  // Clear UI state
3589
+ this.headerContainer.clear();
3529
3590
  this.chatContainer.clear();
3530
3591
  this.pendingMessagesContainer.clear();
3531
3592
  this.compactionQueuedMessages = [];