@markusylisiurunen/tau 0.3.80 → 0.3.82

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 (225) hide show
  1. package/dist/code_mode/command.js +4 -16
  2. package/dist/code_mode/command.js.map +1 -1
  3. package/dist/code_mode/images.js +5 -6
  4. package/dist/code_mode/images.js.map +1 -1
  5. package/dist/code_mode/index.d.ts +1 -3
  6. package/dist/code_mode/index.js +1 -2
  7. package/dist/code_mode/index.js.map +1 -1
  8. package/dist/code_mode/runtime.d.ts +8 -4
  9. package/dist/code_mode/runtime.js +52 -63
  10. package/dist/code_mode/runtime.js.map +1 -1
  11. package/dist/core/code_mode/bash.js +269 -0
  12. package/dist/core/code_mode/bash.js.map +1 -0
  13. package/dist/core/code_mode/capability.js +2 -0
  14. package/dist/core/code_mode/capability.js.map +1 -0
  15. package/dist/core/code_mode/history.js +62 -0
  16. package/dist/core/code_mode/history.js.map +1 -0
  17. package/dist/core/code_mode/mcp.js +121 -0
  18. package/dist/core/code_mode/mcp.js.map +1 -0
  19. package/dist/core/code_mode/models.js +256 -0
  20. package/dist/core/code_mode/models.js.map +1 -0
  21. package/dist/core/{tools → code_mode}/nook.js +13 -77
  22. package/dist/core/code_mode/nook.js.map +1 -0
  23. package/dist/core/code_mode/sdk.js +97 -0
  24. package/dist/core/code_mode/sdk.js.map +1 -0
  25. package/dist/core/{tools → code_mode}/web.js +31 -90
  26. package/dist/core/code_mode/web.js.map +1 -0
  27. package/dist/core/commands/registry.js +0 -22
  28. package/dist/core/commands/registry.js.map +1 -1
  29. package/dist/core/config/content_loader.js +3 -1
  30. package/dist/core/config/content_loader.js.map +1 -1
  31. package/dist/core/debug.js +1 -1
  32. package/dist/core/debug.js.map +1 -1
  33. package/dist/core/index.js +1 -1
  34. package/dist/core/index.js.map +1 -1
  35. package/dist/core/models/openrouter.js +171 -0
  36. package/dist/core/models/openrouter.js.map +1 -0
  37. package/dist/core/{tool → models}/openrouter_decisions.js +6 -7
  38. package/dist/core/models/openrouter_decisions.js.map +1 -0
  39. package/dist/core/models/openrouter_media.js +128 -0
  40. package/dist/core/models/openrouter_media.js.map +1 -0
  41. package/dist/core/personas.js +2 -1
  42. package/dist/core/personas.js.map +1 -1
  43. package/dist/core/runtime/chat_runtime.js +2 -13
  44. package/dist/core/runtime/chat_runtime.js.map +1 -1
  45. package/dist/core/session/compaction.js +5 -3
  46. package/dist/core/session/compaction.js.map +1 -1
  47. package/dist/core/static/code_mode/history/documentation.md +95 -167
  48. package/dist/core/static/code_mode/mcp/documentation.md +144 -67
  49. package/dist/core/static/code_mode/nook/documentation.md +108 -169
  50. package/dist/core/static/code_mode/sandbox_runner.mjs +37 -20
  51. package/dist/core/static/code_mode/web/documentation.md +115 -213
  52. package/dist/core/static/tau_docs/client-tools.md +4 -4
  53. package/dist/core/static/tau_docs/history.md +2 -2
  54. package/dist/core/static/tau_docs/index.md +1 -1
  55. package/dist/core/static/tau_docs/node-sdk.md +6 -7
  56. package/dist/core/static/tau_docs/nook.md +2 -2
  57. package/dist/core/static/tau_docs/personas.md +2 -2
  58. package/dist/core/static/tau_docs/remote-sessions.md +2 -2
  59. package/dist/core/static/tau_docs/security.md +4 -4
  60. package/dist/core/static/tau_docs/session-protocol-methods.md +1 -46
  61. package/dist/core/static/tau_docs/session-protocol.md +11 -11
  62. package/dist/core/static/tau_docs/sessions.md +6 -25
  63. package/dist/core/static/tau_docs/subagents.md +3 -2
  64. package/dist/core/static/tau_docs/telegram.md +1 -1
  65. package/dist/core/static/tau_docs/tools.md +40 -48
  66. package/dist/core/static/tau_docs/troubleshooting.md +2 -2
  67. package/dist/core/static/tau_docs/tui.md +8 -7
  68. package/dist/core/subagents/registry.js +2 -1
  69. package/dist/core/subagents/registry.js.map +1 -1
  70. package/dist/core/subagents/types.js +2 -1
  71. package/dist/core/subagents/types.js.map +1 -1
  72. package/dist/core/telegram/adapter.js +1 -6
  73. package/dist/core/telegram/adapter.js.map +1 -1
  74. package/dist/core/tool/image_generate.js +2 -1
  75. package/dist/core/tool/image_generate.js.map +1 -1
  76. package/dist/core/tool/media.js +1 -49
  77. package/dist/core/tool/media.js.map +1 -1
  78. package/dist/core/tool/openrouter.js +24 -156
  79. package/dist/core/tool/openrouter.js.map +1 -1
  80. package/dist/core/tool/openrouter_input.js +77 -0
  81. package/dist/core/tool/openrouter_input.js.map +1 -0
  82. package/dist/core/tool/speech_generate.js +2 -1
  83. package/dist/core/tool/speech_generate.js.map +1 -1
  84. package/dist/core/tools/bash.js +2 -1
  85. package/dist/core/tools/bash.js.map +1 -1
  86. package/dist/core/tools/bash_jobs.js +34 -5
  87. package/dist/core/tools/bash_jobs.js.map +1 -1
  88. package/dist/core/tools/catalog.js +18 -44
  89. package/dist/core/tools/catalog.js.map +1 -1
  90. package/dist/core/tools/code.js +100 -0
  91. package/dist/core/tools/code.js.map +1 -0
  92. package/dist/core/tools/code_mode.js +9 -30
  93. package/dist/core/tools/code_mode.js.map +1 -1
  94. package/dist/core/tools/code_mode_worker.js +2 -2
  95. package/dist/core/tools/presentation.js +2 -1
  96. package/dist/core/tools/presentation.js.map +1 -1
  97. package/dist/core/tools/tool_names.js +5 -7
  98. package/dist/core/tools/tool_names.js.map +1 -1
  99. package/dist/core/utils/gemini_transcription.js +81 -37
  100. package/dist/core/utils/gemini_transcription.js.map +1 -1
  101. package/dist/core/utils/media_validation.js +50 -0
  102. package/dist/core/utils/media_validation.js.map +1 -0
  103. package/dist/core/utils/user_metadata.js +0 -14
  104. package/dist/core/utils/user_metadata.js.map +1 -1
  105. package/dist/core/version.js +2 -2
  106. package/dist/diff_tool/app/dist/assets/{angular-html-BbLgbIhq.js → angular-html-D20byCHL.js} +1 -1
  107. package/dist/diff_tool/app/dist/assets/{angular-ts-DXk17TRM.js → angular-ts-CvVQslm2.js} +1 -1
  108. package/dist/diff_tool/app/dist/assets/{apl-BsvksCXR.js → apl-DNIxlYWe.js} +1 -1
  109. package/dist/diff_tool/app/dist/assets/{astro-DH775E4V.js → astro-DDOw4EUG.js} +1 -1
  110. package/dist/diff_tool/app/dist/assets/{blade-Ck99Rm59.js → blade-DlhB-SLW.js} +1 -1
  111. package/dist/diff_tool/app/dist/assets/{c-DJpHqu5J.js → c-C1f4vhDm.js} +1 -1
  112. package/dist/diff_tool/app/dist/assets/{chapel-Owff0Csy.js → chapel-Ctt8xOX1.js} +1 -1
  113. package/dist/diff_tool/app/dist/assets/{cobol-Cv2gZuhO.js → cobol-BXw71PAA.js} +1 -1
  114. package/dist/diff_tool/app/dist/assets/{coffee-Bji0YCf_.js → coffee-CRh_5Nmr.js} +1 -1
  115. package/dist/diff_tool/app/dist/assets/{cpp-DTjA_yFF.js → cpp-IlI-zWOZ.js} +1 -1
  116. package/dist/diff_tool/app/dist/assets/{crystal-Dd00NOeb.js → crystal-CXeL28i7.js} +1 -1
  117. package/dist/diff_tool/app/dist/assets/{css-D44TN1V6.js → css-BfST9hFI.js} +1 -1
  118. package/dist/diff_tool/app/dist/assets/{edge-CVmGSi2m.js → edge--Q22k_ty.js} +1 -1
  119. package/dist/diff_tool/app/dist/assets/{elixir-B8Mq7no2.js → elixir-CIfC_rQx.js} +1 -1
  120. package/dist/diff_tool/app/dist/assets/{elm-CXS0I3Z2.js → elm-OkZ29XRO.js} +1 -1
  121. package/dist/diff_tool/app/dist/assets/{erb-B9oDKaUo.js → erb-B8ZXgEqv.js} +1 -1
  122. package/dist/diff_tool/app/dist/assets/{git-rebase-DT-YFebH.js → git-rebase-CxkO_WGd.js} +1 -1
  123. package/dist/diff_tool/app/dist/assets/{glimmer-js-s0DXlNjq.js → glimmer-js-BVadyIrr.js} +1 -1
  124. package/dist/diff_tool/app/dist/assets/{glimmer-ts-QgEB5S2z.js → glimmer-ts-D5J3Qb7n.js} +1 -1
  125. package/dist/diff_tool/app/dist/assets/{glsl-NA0icwbY.js → glsl-B6iy73-Y.js} +1 -1
  126. package/dist/diff_tool/app/dist/assets/{graphql-0_dOlfV0.js → graphql-Dc3rUXf5.js} +1 -1
  127. package/dist/diff_tool/app/dist/assets/{hack-D-mr7l1l.js → hack-q8Utf8Jp.js} +1 -1
  128. package/dist/diff_tool/app/dist/assets/{haml-B0-oQmz7.js → haml-mjMIlj_2.js} +1 -1
  129. package/dist/diff_tool/app/dist/assets/{handlebars-Yq9bXpWN.js → handlebars-CA-BL8Ks.js} +1 -1
  130. package/dist/diff_tool/app/dist/assets/{html-B8bMmdRK.js → html-BmPxhYCX.js} +1 -1
  131. package/dist/diff_tool/app/dist/assets/{html-derivative-BpxSlQb_.js → html-derivative-CvknIjuB.js} +1 -1
  132. package/dist/diff_tool/app/dist/assets/{http-hS_53mxt.js → http-DNxLDRIi.js} +1 -1
  133. package/dist/diff_tool/app/dist/assets/{hurl-B2ST1kwl.js → hurl-kbd3Eq2V.js} +1 -1
  134. package/dist/diff_tool/app/dist/assets/index-D8ZI_2RC.js +340 -0
  135. package/dist/diff_tool/app/dist/assets/{java-D4mj0lZJ.js → java-BuZshgf1.js} +1 -1
  136. package/dist/diff_tool/app/dist/assets/{javascript-wC7rrKiV.js → javascript-DfL2oeFU.js} +1 -1
  137. package/dist/diff_tool/app/dist/assets/{jinja-DbQ3o87F.js → jinja-Bu0KQihU.js} +1 -1
  138. package/dist/diff_tool/app/dist/assets/{jison-CrE9FdvP.js → jison-Bqn7Mf3Q.js} +1 -1
  139. package/dist/diff_tool/app/dist/assets/{json-xjicDyWN.js → json-BuX5LKaB.js} +1 -1
  140. package/dist/diff_tool/app/dist/assets/{jsx-m28lXojQ.js → jsx-DdVJ-ZBp.js} +1 -1
  141. package/dist/diff_tool/app/dist/assets/{julia-19xkOmop.js → julia-CQeijOoQ.js} +1 -1
  142. package/dist/diff_tool/app/dist/assets/{just-Cf7OorTr.js → just-vzAktFGR.js} +1 -1
  143. package/dist/diff_tool/app/dist/assets/{latex-DDb7GQOy.js → latex-Dm60cg0k.js} +1 -1
  144. package/dist/diff_tool/app/dist/assets/{liquid-DHOuQ0rf.js → liquid-vxKzm2P8.js} +1 -1
  145. package/dist/diff_tool/app/dist/assets/{lua-BGyIvonw.js → lua-DIoqi4dd.js} +1 -1
  146. package/dist/diff_tool/app/dist/assets/{marko-DB5OqI1C.js → marko-BTHgFKby.js} +1 -1
  147. package/dist/diff_tool/app/dist/assets/{mdc-DTyNMupO.js → mdc-CEfz8gZ9.js} +1 -1
  148. package/dist/diff_tool/app/dist/assets/{nginx-DfF0fMYD.js → nginx-DNlFDEfJ.js} +1 -1
  149. package/dist/diff_tool/app/dist/assets/{nim-BbwsXuZD.js → nim-DnvT_0lZ.js} +1 -1
  150. package/dist/diff_tool/app/dist/assets/{org-BkOBBl1f.js → org-BbD-ElVf.js} +1 -1
  151. package/dist/diff_tool/app/dist/assets/{perl-BTXTOl4K.js → perl-DTsbnAmK.js} +1 -1
  152. package/dist/diff_tool/app/dist/assets/{php-DIMVQWiA.js → php-CwEsJe-W.js} +1 -1
  153. package/dist/diff_tool/app/dist/assets/{pug-B_nrb4dJ.js → pug-BOttMVH-.js} +1 -1
  154. package/dist/diff_tool/app/dist/assets/{qml-1PXi8G8Z.js → qml-C8KkSItN.js} +1 -1
  155. package/dist/diff_tool/app/dist/assets/{r-CJrAkc2Z.js → r-K4ksJj_R.js} +1 -1
  156. package/dist/diff_tool/app/dist/assets/{razor-DgPUftNd.js → razor-yuWRrrG6.js} +1 -1
  157. package/dist/diff_tool/app/dist/assets/{regexp-C2hS8XvL.js → regexp-CV-jhnUz.js} +1 -1
  158. package/dist/diff_tool/app/dist/assets/{rst-CDouhKnc.js → rst-CLA3Attc.js} +1 -1
  159. package/dist/diff_tool/app/dist/assets/{ruby-CAjKW1uO.js → ruby-DiHR2-DX.js} +1 -1
  160. package/dist/diff_tool/app/dist/assets/{sas-qAHkHLc1.js → sas-DxIjbYJ5.js} +1 -1
  161. package/dist/diff_tool/app/dist/assets/{scss-Bfx2Ydid.js → scss-CShwEaV4.js} +1 -1
  162. package/dist/diff_tool/app/dist/assets/{shellscript-Bu76R8y2.js → shellscript-CeezOnrF.js} +1 -1
  163. package/dist/diff_tool/app/dist/assets/{shellsession-BU8BL0oL.js → shellsession-CjSS2r7j.js} +1 -1
  164. package/dist/diff_tool/app/dist/assets/{soy-FRl8ozP-.js → soy-CI_v23nJ.js} +1 -1
  165. package/dist/diff_tool/app/dist/assets/{sql-BacQgsEs.js → sql-D9GaB00A.js} +1 -1
  166. package/dist/diff_tool/app/dist/assets/{stata-B9kkG-ET.js → stata-hK92TPE_.js} +1 -1
  167. package/dist/diff_tool/app/dist/assets/{surrealql-qvETr7iY.js → surrealql-UO8LtPJG.js} +1 -1
  168. package/dist/diff_tool/app/dist/assets/{svelte-B0z1MgHc.js → svelte-kIlaw_oh.js} +1 -1
  169. package/dist/diff_tool/app/dist/assets/{templ-DTnPshKb.js → templ-DFRz1JP6.js} +1 -1
  170. package/dist/diff_tool/app/dist/assets/{tex-Cosab9_H.js → tex-CfxIXk_z.js} +1 -1
  171. package/dist/diff_tool/app/dist/assets/{ts-tags-DNYvLFUH.js → ts-tags-BtUHl0ff.js} +1 -1
  172. package/dist/diff_tool/app/dist/assets/{tsx-Dstq6j1a.js → tsx-Cd4SAe2C.js} +1 -1
  173. package/dist/diff_tool/app/dist/assets/{twig-BzqZdwaX.js → twig-CWk4q5Y3.js} +1 -1
  174. package/dist/diff_tool/app/dist/assets/{typescript-YOQ_oE25.js → typescript-BqxGJiP0.js} +1 -1
  175. package/dist/diff_tool/app/dist/assets/{typst-DTffwfpc.js → typst-D9nAun2p.js} +1 -1
  176. package/dist/diff_tool/app/dist/assets/{vue-D4OMj_C5.js → vue-D6HYhg6_.js} +1 -1
  177. package/dist/diff_tool/app/dist/assets/{vue-html-kT4WrHGK.js → vue-html-1VRlaENS.js} +1 -1
  178. package/dist/diff_tool/app/dist/assets/{vue-vine-CxeapeMO.js → vue-vine-BaH0We9y.js} +1 -1
  179. package/dist/diff_tool/app/dist/assets/{xml-DWVpuurg.js → xml-C4RWnUuj.js} +1 -1
  180. package/dist/diff_tool/app/dist/assets/{xsl-C0ciup5a.js → xsl-D1iD38ga.js} +1 -1
  181. package/dist/diff_tool/app/dist/assets/{yaml-98Fvyfpc.js → yaml-yAb4W0G-.js} +1 -1
  182. package/dist/diff_tool/app/dist/index.html +1 -1
  183. package/dist/host/local_session_host.js +24 -318
  184. package/dist/host/local_session_host.js.map +1 -1
  185. package/dist/host/session_host.js.map +1 -1
  186. package/dist/host/session_protocol_handler.js +0 -98
  187. package/dist/host/session_protocol_handler.js.map +1 -1
  188. package/dist/nook/README.md +1 -1
  189. package/dist/protocol/index.d.ts +1 -1
  190. package/dist/protocol/index.js.map +1 -1
  191. package/dist/protocol/session_protocol.d.ts +3 -28
  192. package/dist/protocol/session_protocol.js +1 -56
  193. package/dist/protocol/session_protocol.js.map +1 -1
  194. package/dist/sdk/code_mode.js +11 -17
  195. package/dist/sdk/code_mode.js.map +1 -1
  196. package/dist/sdk/index.d.ts +2 -2
  197. package/dist/sdk/index.js +1 -1
  198. package/dist/sdk/index.js.map +1 -1
  199. package/dist/sdk/session.js +0 -20
  200. package/dist/sdk/session.js.map +1 -1
  201. package/dist/sdk/types.d.ts +1 -7
  202. package/dist/store/session_snapshot_migrations.js +72 -1
  203. package/dist/store/session_snapshot_migrations.js.map +1 -1
  204. package/dist/tui/session_chat_controller.js +95 -82
  205. package/dist/tui/session_chat_controller.js.map +1 -1
  206. package/dist/tui/ui/footer.js +2 -5
  207. package/dist/tui/ui/footer.js.map +1 -1
  208. package/package.json +7 -7
  209. package/dist/code_mode/files.d.ts +0 -47
  210. package/dist/code_mode/files.js +0 -296
  211. package/dist/code_mode/files.js.map +0 -1
  212. package/dist/core/session/goal.js +0 -54
  213. package/dist/core/session/goal.js.map +0 -1
  214. package/dist/core/tool/openrouter_decisions.js.map +0 -1
  215. package/dist/core/tool/openrouter_media.js +0 -180
  216. package/dist/core/tool/openrouter_media.js.map +0 -1
  217. package/dist/core/tools/goal.js +0 -167
  218. package/dist/core/tools/goal.js.map +0 -1
  219. package/dist/core/tools/history.js +0 -118
  220. package/dist/core/tools/history.js.map +0 -1
  221. package/dist/core/tools/mcp.js +0 -167
  222. package/dist/core/tools/mcp.js.map +0 -1
  223. package/dist/core/tools/nook.js.map +0 -1
  224. package/dist/core/tools/web.js.map +0 -1
  225. package/dist/diff_tool/app/dist/assets/index-CBT_sNIz.js +0 -340
