@xopcai/xopc 0.0.303 → 0.0.306

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 (363) hide show
  1. package/README.md +4 -4
  2. package/README.zh-CN.md +4 -4
  3. package/dist/browser-ext/dist/assets/{auth-B_9ZuGDx.js → auth-C3yV1y_l.js} +67 -22
  4. package/dist/browser-ext/dist/background.js +4 -4
  5. package/dist/browser-ext/dist/sidepanel.html +1 -1
  6. package/dist/browser-ext/dist/sidepanel.js +3 -3
  7. package/dist/browser-ext/manifest.json +1 -1
  8. package/dist/extensions/feishu/xopc.extension.json +0 -3
  9. package/dist/extensions/telegram/xopc.extension.json +1 -4
  10. package/dist/extensions/weixin/xopc.extension.json +0 -3
  11. package/dist/gateway/static/root/assets/{activity-store-DCi5rh4e.js → activity-store-DLtim-_I.js} +1 -1
  12. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Ch3DzUvP.js → agent-avatar-dicebear-iQXtiilH.js} +1 -1
  13. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CxOv4ivK.js +1 -0
  14. package/dist/gateway/static/root/assets/agents-DzKx7z3k.js +1 -0
  15. package/dist/gateway/static/root/assets/{api-CAV9PN9i.js → api-DfSU0-lD.js} +1 -1
  16. package/dist/gateway/static/root/assets/api-gpHh07OL.js +1 -0
  17. package/dist/gateway/static/root/assets/app-management-settings-panel-BpYFKz7B.js +1 -0
  18. package/dist/gateway/static/root/assets/{appearance-settings-izNAyDhW.js → appearance-settings-BQfR5vrq.js} +1 -1
  19. package/dist/gateway/static/root/assets/apps-page-BceB7JHZ.js +1 -0
  20. package/dist/gateway/static/root/assets/{archive-plugin-BKGzaVvM.js → archive-plugin-BxOvZ-ZX.js} +1 -1
  21. package/dist/gateway/static/root/assets/{attachment-load-8bARdLnp.js → attachment-load-B0FzTMAJ.js} +1 -1
  22. package/dist/gateway/static/root/assets/{automations-page-BAEenyzx.js → automations-page-BpXuPaPg.js} +1 -1
  23. package/dist/gateway/static/root/assets/automations-workspace-Cn_p8zY_.js +6 -0
  24. package/dist/gateway/static/root/assets/{binary-plugins-Cv3GS9Eo.js → binary-plugins-BP7wfpqy.js} +1 -1
  25. package/dist/gateway/static/root/assets/{block-editor-D4ZIVQbk.css → block-editor-BdOTO0Yo.css} +1 -1
  26. package/dist/gateway/static/root/assets/{block-editor-DUeb92LG.js → block-editor-oMLvdnOQ.js} +3 -3
  27. package/dist/gateway/static/root/assets/{browser-automation-inputs-BGT0xoTv.js → browser-automation-inputs-DTxSZ00u.js} +1 -1
  28. package/dist/gateway/static/root/assets/{browser-automations-page-D1O22WIf.js → browser-automations-page-IbJnwEY4.js} +2 -2
  29. package/dist/gateway/static/root/assets/browser-settings-page-CCUO3G23.js +3 -0
  30. package/dist/gateway/static/root/assets/button-CS04eWY9.js +1 -0
  31. package/dist/gateway/static/root/assets/capabilities-settings-panel-BjMb5H2_.js +8 -0
  32. package/dist/gateway/static/root/assets/channels-settings-P22-_i13.js +1 -0
  33. package/dist/gateway/static/root/assets/{channels-status-swr-C_icwbWj.js → channels-status-swr-D2AmAoty.js} +1 -1
  34. package/dist/gateway/static/root/assets/{chat-terminal-dock-D-JYPVYl.js → chat-terminal-dock-B-yI3Mi1.js} +2 -2
  35. package/dist/gateway/static/root/assets/{computer-settings-page-Bcfp948A.js → computer-settings-page-CWx_jnng.js} +1 -1
  36. package/dist/gateway/static/root/assets/connectors-page-BLgPORmH.js +2 -0
  37. package/dist/gateway/static/root/assets/cron-expression-DMRRL4Zg.js +2 -0
  38. package/dist/gateway/static/root/assets/date-picker-BSwL0e6E.js +1 -0
  39. package/dist/gateway/static/root/assets/{dependency-picker-UtoUm57Q.js → dependency-picker-BQTspLzC.js} +1 -1
  40. package/dist/gateway/static/root/assets/{desktop-pet-Bryx7gRM.js → desktop-pet-C3lFxDF6.js} +1 -1
  41. package/dist/gateway/static/root/assets/desktop-pet-settings-Y8pjpXFE.js +1 -0
  42. package/dist/gateway/static/root/assets/device-pairing-wizard-DM4_GMzo.js +1 -0
  43. package/dist/gateway/static/root/assets/{extension-debug-page-DQlFTVBx.js → extension-debug-page-CVGiGVcR.js} +1 -1
  44. package/dist/gateway/static/root/assets/{extension-page-BSsqRDXh.js → extension-page-g3JtCP_y.js} +1 -1
  45. package/dist/gateway/static/root/assets/{extension-settings-page-DbVZv9ve.js → extension-settings-page-CjpoKV1f.js} +1 -1
  46. package/dist/gateway/static/root/assets/{gateway-config-swr-D5AM8cyQ.js → gateway-config-swr-BSvXXpKM.js} +1 -1
  47. package/dist/gateway/static/root/assets/gateway-realtime-BDCpS7U1.js +1 -0
  48. package/dist/gateway/static/root/assets/gateway-realtime-store-BGmP1obI.js +1 -0
  49. package/dist/gateway/static/root/assets/gateway-settings-CYG9WCZn.js +1 -0
  50. package/dist/gateway/static/root/assets/{gateway-startup-retry-CSJWdnFs.js → gateway-startup-retry-Caf8g3sC.js} +1 -1
  51. package/dist/gateway/static/root/assets/{heartbeat-settings-Cxowc29b.js → heartbeat-settings-Cl834-SS.js} +1 -1
  52. package/dist/gateway/static/root/assets/home-page-CB_XVtIM.js +1 -0
  53. package/dist/gateway/static/root/assets/{image-generation-api-BNh604hw.js → image-generation-api-BwEWBUVC.js} +1 -1
  54. package/dist/gateway/static/root/assets/imports-page-CoMlgSIA.js +1 -0
  55. package/dist/gateway/static/root/assets/index-CI37dTAn.css +1 -0
  56. package/dist/gateway/static/root/assets/index-Do9MltC4.js +79 -0
  57. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CNq5D4pe.js +1 -0
  58. package/dist/gateway/static/root/assets/local-app-workbench-page-BxQlEje6.js +2 -0
  59. package/dist/gateway/static/root/assets/{local-apps-page-CXPaPDGm.js → local-apps-page-DQnRA598.js} +1 -1
  60. package/dist/gateway/static/root/assets/{locale-store-DLK05Y1a.js → locale-store-D16nmbaN.js} +1 -1
  61. package/dist/gateway/static/root/assets/logs-page-CT5GrcMs.js +2 -0
  62. package/dist/gateway/static/root/assets/management-settings-DKcO5fQ-.js +1 -0
  63. package/dist/gateway/static/root/assets/{markdown-view-B8maDRWh.js → markdown-view-DCp4BlZP.js} +2 -2
  64. package/dist/gateway/static/root/assets/{media-plugins-tSJ0CvcX.js → media-plugins-Cy64sn_C.js} +1 -1
  65. package/dist/gateway/static/root/assets/messages-C-9oo69N.js +3 -0
  66. package/dist/gateway/static/root/assets/note-detail-panel-5dc3LKTL.js +5 -0
  67. package/dist/gateway/static/root/assets/notes-page-AbwxgXuG.js +8 -0
  68. package/dist/gateway/static/root/assets/{page-tabs-CQx6H-GS.js → page-tabs-CgEoHSVT.js} +1 -1
  69. package/dist/gateway/static/root/assets/{popover-select-DldSX8GX.js → popover-select-9i-ZtHXL.js} +1 -1
  70. package/dist/gateway/static/root/assets/{preview-open-alternatives-A3-bVtdy.js → preview-open-alternatives-Ck2uKTbf.js} +1 -1
  71. package/dist/gateway/static/root/assets/{proactive-page-D46cR3sf.js → proactive-page-Dr1mCJhZ.js} +1 -1
  72. package/dist/gateway/static/root/assets/{product-open-page-CujZXOea.js → product-open-page-DbZvJ5GE.js} +1 -1
  73. package/dist/gateway/static/root/assets/project-detail-page-DnE1zI1c.js +1 -0
  74. package/dist/gateway/static/root/assets/projects-page-BD0nLYxk.js +1 -0
  75. package/dist/gateway/static/root/assets/{registry-api-BMFL4vis.js → registry-api-DcQdwpPu.js} +1 -1
  76. package/dist/gateway/static/root/assets/remote-access-hub-TYuE6A3S.js +1 -0
  77. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CR0qvq9C.js → runtime-tools-settings-panel-CPwdgWKo.js} +2 -2
  78. package/dist/gateway/static/root/assets/{schema-form-BUD9lLEE.js → schema-form-8psK4cFO.js} +1 -1
  79. package/dist/gateway/static/root/assets/sessions-page-BcWDQQFX.js +1 -0
  80. package/dist/gateway/static/root/assets/settings-advanced-gate-DzGQX6Hq.js +1 -0
  81. package/dist/gateway/static/root/assets/{settings-form-section-BZPCUH6a.js → settings-form-section-D_Gsz5rl.js} +1 -1
  82. package/dist/gateway/static/root/assets/{settings-page-XoHmqIdm.js → settings-page-C_Tj_mkZ.js} +1 -1
  83. package/dist/gateway/static/root/assets/setup-status-panel-CE2X89qN.js +1 -0
  84. package/dist/gateway/static/root/assets/share-preview-page-B_M_oPsT.js +2 -0
  85. package/dist/gateway/static/root/assets/shares-settings-BL4H9Iym.js +1 -0
  86. package/dist/gateway/static/root/assets/skill-reload-api-WMKIgUOp.js +1 -0
  87. package/dist/gateway/static/root/assets/skills-page-DYgwzl5B.js +2 -0
  88. package/dist/gateway/static/root/assets/{skills-page.utils-CH-quGxZ.js → skills-page.utils-Cuh6s2HM.js} +1 -1
  89. package/dist/gateway/static/root/assets/{system-settings-panel-CGC7eBso.js → system-settings-panel-aassGyNb.js} +1 -1
  90. package/dist/gateway/static/root/assets/task-detail-page-BjeRslap.js +1 -0
  91. package/dist/gateway/static/root/assets/theme-store-RUBQBsFP.js +1 -0
  92. package/dist/gateway/static/root/assets/tunnel-api-DJYcPWIV.js +1 -0
  93. package/dist/gateway/static/root/assets/{use-autosave-BydB6x2K.js → use-autosave-QGYG7oMZ.js} +1 -1
  94. package/dist/gateway/static/root/assets/user-model-page-PrRsd4go.js +2 -0
  95. package/dist/gateway/static/root/assets/{voice-api-key-field-CPUDBcag.js → voice-api-key-field-D1s0gIRW.js} +1 -1
  96. package/dist/gateway/static/root/assets/{voice-config-api-bZqN8-UF.js → voice-config-api-D2goEn5e.js} +1 -1
  97. package/dist/gateway/static/root/assets/{work-discovery-overlay-D_FmJbGH.js → work-discovery-overlay-DkFW9aJ6.js} +1 -1
  98. package/dist/gateway/static/root/assets/workflow-run-setup-panel-BYToUPUY.js +3 -0
  99. package/dist/gateway/static/root/assets/workflows-page-Z8iZe9YP.js +6 -0
  100. package/dist/gateway/static/root/index.html +14 -12
  101. package/dist/package.js +1 -1
  102. package/dist/packages/gateway-contract/src/device-pairing.js +100 -7
  103. package/dist/packages/gateway-contract/src/gateway-scopes.js +53 -0
  104. package/dist/packages/gateway-contract/src/index.js +2 -0
  105. package/dist/packages/realtime-client/src/index.js +14 -2
  106. package/dist/packages/realtime-protocol/src/index.js +18 -14
  107. package/dist/src/agent/agent-instance-gateway.d.ts +2 -0
  108. package/dist/src/agent/agent-manager.d.ts +2 -0
  109. package/dist/src/agent/agent-manager.js +40 -12
  110. package/dist/src/agent/agent-scope.d.ts +4 -1
  111. package/dist/src/agent/agent-scope.js +19 -3
  112. package/dist/src/agent/commands/command-isolation.js +11 -9
  113. package/dist/src/agent/commands/command-registry.js +18 -33
  114. package/dist/src/agent/context/audit.js +12 -2
  115. package/dist/src/agent/context/coordinator.d.ts +13 -3
  116. package/dist/src/agent/context/coordinator.js +27 -11
  117. package/dist/src/agent/context/execution-context.js +42 -22
  118. package/dist/src/agent/context/execution-context.types.d.ts +4 -2
  119. package/dist/src/agent/context/execution-scope.d.ts +2 -2
  120. package/dist/src/agent/context/execution-scope.js +1 -1
  121. package/dist/src/agent/context/project-context.d.ts +2 -2
  122. package/dist/src/agent/context/project-context.js +3 -3
  123. package/dist/src/agent/embedded/run-for-session.d.ts +1 -0
  124. package/dist/src/agent/embedded/run-for-session.js +7 -1
  125. package/dist/src/agent/inbound/attachment-pipeline.d.ts +2 -0
  126. package/dist/src/agent/inbound/attachment-pipeline.js +3 -3
  127. package/dist/src/agent/inbound/inbound-loop.js +1 -0
  128. package/dist/src/agent/inbound/turn-dispatcher.js +3 -3
  129. package/dist/src/agent/mcp/mcp-stdio-transport.js +5 -2
  130. package/dist/src/agent/memory/compaction-promotion.js +7 -2
  131. package/dist/src/agent/memory/create-memory-manager.js +1 -0
  132. package/dist/src/agent/memory/manager.d.ts +6 -0
  133. package/dist/src/agent/memory/manager.js +74 -39
  134. package/dist/src/agent/memory/runtime.d.ts +3 -3
  135. package/dist/src/agent/memory/runtime.js +11 -4
  136. package/dist/src/agent/orchestration/agent-orchestrator.js +4 -1
  137. package/dist/src/agent/prompt/cache-boundary.d.ts +2 -0
  138. package/dist/src/agent/prompt/cache-boundary.js +10 -1
  139. package/dist/src/agent/service/build-direct-message-content.d.ts +1 -0
  140. package/dist/src/agent/service/build-direct-message-content.js +2 -1
  141. package/dist/src/agent/service/direct-turn-helpers.js +3 -2
  142. package/dist/src/agent/service/process-direct-streaming.d.ts +3 -1
  143. package/dist/src/agent/service/process-direct-streaming.js +3 -2
  144. package/dist/src/agent/service/webchat-tts.d.ts +0 -4
  145. package/dist/src/agent/service/webchat-tts.js +20 -19
  146. package/dist/src/agent/tools/factory.js +3 -3
  147. package/dist/src/agent/tools/knowledge-memory-tool.d.ts +2 -2
  148. package/dist/src/agent/tools/knowledge-memory-tool.js +7 -7
  149. package/dist/src/browser/native-messaging-host.js +2 -2
  150. package/dist/src/channels/attachments/voice-stt-webchat.d.ts +3 -0
  151. package/dist/src/channels/attachments/voice-stt-webchat.js +22 -9
  152. package/dist/src/cli/commands/agent.js +2 -0
  153. package/dist/src/cli/commands/config.js +8 -9
  154. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  155. package/dist/src/cli/commands/extension-marketplace.js +69 -44
  156. package/dist/src/cli/commands/extension-pack.js +0 -2
  157. package/dist/src/cli/commands/extension.js +4 -25
  158. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  159. package/dist/src/cli/commands/onboard/gateway.js +2 -1
  160. package/dist/src/cli/commands/update.js +1 -1
  161. package/dist/src/cli/utils/init-workspace-core.js +5 -2
  162. package/dist/src/config/index.js +2 -2
  163. package/dist/src/config/loader.d.ts +1 -0
  164. package/dist/src/config/loader.js +14 -1
  165. package/dist/src/config/schema.d.ts +10 -3
  166. package/dist/src/config/schema.js +9 -1
  167. package/dist/src/execution-environments/local-worktree-manager.js +17 -15
  168. package/dist/src/execution-environments/store.js +4 -2
  169. package/dist/src/execution-environments/types.d.ts +3 -0
  170. package/dist/src/execution-environments/types.js +2 -1
  171. package/dist/src/execution-environments/worktree-safety.d.ts +8 -0
  172. package/dist/src/execution-environments/worktree-safety.js +43 -0
  173. package/dist/src/extensions/activation-planner.d.ts +1 -1
  174. package/dist/src/extensions/activation-planner.js +1 -1
  175. package/dist/src/extensions/api-version.d.ts +4 -0
  176. package/dist/src/extensions/api-version.js +15 -0
  177. package/dist/src/extensions/api.d.ts +3 -9
  178. package/dist/src/extensions/api.js +26 -32
  179. package/dist/src/extensions/config-validation.d.ts +8 -0
  180. package/dist/src/extensions/config-validation.js +25 -0
  181. package/dist/src/extensions/extension-registry-impl.d.ts +20 -9
  182. package/dist/src/extensions/extension-registry-impl.js +79 -11
  183. package/dist/src/extensions/hooks.d.ts +1 -1
  184. package/dist/src/extensions/index.d.ts +2 -1
  185. package/dist/src/extensions/install-transaction.d.ts +2 -0
  186. package/dist/src/extensions/install-transaction.js +32 -21
  187. package/dist/src/extensions/install.js +18 -1
  188. package/dist/src/extensions/loader.d.ts +5 -5
  189. package/dist/src/extensions/loader.js +109 -47
  190. package/dist/src/extensions/lockfile.d.ts +3 -5
  191. package/dist/src/extensions/lockfile.js +41 -14
  192. package/dist/src/extensions/normalize-manifest.js +6 -60
  193. package/dist/src/extensions/sdk/index.d.ts +3 -2
  194. package/dist/src/extensions/sdk/index.js +2 -2
  195. package/dist/src/extensions/sdk/testing.js +0 -4
  196. package/dist/src/extensions/security.js +5 -7
  197. package/dist/src/extensions/types/core.d.ts +0 -5
  198. package/dist/src/extensions/types/index.d.ts +1 -1
  199. package/dist/src/extensions/types/manifest.d.ts +1 -25
  200. package/dist/src/extensions/types/providers.d.ts +1 -1
  201. package/dist/src/extensions/types/registration.d.ts +0 -12
  202. package/dist/src/extensions/update.js +71 -30
  203. package/dist/src/gateway/heartbeat/service.js +2 -2
  204. package/dist/src/gateway/hono/lib/config-payload.d.ts +3 -1
  205. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +47 -10
  206. package/dist/src/gateway/hono/routes/devices.js +10 -7
  207. package/dist/src/gateway/hono/routes/endpoint-compatibility.js +6 -0
  208. package/dist/src/gateway/hono/routes/extension-gateway.js +0 -33
  209. package/dist/src/gateway/hono/routes/imports.js +1 -1
  210. package/dist/src/gateway/hono/routes/lazy-bundles.js +0 -1
  211. package/dist/src/gateway/hono/routes/local-apps.js +1 -1
  212. package/dist/src/gateway/hono/routes/realtime.js +30 -8
  213. package/dist/src/gateway/hono/routes/update.js +2 -2
  214. package/dist/src/gateway/hono/routes/user-model.js +25 -6
  215. package/dist/src/gateway/index.js +5 -2
  216. package/dist/src/gateway/lock.d.ts +2 -0
  217. package/dist/src/gateway/lock.js +31 -14
  218. package/dist/src/gateway/run-loop.js +3 -2
  219. package/dist/src/gateway/security/gateway-scopes.d.ts +2 -5
  220. package/dist/src/gateway/security/gateway-scopes.js +3 -45
  221. package/dist/src/gateway/security/index.js +2 -1
  222. package/dist/src/gateway/service.js +11 -7
  223. package/dist/src/heartbeat/index.js +1 -1
  224. package/dist/src/imports/importService.d.ts +1 -1
  225. package/dist/src/imports/inventory.js +16 -2
  226. package/dist/src/imports/productImport.js +5 -5
  227. package/dist/src/imports/types.d.ts +3 -3
  228. package/dist/src/infra/exec.d.ts +2 -2
  229. package/dist/src/infra/exec.js +32 -27
  230. package/dist/src/infra/gateway-processes.js +1 -1
  231. package/dist/src/infra/run-command.js +15 -50
  232. package/dist/src/infra/update-restart.js +1 -1
  233. package/dist/src/infra/update-runner.js +2 -2
  234. package/dist/src/infra/update-startup.js +1 -1
  235. package/dist/src/knowledge/connected-knowledge-pipeline.js +13 -3
  236. package/dist/src/knowledge-memory/domain.d.ts +17 -1
  237. package/dist/src/knowledge-memory/index.js +2 -2
  238. package/dist/src/knowledge-memory/repository.d.ts +26 -4
  239. package/dist/src/knowledge-memory/repository.js +171 -36
  240. package/dist/src/mcp/channel-bridge.js +7 -3
  241. package/dist/src/media-understanding/registry.js +6 -1
  242. package/dist/src/migrations/knowledge-memory-read-policy-config.d.ts +2 -0
  243. package/dist/src/migrations/knowledge-memory-read-policy-config.js +48 -0
  244. package/dist/src/migrations/runner.js +2 -1
  245. package/dist/src/process/bounded-output.d.ts +10 -0
  246. package/dist/src/process/bounded-output.js +41 -0
  247. package/dist/src/process/kill-tree.d.ts +6 -17
  248. package/dist/src/process/kill-tree.js +43 -75
  249. package/dist/src/process/process-spec.d.ts +39 -0
  250. package/dist/src/process/process-spec.js +13 -0
  251. package/dist/src/process/run-process.d.ts +4 -0
  252. package/dist/src/process/run-process.js +97 -0
  253. package/dist/src/providers/plugin-registry.d.ts +1 -1
  254. package/dist/src/providers/plugin-registry.js +6 -0
  255. package/dist/src/realtime/runtime.js +3 -1
  256. package/dist/src/session/store.js +1 -1
  257. package/dist/src/storage/sqlite/device-pairing-approval.js +1 -1
  258. package/dist/src/storage/sqlite/index.d.ts +1 -1
  259. package/dist/src/storage/sqlite/index.js +2 -2
  260. package/dist/src/storage/sqlite/migrations/180_execution_environment_ownership.sql +7 -0
  261. package/dist/src/storage/sqlite/migrations/181_knowledge_item_status_events.sql +12 -0
  262. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  263. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  264. package/dist/src/storage/sqlite/schema.js +1 -1
  265. package/dist/src/storage/sqlite/schema.sql +13 -0
  266. package/dist/src/storage/sqlite/transcript-repository.d.ts +4 -0
  267. package/dist/src/storage/sqlite/transcript-repository.js +36 -1
  268. package/dist/src/tui/backends/embedded-backend.d.ts +24 -8
  269. package/dist/src/tui/backends/embedded-backend.js +114 -10
  270. package/dist/src/tui/backends/gateway-realtime-backend.d.ts +18 -0
  271. package/dist/src/tui/backends/gateway-realtime-backend.js +32 -5
  272. package/dist/src/tui/components/assistant-message.d.ts +4 -1
  273. package/dist/src/tui/components/assistant-message.js +10 -2
  274. package/dist/src/tui/components/cell-render-mode.d.ts +4 -0
  275. package/dist/src/tui/components/cell-render-mode.js +1 -0
  276. package/dist/src/tui/components/chat-log.d.ts +17 -4
  277. package/dist/src/tui/components/chat-log.js +68 -50
  278. package/dist/src/tui/components/custom-editor.d.ts +2 -2
  279. package/dist/src/tui/components/custom-editor.js +5 -1
  280. package/dist/src/tui/components/pending-input-preview.d.ts +9 -0
  281. package/dist/src/tui/components/pending-input-preview.js +33 -0
  282. package/dist/src/tui/components/semantic-cell.d.ts +17 -0
  283. package/dist/src/tui/components/semantic-cell.js +29 -0
  284. package/dist/src/tui/components/tool-execution.d.ts +5 -1
  285. package/dist/src/tui/components/tool-execution.js +33 -10
  286. package/dist/src/tui/components/transcript-overlay.d.ts +29 -0
  287. package/dist/src/tui/components/transcript-overlay.js +114 -0
  288. package/dist/src/tui/components/tui-bottom-bar.js +3 -1
  289. package/dist/src/tui/components/user-message.d.ts +5 -1
  290. package/dist/src/tui/components/user-message.js +12 -1
  291. package/dist/src/tui/extension-host/load-extensions.d.ts +1 -1
  292. package/dist/src/tui/extension-host/runtime-context.js +2 -1
  293. package/dist/src/tui/extension-host/runtime.d.ts +1 -1
  294. package/dist/src/tui/format-tui-hotkeys.js +8 -1
  295. package/dist/src/tui/tui-agent-events.js +31 -0
  296. package/dist/src/tui/tui-backend.d.ts +23 -11
  297. package/dist/src/tui/tui-backend.js +1 -9
  298. package/dist/src/tui/tui-chat-input-state.d.ts +25 -0
  299. package/dist/src/tui/tui-chat-input-state.js +36 -0
  300. package/dist/src/tui/tui-command-formatters.js +2 -1
  301. package/dist/src/tui/tui-commands.js +1 -1
  302. package/dist/src/tui/tui-types.d.ts +2 -1
  303. package/dist/src/tui/tui-types.js +2 -1
  304. package/dist/src/tui/tui.js +122 -30
  305. package/dist/src/tui/xopc-tui-keybindings.d.ts +23 -3
  306. package/dist/src/tui/xopc-tui-keybindings.js +22 -2
  307. package/dist/src/user-context/access-policy.d.ts +2 -2
  308. package/dist/src/user-context/access-policy.js +10 -2
  309. package/dist/src/user-context/config.d.ts +23 -6
  310. package/dist/src/user-context/config.js +54 -7
  311. package/dist/src/voice/platform-streams.js +11 -1
  312. package/dist/src/voice/realtime/omniEngine.js +13 -1
  313. package/dist/src/voice/realtime/runtime.js +2 -1
  314. package/dist/src/voice/tts/audio.js +1 -1
  315. package/dist/src/voice/tts/speech-registry.js +6 -1
  316. package/package.json +7 -5
  317. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-4oGrNj3m.js +0 -1
  318. package/dist/gateway/static/root/assets/agents-DXHD-ST3.js +0 -1
  319. package/dist/gateway/static/root/assets/api-fPapljyb.js +0 -1
  320. package/dist/gateway/static/root/assets/app-management-settings-panel-CdXnNtTg.js +0 -1
  321. package/dist/gateway/static/root/assets/apps-page-BQb3RCga.js +0 -1
  322. package/dist/gateway/static/root/assets/automations-workspace-5vTl4x0h.js +0 -6
  323. package/dist/gateway/static/root/assets/browser-settings-page-CH9prS-f.js +0 -3
  324. package/dist/gateway/static/root/assets/button-CGlRPNzi.js +0 -1
  325. package/dist/gateway/static/root/assets/capabilities-settings-panel-DMURlZbj.js +0 -8
  326. package/dist/gateway/static/root/assets/channels-settings-CFBS3Yqy.js +0 -1
  327. package/dist/gateway/static/root/assets/connectors-page-DI1c3BMz.js +0 -2
  328. package/dist/gateway/static/root/assets/cron-expression-BJMBFKCh.js +0 -2
  329. package/dist/gateway/static/root/assets/date-picker-BFRIn5y9.js +0 -1
  330. package/dist/gateway/static/root/assets/desktop-pet-settings-DFsyEJUr.js +0 -1
  331. package/dist/gateway/static/root/assets/device-pairing-wizard-C3TQVPRy.js +0 -1
  332. package/dist/gateway/static/root/assets/gateway-settings-DUqVsB3X.js +0 -1
  333. package/dist/gateway/static/root/assets/home-page-CLkumXdN.js +0 -1
  334. package/dist/gateway/static/root/assets/imports-page-DXNfRmk9.js +0 -1
  335. package/dist/gateway/static/root/assets/index-BLRIcVQa.css +0 -1
  336. package/dist/gateway/static/root/assets/index-gheM453N.js +0 -79
  337. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-5Hcec8Xf.js +0 -1
  338. package/dist/gateway/static/root/assets/local-app-workbench-page-BDg1-fcw.js +0 -2
  339. package/dist/gateway/static/root/assets/logs-page-BWZc5jwO.js +0 -2
  340. package/dist/gateway/static/root/assets/management-settings-COa3PhMs.js +0 -1
  341. package/dist/gateway/static/root/assets/messages-C9h8SImu.js +0 -3
  342. package/dist/gateway/static/root/assets/note-detail-panel-D_YGzNcR.js +0 -5
  343. package/dist/gateway/static/root/assets/notes-page-D1f2oI2-.js +0 -8
  344. package/dist/gateway/static/root/assets/project-detail-page-CRlD_Rwv.js +0 -1
  345. package/dist/gateway/static/root/assets/projects-page-mmX0SavY.js +0 -1
  346. package/dist/gateway/static/root/assets/remote-access-hub-Cqr3K6T5.js +0 -1
  347. package/dist/gateway/static/root/assets/sessions-page-CPkvbdJP.js +0 -1
  348. package/dist/gateway/static/root/assets/settings-advanced-gate-Cu0DAbeH.js +0 -1
  349. package/dist/gateway/static/root/assets/setup-status-panel-D8fQF1jZ.js +0 -1
  350. package/dist/gateway/static/root/assets/share-preview-page-BgHqwTuT.js +0 -2
  351. package/dist/gateway/static/root/assets/shares-settings-Id4vRHzI.js +0 -1
  352. package/dist/gateway/static/root/assets/skill-reload-api-BB2Fj_di.js +0 -1
  353. package/dist/gateway/static/root/assets/skills-page-BAwF4LpS.js +0 -2
  354. package/dist/gateway/static/root/assets/task-detail-page-BVjw812D.js +0 -1
  355. package/dist/gateway/static/root/assets/theme-store-KfFEGMlp.js +0 -1
  356. package/dist/gateway/static/root/assets/tunnel-api-Do98Xk05.js +0 -1
  357. package/dist/gateway/static/root/assets/user-model-page-Nv68a4ak.js +0 -2
  358. package/dist/gateway/static/root/assets/workflow-run-setup-panel-1lZ_btki.js +0 -3
  359. package/dist/gateway/static/root/assets/workflows-page-DFOhccm3.js +0 -6
  360. package/dist/src/extensions/when-context.d.ts +0 -6
  361. package/dist/src/extensions/when-context.js +0 -26
  362. package/dist/src/extensions/when-expression.d.ts +0 -11
  363. package/dist/src/extensions/when-expression.js +0 -213
