chainlesschain 0.165.4 → 0.165.6

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 (214) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-C__nnraW.js → AIOps-vfoDb6HZ.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CsKWHEZ-.js → ActionButton-Cm5f7p93.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-BhIjfjWO.js → Analytics-yRuvgWxa.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-BjuXFzWZ.js → AppLayout-BROsC4h1.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-k6whDkZJ.js → Artifacts-CimHApb1.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-C4FBMYRh.js → Audit-DI8kr8zI.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-C_vRrSXk.js → BackgroundAgents-DSLzKy-n.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-CngFZeVp.js → Backup-DkH_n2r1.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-B_H9EBRm.js → BaseInput-CKSrUoRA.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-DLEC5kt7.js → Chat-ClwfMXUS.js} +3 -3
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-CjMaqfL7.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-m3ClR4xh.js → Checkbox-BYTehcQG.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-CmLSFrgp.js → Codegen-B8AMcp6J.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-DFGQteHN.js → Col-BNSogPo3.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-EUUVORHE.js → Community-JxPvGb8O.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-2PSg0Yr7.js → Compact-DF7bFAgE.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-CcKur7gB.js → Compliance-Bvhqnwrq.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-DK_Fezfa.js → Cowork-BDS0CJvM.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-Dbw89xl7.js → Cron-DqvRfxoQ.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-CH66h_Ec.js → Crosschain-CDcIvnqS.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-D1igRb17.js → DID-D7jaUxU3.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-DVAsrobk.js → Dashboard-B5A18wEV.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-Dl7W8AQs.js → Dropdown-_6IVkGag.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-D5tpaEQC.js → EmailListRenderer-C9PeiKCG.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-O_VQf8gq.js → FamilyGuardDashboard-DXjuEHrX.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-BTVcgS9n.js → Federation-B4IAR9zv.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-BRnkJAIz.js → FormItemContext-CxQeSNx1.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-8OWSCkDj.js → GenericCardRenderer-B8GS-Y3N.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-WXLYTQj2.js → Git-BS8SouUX.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-BezaUhtc.js → Governance-Dq9aYb5Q.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-CuRay3Gu.js → Inference-BrCEe9AJ.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-DfWLDW1m.js → KnowledgeGraph-DybOpiY2.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-C55y2pPY.js → Logs-DBpzbRfx.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-CFyt8iUd.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-Dk08Uycg.js → Marketplace-Cc7CCSCu.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-C11fSB5V.js → McpTools-DFaIhOfu.js} +3 -3
  39. package/src/assets/web-panel/assets/{Memory-mr0eZc97.js → Memory-KCqlp9ol.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-C0iCSRbb.js → MobileBridge-Bys84ySN.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-CY-xMG8Z.js → MobileProjects-B-6qU-je.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-Bplqc_Wc.js → Mtc-BgY-fvCq.js} +4 -4
  43. package/src/assets/web-panel/assets/{MtcAudit-BlzwsoSM.js → MtcAudit-B8pCmqQJ.js} +4 -4
  44. package/src/assets/web-panel/assets/{Multisig-BBLmTty6.js → Multisig-BbOmYutA.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-DtT1uf1W.js → NLProgramming-BocLQz_M.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-DcqQAxTK.js → Notes-CSwbxEop.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-cb0kWoZe.js → NotificationSettings-CqFNSYG3.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-kw9HZQNN.js → OrderTableRenderer-C6gMfAk7.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-DlTlbkUN.js → Organization-QrDXVdMJ.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-pp1qs-oY.js → Overflow-Cxntotjt.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-BESLnyYz.js → P2P-CIdBOwNq.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-B-J1mGuf.js → PdhVaultBrowser-CT5aP8rD.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-B36PeT1_.js → Permissions-DH7OM8XU.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-CTK2ad-3.js → PersonalDataHub-CnJqbWce.js} +3 -3
  55. package/src/assets/web-panel/assets/{Pipeline-zJNGXsac.js → Pipeline-5C3HG1kH.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-b9fz0Qf0.js → Privacy-B4yIp7xK.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-DjZbZgiB.js → ProjectInit-BMvt-2M0.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-C-hHJXlD.js → ProjectSettings-CvSTEMRG.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-BKBJxEek.js +1 -0
  60. package/src/assets/web-panel/assets/Providers-BdwUqFWN.js +1 -0
  61. package/src/assets/web-panel/assets/{QrScannerModal-A0yoQ3-3.js → QrScannerModal-DtnCKlTm.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-DrFgFJNC.js → QuickAsk-sTbgwyNr.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-KC8hF1g4.js → Recommend-Bzr14gSb.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-DGTPIk6u.js → RemoteSession-C_TF5IaJ.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-QmbwM7Yk.js → Reputation-GCAM4H2K.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-BxjJylia.js → Row-Dir0r6OQ.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-B7Wda1J6.js → RssFeed-CpGnlecX.js} +2 -2
  68. package/src/assets/web-panel/assets/{Search-_plQ_YSA.js → Search-DMMamC6u.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-CD2YJZfx.js → Security-yqay5yG-.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-qQE7NmwE.js → Services-C5i2wh9G.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-DgQqkFf7.js → Skeleton-vUqk35yj.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-C4C0oFFt.js → Skills-DzcSkhot.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-Px2N2B5c.js → Sla-CB6qbYNr.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-DN6C3lQd.js → SpeechSettings-BHUI7cox.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-jm5aH_m7.js → SyncSettings-D-RrsxTJ.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-DlkJcv67.js → Tasks-DFxdOJiq.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-DyrTHUBs.js → Templates-SKAob_Aq.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-mC434PtL.js → Tenant-BPfsfHQ-.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-o0_s3NgK.js → Terminal-8iw7FpUf.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-DAGlAXOw.js → TimelineRenderer-C4Gjj5Su.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-BnulS_bs.js → Tokens-COYhN18e.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-suQbVXYM.js → Trigger-B-JzXcf6.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-DbIJAPo5.js → Trust-BJ5bg0nI.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-CQNpbIHi.js → UkeySign-BG_ByRMf.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-D8aWCERk.js → VideoEditing-B3kOnSiU.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-CuLpYfZc.js → Wallet-CcoGFnK7.js} +2 -2
  87. package/src/assets/web-panel/assets/{WebAuthn-CsfG8ZMc.js → WebAuthn-DdT8vRC_.js} +4 -4
  88. package/src/assets/web-panel/assets/{WorkflowEditor-BYsEAZbd.js → WorkflowEditor-CZu3M9N8.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-FT4Um3-I.js → chat-DxJt3Qba.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-CKbS_Wlt.js → colors-DdYfwJaB.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-CFJtzuJM.js → compact-item-BG3SUzwj.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-B9kSRW6K.js → createContext-By51z2-1.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-DorRZcI9.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-DR-x0Xpi.js → hasIn-B0apZ3KJ.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DjEP7WkH.js → index-3jWkIu5j.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-7jHr_A_k.js → index-B3rWuPMW.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DcfxhKXR.js → index-B5rLiEo0.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-tqSEHPRT.js → index-BBPf3TpM.js} +1 -1
  99. package/src/assets/web-panel/assets/index-BETiL0a3.js +1 -0
  100. package/src/assets/web-panel/assets/{index-Cr2FLUsD.js → index-BIrJfqO4.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-Bt4fS2eL.js → index-BLIbGOLX.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BwR7yc2h.js → index-BP94CrBV.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BVPU43b1.js → index-BWF8_mkx.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DShSkww-.js → index-BYINoRLK.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Bzz0C1BZ.js → index-BZ_0qm4g.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-KqDaCApw.js → index-BewKYrX9.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BW-t9n-q.js → index-BfWYsB9t.js} +1 -1
  108. package/src/assets/web-panel/assets/index-BhAVHuW8.js +1 -0
  109. package/src/assets/web-panel/assets/{index-B7osrXqy.js → index-Bissefox.js} +3 -3
  110. package/src/assets/web-panel/assets/{index-DW4BWjTk.js → index-BkvcEo4p.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DdkIhfi-.js → index-Bos5_aMV.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DTxNy0ZU.js → index-C1C9i79A.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-QBSeNVO3.js → index-CAhHirVH.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-D4LfPvWA.js → index-CNIxXMmN.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-C_enk9I_.js → index-CW93tZDv.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-WE08gMJP.js → index-CWEuZWCK.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-r2VI1Ikk.js → index-Cp6e-hGw.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Dap9c3eD.js → index-CpjZhgNd.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DWdqx7zI.js → index-CzmQElZy.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BGbPnC5x.js → index-DCn8IcxV.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DiNUEpSQ.js → index-DE76D-kA.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DtkFqPVA.js → index-DaIz0NAW.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CGaXUsIs.js → index-Da_WBdLX.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-B3ZX81mK.js → index-Dz49VOyQ.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BK3TiKVq.js → index-Q2SCX-MI.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CJmIQ9XR.js → index-RD6O-0C6.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CvrCCqJt.js → index-SQqOlR3d.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BI5hP_qy.js → index-ZFbps9po.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DeSgw-WV.js → index-ZxtP8jG7.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DMGmg497.js → index-bP_VlDb4.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BfFCQHL3.js → index-kf57LJ93.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-OSzjTzGM.js → index-oxRrmFO9.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-C2JvmYRc.js → index-p1_8SbI1.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-Dd7n7VgI.js → initDefaultProps-BWJktcg8.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BwxouRw1.js → motion-BEXBzUFV.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-DObN0PG9.js → move-BUKwn2sx.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-B3nOUQc7.js → mtc-parser-FTI7btqQ.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-o9WU2Nbl.js → omit-CsLtSPH3.js} +1 -1
  139. package/src/assets/web-panel/assets/parsers-YNLm7sQ0.js +4 -0
  140. package/src/assets/web-panel/assets/{pickAttrs-CL_vvfQ_.js → pickAttrs-DWZxsT_S.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-CYrM2tyK.js → placementArrow-Bcfs43CX.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-k_06cQ96.js → responsiveObserve-a9bcC1p-.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-CPKG0pxS.js → slide-BDTzgOXN.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-BDDEeLTw.js → statusUtils-Iq1j_HUg.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-Cmb7RTh7.js → styleChecker-DAZEYxeh.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-e2IedC4N.js → useFlexGapSupport-DVkjyDrh.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-CE_gxVnm.js → useFs-wXTpNTHt.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-BkMIIKMz.js → usePersonalDataHub-CtQM_aZr.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-DW886XV1.js → vnode-hjEoG85v.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-Dwo_adaf.js → zoom-BHVpyKg_.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/command-help-index.json +3 -3
  153. package/src/commands/agent.js +14 -2
  154. package/src/commands/artifacts.js +235 -0
  155. package/src/commands/background-session.js +100 -10
  156. package/src/commands/cowork.js +86 -57
  157. package/src/commands/mcp.js +5 -0
  158. package/src/commands/plugin.js +145 -29
  159. package/src/commands/remote-control.js +295 -110
  160. package/src/commands/session-location.js +20 -1
  161. package/src/commands/session-message.js +171 -0
  162. package/src/commands/session.js +75 -69
  163. package/src/data/changelog.json +29 -3
  164. package/src/gateways/ws/message-dispatcher.js +57 -0
  165. package/src/harness/mcp-client.js +141 -10
  166. package/src/lib/artifact-access-ledger.js +1 -0
  167. package/src/lib/artifact-deletion-ledger.js +1 -0
  168. package/src/lib/artifact-recovery.js +970 -0
  169. package/src/lib/artifact-workbench-projection.js +171 -0
  170. package/src/lib/background-session-transport.js +153 -27
  171. package/src/lib/dynamic-workflow-runtime.js +408 -1
  172. package/src/lib/execution-location-target.js +4 -2
  173. package/src/lib/mcp-client.js +2 -0
  174. package/src/lib/mcp-headers-helper.js +47 -5
  175. package/src/lib/mcp-oauth.js +55 -6
  176. package/src/lib/mcp-stdio-executable-identity.js +16 -0
  177. package/src/lib/mcp-stdio-native-code-policy.js +74 -0
  178. package/src/lib/mcp-stdio-package-materialization.js +12 -3
  179. package/src/lib/mcp-tls.js +230 -0
  180. package/src/lib/output-styles.js +12 -0
  181. package/src/lib/plugin-runtime/install.js +614 -71
  182. package/src/lib/plugin-runtime/marketplace-archive-source.js +331 -0
  183. package/src/lib/plugin-runtime/marketplace-catalog.js +52 -6
  184. package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1 -0
  185. package/src/lib/plugin-runtime/marketplace-source-adapter.js +163 -0
  186. package/src/lib/plugin-runtime/marketplace-source-cache.js +11 -1
  187. package/src/lib/plugin-runtime/remote-source.js +435 -55
  188. package/src/lib/plugin-security.js +393 -41
  189. package/src/lib/plugin-source-identity.js +850 -0
  190. package/src/lib/process-execution-broker/index.js +112 -0
  191. package/src/lib/process-execution-broker/platform-sandbox.js +57 -3
  192. package/src/lib/process-execution-broker/workspace-transaction.js +26 -0
  193. package/src/lib/remote-approval-bridge.js +136 -46
  194. package/src/lib/remote-control.js +217 -31
  195. package/src/lib/session-message-fabric.js +1105 -0
  196. package/src/lib/session-projection.js +171 -12
  197. package/src/lib/session-runtime-retention.js +155 -0
  198. package/src/lib/settings-loader.cjs +29 -0
  199. package/src/repl/agent-repl.js +51 -14
  200. package/src/repl/permission-prompt.js +31 -8
  201. package/src/repl/repl-keybindings.js +55 -0
  202. package/src/runtime/agent-core.js +63 -2
  203. package/src/runtime/headless-runner.js +47 -66
  204. package/src/runtime/headless-stream.js +18 -24
  205. package/src/runtime/mcp-config.js +2 -0
  206. package/src/runtime/policies/agent-policy.js +2 -0
  207. package/src/assets/web-panel/assets/ChatBubbleRenderer-xijcWkJe.js +0 -1
  208. package/src/assets/web-panel/assets/MarkdownRenderer-hDpWdiBc.js +0 -1
  209. package/src/assets/web-panel/assets/Projects-BC9KSDM6.js +0 -1
  210. package/src/assets/web-panel/assets/Providers-Dz-CAYYU.js +0 -1
  211. package/src/assets/web-panel/assets/devWarning-DJZ0gAMu.js +0 -1
  212. package/src/assets/web-panel/assets/index-Bizb4hkw.js +0 -1
  213. package/src/assets/web-panel/assets/index-OHSl-xCh.js +0 -1
  214. package/src/assets/web-panel/assets/parsers-UEvh_ShA.js +0 -4
@@ -14,8 +14,8 @@ import {
14
14
  SESSION_STATES,
15
15
  } from "./session-lifecycle.js";
16
16
 
17
- export const SESSION_PROJECTION_SCHEMA = "chainlesschain.session-projection/v1";
18
- export const SESSION_PROJECTION_VERSION = 1;
17
+ export const SESSION_PROJECTION_SCHEMA = "chainlesschain.session-projection/v2";
18
+ export const SESSION_PROJECTION_VERSION = 2;
19
19
 
20
20
  export const PROJECTION_KINDS = Object.freeze([
21
21
  "local",
@@ -23,6 +23,7 @@ export const PROJECTION_KINDS = Object.freeze([
23
23
  "remote",
24
24
  "team",
25
25
  "workflow",
26
+ "dynamic_workflow",
26
27
  ]);
27
28
 
28
29
  export const PROJECTION_STATES = Object.freeze([
@@ -43,6 +44,9 @@ export const PROJECTION_ACTIONS = Object.freeze([
43
44
  "stop",
44
45
  "checkpoint",
45
46
  "archive",
47
+ "pause",
48
+ "resume",
49
+ "recover",
46
50
  ]);
47
51
 
48
52
  export const PROJECTION_ACTION_EXECUTORS = Object.freeze([
@@ -115,6 +119,7 @@ function sourceSessionId(source, fallback = null) {
115
119
  asText(source?.sessionId) ||
116
120
  asText(source?.agentSessionId) ||
117
121
  asText(source?.remoteSessionId) ||
122
+ asText(source?.executionAuthoritySessionId) ||
118
123
  fallback
119
124
  );
120
125
  }
@@ -214,6 +219,22 @@ function mapWorkflowState(source) {
214
219
  return "working";
215
220
  }
216
221
 
222
+ function mapDynamicWorkflowState(source) {
223
+ const status = String(source?.status || "")
224
+ .trim()
225
+ .toLowerCase();
226
+ if (status === "completed") return "done";
227
+ if (status === "stopped") return "stopped";
228
+ if (status === "failed") return "failed";
229
+ if (["input_requested", "needs_input"].includes(status)) {
230
+ return "needs_input";
231
+ }
232
+ if (["pause_requested", "paused", "blocked"].includes(status)) {
233
+ return "blocked";
234
+ }
235
+ return ["ready", "running"].includes(status) ? "working" : "failed";
236
+ }
237
+
217
238
  function preview(executor, argv, { mutates = false, input = null } = {}) {
218
239
  return {
219
240
  executor,
@@ -290,6 +311,49 @@ function actionPreviews(kind, state, source, sourceId, linkedSessionId) {
290
311
  "--cwd",
291
312
  cwd,
292
313
  ]);
314
+ } else if (kind === "dynamic_workflow" && cwd) {
315
+ const expectedRevision = String(source?.revision || "");
316
+ const runtimeArgs = (action) => [
317
+ "cowork",
318
+ "workflow",
319
+ `runtime-${action}`,
320
+ sourceId,
321
+ "--expected-revision",
322
+ expectedRevision,
323
+ "--cwd",
324
+ cwd,
325
+ "--json",
326
+ ];
327
+ routes.peek = preview("cli", [
328
+ "cowork",
329
+ "workflow",
330
+ "runtime-status",
331
+ sourceId,
332
+ "--cwd",
333
+ cwd,
334
+ "--json",
335
+ ]);
336
+ if (
337
+ !TERMINAL_PROJECTION_STATES.has(state) &&
338
+ !["paused", "input_requested", "needs_input"].includes(source?.status)
339
+ ) {
340
+ routes.pause = preview("cli", runtimeArgs("pause"), { mutates: true });
341
+ }
342
+ if (
343
+ ["paused", "failed", "blocked"].includes(source?.status) &&
344
+ Number(source?.agents?.pending || 0) === 0 &&
345
+ Number(source?.input?.pending || 0) === 0
346
+ ) {
347
+ routes.resume = preview("cli", runtimeArgs("resume"), { mutates: true });
348
+ }
349
+ if (!["completed", "stopped"].includes(source?.status)) {
350
+ routes.stop = preview("cli", runtimeArgs("stop"), { mutates: true });
351
+ }
352
+ if (Number(source?.recovery?.terminal || 0) > 0) {
353
+ routes.recover = preview("cli", runtimeArgs("recover-checkpoints"), {
354
+ mutates: true,
355
+ });
356
+ }
293
357
  }
294
358
 
295
359
  if (checkpointAvailable) {
@@ -356,6 +420,18 @@ function actionAvailability(kind, state, source, sourceId, linkedSessionId) {
356
420
  : kind === "workflow"
357
421
  ? "coding workflow state has no non-destructive archive route"
358
422
  : "no non-destructive session archive capability is available",
423
+ pause:
424
+ kind === "dynamic_workflow"
425
+ ? "workflow run cannot be paused in its current state"
426
+ : "pause is only supported by durable dynamic workflow runs",
427
+ resume:
428
+ kind === "dynamic_workflow"
429
+ ? "workflow run has pending input/effects or is not resumable"
430
+ : "resume is only supported by durable dynamic workflow runs",
431
+ recover:
432
+ kind === "dynamic_workflow"
433
+ ? "no terminal checkpoint recovery is currently available"
434
+ : "recovery is only supported by durable dynamic workflow runs",
359
435
  };
360
436
 
361
437
  return PROJECTION_ACTIONS.map((id) => {
@@ -464,6 +540,24 @@ function artifactSummary(sessionIds, artifacts) {
464
540
  };
465
541
  }
466
542
 
543
+ function dynamicWorkflowSummary(source) {
544
+ if (source?.schema !== "cc-dynamic-workflow-workbench-state/v1") return null;
545
+ return {
546
+ runtimeRevision: source.revision,
547
+ phase: source.phase,
548
+ agents: source.agents,
549
+ budget: source.budget,
550
+ artifacts: source.artifacts,
551
+ checkpoints: source.checkpoints,
552
+ recovery: source.recovery,
553
+ recoveryPolicy: source.recoveryPolicy,
554
+ recent: source.recent,
555
+ definitionDigest: source.definitionDigest,
556
+ admissionDigest: source.admissionDigest,
557
+ stateDigest: source.stateDigest,
558
+ };
559
+ }
560
+
467
561
  function prSummary(sessionIds, prLinks) {
468
562
  const linked = [];
469
563
  for (const sessionId of Array.isArray(sessionIds)
@@ -501,20 +595,57 @@ function approvalSummary(source, state) {
501
595
  0,
502
596
  );
503
597
  }
598
+ if (source?.schema === "cc-dynamic-workflow-workbench-state/v1") {
599
+ count +=
600
+ asCount(source?.input?.pending) + asCount(source?.recovery?.terminal);
601
+ }
504
602
  const needsInput = state === "needs_input";
505
603
  return {
506
604
  pending: needsInput || state === "blocked" || count > 0,
507
605
  type: needsInput
508
606
  ? "input"
509
- : Array.isArray(source?.units) && count > 0
510
- ? "adjudication"
511
- : count > 0
512
- ? "approval"
513
- : null,
607
+ : source?.schema === "cc-dynamic-workflow-workbench-state/v1" && count > 0
608
+ ? "recovery"
609
+ : Array.isArray(source?.units) && count > 0
610
+ ? "adjudication"
611
+ : count > 0
612
+ ? "approval"
613
+ : null,
514
614
  count,
515
615
  };
516
616
  }
517
617
 
618
+ function messagingSummary(sessionIds, fabric) {
619
+ const linked = new Set(
620
+ (Array.isArray(sessionIds) ? sessionIds : [sessionIds]).filter(Boolean),
621
+ );
622
+ const endpoints = Array.isArray(fabric?.endpoints)
623
+ ? fabric.endpoints
624
+ .filter((endpoint) => linked.has(endpoint?.sessionId))
625
+ .map((endpoint) => ({
626
+ name: asText(endpoint?.name),
627
+ address: asText(endpoint?.address),
628
+ policy: ["accept", "hold", "refuse"].includes(endpoint?.policy)
629
+ ? endpoint.policy
630
+ : "refuse",
631
+ online: endpoint?.online === true,
632
+ idle: endpoint?.idle === true,
633
+ unread: asCount(endpoint?.unread),
634
+ held: asCount(endpoint?.held),
635
+ }))
636
+ .filter((endpoint) => endpoint.name && endpoint.address)
637
+ .sort((left, right) => left.name.localeCompare(right.name))
638
+ : [];
639
+ return {
640
+ authority: "cli",
641
+ registered: endpoints.length > 0,
642
+ revision: Number.isSafeInteger(fabric?.revision) ? fabric.revision : 0,
643
+ unread: endpoints.reduce((total, endpoint) => total + endpoint.unread, 0),
644
+ held: endpoints.reduce((total, endpoint) => total + endpoint.held, 0),
645
+ endpoints,
646
+ };
647
+ }
648
+
518
649
  function lastEventFor(source, state) {
519
650
  const at =
520
651
  toIso(source?.lastEvent?.at) ||
@@ -529,7 +660,11 @@ function lastEventFor(source, state) {
529
660
  };
530
661
  }
531
662
 
532
- function projectOne(kind, source, { artifacts, prLinks }) {
663
+ function projectOne(
664
+ kind,
665
+ source,
666
+ { artifacts, prLinks, sessionMessageFabric },
667
+ ) {
533
668
  let sourceId;
534
669
  if (kind === "remote") {
535
670
  const stateFile = asText(source?.stateFile);
@@ -552,7 +687,9 @@ function projectOne(kind, source, { artifacts, prLinks }) {
552
687
  if (kind === "local") state = "stopped";
553
688
  else if (kind === "team") state = mapTeamState(source);
554
689
  else if (kind === "workflow") state = mapWorkflowState(source);
555
- else if (kind === "remote") {
690
+ else if (kind === "dynamic_workflow") {
691
+ state = mapDynamicWorkflowState(source);
692
+ } else if (kind === "remote") {
556
693
  state = source?.invalid ? "failed" : source?.alive ? "working" : "stopped";
557
694
  } else state = mapLifecycleState(source);
558
695
 
@@ -583,7 +720,9 @@ function projectOne(kind, source, { artifacts, prLinks }) {
583
720
  ? `Team run ${sourceId}`
584
721
  : kind === "workflow"
585
722
  ? `Workflow ${sourceId}`
586
- : `${kind} ${sourceId}`),
723
+ : kind === "dynamic_workflow"
724
+ ? `Dynamic workflow ${source?.workflowId || sourceId}`
725
+ : `${kind} ${sourceId}`),
587
726
  capabilities: actions
588
727
  .filter((action) => action.available)
589
728
  .map((action) => action.id),
@@ -592,9 +731,14 @@ function projectOne(kind, source, { artifacts, prLinks }) {
592
731
  owner: ownerSummary(source, kind),
593
732
  environment: environmentSummary(source, kind),
594
733
  worktree: worktreeSummary(source),
595
- artifact: artifactSummary(linkedSessionIds, artifacts),
734
+ artifact:
735
+ kind === "dynamic_workflow"
736
+ ? { count: asCount(source?.artifacts?.count), latest: null }
737
+ : artifactSummary(linkedSessionIds, artifacts),
596
738
  approval: approvalSummary(source, state),
739
+ messaging: messagingSummary(linkedSessionIds, sessionMessageFabric),
597
740
  pr: prSummary(linkedSessionIds, prLinks),
741
+ workflow: dynamicWorkflowSummary(source),
598
742
  lastEvent: lastEventFor(source, state),
599
743
  };
600
744
  return { ...projected, revision: projectionRevision(projected) };
@@ -615,12 +759,14 @@ export function buildSessionProjection({
615
759
  remote = [],
616
760
  team = [],
617
761
  workflow = [],
762
+ dynamicWorkflow = [],
618
763
  artifacts = [],
619
764
  prLinks = {},
765
+ sessionMessageFabric = null,
620
766
  sourceErrors = {},
621
767
  generatedAt = new Date().toISOString(),
622
768
  } = {}) {
623
- const context = { artifacts, prLinks };
769
+ const context = { artifacts, prLinks, sessionMessageFabric };
624
770
  const sessions = [
625
771
  ...(Array.isArray(local) ? local : []).map((source) =>
626
772
  projectOne("local", source, context),
@@ -637,6 +783,9 @@ export function buildSessionProjection({
637
783
  ...(Array.isArray(workflow) ? workflow : []).map((source) =>
638
784
  projectOne("workflow", source, context),
639
785
  ),
786
+ ...(Array.isArray(dynamicWorkflow) ? dynamicWorkflow : []).map((source) =>
787
+ projectOne("dynamic_workflow", source, context),
788
+ ),
640
789
  ].sort((left, right) => {
641
790
  const priority = { needs_input: 0, blocked: 1, working: 2 };
642
791
  const rank = (item) => priority[item.state] ?? 3;
@@ -669,6 +818,16 @@ export function buildSessionProjection({
669
818
  Array.isArray(workflow) ? workflow.length : 0,
670
819
  sourceErrors.workflow,
671
820
  ),
821
+ dynamicWorkflow: sourceStatus(
822
+ Array.isArray(dynamicWorkflow) ? dynamicWorkflow.length : 0,
823
+ sourceErrors.dynamicWorkflow,
824
+ ),
825
+ sessionMessageFabric: sourceStatus(
826
+ Array.isArray(sessionMessageFabric?.endpoints)
827
+ ? sessionMessageFabric.endpoints.length
828
+ : 0,
829
+ sourceErrors.sessionMessageFabric,
830
+ ),
672
831
  };
673
832
  const revision = projectionRevision({
674
833
  schema: SESSION_PROJECTION_SCHEMA,
@@ -0,0 +1,155 @@
1
+ /** Bounded live-state retention for long-running agent conversations. */
2
+
3
+ import { createHash } from "node:crypto";
4
+
5
+ export const SESSION_RUNTIME_RETENTION_LIMITS = Object.freeze({
6
+ recentResults: 32,
7
+ retainedResultChars: 512,
8
+ markerHeadChars: 128,
9
+ markerTailChars: 128,
10
+ });
11
+
12
+ export const SESSION_RUNTIME_RELEASE_MARKER = "…[live result released:";
13
+ const BACKGROUND_RESULT_PREFIX = '[Background sub-agent "';
14
+
15
+ function normalizedLimit(value, fallback, minimum = 0) {
16
+ return Number.isFinite(value)
17
+ ? Math.max(minimum, Math.floor(value))
18
+ : fallback;
19
+ }
20
+
21
+ function resultContent(message) {
22
+ if (!message || typeof message.content !== "string") return null;
23
+ if (message.role === "tool") return message.content;
24
+ if (
25
+ message.role === "user" &&
26
+ message.content.startsWith(BACKGROUND_RESULT_PREFIX)
27
+ ) {
28
+ return message.content;
29
+ }
30
+ return null;
31
+ }
32
+
33
+ // V8 may represent `slice()` as a view that keeps the entire source string's
34
+ // backing store alive. Joining individual UTF-16 code units forces a small,
35
+ // independent flat string while preserving even unpaired surrogate units.
36
+ function detachedSlice(content, start, end) {
37
+ const length = Math.max(0, end - start);
38
+ const units = new Array(length);
39
+ for (let index = 0; index < length; index += 1) {
40
+ units[index] = content.charAt(start + index);
41
+ }
42
+ return units.join("");
43
+ }
44
+
45
+ function releaseProjection(content, options) {
46
+ const digest = createHash("sha256").update(content, "utf8").digest("hex");
47
+ const marker =
48
+ `${SESSION_RUNTIME_RELEASE_MARKER} ${content.length} chars; sha256:${digest}; ` +
49
+ "full evidence remains in the durable transcript]";
50
+ const maxChars = options.retainedResultChars;
51
+ if (marker.length >= maxChars) {
52
+ return { content: marker.slice(0, maxChars), digest };
53
+ }
54
+ const remaining = maxChars - marker.length - 2;
55
+ const headChars = Math.min(
56
+ options.markerHeadChars,
57
+ Math.max(0, Math.floor(remaining / 2)),
58
+ );
59
+ const tailChars = Math.min(
60
+ options.markerTailChars,
61
+ Math.max(0, remaining - headChars),
62
+ );
63
+ const head = detachedSlice(content, 0, headChars);
64
+ const tail =
65
+ tailChars > 0
66
+ ? detachedSlice(content, content.length - tailChars, content.length)
67
+ : "";
68
+ return {
69
+ content: `${head}\n${marker}\n${tail}`.slice(0, maxChars),
70
+ digest,
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Replace old live tool/subagent result bodies with a bounded head/tail,
76
+ * digest, and durable-transcript locator. The message and pairing structure is
77
+ * retained; only old result content is released. The returned array is new and
78
+ * the input is never mutated.
79
+ */
80
+ export function releaseOldLiveSessionResults(messages, configured = {}) {
81
+ if (!Array.isArray(messages)) {
82
+ return {
83
+ messages,
84
+ stats: {
85
+ strategy: "session-runtime-retention",
86
+ released: 0,
87
+ savedChars: 0,
88
+ recentResults: 0,
89
+ durableReferences: [],
90
+ },
91
+ };
92
+ }
93
+ const options = {
94
+ recentResults: normalizedLimit(
95
+ configured.recentResults,
96
+ SESSION_RUNTIME_RETENTION_LIMITS.recentResults,
97
+ ),
98
+ retainedResultChars: normalizedLimit(
99
+ configured.retainedResultChars,
100
+ SESSION_RUNTIME_RETENTION_LIMITS.retainedResultChars,
101
+ 256,
102
+ ),
103
+ markerHeadChars: normalizedLimit(
104
+ configured.markerHeadChars,
105
+ SESSION_RUNTIME_RETENTION_LIMITS.markerHeadChars,
106
+ ),
107
+ markerTailChars: normalizedLimit(
108
+ configured.markerTailChars,
109
+ SESSION_RUNTIME_RETENTION_LIMITS.markerTailChars,
110
+ ),
111
+ };
112
+ const resultIndexes = [];
113
+ for (let index = 0; index < messages.length; index += 1) {
114
+ if (resultContent(messages[index]) != null) resultIndexes.push(index);
115
+ }
116
+ const releaseCount = Math.max(
117
+ 0,
118
+ resultIndexes.length - options.recentResults,
119
+ );
120
+ const releaseIndexes = new Set(resultIndexes.slice(0, releaseCount));
121
+ let released = 0;
122
+ let savedChars = 0;
123
+ const durableReferences = [];
124
+ const output = messages.map((message, index) => {
125
+ if (!releaseIndexes.has(index)) return message;
126
+ const content = resultContent(message);
127
+ if (content.length <= options.retainedResultChars) {
128
+ return message;
129
+ }
130
+ const projection = releaseProjection(content, options);
131
+ released += 1;
132
+ savedChars += content.length - projection.content.length;
133
+ durableReferences.push({
134
+ messageIndex: index,
135
+ digest: `sha256:${projection.digest}`,
136
+ originalChars: content.length,
137
+ retainedChars: projection.content.length,
138
+ });
139
+ return { ...message, content: projection.content };
140
+ });
141
+ return {
142
+ messages: output,
143
+ stats: {
144
+ strategy: "session-runtime-retention",
145
+ released,
146
+ savedChars,
147
+ saved: savedChars,
148
+ recentResults: Math.min(options.recentResults, resultIndexes.length),
149
+ retainedResultChars: options.retainedResultChars,
150
+ originalMessages: messages.length,
151
+ compressedMessages: output.length,
152
+ durableReferences,
153
+ },
154
+ };
155
+ }
@@ -438,6 +438,34 @@ function readBooleanSetting(key, opts = {}) {
438
438
  return value;
439
439
  }
440
440
 
441
+ /**
442
+ * Read a string setting across the layered `.claude/settings.json` files.
443
+ * The closest layer wins and managed settings remain authoritative. Blank and
444
+ * non-string values are ignored so they cannot erase a valid lower layer.
445
+ *
446
+ * @param {string} key settings key or dotted path
447
+ * @param {object} [opts]
448
+ * @returns {string|undefined}
449
+ */
450
+ function readStringSetting(key, opts = {}) {
451
+ const cwd = opts.cwd || process.cwd();
452
+ const parts = String(key).split(".");
453
+ let value;
454
+ const absorb = (data) => {
455
+ let node = data;
456
+ for (const part of parts) {
457
+ node = node && typeof node === "object" ? node[part] : undefined;
458
+ }
459
+ if (typeof node === "string" && node.trim()) value = node.trim();
460
+ };
461
+ for (const file of settingsPaths(cwd, opts.settingsFile)) {
462
+ absorb(readSettingsFile(file, { onWarn: opts.onWarn }));
463
+ }
464
+ const managed = loadManagedSettings(opts);
465
+ if (managed.settings) absorb(managed.settings);
466
+ return value;
467
+ }
468
+
441
469
  /**
442
470
  * Read a string-array setting across the layered `.claude/settings.json` files
443
471
  * plus managed settings. Unlike {@link readBooleanSetting} (last-layer wins),
@@ -484,6 +512,7 @@ module.exports = {
484
512
  loadSettingsConfig,
485
513
  readSettingsFile,
486
514
  readBooleanSetting,
515
+ readStringSetting,
487
516
  readStringArraySetting,
488
517
  settingsPaths,
489
518
  managedSettingsPath,
@@ -185,6 +185,11 @@ import {
185
185
  createPromptInteractionSurface,
186
186
  mergeClipboardImageChips,
187
187
  } from "./prompt-interactions.js";
188
+ import {
189
+ isReadlineWordRuboutKey,
190
+ readlineWordRubout,
191
+ resolveReplKeybindingFlavor,
192
+ } from "./repl-keybindings.js";
188
193
  import { createSystemClipboardImageBinding } from "./clipboard-image.js";
189
194
  import {
190
195
  buildPermissionPrompt,
@@ -2760,15 +2765,11 @@ export async function runReplStartupBoundary(options, startupDependencies) {
2760
2765
  "CC_REPL_STARTUP_DEPENDENCY_INVALID",
2761
2766
  );
2762
2767
  }
2763
- const root = openBudgetRoot(
2764
- leaseSessionId,
2765
- options.sessionBudgetRoot,
2766
- {
2767
- persist: true,
2768
- signal: combineReplSignals(options.signal, leaseScope.lease.signal),
2769
- table: options.sessionBudgetRoot.table,
2770
- },
2771
- );
2768
+ const root = openBudgetRoot(leaseSessionId, options.sessionBudgetRoot, {
2769
+ persist: true,
2770
+ signal: combineReplSignals(options.signal, leaseScope.lease.signal),
2771
+ table: options.sessionBudgetRoot.table,
2772
+ });
2772
2773
  if (
2773
2774
  root?.enabled !== true ||
2774
2775
  !root.budget ||
@@ -2824,10 +2825,7 @@ export function startReplJsonlSession(
2824
2825
  ...meta,
2825
2826
  ...(observabilityScope != null ? { observabilityScope } : {}),
2826
2827
  });
2827
- if (
2828
- requireDurable &&
2829
- (typeof sessionId !== "string" || !sessionId)
2830
- ) {
2828
+ if (requireDurable && (typeof sessionId !== "string" || !sessionId)) {
2831
2829
  throw new Error("JSONL session creation returned no durable session id");
2832
2830
  }
2833
2831
  return sessionId || null;
@@ -3187,6 +3185,7 @@ async function startAgentReplInWorkspaceOwned(
3187
3185
  let _visionModel;
3188
3186
  let _promptInteractionConfig = {};
3189
3187
  let _persistPromptSuggestionsEnabled = null;
3188
+ let _keybindingFlavor = "classic";
3190
3189
  // Hard stream inactivity timeout override (config.llm.streamStallTimeoutMs,
3191
3190
  // ms): a stream silent that long is aborted + retried instead of hanging.
3192
3191
  // Unset → agent-core's 180s default (matches cc chat/ask). Set to 0 to
@@ -3218,6 +3217,23 @@ async function startAgentReplInWorkspaceOwned(
3218
3217
  } catch {
3219
3218
  /* optional — resolveVisionLlm falls back to DEFAULT_VISION_MODEL */
3220
3219
  }
3220
+ try {
3221
+ const { readStringSetting } = await import("../lib/settings-loader.cjs");
3222
+ const configuredFlavor = readStringSetting("keybindingFlavor", {
3223
+ cwd: process.cwd(),
3224
+ settingsFile: options.settingsFile || null,
3225
+ managedSettingsFile: options.managedSettingsFile || null,
3226
+ onWarn: (message) => logger.warn(message),
3227
+ });
3228
+ const resolvedFlavor = resolveReplKeybindingFlavor(configuredFlavor);
3229
+ _keybindingFlavor = resolvedFlavor.flavor;
3230
+ if (resolvedFlavor.error) {
3231
+ logger.warn(`settings: ${resolvedFlavor.error}; using classic`);
3232
+ }
3233
+ } catch (error) {
3234
+ if (error?.code === "CC_MANAGED_SETTINGS_INVALID") throw error;
3235
+ logger.warn(`settings: could not load keybindingFlavor (${error.message})`);
3236
+ }
3221
3237
  // Extra workspace roots (--add-dir): advertised in the system prompt and
3222
3238
  // spanned by search_files.
3223
3239
  const additionalDirectories = Array.isArray(options.additionalDirectories)
@@ -3815,6 +3831,8 @@ async function startAgentReplInWorkspaceOwned(
3815
3831
  agentSessionId:
3816
3832
  sessionId || `repl-${process.pid}-${Date.now().toString(36)}`,
3817
3833
  isText: false, // the REPL prints its own pairing lines below
3834
+ allowLan: options.remoteControlAllowLan === true,
3835
+ env: process.env,
3818
3836
  });
3819
3837
  _remoteApproval = {
3820
3838
  bridge: started.bridge,
@@ -5201,6 +5219,25 @@ async function startAgentReplInWorkspaceOwned(
5201
5219
  return;
5202
5220
  }
5203
5221
 
5222
+ // 1.875) The opt-in readline flavor makes Ctrl+W a whitespace-delimited
5223
+ // unix-word-rubout. Classic stays byte-identical and lets Node readline
5224
+ // own the chord; Vim NORMAL mode continues to use the existing engine.
5225
+ if (
5226
+ !_turnAbort &&
5227
+ (!_vimEnabled || !_vim) &&
5228
+ _keybindingFlavor === "readline" &&
5229
+ isReadlineWordRuboutKey(_str, k)
5230
+ ) {
5231
+ _consumeReadlineKeypress(key);
5232
+ const next = readlineWordRubout(rl.line, rl.cursor);
5233
+ if (next.changed) {
5234
+ rl.line = next.line;
5235
+ rl.cursor = next.cursor;
5236
+ rl._refreshLine?.();
5237
+ }
5238
+ return;
5239
+ }
5240
+
5204
5241
  // 2) Vim mode: modal editing on the current input line.
5205
5242
  if (_vimEnabled && !_turnAbort) {
5206
5243
  if (!_vim) {
@@ -5625,7 +5662,7 @@ async function startAgentReplInWorkspaceOwned(
5625
5662
  ` ${chalk.cyan("/voice")} Speech dictation — local-first STT (/voice hold|tap|off)`,
5626
5663
  );
5627
5664
  logger.log(
5628
- ` ${chalk.cyan("/output-style")} Response persona (/output-style <name|list>; explanatory/learning built-in)`,
5665
+ ` ${chalk.cyan("/output-style")} Response persona (/output-style <name|list>; concise/explanatory/learning built-in)`,
5629
5666
  );
5630
5667
  logger.log(
5631
5668
  ` ${chalk.cyan("/editor")} Edit a draft prompt in an external editor`,
@@ -14,15 +14,38 @@
14
14
  *
15
15
  * @returns {string} the prompt header (no styling, no trailing "Proceed?")
16
16
  */
17
+ export function visualizePermissionText(value) {
18
+ return String(value ?? "").replace(
19
+ /[\u0000-\u001f\u007f-\u009f\u00ad\u034f\u061c\u115f\u1160\u17b4\u17b5\u180b-\u180f\u200b-\u200f\u202a-\u202e\u2060-\u206f\u3164\ufeff\uffa0]/gu,
20
+ (character) => {
21
+ if (character === "\t") return "<TAB>";
22
+ if (character === "\n") return "<LF>";
23
+ if (character === "\r") return "<CR>";
24
+ return `<U+${character.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")}>`;
25
+ },
26
+ );
27
+ }
28
+
17
29
  export function buildPermissionPrompt({ tool, args, rule, reason } = {}) {
18
- const detail = args?.command
19
- ? ` ${args.command}`
20
- : args?.path
21
- ? ` ${args.path}`
22
- : "";
23
- if (rule) return `[Permission] rule "${rule}" asks before ${tool}:${detail}`;
24
- if (reason) return `[Permission] ${reason}`;
25
- return `[Permission] confirm ${tool}:${detail}`;
30
+ const visibleTool = visualizePermissionText(tool);
31
+ const command = typeof args?.command === "string" ? args.command : "";
32
+ const source = args?.path ?? args?.file_path ?? args?.source ?? "";
33
+ const destination = args?.destination ?? args?.new_path ?? args?.to ?? "";
34
+ const rawDetail = command
35
+ ? command
36
+ : source && destination
37
+ ? `${source} -> ${destination}`
38
+ : source || destination;
39
+ const detail = rawDetail ? ` ${visualizePermissionText(rawDetail)}` : "";
40
+ if (rule) {
41
+ return `[Permission] rule "${visualizePermissionText(rule)}" asks before ${visibleTool}:${detail}`;
42
+ }
43
+ if (reason) {
44
+ const reasonText = String(reason);
45
+ const missingTarget = rawDetail && !reasonText.includes(String(rawDetail));
46
+ return `[Permission] ${visualizePermissionText(reasonText)}${missingTarget ? `:${detail}` : ""}`;
47
+ }
48
+ return `[Permission] confirm ${visibleTool}:${detail}`;
26
49
  }
27
50
 
28
51
  /**