@@ -115,7 +115,6 @@ export class SessionChatController {
115
115
  newSession: () => this.createNewSession(),
116
116
  rewind: () => this.startRewindFlow(),
117
117
  diff: (argsText) => this.startDiffReview(argsText),
118
- goal: (action) => this.handleGoalAction(action),
119
118
  compactSummaryOnly: (extra) => this.compactSession("summary-only", extra),
120
119
  compactSummaryAndLast: (extra) => this.compactSession("summary-and-last", extra),
121
120
  reload: () => this.reloadContent(),
@@ -586,13 +585,18 @@ export class SessionChatController {
586
585
  this.view.showFooterNotice("interrupted", "default");
587
586
  return;
588
587
  }
589
- if (this.listenStartupAbortController) {
590
- this.listenStartupAbortController.abort(LISTEN_CAPTURE_START_CANCELLED);
591
- this.view.showFooterNotice("interrupted", "default");
592
- return;
593
- }
594
- if (this.listenRecording) {
595
- void this.runListenTransition(() => this.stopListenCapture());
588
+ if (this.listenStartupAbortController ||
589
+ this.listenRecording ||
590
+ this.listenTransition ||
591
+ this.listenPreview) {
592
+ this.listenStartupAbortController?.abort(LISTEN_CAPTURE_START_CANCELLED);
593
+ this.activeListenTranscription?.abort();
594
+ this.endListenPreview();
595
+ this.listenActivityLabel = undefined;
596
+ if (this.listenRecording) {
597
+ void this.runListenTransition(() => this.cancelListenCapture());
598
+ }
599
+ this.refreshStatus();
596
600
  return;
597
601
  }
598
602
  if (this.speakTask) {
@@ -668,14 +672,24 @@ export class SessionChatController {
668
672
  return;
669
673
  }
670
674
  this.pendingAutoSpeak = undefined;
671
- await this.runListenTransition(async () => {
672
- if (this.speakTask) {
673
- this.speakTask.abortController.abort();
674
- await this.speakTask.completion.catch(() => { });
675
+ const abortController = new AbortController();
676
+ this.listenStartupAbortController = abortController;
677
+ try {
678
+ await this.runListenTransition(async () => {
679
+ if (this.speakTask) {
680
+ this.speakTask.abortController.abort();
681
+ await this.speakTask.completion.catch(() => { });
682
+ }
683
+ if (!this.disposed && !abortController.signal.aborted) {
684
+ await this.startListenCapture(abortController);
685
+ }
686
+ });
687
+ }
688
+ finally {
689
+ if (this.listenStartupAbortController === abortController) {
690
+ this.listenStartupAbortController = undefined;
675
691
  }
676
- if (!this.disposed)
677
- await this.startListenCapture();
678
- });
692
+ }
679
693
  }
680
694
  async runListenTransition(task) {
681
695
  if (this.listenTransition) {
@@ -692,7 +706,7 @@ export class SessionChatController {
692
706
  }
693
707
  }
694
708
  }
695
- async startListenCapture() {
709
+ async startListenCapture(abortController) {
696
710
  if (this.deps.env.platform() !== "darwin") {
697
711
  this.view.showFooterNotice("/listen is currently supported only on macOS.", "default");
698
712
  return;
@@ -708,15 +722,14 @@ export class SessionChatController {
708
722
  const retainedAudio = this.retainedListenAudio;
709
723
  let audioPath;
710
724
  let transcription;
711
- let abortController;
712
725
  let completion;
713
726
  try {
714
727
  audioPath = await createListenTempFilePath(this.deps);
715
728
  if (this.disposed)
716
729
  throw new Error("speech recording startup cancelled");
730
+ abortController.signal.throwIfAborted();
717
731
  transcription = this.createSpeechTranscription("streaming");
718
- abortController = new AbortController();
719
- this.listenStartupAbortController = abortController;
732
+ this.activeListenTranscription = transcription;
720
733
  const capture = startListenAudioCapture({
721
734
  deps: this.deps,
722
735
  audioPath,
@@ -726,12 +739,7 @@ export class SessionChatController {
726
739
  });
727
740
  completion = capture.completion;
728
741
  await this.waitForListenCaptureStart(capture.started, abortController);
729
- if (abortController.signal.aborted) {
730
- throw abortController.signal.reason;
731
- }
732
- if (this.listenStartupAbortController === abortController) {
733
- this.listenStartupAbortController = undefined;
734
- }
742
+ abortController.signal.throwIfAborted();
735
743
  if (retainedAudio) {
736
744
  try {
737
745
  await deleteListenTempFile(retainedAudio.audioPath);
@@ -744,13 +752,16 @@ export class SessionChatController {
744
752
  transcription.abort();
745
753
  await completion.catch(() => undefined);
746
754
  await cleanupListenTempFile(audioPath);
747
- this.view.addTranscriptNotice("failed to replace retained recording", "error", [
748
- error.message,
749
- `recording retained at ${retainedAudio.audioPath}`,
750
- ]);
755
+ if (abortController.signal.reason !== LISTEN_CAPTURE_START_CANCELLED && !this.disposed) {
756
+ this.view.addTranscriptNotice("failed to replace retained recording", "error", [
757
+ error.message,
758
+ `recording retained at ${retainedAudio.audioPath}`,
759
+ ]);
760
+ }
751
761
  return;
752
762
  }
753
763
  }
764
+ abortController.signal.throwIfAborted();
754
765
  const recording = {
755
766
  audioPath,
756
767
  startedAt: Date.now(),
@@ -769,8 +780,8 @@ export class SessionChatController {
769
780
  void this.watchListenRecording(recording);
770
781
  }
771
782
  catch (err) {
772
- const cancelled = this.disposed || abortController?.signal.reason === LISTEN_CAPTURE_START_CANCELLED;
773
- abortController?.abort();
783
+ const cancelled = this.disposed || abortController.signal.reason === LISTEN_CAPTURE_START_CANCELLED;
784
+ abortController.abort();
774
785
  transcription?.abort();
775
786
  await completion?.catch(() => undefined);
776
787
  if (audioPath) {
@@ -783,11 +794,9 @@ export class SessionChatController {
783
794
  }
784
795
  }
785
796
  finally {
797
+ this.activeListenTranscription = undefined;
786
798
  if (!this.listenRecording)
787
799
  this.endListenPreview();
788
- if (this.listenStartupAbortController === abortController) {
789
- this.listenStartupAbortController = undefined;
790
- }
791
800
  }
792
801
  }
793
802
  async waitForListenCaptureStart(started, abortController) {
@@ -814,25 +823,41 @@ export class SessionChatController {
814
823
  const recording = this.listenRecording;
815
824
  if (!recording)
816
825
  return;
826
+ const preview = this.listenPreview;
817
827
  recording.stopRequested = true;
818
828
  this.clearListenRecordingMaxDurationTimeout(recording);
819
829
  this.listenRecording = undefined;
830
+ this.activeListenTranscription = recording.transcription;
820
831
  this.refreshStatus();
821
832
  recording.abortController.abort();
822
833
  try {
823
- await recording.completion;
834
+ try {
835
+ await recording.completion;
836
+ }
837
+ catch (err) {
838
+ if (this.listenPreview === preview) {
839
+ this.view.addTranscriptNotice("failed to record audio", "error", [
840
+ err.message,
841
+ ]);
842
+ }
843
+ recording.transcription.abort();
844
+ this.endListenPreview();
845
+ await cleanupListenTempFile(recording.audioPath);
846
+ return;
847
+ }
848
+ if (this.listenPreview !== preview || this.disposed) {
849
+ recording.transcription.abort();
850
+ await cleanupListenTempFile(recording.audioPath);
851
+ return;
852
+ }
853
+ const durationMs = Math.min(Math.max(Date.now() - recording.startedAt, 0), SPEECH_TO_TEXT_CLIENT_MAX_DURATION_MS);
854
+ const transcribed = await this.transcribeListenAudioFile(recording.audioPath, durationMs, recording.transcription);
855
+ if (mode && transcribed && !this.disposed)
856
+ this.view.submitEditor(mode);
824
857
  }
825
- catch (err) {
826
- recording.transcription.abort();
827
- this.endListenPreview();
828
- this.view.addTranscriptNotice("failed to record audio", "error", [err.message]);
829
- await cleanupListenTempFile(recording.audioPath);
830
- return;
858
+ finally {
859
+ this.activeListenTranscription = undefined;
831
860
  }
832
- const durationMs = Math.min(Math.max(Date.now() - recording.startedAt, 0), SPEECH_TO_TEXT_CLIENT_MAX_DURATION_MS);
833
- const transcribed = await this.transcribeListenAudioFile(recording.audioPath, durationMs, recording.transcription);
834
- if (mode && transcribed && !this.disposed)
835
- this.view.submitEditor(mode);
836
861
  }
837
862
  async retryRetainedListenAudio() {
838
863
  if (this.pendingEditorMutations > 0) {
@@ -929,26 +954,28 @@ export class SessionChatController {
929
954
  }
930
955
  catch (error) {
931
956
  transcription?.abort();
932
- this.view.addTranscriptNotice("failed to read speech recording", "error", [
933
- error.message,
934
- ]);
957
+ if (this.listenPreview === preview) {
958
+ this.view.addTranscriptNotice("failed to read speech recording", "error", [
959
+ error.message,
960
+ ]);
961
+ }
935
962
  if (this.retainedListenAudio?.audioPath === audioPath) {
936
963
  this.retainedListenAudio = undefined;
937
964
  }
938
965
  await cleanupListenTempFile(audioPath);
939
966
  return false;
940
967
  }
941
- if (audio.byteLength < LISTEN_RECORDING_MIN_BYTES) {
968
+ if (this.disposed || this.listenPreview !== preview) {
942
969
  transcription?.abort();
943
- this.view.showFooterNotice("recording too short, try again", "default");
944
970
  if (this.retainedListenAudio?.audioPath === audioPath) {
945
971
  this.retainedListenAudio = undefined;
946
972
  }
947
973
  await cleanupListenTempFile(audioPath);
948
974
  return false;
949
975
  }
950
- if (this.disposed) {
976
+ if (audio.byteLength < LISTEN_RECORDING_MIN_BYTES) {
951
977
  transcription?.abort();
978
+ this.view.showFooterNotice("recording too short, try again", "default");
952
979
  if (this.retainedListenAudio?.audioPath === audioPath) {
953
980
  this.retainedListenAudio = undefined;
954
981
  }
@@ -967,10 +994,6 @@ export class SessionChatController {
967
994
  });
968
995
  if (this.listenPreview !== preview)
969
996
  return false;
970
- preview.commit(text);
971
- if (text.trim() && !this.editorHiddenSystemMessages.includes(TRANSCRIPTION_GUIDANCE)) {
972
- this.editorHiddenSystemMessages.push(TRANSCRIPTION_GUIDANCE);
973
- }
974
997
  this.retainedListenAudio = undefined;
975
998
  try {
976
999
  await deleteListenTempFile(audioPath);
@@ -981,9 +1004,17 @@ export class SessionChatController {
981
1004
  `recording remains at ${audioPath}; delete it manually`,
982
1005
  ]);
983
1006
  }
1007
+ if (this.listenPreview !== preview)
1008
+ return false;
1009
+ preview.commit(text);
1010
+ if (text.trim() && !this.editorHiddenSystemMessages.includes(TRANSCRIPTION_GUIDANCE)) {
1011
+ this.editorHiddenSystemMessages.push(TRANSCRIPTION_GUIDANCE);
1012
+ }
984
1013
  return Boolean(text.trim());
985
1014
  }
986
1015
  catch (error) {
1016
+ if (this.listenPreview !== preview)
1017
+ return false;
987
1018
  this.retainedListenAudio = { audioPath, durationMs };
988
1019
  this.view.addTranscriptNotice("failed to transcribe speech", "error", [
989
1020
  error.message,
@@ -1002,7 +1033,15 @@ export class SessionChatController {
1002
1033
  }
1003
1034
  }
1004
1035
  finally {
1005
- this.endListenPreview();
1036
+ if (this.listenPreview !== preview) {
1037
+ if (this.retainedListenAudio?.audioPath === audioPath) {
1038
+ this.retainedListenAudio = undefined;
1039
+ }
1040
+ await cleanupListenTempFile(audioPath);
1041
+ }
1042
+ else {
1043
+ this.endListenPreview();
1044
+ }
1006
1045
  }
1007
1046
  }
1008
1047
  async cancelListenCapture() {
@@ -1345,7 +1384,6 @@ export class SessionChatController {
1345
1384
  switch (change.type) {
1346
1385
  case "agent-state.set":
1347
1386
  case "lifecycle.set":
1348
- case "goal.set":
1349
1387
  case "cost.set":
1350
1388
  case "settings.set":
1351
1389
  case "turn.set":
@@ -1414,7 +1452,6 @@ export class SessionChatController {
1414
1452
  switch (change.type) {
1415
1453
  case "agent-state.set":
1416
1454
  case "lifecycle.set":
1417
- case "goal.set":
1418
1455
  case "cost.set":
1419
1456
  case "settings.set":
1420
1457
  case "turn.set":
@@ -2032,29 +2069,6 @@ export class SessionChatController {
2032
2069
  this.refreshStatus();
2033
2070
  }
2034
2071
  }
2035
- async handleGoalAction(action) {
2036
- if (action.type === "show") {
2037
- const goal = this.snapshot.goal;
2038
- this.view.addTranscriptNotice(goal ? `goal ${goal.status}` : "no session goal", "default", goal ? [goal.objective] : undefined);
2039
- return;
2040
- }
2041
- if (action.type === "start") {
2042
- await this.runSessionTurn(() => this.session.startGoal(action.objective));
2043
- return;
2044
- }
2045
- if (action.type === "resume") {
2046
- await this.runSessionTurn(() => this.session.resumeGoal());
2047
- return;
2048
- }
2049
- try {
2050
- this.snapshot = await this.session.clearGoal();
2051
- this.refreshStatus();
2052
- this.view.showFooterNotice("session goal cleared", "default");
2053
- }
2054
- catch (error) {
2055
- this.view.addTranscriptNotice("failed to clear goal", "error", [error.message]);
2056
- }
2057
- }
2058
2072
  setAutoSpeak(enabled) {
2059
2073
  if ((enabled ?? !this.autoSpeak) && this.deps.env.platform() !== "darwin") {
2060
2074
  this.view.showFooterNotice("auto-speak is currently supported only on macOS", "default");
@@ -2188,7 +2202,6 @@ export class SessionChatController {
2188
2202
  contextUsage: this.getContextUsageString(),
2189
2203
  sessionCost: this.getSessionCostString(),
2190
2204
  duration: this.getTurnDurationString(),
2191
- pursuingGoal: this.snapshot.goal?.status === "active",
2192
2205
  autoSpeak: this.autoSpeak,
2193
2206
  },
2194
2207
  editor: {