@@ -15,6 +15,10 @@ function sanitize(text) {
15
15
  function trimTrailingBlankDisplayLines(text) {
16
16
  return text.replace(/(?:\r?\n[ \t]*)+$/g, "");
17
17
  }
18
+ function semanticToolLabel(toolName) {
19
+ if (toolName === "web_search" || toolName === "web_fetch" || toolName === "web_extract") return "WEB";
20
+ if (toolName.startsWith("mcp:") || toolName.includes("__")) return "MCP";
21
+ }
18
22
  function getToolResultDisplayText(content, options) {
19
23
  const parts = [];
20
24
  for (const block of content) {
@@ -66,6 +70,7 @@ var ToolExecutionComponent = class extends Container {
66
70
  executionStarted = false;
67
71
  startedAt = Date.now();
68
72
  completedAt;
73
+ renderMode = "compact";
69
74
  constructor(toolName, toolCallId, args, options = {}) {
70
75
  super();
71
76
  this.toolName = toolName;
@@ -100,6 +105,24 @@ var ToolExecutionComponent = class extends Container {
100
105
  this.expanded = expanded;
101
106
  this.refresh();
102
107
  }
108
+ setRenderMode(mode) {
109
+ if (this.renderMode === mode) return;
110
+ this.renderMode = mode;
111
+ this.refresh();
112
+ }
113
+ render(width) {
114
+ if (this.renderMode === "raw") return new Text(JSON.stringify({
115
+ type: "tool",
116
+ toolName: this.toolName,
117
+ toolCallId: this.toolCallId,
118
+ args: this.args,
119
+ result: this.resultContent ?? this.resultText,
120
+ details: this.resultDetails,
121
+ isError: this.isError,
122
+ isPartial: this.isPartial
123
+ }, null, 2), 0, 0).render(width);
124
+ return super.render(width);
125
+ }
103
126
  updateResult(result, isPartial = false, isError = false) {
104
127
  const parsed = parseTuiToolResult(result);
105
128
  this.resultText = sanitize(parsed.text);
@@ -231,13 +254,13 @@ var ToolExecutionComponent = class extends Container {
231
254
  argsComplete: this.argsComplete,
232
255
  isError: this.isError,
233
256
  isPartial: this.isPartial,
234
- expanded: this.expanded,
257
+ expanded: this.renderMode === "transcript" || this.expanded,
235
258
  showImages: this.showImages
236
259
  };
237
260
  }
238
261
  formatToolCallFallback() {
239
262
  const argsStr = formatArgsSummary(this.args, this.toolName);
240
- const titleParts = [theme.dim(this.toolStatusLabel()), theme.toolTitle(theme.bold(displayToolName(this.toolName)))];
263
+ const titleParts = [theme.dim(this.toolStatusLabel()), theme.toolTitle(theme.bold([semanticToolLabel(this.toolName), displayToolName(this.toolName)].filter(Boolean).join(" · ")))];
241
264
  if (argsStr) titleParts.push(theme.dim(`(${argsStr})`));
242
265
  const duration = this.toolDurationLabel();
243
266
  if (duration) titleParts.push(theme.dim(duration));
@@ -251,9 +274,9 @@ var ToolExecutionComponent = class extends Container {
251
274
  const expandKey = this.keybindings ? formatKeyIds(this.keybindings, "app.tools.expand", { capitalize: true }) : "Ctrl+O";
252
275
  const lineCount = output.split("\n").length;
253
276
  const useDiff = isDiffFriendlyTool(this.toolName) && looksLikeUnifiedDiff(output);
254
- if (this.expanded && useDiff) text += renderPatchSummary(output) ?? renderUnifiedDiff(output);
255
- else if (this.expanded && isExecStyleTool(this.toolName)) this.refreshExpandedOutput(theme.toolOutput(formatExecExpandedOutput(output, this.resultDetails)));
256
- else if (this.expanded) this.refreshExpandedOutput(theme.toolOutput(output));
277
+ if ((this.renderMode === "transcript" || this.expanded) && useDiff) text += renderPatchSummary(output) ?? renderUnifiedDiff(output);
278
+ else if ((this.renderMode === "transcript" || this.expanded) && isExecStyleTool(this.toolName)) this.refreshExpandedOutput(theme.toolOutput(formatExecExpandedOutput(output, this.resultDetails)));
279
+ else if (this.renderMode === "transcript" || this.expanded) this.refreshExpandedOutput(theme.toolOutput(output));
257
280
  else if (useDiff) text += theme.dim("preview");
258
281
  else if (getToolSummaryKind(this.toolName) !== "generic") text += this.collapsedSpecializedSummary(output, expandKey);
259
282
  else {
@@ -269,7 +292,7 @@ var ToolExecutionComponent = class extends Container {
269
292
  }
270
293
  formatToolExecution() {
271
294
  const argsStr = formatArgsSummary(this.args, this.toolName);
272
- const titleParts = [theme.dim(this.toolStatusLabel()), theme.toolTitle(theme.bold(displayToolName(this.toolName)))];
295
+ const titleParts = [theme.dim(this.toolStatusLabel()), theme.toolTitle(theme.bold([semanticToolLabel(this.toolName), displayToolName(this.toolName)].filter(Boolean).join(" · ")))];
273
296
  if (argsStr) titleParts.push(theme.dim(`(${argsStr})`));
274
297
  const duration = this.toolDurationLabel();
275
298
  if (duration) titleParts.push(theme.dim(duration));
@@ -279,9 +302,9 @@ var ToolExecutionComponent = class extends Container {
279
302
  const expandKey = this.keybindings ? formatKeyIds(this.keybindings, "app.tools.expand", { capitalize: true }) : "Ctrl+O";
280
303
  const lineCount = output.split("\n").length;
281
304
  const useDiff = isDiffFriendlyTool(this.toolName) && looksLikeUnifiedDiff(output);
282
- if (this.expanded && useDiff) text += `\n${renderPatchSummary(output) ?? renderUnifiedDiff(output)}`;
283
- else if (this.expanded && isExecStyleTool(this.toolName)) this.refreshExpandedOutput(theme.toolOutput(formatExecExpandedOutput(output, this.resultDetails)));
284
- else if (this.expanded) this.refreshExpandedOutput(theme.toolOutput(output));
305
+ if ((this.renderMode === "transcript" || this.expanded) && useDiff) text += `\n${renderPatchSummary(output) ?? renderUnifiedDiff(output)}`;
306
+ else if ((this.renderMode === "transcript" || this.expanded) && isExecStyleTool(this.toolName)) this.refreshExpandedOutput(theme.toolOutput(formatExecExpandedOutput(output, this.resultDetails)));
307
+ else if (this.renderMode === "transcript" || this.expanded) this.refreshExpandedOutput(theme.toolOutput(output));
285
308
  else if (useDiff) {
286
309
  const suffix = output.split("\n").length > COLLAPSED_RESULT_VISUAL_LINES ? theme.dim(` (${output.split("\n").length} lines; ${expandKey} to expand)`) : "";
287
310
  text += `\n${theme.dim(`preview${suffix}`)}`;
@@ -323,7 +346,7 @@ var ToolExecutionComponent = class extends Container {
323
346
  }));
324
347
  }
325
348
  shouldRenderDetailsPreview() {
326
- return this.expanded && this.resultDetails !== void 0 && !isExecStyleTool(this.toolName);
349
+ return (this.renderMode === "transcript" || this.expanded) && this.resultDetails !== void 0 && !isExecStyleTool(this.toolName);
327
350
  }
328
351
  getDisplayResultText() {
329
352
  if (!this.resultContent) return trimTrailingBlankDisplayLines(this.resultText);
@@ -0,0 +1,29 @@
1
+ import { Container, type Focusable, type KeybindingsManager } from '@earendil-works/pi-tui';
2
+ import type { TuiHistoryWindow } from '../tui-backend.js';
3
+ import type { CellRenderMode } from './cell-render-mode.js';
4
+ export interface TranscriptOverlayOptions {
5
+ keybindings: KeybindingsManager;
6
+ loadWindow: (rowNumber: number) => Promise<TuiHistoryWindow>;
7
+ onClose: () => void;
8
+ onRender: () => void;
9
+ viewportRows: () => number;
10
+ initialMode?: Exclude<CellRenderMode, 'compact'>;
11
+ }
12
+ export declare class TranscriptOverlay extends Container implements Focusable {
13
+ private readonly options;
14
+ private readonly log;
15
+ private messages;
16
+ private startRowNumber;
17
+ private totalRows;
18
+ private scrollOffset;
19
+ private loading;
20
+ private mode;
21
+ private _focused;
22
+ constructor(options: TranscriptOverlayOptions);
23
+ get focused(): boolean;
24
+ set focused(value: boolean);
25
+ initialize(): Promise<void>;
26
+ handleInput(data: string): void;
27
+ render(width: number): string[];
28
+ private loadPage;
29
+ }
@@ -0,0 +1,114 @@
1
+ import { theme } from "../theme.js";
2
+ import { appendHistoryToChatLog } from "../chat-history.js";
3
+ import { ChatLog } from "./chat-log.js";
4
+ import { Container } from "@earendil-works/pi-tui";
5
+ //#region src/tui/components/transcript-overlay.ts
6
+ var TranscriptOverlay = class extends Container {
7
+ log;
8
+ messages = [];
9
+ startRowNumber = 0;
10
+ totalRows = 0;
11
+ scrollOffset = 0;
12
+ loading = false;
13
+ mode;
14
+ _focused = false;
15
+ constructor(options) {
16
+ super();
17
+ this.options = options;
18
+ this.mode = options.initialMode ?? "transcript";
19
+ this.log = new ChatLog(options.keybindings);
20
+ this.log.setRenderMode(this.mode);
21
+ }
22
+ get focused() {
23
+ return this._focused;
24
+ }
25
+ set focused(value) {
26
+ this._focused = value;
27
+ }
28
+ async initialize() {
29
+ await this.loadPage(Number.MAX_SAFE_INTEGER, false);
30
+ }
31
+ handleInput(data) {
32
+ if (this.options.keybindings.matches(data, "tui.select.cancel") || data === "\x1B") {
33
+ this.options.onClose();
34
+ return;
35
+ }
36
+ if (this.options.keybindings.matches(data, "app.transcript.open")) {
37
+ this.options.onClose();
38
+ return;
39
+ }
40
+ if (this.options.keybindings.matches(data, "app.transcript.raw")) {
41
+ this.mode = this.mode === "raw" ? "transcript" : "raw";
42
+ this.log.setRenderMode(this.mode);
43
+ this.options.onRender();
44
+ return;
45
+ }
46
+ const page = Math.max(4, this.options.viewportRows() - 5);
47
+ if (data === "\x1B[5~") {
48
+ this.scrollOffset += page;
49
+ if (this.startRowNumber > 1) this.loadPage(this.startRowNumber - 1, true);
50
+ this.options.onRender();
51
+ return;
52
+ }
53
+ if (data === "\x1B[6~") {
54
+ this.scrollOffset = Math.max(0, this.scrollOffset - page);
55
+ this.options.onRender();
56
+ return;
57
+ }
58
+ if (this.options.keybindings.matches(data, "tui.select.up")) {
59
+ this.scrollOffset++;
60
+ this.options.onRender();
61
+ return;
62
+ }
63
+ if (this.options.keybindings.matches(data, "tui.select.down")) {
64
+ this.scrollOffset = Math.max(0, this.scrollOffset - 1);
65
+ this.options.onRender();
66
+ }
67
+ }
68
+ render(width) {
69
+ const viewportRows = Math.max(6, this.options.viewportRows() - 3);
70
+ const content = this.log.render(width);
71
+ this.scrollOffset = Math.min(this.scrollOffset, Math.max(0, content.length - viewportRows));
72
+ const end = Math.max(0, content.length - this.scrollOffset);
73
+ const start = Math.max(0, end - viewportRows);
74
+ const position = this.totalRows > 0 ? `${this.startRowNumber}-${this.totalRows}` : "empty";
75
+ return [
76
+ theme.bold(theme.accent(`Transcript · ${this.mode} · rows ${position}`)),
77
+ theme.dim("↑/↓ scroll · PgUp/PgDn page · Alt+R raw · Ctrl+T/Esc close"),
78
+ ...this.loading ? [theme.dim("Loading SQLite transcript…")] : [],
79
+ ...content.slice(start, end)
80
+ ];
81
+ }
82
+ async loadPage(rowNumber, prepend) {
83
+ if (this.loading) return;
84
+ this.loading = true;
85
+ this.options.onRender();
86
+ try {
87
+ const page = await this.options.loadWindow(rowNumber);
88
+ const merged = prepend ? [...page.messages, ...this.messages] : page.messages;
89
+ const seen = /* @__PURE__ */ new Set();
90
+ this.messages = merged.filter((message) => {
91
+ const key = message.id ? `id:${message.id}` : JSON.stringify([
92
+ message.kind,
93
+ message.role,
94
+ message.timestamp,
95
+ message.content
96
+ ]);
97
+ if (seen.has(key)) return false;
98
+ seen.add(key);
99
+ return true;
100
+ });
101
+ this.startRowNumber = page.startRowNumber;
102
+ this.totalRows = page.totalRows;
103
+ this.log.clearAll();
104
+ appendHistoryToChatLog(this.log, this.messages, true, true);
105
+ this.log.setRenderMode(this.mode);
106
+ if (prepend) this.scrollOffset = Number.MAX_SAFE_INTEGER;
107
+ } finally {
108
+ this.loading = false;
109
+ this.options.onRender();
110
+ }
111
+ }
112
+ };
113
+ //#endregion
114
+ export { TranscriptOverlay };
@@ -1,4 +1,5 @@
1
1
  import { theme } from "../theme.js";
2
+ import { countPendingChatInputs } from "../tui-chat-input-state.js";
2
3
  import { formatContextUsageLabel } from "../tui-context-usage.js";
3
4
  import { getGitBranchCached } from "../tui-git-branch.js";
4
5
  import { formatActiveRunStatus } from "../tui-run-status-format.js";
@@ -95,7 +96,8 @@ var TuiBottomBar = class {
95
96
  if (ctxLabel) leftParts.push(ctxLabel);
96
97
  if (state.isCompacting) leftParts.push("compact…");
97
98
  else if (state.compactionQueue.length > 0) leftParts.push(`C${state.compactionQueue.length}`);
98
- if (state.pendingInputCount > 0) leftParts.push(`Q${state.pendingInputCount}`);
99
+ const pendingInputCount = countPendingChatInputs(state.chatInputState?.inputs ?? []);
100
+ if (pendingInputCount > 0) leftParts.push(`Q${pendingInputCount}`);
99
101
  let statsLeft = leftParts.join(" · ");
100
102
  const modelId = state.sessionInfo.model ?? "unknown";
101
103
  const prov = state.sessionInfo.modelProvider;
@@ -1,8 +1,12 @@
1
1
  import { Container } from '@earendil-works/pi-tui';
2
+ import type { CellRenderMode, ModeAwareCell } from './cell-render-mode.js';
2
3
  export declare function normalizeUserContent(content: string | unknown[]): string;
3
- export declare class UserMessageComponent extends Container {
4
+ export declare class UserMessageComponent extends Container implements ModeAwareCell {
4
5
  private body;
6
+ private content;
7
+ private renderMode;
5
8
  constructor(text: string | unknown[]);
6
9
  setText(text: string | unknown[]): void;
10
+ setRenderMode(mode: CellRenderMode): void;
7
11
  render(width: number): string[];
8
12
  }
@@ -1,5 +1,5 @@
1
1
  import { markdownTheme, theme } from "../theme.js";
2
- import { Box, Container, Markdown } from "@earendil-works/pi-tui";
2
+ import { Box, Container, Markdown, Text } from "@earendil-works/pi-tui";
3
3
  //#region src/tui/components/user-message.ts
4
4
  const OSC133_ZONE_START = "\x1B]133;A\x07";
5
5
  const OSC133_ZONE_END = "\x1B]133;B\x07";
@@ -31,17 +31,28 @@ function normalizeUserContent(content) {
31
31
  }
32
32
  var UserMessageComponent = class extends Container {
33
33
  body;
34
+ content;
35
+ renderMode = "compact";
34
36
  constructor(text) {
35
37
  super();
38
+ this.content = text;
36
39
  this.body = new Markdown(normalizeUserContent(text), 1, 0, markdownTheme, { color: (line) => theme.userText(line) }, { preserveOrderedListMarkers: true });
37
40
  const box = new Box(1, 1, (line) => theme.userBg(line));
38
41
  box.addChild(this.body);
39
42
  this.addChild(box);
40
43
  }
41
44
  setText(text) {
45
+ this.content = text;
42
46
  this.body.setText(normalizeUserContent(text));
43
47
  }
48
+ setRenderMode(mode) {
49
+ this.renderMode = mode;
50
+ }
44
51
  render(width) {
52
+ if (this.renderMode === "raw") return new Text(JSON.stringify({
53
+ role: "user",
54
+ content: this.content
55
+ }, null, 2), 0, 0).render(width);
45
56
  const lines = super.render(width);
46
57
  if (lines.length === 0) return lines;
47
58
  lines[0] = OSC133_ZONE_START + lines[0];
@@ -1,4 +1,4 @@
1
- import type { ExtensionRegistryImpl } from '../../extensions/loader.js';
1
+ import type { ExtensionRegistryImpl } from '../../extensions/extension-registry-impl.js';
2
2
  /** Load activated extensions for embedded TUI (shared registry with AgentService). */
3
3
  export declare function loadExtensionsForTuiLocalMode(runtime?: {
4
4
  setLabel?: (entryId: string, label: string | undefined) => void;
@@ -1,5 +1,6 @@
1
1
  import { getAllModels, getApiKey, init_providers } from "../../providers/index.js";
2
2
  import { theme } from "../theme.js";
3
+ import { countPendingChatInputs } from "../tui-chat-input-state.js";
3
4
  import { computeContextUsagePercent } from "../tui-context-usage.js";
4
5
  //#region src/tui/extension-host/runtime-context.ts
5
6
  init_providers();
@@ -85,7 +86,7 @@ function isTuiIdle(state) {
85
86
  return state.activeRunId == null && !state.isCompacting && !BUSY_ACTIVITY_STATUSES.has(state.activityStatus);
86
87
  }
87
88
  function hasPendingTuiMessages(state) {
88
- return (state.pendingInputCount ?? 0) > 0 || (state.compactionQueue?.length ?? 0) > 0;
89
+ return countPendingChatInputs(state.chatInputState?.inputs ?? []) > 0 || (state.compactionQueue?.length ?? 0) > 0;
89
90
  }
90
91
  function getTuiContextUsage(state) {
91
92
  const sessionInfo = state.sessionInfo;
@@ -1,5 +1,5 @@
1
1
  import { type Component, type AutocompleteItem, type AutocompleteProvider, type KeybindingsManager, type OverlayHandle, type OverlayOptions, type TUI } from '@earendil-works/pi-tui';
2
- import type { ExtensionRegistryImpl } from '../../extensions/loader.js';
2
+ import type { ExtensionRegistryImpl } from '../../extensions/extension-registry-impl.js';
3
3
  import type { TuiAutocompleteSuggestion, TuiCompactOptions, TuiCompactResult, TuiEditorFactory, TuiForkOptions, TuiModelRegistry, TuiNavigateTreeOptions, TuiNewSessionOptions, TuiReasoningLevel, TuiReplacedSessionContext, TuiReplacementResult, TuiReadonlySessionManager, TuiSlashCommandContext, TuiShortcutHandler, TuiSlashCommandHandler, TuiSwitchSessionOptions, TuiSystemPromptOptions, TuiTerminalInputHandler, TuiSetThemeResult, TuiTheme, TuiThemeInfo, TuiThinkingLevel, TuiVerboseLevel, TuiWorkingIndicatorOptions } from '../../extensions/types/tui.js';
4
4
  import type { ChatLog } from '../components/chat-log.js';
5
5
  import type { TuiHeader } from '../components/tui-header.js';
@@ -2,9 +2,16 @@ import { theme } from "./theme.js";
2
2
  import { XOPC_TUI_HOTKEY_ORDER } from "./xopc-tui-keybindings.js";
3
3
  import { getTuiKeybindingsPath } from "./tui-keybindings-file.js";
4
4
  //#region src/tui/format-tui-hotkeys.ts
5
+ const KEY_DISPLAY = {
6
+ up: "↑",
7
+ down: "↓",
8
+ left: "←",
9
+ right: "→"
10
+ };
5
11
  function formatKeyText(key, options = {}) {
6
12
  return key.split("/").map((part) => part.split("+").map((keyPart) => {
7
- const display = process.platform === "darwin" && keyPart.toLowerCase() === "alt" ? "option" : keyPart;
13
+ const normalized = keyPart.toLowerCase();
14
+ const display = KEY_DISPLAY[normalized] ?? (process.platform === "darwin" && normalized === "alt" ? "option" : keyPart);
8
15
  return options.capitalize ? display.charAt(0).toUpperCase() + display.slice(1) : display;
9
16
  }).join("+")).join("/");
10
17
  }
@@ -341,6 +341,37 @@ function dispatchAgentEvent(event, data, state, chatLog, tui, setActivityStatus,
341
341
  tui.requestRender();
342
342
  break;
343
343
  }
344
+ case "task_plan_updated": {
345
+ const lines = (Array.isArray(p.items) ? p.items : []).flatMap((item) => {
346
+ if (!item || typeof item !== "object") return [];
347
+ const record = item;
348
+ const status = typeof record.status === "string" ? record.status : "pending";
349
+ const title = typeof record.title === "string" ? record.title : "";
350
+ return title ? [`[${status}] ${title}`] : [];
351
+ });
352
+ const planId = typeof p.planId === "string" ? p.planId : `${runId}:plan`;
353
+ chatLog.upsertSemanticCell(planId, {
354
+ kind: "plan",
355
+ title: typeof p.explanation === "string" && p.explanation.trim() ? p.explanation : "Execution plan",
356
+ lines,
357
+ raw: p
358
+ });
359
+ tui.requestRender();
360
+ break;
361
+ }
362
+ case "clarify_request": {
363
+ const requestId = typeof p.requestId === "string" ? p.requestId : `${runId}:question`;
364
+ const kind = p.kind === "approval" ? "approval" : "question";
365
+ const choices = Array.isArray(p.choices) ? p.choices.filter((choice) => typeof choice === "string") : [];
366
+ chatLog.upsertSemanticCell(requestId, {
367
+ kind,
368
+ title: typeof p.question === "string" ? p.question : kind === "approval" ? "Approval required" : "Input required",
369
+ lines: choices.map((choice) => `• ${choice}`),
370
+ raw: p
371
+ });
372
+ tui.requestRender();
373
+ break;
374
+ }
344
375
  }
345
376
  }
346
377
  const DEFAULT_STREAMING_WATCHDOG_MS = 3e4;
@@ -3,6 +3,9 @@ import type { SessionTimelineItem } from '../session/transcript-outline.js';
3
3
  import type { ExportFormat } from '../session/types.js';
4
4
  import type { ReviewContext } from '../review/review-git.js';
5
5
  import type { SessionInfo, TuiEventSource } from './tui-types.js';
6
+ import type { TuiChatInputDelivery, TuiChatInputState } from './tui-chat-input-state.js';
7
+ export type { TuiChatInput, TuiChatInputDelivery, TuiChatInputState, TuiChatInputStatus } from './tui-chat-input-state.js';
8
+ export { countPendingChatInputs } from './tui-chat-input-state.js';
6
9
  /** Options for sending a chat message. */
7
10
  export interface ChatSendOptions {
8
11
  conversationId: string;
@@ -120,15 +123,6 @@ export interface TuiStartupResources {
120
123
  workflows: string[];
121
124
  connectors: string[];
122
125
  }
123
- export interface TuiChatInputState {
124
- conversationId: string;
125
- revision: number;
126
- inputs: Array<{
127
- id: string;
128
- status: string;
129
- }>;
130
- }
131
- export declare function countPendingChatInputs(inputs: readonly unknown[]): number;
132
126
  export interface TuiWorkspaceFileSearchEntry {
133
127
  name: string;
134
128
  path: string;
@@ -224,12 +218,30 @@ export interface TuiBackend {
224
218
  submitChatInput(opts: {
225
219
  conversationId: string;
226
220
  message: string;
227
- delivery: 'next' | 'steer';
221
+ delivery: TuiChatInputDelivery;
228
222
  }): Promise<{
229
223
  ok: boolean;
230
- effectiveDelivery?: 'next' | 'steer';
224
+ effectiveDelivery?: TuiChatInputDelivery;
225
+ state?: TuiChatInputState;
231
226
  }>;
232
227
  getChatInputState(conversationId: string): Promise<TuiChatInputState>;
228
+ updateChatInput(opts: {
229
+ conversationId: string;
230
+ inputId: string;
231
+ version: number;
232
+ content: string;
233
+ }): Promise<{
234
+ ok: boolean;
235
+ state?: TuiChatInputState;
236
+ }>;
237
+ removeChatInput(opts: {
238
+ conversationId: string;
239
+ inputId: string;
240
+ version: number;
241
+ }): Promise<{
242
+ ok: boolean;
243
+ state?: TuiChatInputState;
244
+ }>;
233
245
  /** Start a workflow run directly, without routing through the LLM. */
234
246
  startWorkflowRun?(opts: TuiWorkflowRunStartRequest): Promise<TuiWorkflowRunStartResult>;
235
247
  /** Resolve or create the project implied by the TUI launch workspace. */
@@ -1,10 +1,2 @@
1
- //#region src/tui/tui-backend.ts
2
- function countPendingChatInputs(inputs) {
3
- return inputs.filter((input) => {
4
- if (!input || typeof input !== "object") return false;
5
- const status = input.status;
6
- return status === "queued" || status === "interrupted";
7
- }).length;
8
- }
9
- //#endregion
1
+ import { countPendingChatInputs } from "./tui-chat-input-state.js";
10
2
  export { countPendingChatInputs };
@@ -0,0 +1,25 @@
1
+ export type TuiChatInputDelivery = 'next' | 'steer';
2
+ export type TuiChatInputStatus = 'queued' | 'running' | 'injecting' | 'completed' | 'cancelled' | 'failed' | 'interrupted' | 'suspended';
3
+ export interface TuiChatInput {
4
+ id: string;
5
+ content: string;
6
+ requestedDelivery: TuiChatInputDelivery;
7
+ effectiveDelivery: TuiChatInputDelivery;
8
+ status: TuiChatInputStatus;
9
+ version: number;
10
+ position?: number;
11
+ error?: string;
12
+ }
13
+ export interface TuiChatInputState {
14
+ conversationId: string;
15
+ revision: number;
16
+ activeRunId?: string;
17
+ activeInputId?: string;
18
+ inputs: TuiChatInput[];
19
+ }
20
+ export declare function createEmptyChatInputState(conversationId: string): TuiChatInputState;
21
+ export declare function isPendingChatInput(input: TuiChatInput): boolean;
22
+ export declare function countPendingChatInputs(inputs: readonly TuiChatInput[]): number;
23
+ export declare function acceptChatInputState(current: TuiChatInputState, incoming: TuiChatInputState): TuiChatInputState;
24
+ export declare function findLastEditableChatInput(state: TuiChatInputState): TuiChatInput | undefined;
25
+ export declare function commitDeliveredChatInput(state: TuiChatInputState, content: string): TuiChatInputState;
@@ -0,0 +1,36 @@
1
+ //#region src/tui/tui-chat-input-state.ts
2
+ function createEmptyChatInputState(conversationId) {
3
+ return {
4
+ conversationId,
5
+ revision: -1,
6
+ inputs: []
7
+ };
8
+ }
9
+ function isPendingChatInput(input) {
10
+ return input.status === "queued" || input.status === "injecting" || input.status === "interrupted";
11
+ }
12
+ function countPendingChatInputs(inputs) {
13
+ return inputs.filter(isPendingChatInput).length;
14
+ }
15
+ function acceptChatInputState(current, incoming) {
16
+ if (current.conversationId !== incoming.conversationId) return incoming;
17
+ return incoming.revision >= current.revision ? incoming : current;
18
+ }
19
+ function findLastEditableChatInput(state) {
20
+ return state.inputs.filter((input) => input.status === "queued").sort((left, right) => (left.position ?? 0) - (right.position ?? 0)).at(-1);
21
+ }
22
+ function commitDeliveredChatInput(state, content) {
23
+ const normalized = content.trim();
24
+ if (!normalized) return state;
25
+ const matches = (input, status) => input.status === status && input.content.trim() === normalized;
26
+ let index = state.inputs.findIndex((input) => matches(input, "injecting"));
27
+ if (index < 0) index = state.inputs.findIndex((input) => matches(input, "queued"));
28
+ if (index < 0) return state;
29
+ return {
30
+ ...state,
31
+ revision: state.revision + 1,
32
+ inputs: state.inputs.filter((_, inputIndex) => inputIndex !== index)
33
+ };
34
+ }
35
+ //#endregion
36
+ export { acceptChatInputState, commitDeliveredChatInput, countPendingChatInputs, createEmptyChatInputState, findLastEditableChatInput, isPendingChatInput };
@@ -6,6 +6,7 @@ import { getProviderDisplayName, getSortedProviders, init_providers, providerSup
6
6
  import { createWorkflowCatalog } from "../agent/workflow/catalog.js";
7
7
  import { normalizeVerboseLevel } from "../agent/transcript/thinking-types.js";
8
8
  import "../config/index.js";
9
+ import { countPendingChatInputs } from "./tui-chat-input-state.js";
9
10
  import { computeContextUsagePercent, formatContextUsageLabel } from "./tui-context-usage.js";
10
11
  import { formatSessionPickerDescription } from "./tui-session-format.js";
11
12
  import { formatTuiTranscriptTreeEntryDisplayText } from "./tui-transcript-tree.js";
@@ -455,7 +456,7 @@ function formatTuiSessionInfo(state, stats) {
455
456
  `Context: ${contextLabel}`,
456
457
  `Tools: ${state.toolsExpanded ? "expanded" : "collapsed"}`,
457
458
  `Thinking Display: ${state.showThinking ? "on" : "off"}`,
458
- `Pending Inputs: ${state.pendingInputCount}`,
459
+ `Pending Inputs: ${countPendingChatInputs(state.chatInputState?.inputs ?? [])}`,
459
460
  ...formatTuiSessionStatsBlock(stats)
460
461
  ].join("\n");
461
462
  }
@@ -272,7 +272,7 @@ function formatTuiHelpText(isLocal, keybindings, extraSlashCommands = [], skillS
272
272
  const thinkingToggle = keyLabel(keybindings, "app.thinking.toggle", "Ctrl+T");
273
273
  const editorExternal = keyLabel(keybindings, "app.editor.external", "Ctrl+G");
274
274
  const suspend = keyLabel(keybindings, "app.suspend", "Ctrl+Z");
275
- const followUp = keyLabel(keybindings, "app.message.followUp", "Alt+Enter");
275
+ const followUp = keyLabel(keybindings, "app.message.followUp", "Tab");
276
276
  const pasteImage = keyLabel(keybindings, "app.clipboard.pasteImage", "Ctrl+V / Alt+V");
277
277
  const clearInput = keyLabel(keybindings, "app.clear", "Ctrl+C");
278
278
  const exit = keyLabel(keybindings, "app.exit", "Ctrl+D");
@@ -1,4 +1,5 @@
1
1
  import type { GatewayCredential } from '../gateway/credential.js';
2
+ import { type TuiChatInputState } from './tui-chat-input-state.js';
2
3
  /** TUI configuration options passed from CLI. */
3
4
  export interface TuiOptions {
4
5
  /** Connect to a running gateway instead of embedded mode. */
@@ -77,7 +78,7 @@ export interface TuiState {
77
78
  /** Last Ctrl+C timestamp for double-press exit (see `resolveCtrlCAction`). */
78
79
  lastCtrlCAt: number;
79
80
  exitRequested: boolean;
80
- pendingInputCount: number;
81
+ chatInputState: TuiChatInputState;
81
82
  /** Ctrl+P cycle filter; `null` = all models from catalog. */
82
83
  scopedModelRefs: string[] | null;
83
84
  /** Last Escape timestamp for double-press actions. */
@@ -1,3 +1,4 @@
1
+ import { createEmptyChatInputState } from "./tui-chat-input-state.js";
1
2
  //#region src/tui/tui-types.ts
2
3
  function createInitialState(conversationId) {
3
4
  return {
@@ -24,7 +25,7 @@ function createInitialState(conversationId) {
24
25
  showThinking: false,
25
26
  lastCtrlCAt: 0,
26
27
  exitRequested: false,
27
- pendingInputCount: 0,
28
+ chatInputState: createEmptyChatInputState(conversationId),
28
29
  scopedModelRefs: null,
29
30
  lastEscapeAt: 0,
30
31
  progressMessage: null,