chainlesschain 0.162.188 → 0.162.193

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 (337) hide show
  1. package/README.md +61 -11
  2. package/bin/chainlesschain.js +7 -52
  3. package/completions/_cc +209 -0
  4. package/completions/cc.bash +18 -0
  5. package/completions/cc.fish +13 -0
  6. package/completions/cc.ps1 +226 -0
  7. package/package.json +10 -2
  8. package/src/assets/web-panel/assets/{AIOps-Brr1LVcE.js → AIOps-DBLkaTje.js} +1 -1
  9. package/src/assets/web-panel/assets/{ActionButton-DQU74DKG.js → ActionButton-BAy-Qebo.js} +1 -1
  10. package/src/assets/web-panel/assets/{Analytics-CYp9178y.js → Analytics-Dfb1Mlau.js} +3 -3
  11. package/src/assets/web-panel/assets/{AppLayout-DW4SCYsW.js → AppLayout-BbFkN8m0.js} +5 -5
  12. package/src/assets/web-panel/assets/{Artifacts-CYlD_ed1.js → Artifacts-kM4-cEEH.js} +1 -1
  13. package/src/assets/web-panel/assets/{Audit-CWl1rZOi.js → Audit-BSQfYWf3.js} +1 -1
  14. package/src/assets/web-panel/assets/{BackgroundAgents-BOR-LPsa.js → BackgroundAgents-CWDbI_fG.js} +1 -1
  15. package/src/assets/web-panel/assets/{Backup-DLpG7j1X.js → Backup-BxLPbq_Q.js} +1 -1
  16. package/src/assets/web-panel/assets/{BaseInput-B35K9wdr.js → BaseInput-DuIbdrp6.js} +1 -1
  17. package/src/assets/web-panel/assets/{Chat-CwUJb9gB.js → Chat-NEmjGahU.js} +5 -5
  18. package/src/assets/web-panel/assets/{ChatBubbleRenderer-1v6aMS1m.js → ChatBubbleRenderer-DfJEo-5_.js} +1 -1
  19. package/src/assets/web-panel/assets/{Checkbox-pi3-tPNW.js → Checkbox-CaoeG3Ns.js} +1 -1
  20. package/src/assets/web-panel/assets/{Codegen-FyNF35eL.js → Codegen-BFf_g3xY.js} +1 -1
  21. package/src/assets/web-panel/assets/{Col-tGt_JDEr.js → Col-CNOd8mdQ.js} +1 -1
  22. package/src/assets/web-panel/assets/{Community-CC7LonQX.js → Community-BhpDqz-i.js} +1 -1
  23. package/src/assets/web-panel/assets/{Compact-BGXrHHjE.js → Compact-CQ42T7Z6.js} +1 -1
  24. package/src/assets/web-panel/assets/{Compliance-DSW0TBZ8.js → Compliance-DI5PcLMN.js} +1 -1
  25. package/src/assets/web-panel/assets/{Cowork-Bhk7rbvE.js → Cowork-wYYZe0wR.js} +3 -3
  26. package/src/assets/web-panel/assets/{Cron-DxyiQ2NZ.js → Cron-Dlq03DD_.js} +2 -2
  27. package/src/assets/web-panel/assets/{Crosschain-B2ZkxHok.js → Crosschain-BzqS8PP3.js} +1 -1
  28. package/src/assets/web-panel/assets/{DID-yOJV99eJ.js → DID-It55Yem7.js} +2 -2
  29. package/src/assets/web-panel/assets/{Dashboard-CKsttz7D.js → Dashboard-9HkH6oxn.js} +2 -2
  30. package/src/assets/web-panel/assets/{Dropdown-CVFldXSL.js → Dropdown-00e2YWRB.js} +1 -1
  31. package/src/assets/web-panel/assets/{EmailListRenderer-Bufv638J.js → EmailListRenderer-By-ugRDL.js} +1 -1
  32. package/src/assets/web-panel/assets/{FamilyGuardDashboard-4ncjoIjL.js → FamilyGuardDashboard-C396yu5m.js} +1 -1
  33. package/src/assets/web-panel/assets/{Federation-DsknEDoX.js → Federation-BME5sbZY.js} +1 -1
  34. package/src/assets/web-panel/assets/{FormItemContext-Cqe5jWXA.js → FormItemContext-B4TEZCr-.js} +1 -1
  35. package/src/assets/web-panel/assets/{GenericCardRenderer-NAJaFKxc.js → GenericCardRenderer-_9CX9ieY.js} +1 -1
  36. package/src/assets/web-panel/assets/{Git-CszKQpnl.js → Git-BrS6WVSr.js} +2 -2
  37. package/src/assets/web-panel/assets/{Governance-BXGodXi6.js → Governance-BMdCWnKF.js} +1 -1
  38. package/src/assets/web-panel/assets/{Inference-CkoYuG2c.js → Inference-Bcp3vzcA.js} +1 -1
  39. package/src/assets/web-panel/assets/{KnowledgeGraph-DFlEr_T0.js → KnowledgeGraph-DlLuqGY5.js} +1 -1
  40. package/src/assets/web-panel/assets/{Logs-CVaENddA.js → Logs-D-W_6x09.js} +2 -2
  41. package/src/assets/web-panel/assets/MarkdownRenderer-DElGPxCZ.js +1 -0
  42. package/src/assets/web-panel/assets/{Marketplace-CDlLT0fw.js → Marketplace-Dzn2guvI.js} +1 -1
  43. package/src/assets/web-panel/assets/{McpTools-DdwOyszN.js → McpTools-uPict-KL.js} +6 -6
  44. package/src/assets/web-panel/assets/{Memory-DKQnkKuG.js → Memory-BCw43kOb.js} +2 -2
  45. package/src/assets/web-panel/assets/{MobileBridge-DGseqlzJ.js → MobileBridge-DmV8Wv7F.js} +1 -1
  46. package/src/assets/web-panel/assets/{MobileProjects-COBbEOlj.js → MobileProjects-C-HaCmSM.js} +1 -1
  47. package/src/assets/web-panel/assets/{Mtc-O61Vwyli.js → Mtc-C6jxJ34Y.js} +5 -5
  48. package/src/assets/web-panel/assets/{MtcAudit-Dw2SyasS.js → MtcAudit-Za8ExwhQ.js} +5 -5
  49. package/src/assets/web-panel/assets/{Multisig-hSu_l8kf.js → Multisig-KKDbuEgb.js} +3 -3
  50. package/src/assets/web-panel/assets/{NLProgramming-CX1Epurr.js → NLProgramming-Dj97zbCk.js} +1 -1
  51. package/src/assets/web-panel/assets/{Notes-R9xX8o8_.js → Notes-DBXvMraU.js} +4 -4
  52. package/src/assets/web-panel/assets/{NotificationSettings-jtSNLCuK.js → NotificationSettings-DOxITLYl.js} +1 -1
  53. package/src/assets/web-panel/assets/OrderTableRenderer-7DVjZwMM.js +1 -0
  54. package/src/assets/web-panel/assets/{Organization-Pu2WO-U3.js → Organization-D1i73mjb.js} +4 -4
  55. package/src/assets/web-panel/assets/{Overflow-BjnqUyFp.js → Overflow-kW6Q3rvg.js} +1 -1
  56. package/src/assets/web-panel/assets/{P2P-jjkvz44c.js → P2P-C-v_8p2v.js} +2 -2
  57. package/src/assets/web-panel/assets/PdhVaultBrowser-tUbbY64W.js +7 -0
  58. package/src/assets/web-panel/assets/{Permissions-D4yDpivd.js → Permissions-DkHxEZ58.js} +4 -4
  59. package/src/assets/web-panel/assets/{PersonalDataHub-0qsL6iH1.js → PersonalDataHub-DWuMPGrK.js} +5 -5
  60. package/src/assets/web-panel/assets/{Pipeline-Cx7Ybrk2.js → Pipeline-30IYXWWm.js} +1 -1
  61. package/src/assets/web-panel/assets/{Privacy-PbfR_M_V.js → Privacy-DZNQ4RrH.js} +1 -1
  62. package/src/assets/web-panel/assets/{ProjectInit-CyV6Gsub.js → ProjectInit-De2MCElf.js} +2 -2
  63. package/src/assets/web-panel/assets/{ProjectSettings-C7KZ2Wdk.js → ProjectSettings-5uHk9wsC.js} +2 -2
  64. package/src/assets/web-panel/assets/{Projects-DQDjO-yK.js → Projects-XjDfrFLb.js} +1 -1
  65. package/src/assets/web-panel/assets/{Providers-DyFVBBMX.js → Providers-Bgwj6gcE.js} +1 -1
  66. package/src/assets/web-panel/assets/{QrScannerModal-CzB1BC9_.js → QrScannerModal-gKql9umv.js} +1 -1
  67. package/src/assets/web-panel/assets/{QuickAsk-Bk636mC1.js → QuickAsk-BWvmwkh7.js} +1 -1
  68. package/src/assets/web-panel/assets/{Recommend-DoWxHIT3.js → Recommend-Uok4hZPd.js} +1 -1
  69. package/src/assets/web-panel/assets/{RemoteSession-oOVIv9wq.js → RemoteSession-DLJzTk9a.js} +3 -3
  70. package/src/assets/web-panel/assets/{Reputation-BucoReGG.js → Reputation-ZVwIPMSO.js} +1 -1
  71. package/src/assets/web-panel/assets/{Row-DzmOdJU7.js → Row-CN04HxWR.js} +1 -1
  72. package/src/assets/web-panel/assets/{RssFeed-C1tK7KGU.js → RssFeed-BdSrEG4g.js} +3 -3
  73. package/src/assets/web-panel/assets/{Search-CSnInOqk.js → Search-5PwVd0IR.js} +1 -1
  74. package/src/assets/web-panel/assets/{Security-dlejr15l.js → Security-DdBo4zjN.js} +3 -3
  75. package/src/assets/web-panel/assets/{Services-BioPZuNh.js → Services-D3letU7M.js} +2 -2
  76. package/src/assets/web-panel/assets/{Skeleton-DWMibwpC.js → Skeleton--Jb83f1v.js} +1 -1
  77. package/src/assets/web-panel/assets/{Skills-BAAnx1B2.js → Skills-Bg-CulHX.js} +1 -1
  78. package/src/assets/web-panel/assets/{Sla-jWNp4hNO.js → Sla-7QOa7S-X.js} +1 -1
  79. package/src/assets/web-panel/assets/{SpeechSettings-y5kqKha-.js → SpeechSettings-DQwppjRw.js} +1 -1
  80. package/src/assets/web-panel/assets/{SyncSettings-B9GNsc3e.js → SyncSettings-dNPQGL-s.js} +2 -2
  81. package/src/assets/web-panel/assets/{Tasks-BDBYKRen.js → Tasks-Ggs-Z48q.js} +1 -1
  82. package/src/assets/web-panel/assets/{Templates-DRiE5eaN.js → Templates-78TYHgRO.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tenant-BGlAvExF.js → Tenant-xHwwv9vO.js} +1 -1
  84. package/src/assets/web-panel/assets/{Terminal-B8uzrbNY.js → Terminal-BJXSJfm4.js} +2 -2
  85. package/src/assets/web-panel/assets/{TimelineRenderer-Df48iveY.js → TimelineRenderer-fLbjRhJw.js} +1 -1
  86. package/src/assets/web-panel/assets/{Tokens-CcmHndN6.js → Tokens-oMSBSBmB.js} +1 -1
  87. package/src/assets/web-panel/assets/{Trigger-DPkWxmQ2.js → Trigger-CfnY_wX_.js} +1 -1
  88. package/src/assets/web-panel/assets/{Trust-DTb5a5AV.js → Trust-AdyTgYKO.js} +1 -1
  89. package/src/assets/web-panel/assets/{UkeySign-CBmg5vch.js → UkeySign-C5K_81dS.js} +1 -1
  90. package/src/assets/web-panel/assets/{VideoEditing-B0mZrz4O.js → VideoEditing-vcGVDqki.js} +1 -1
  91. package/src/assets/web-panel/assets/{Wallet-Bxs7_mpd.js → Wallet-hhOc3hlY.js} +4 -4
  92. package/src/assets/web-panel/assets/{WebAuthn-C8x3cMxU.js → WebAuthn-CVloC11s.js} +3 -3
  93. package/src/assets/web-panel/assets/{WorkflowEditor-DPrNznrP.js → WorkflowEditor-CYeE32R5.js} +1 -1
  94. package/src/assets/web-panel/assets/{chat-D3bYWu7S.js → chat-CNROR5bN.js} +1 -1
  95. package/src/assets/web-panel/assets/{colors-DY-PwMu4.js → colors-Cjx-cnwU.js} +1 -1
  96. package/src/assets/web-panel/assets/{compact-item-LDk10Kw6.js → compact-item-DOIfelvD.js} +1 -1
  97. package/src/assets/web-panel/assets/{createContext-C-2MZnFq.js → createContext-DfA7UZ8u.js} +1 -1
  98. package/src/assets/web-panel/assets/devWarning-ChcCBGs7.js +1 -0
  99. package/src/assets/web-panel/assets/{hasIn-BQIBjcnB.js → hasIn-BMSCzcfM.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CQVb2dWp.js → index-5-HXgOX5.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BdXnYMCZ.js → index-AWg-0M1S.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Cx6D_dx2.js → index-B4iYzpkL.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-_HRO_cIu.js → index-B5Udeb_6.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DlRYqt3S.js → index-B7gf77CJ.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BrnRO9yE.js → index-BEMwBBHk.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-VCh5zNJo.js → index-BM1y_9hM.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BRI3ngNg.js → index-BUonmKSE.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-C3GNvExG.js → index-BbQ2eQ8H.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DSvo_bp0.js → index-BemJ2u_E.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-L6qixyLc.js → index-BolaOQxx.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BI4KgcYC.js → index-BxOk9vkG.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CY4KnaO9.js → index-By61ojUx.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-L3smcoQX.js → index-C2K9SNVX.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BX2b9Orc.js → index-C3L5gdiD.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Cz4b6Z_7.js → index-C7xn0Nub.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-COG61sRv.js → index-CAnvhwg6.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-C7FC8cP2.js → index-CEKMcOyU.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BN-xdSWZ.js → index-CNC5onm4.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DY2FIrmz.js → index-CVL27kXC.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CiTvBAr-.js → index-CVm1_i3t.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DhRt9cYJ.js → index-CdYBye8B.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-B5pgtZnY.js → index-ClNMrqEY.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-7xKu7Fns.js → index-Cs6l7uRu.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-D4K1weKc.js → index-CshQbilz.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-k7C_oDCO.js → index-Cyweh0Hy.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-D3Oq-DLL.js → index-DBpWXFed.js} +3 -3
  127. package/src/assets/web-panel/assets/{index-DYyLJPlF.js → index-DHtpHZAQ.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Dh-tkpKQ.js → index-DLmn0BoK.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-8JC9BJa1.js → index-DPAWBrMf.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Dd2Km97U.js → index-DjEsxO5h.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-KFZO_lcx.js → index-FBc_CJBd.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DTIZpPtG.js → index-Icdoqmzt.js} +1 -1
  133. package/src/assets/web-panel/assets/index-Q2IajL54.js +1 -0
  134. package/src/assets/web-panel/assets/index-bRkHgOMc.js +1 -0
  135. package/src/assets/web-panel/assets/{index-lmm9p-jm.js → index-dCd8cSUq.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-HasPt4-h.js → index-m2vG9gG_.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-CaslYch6.js → index-mTpHoEzr.js} +1 -1
  138. package/src/assets/web-panel/assets/{index-CbR6ROOa.js → index-ti_lnTWl.js} +1 -1
  139. package/src/assets/web-panel/assets/{initDefaultProps-zQPSHf2C.js → initDefaultProps-Bu8k7H1Y.js} +1 -1
  140. package/src/assets/web-panel/assets/{motion-CKCStGVk.js → motion-s3iVK41k.js} +1 -1
  141. package/src/assets/web-panel/assets/{move-BufVDGYF.js → move-B6B-E5Jz.js} +1 -1
  142. package/src/assets/web-panel/assets/{mtc-parser-DcaFxy5D.js → mtc-parser-BiYgTidA.js} +1 -1
  143. package/src/assets/web-panel/assets/{omit-EScpkGdo.js → omit-pU1RdUDA.js} +1 -1
  144. package/src/assets/web-panel/assets/{pickAttrs-72hG_qfT.js → pickAttrs-Cdoq_SeM.js} +1 -1
  145. package/src/assets/web-panel/assets/{placementArrow-CMFWiH20.js → placementArrow-DIuvAn2K.js} +1 -1
  146. package/src/assets/web-panel/assets/{responsiveObserve-DKQHS41p.js → responsiveObserve-8w16YR2D.js} +1 -1
  147. package/src/assets/web-panel/assets/{slide-QVAFHTIQ.js → slide-VZ01cZe3.js} +1 -1
  148. package/src/assets/web-panel/assets/{statusUtils-DIz38e2G.js → statusUtils-lh8YMN8Z.js} +1 -1
  149. package/src/assets/web-panel/assets/{styleChecker-zK5cyLby.js → styleChecker-CmDyreec.js} +1 -1
  150. package/src/assets/web-panel/assets/{useFlexGapSupport-DhZngk62.js → useFlexGapSupport-hiJWMU5y.js} +1 -1
  151. package/src/assets/web-panel/assets/{useFs-BvV2cvkg.js → useFs-Thnu-Iaj.js} +1 -1
  152. package/src/assets/web-panel/assets/{usePersonalDataHub-CRmxb9l3.js → usePersonalDataHub-LBdOxjwY.js} +1 -1
  153. package/src/assets/web-panel/assets/{vnode-CgQIbobP.js → vnode-Cg6lFY_X.js} +1 -1
  154. package/src/assets/web-panel/assets/{zoom-D4XrrO0R.js → zoom-DVfsR1YO.js} +1 -1
  155. package/src/assets/web-panel/index.html +1 -1
  156. package/src/cli-help.js +181 -0
  157. package/src/command-help-index.json +181 -0
  158. package/src/command-manifest.json +1107 -175
  159. package/src/command-surface-policy.js +197 -0
  160. package/src/commands/agent.js +98 -33
  161. package/src/commands/artifacts.js +400 -2
  162. package/src/commands/background-session.js +41 -3
  163. package/src/commands/checkpoint-managed.js +1059 -0
  164. package/src/commands/checkpoint-restore-recovery.js +1476 -0
  165. package/src/commands/checkpoint.js +950 -22
  166. package/src/commands/compact.js +101 -25
  167. package/src/commands/config.js +506 -20
  168. package/src/commands/doctor.js +4 -1
  169. package/src/commands/hub.js +1 -1
  170. package/src/commands/mcp.js +688 -24
  171. package/src/commands/pack.js +16 -2
  172. package/src/commands/plugin.js +20 -12
  173. package/src/commands/session-mcp-recovery.js +218 -0
  174. package/src/commands/session.js +470 -110
  175. package/src/commands/setup.js +36 -10
  176. package/src/commands/skill.js +181 -110
  177. package/src/commands/status.js +21 -5
  178. package/src/commands/team-distributed.js +3324 -0
  179. package/src/commands/team.js +1130 -74
  180. package/src/commands/update.js +68 -6
  181. package/src/constants.js +11 -0
  182. package/src/data/changelog.json +26 -0
  183. package/src/gateways/ws/action-protocol.js +10 -0
  184. package/src/gateways/ws/session-protocol.js +555 -27
  185. package/src/gateways/ws/ws-agent-handler.js +541 -14
  186. package/src/gateways/ws/ws-session-gateway.js +129 -22
  187. package/src/gateways/ws/ws-session-state.js +431 -0
  188. package/src/harness/background-task-manager.js +233 -36
  189. package/src/harness/jsonl-session-store.js +2551 -167
  190. package/src/harness/mcp-client.js +802 -61
  191. package/src/harness/prompt-compressor.js +227 -27
  192. package/src/harness/session-index.js +89 -38
  193. package/src/harness/session-list-index.js +254 -0
  194. package/src/harness/structured-handoff.js +410 -0
  195. package/src/lazy-dispatch.js +747 -84
  196. package/src/lib/__tests__/logger.test.js +50 -2
  197. package/src/lib/advisor-runtime.js +1047 -0
  198. package/src/lib/agent-core.js +2 -0
  199. package/src/lib/agent-sandbox.js +120 -26
  200. package/src/lib/agent-session-export.js +20 -0
  201. package/src/lib/agent-team/task-lease.js +271 -3
  202. package/src/lib/agent-team/team-adjudication.js +1501 -0
  203. package/src/lib/agent-team/team-budget.js +4 -1
  204. package/src/lib/agent-team/team-control-store.js +582 -0
  205. package/src/lib/agent-team/team-distributed-queue.js +5246 -0
  206. package/src/lib/agent-team/team-process-checkpoint.js +211 -0
  207. package/src/lib/agent-team/team-runner.js +543 -24
  208. package/src/lib/agent-team/team-worktree.js +1403 -95
  209. package/src/lib/artifact-store.js +131 -8
  210. package/src/lib/background-agent-supervisor.js +185 -13
  211. package/src/lib/background-interaction-journal.js +37 -9
  212. package/src/lib/background-launch-profile.js +1058 -0
  213. package/src/lib/checkpoint-restore-already-completed-controller.js +902 -0
  214. package/src/lib/checkpoint-restore-orchestrator.js +987 -0
  215. package/src/lib/checkpoint-restore-partial-rollback-controller.js +1953 -0
  216. package/src/lib/checkpoint-restore-recovery-controller.js +689 -0
  217. package/src/lib/checkpoint-restore-recovery.js +884 -0
  218. package/src/lib/checkpoint-restore-retention.js +126 -0
  219. package/src/lib/checkpoint-restore-saga.js +5079 -0
  220. package/src/lib/checkpoint-restore-session-recovery.js +1178 -0
  221. package/src/lib/checkpoint-restore-workspace-target-verifier.js +270 -0
  222. package/src/lib/checkpoint-store.js +1688 -97
  223. package/src/lib/checkpoint-timeline-authority.js +522 -0
  224. package/src/lib/checkpoint-timeline.js +642 -0
  225. package/src/lib/config-keys.js +18 -119
  226. package/src/lib/config-manager.js +446 -27
  227. package/src/lib/config-redaction.js +57 -0
  228. package/src/lib/config-schema.js +853 -0
  229. package/src/lib/cowork-mcp-tools.js +5 -0
  230. package/src/lib/cowork-task-runner.js +458 -63
  231. package/src/lib/delivery-coordinator.js +1234 -0
  232. package/src/lib/delivery-evidence.js +450 -0
  233. package/src/lib/doctor-checkup.js +199 -14
  234. package/src/lib/executable-path.js +34 -0
  235. package/src/lib/fatal-handler.js +16 -0
  236. package/src/lib/file-checkpoint.js +4909 -186
  237. package/src/lib/file-lines.js +125 -0
  238. package/src/lib/headless-config-command.js +16 -5
  239. package/src/lib/hook-runner.cjs +139 -38
  240. package/src/lib/hooks-v2-workspace-context.js +10 -0
  241. package/src/lib/impacted-gate-selector.js +424 -0
  242. package/src/lib/interaction-adapter.js +62 -0
  243. package/src/lib/jsonl-session-store.js +1 -35
  244. package/src/lib/logger.js +66 -14
  245. package/src/lib/managed-checkpoint-render.js +60 -0
  246. package/src/lib/managed-tool-checkpoint.js +194 -0
  247. package/src/lib/mcp-call-ledger-store.js +1069 -0
  248. package/src/lib/mcp-call-ledger.js +747 -0
  249. package/src/lib/mcp-client.js +5 -0
  250. package/src/lib/mcp-conflict-scheduler.js +468 -0
  251. package/src/lib/mcp-effect-contract.js +102 -0
  252. package/src/lib/mcp-headers-helper-trust.js +145 -0
  253. package/src/lib/mcp-headers-helper.js +616 -0
  254. package/src/lib/mcp-host-recovery-runtime.js +131 -0
  255. package/src/lib/mcp-ledger-recovery-admission.js +1065 -0
  256. package/src/lib/mcp-recovery-adjudication.js +443 -0
  257. package/src/lib/output-context.js +86 -0
  258. package/src/lib/packer/file-identity.js +170 -0
  259. package/src/lib/packer/index.js +3 -0
  260. package/src/lib/packer/native-update-state.js +277 -0
  261. package/src/lib/packer/pack-update-applier.js +1983 -136
  262. package/src/lib/packer/pack-update-checker.js +34 -0
  263. package/src/lib/packer/pack-update-downloader.js +875 -86
  264. package/src/lib/packer/pack-update-signature.js +86 -0
  265. package/src/lib/packer/pkg-config-generator.js +6 -0
  266. package/src/lib/paths.js +65 -10
  267. package/src/lib/plan-mode.js +831 -14
  268. package/src/lib/plan-persistence.js +540 -0
  269. package/src/lib/plugin-runtime/hooks.js +227 -69
  270. package/src/lib/plugin-runtime/plugin-options.js +189 -44
  271. package/src/lib/pr-automation-policy.js +146 -8
  272. package/src/lib/process-execution-broker/credential-agent.js +7 -0
  273. package/src/lib/process-execution-broker/index.js +491 -13
  274. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +28 -1
  275. package/src/lib/process-execution-broker/linux-generic-bwrap.js +28 -4
  276. package/src/lib/process-execution-broker/platform-sandbox.js +92 -70
  277. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  278. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  279. package/src/lib/process-execution-broker/windows-sandbox.cs +284 -19
  280. package/src/lib/process-execution-broker/workspace-transaction.js +4459 -0
  281. package/src/lib/project-instructions.js +165 -29
  282. package/src/lib/project-mcp-trust.js +67 -0
  283. package/src/lib/public-ide-capability-manifest.js +272 -0
  284. package/src/lib/public-ide-capability-validation.js +351 -0
  285. package/src/lib/secret-store.js +267 -43
  286. package/src/lib/secure-file-identity.js +433 -0
  287. package/src/lib/secure-fs.js +1089 -0
  288. package/src/lib/security-audit.js +58 -0
  289. package/src/lib/service-manager.js +34 -13
  290. package/src/lib/session-budget-runtime.js +1452 -0
  291. package/src/lib/session-host-snapshot.js +388 -0
  292. package/src/lib/session-message-provenance.js +429 -0
  293. package/src/lib/session-projection.js +804 -0
  294. package/src/lib/session-resource-budget.js +1495 -0
  295. package/src/lib/settings-hooks.cjs +138 -22
  296. package/src/lib/settings-loader.cjs +25 -2
  297. package/src/lib/side-effect-ledger-store.js +45 -23
  298. package/src/lib/skill-execution-identity.js +217 -0
  299. package/src/lib/skill-loader.js +299 -18
  300. package/src/lib/sub-agent-context.js +236 -28
  301. package/src/lib/sub-agent-registry.js +5 -0
  302. package/src/lib/subagent-contract.js +94 -0
  303. package/src/lib/todo-manager.js +185 -18
  304. package/src/lib/todo-persistence.js +417 -0
  305. package/src/lib/turn-binding-store.js +41 -23
  306. package/src/lib/turn-binding.js +160 -2
  307. package/src/lib/with-file-lock.js +165 -24
  308. package/src/lib/ws-chat-handler.js +21 -0
  309. package/src/program-base.js +18 -0
  310. package/src/repl/advisor-command.js +103 -0
  311. package/src/repl/agent-repl.js +2175 -146
  312. package/src/repl/btw-command.js +93 -10
  313. package/src/repl/clipboard-image.js +119 -0
  314. package/src/repl/config-summary.js +64 -108
  315. package/src/repl/prompt-editor.js +233 -0
  316. package/src/repl/prompt-interactions.js +344 -0
  317. package/src/repl/prompt-stash.js +354 -0
  318. package/src/repl/prompt-suggestions.js +312 -0
  319. package/src/repl/repl-keybindings.js +227 -0
  320. package/src/repl/session-recap.js +217 -0
  321. package/src/repl/slash-command-registry.js +22 -0
  322. package/src/repl/terminal-layout.js +88 -0
  323. package/src/runtime/agent-core.js +1630 -447
  324. package/src/runtime/coding-agent-contract-shared.cjs +13 -1
  325. package/src/runtime/coding-agent-managed-tool-policy.cjs +7 -2
  326. package/src/runtime/diagnostics.js +32 -13
  327. package/src/runtime/headless-runner.js +310 -118
  328. package/src/runtime/headless-stream.js +356 -95
  329. package/src/runtime/mcp-config.js +148 -14
  330. package/src/runtime/policies/agent-policy.js +14 -0
  331. package/src/runtime/status-diagnostics-lite.js +137 -0
  332. package/src/assets/web-panel/assets/MarkdownRenderer-7iWGwZ-r.js +0 -1
  333. package/src/assets/web-panel/assets/OrderTableRenderer-BU2Yqq5H.js +0 -1
  334. package/src/assets/web-panel/assets/PdhVaultBrowser-69ca_WeR.js +0 -7
  335. package/src/assets/web-panel/assets/devWarning-B4dXIJqD.js +0 -1
  336. package/src/assets/web-panel/assets/index-C-C7DaG6.js +0 -1
  337. package/src/assets/web-panel/assets/index-DkfWzWtd.js +0 -1
@@ -0,0 +1,233 @@
1
+ /** External-editor prompt editing for the agent REPL. */
2
+ import {
3
+ mkdtempSync,
4
+ lstatSync,
5
+ readFileSync,
6
+ rmSync,
7
+ statSync,
8
+ writeFileSync,
9
+ } from "node:fs";
10
+ import { tmpdir } from "node:os";
11
+ import { join } from "node:path";
12
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
13
+ import {
14
+ ensurePrivateDirectory,
15
+ ensurePrivateFile,
16
+ PRIVATE_FILE_MODE,
17
+ } from "../lib/secure-fs.js";
18
+
19
+ export const MAX_EDITED_PROMPT_BYTES = 1024 * 1024;
20
+
21
+ /** Parse a conventional EDITOR command without invoking a shell. */
22
+ export function parsePromptEditorCommand(value) {
23
+ const input = String(value || "").trim();
24
+ if (!input) return [];
25
+ const tokens = [];
26
+ let token = "";
27
+ let quote = null;
28
+ let started = false;
29
+ for (let index = 0; index < input.length; index += 1) {
30
+ const char = input[index];
31
+ if (quote) {
32
+ if (char === quote) {
33
+ quote = null;
34
+ started = true;
35
+ } else if (char === "\\" && input[index + 1] === quote) {
36
+ token += quote;
37
+ index += 1;
38
+ } else {
39
+ token += char;
40
+ }
41
+ continue;
42
+ }
43
+ if (char === '"' || char === "'") {
44
+ quote = char;
45
+ started = true;
46
+ continue;
47
+ }
48
+ if (/\s/.test(char)) {
49
+ if (started || token) tokens.push(token);
50
+ token = "";
51
+ started = false;
52
+ continue;
53
+ }
54
+ if (
55
+ char === "\\" &&
56
+ (input[index + 1] === '"' || input[index + 1] === "'")
57
+ ) {
58
+ token += input[index + 1];
59
+ index += 1;
60
+ started = true;
61
+ continue;
62
+ }
63
+ token += char;
64
+ started = true;
65
+ }
66
+ if (quote) throw new Error("EDITOR contains an unterminated quote");
67
+ if (started || token) tokens.push(token);
68
+ return tokens;
69
+ }
70
+
71
+ export function resolvePromptEditor(
72
+ env = process.env,
73
+ platform = process.platform,
74
+ ) {
75
+ if (String(env.EDITOR || "").trim()) {
76
+ return { command: String(env.EDITOR), source: "EDITOR" };
77
+ }
78
+ if (String(env.VISUAL || "").trim()) {
79
+ return { command: String(env.VISUAL), source: "VISUAL" };
80
+ }
81
+ return {
82
+ command: platform === "win32" ? "notepad" : "vi",
83
+ source: "platform-default",
84
+ };
85
+ }
86
+
87
+ function normalizeEditedPrompt(value) {
88
+ return String(value || "")
89
+ .replace(/^\uFEFF/, "")
90
+ .replace(/\r\n/g, "\n")
91
+ .replace(/\r/g, "\n")
92
+ .replace(/\n$/, "");
93
+ }
94
+
95
+ const defaultDeps = {
96
+ mkdtempSync,
97
+ lstatSync,
98
+ readFileSync,
99
+ rmSync,
100
+ statSync,
101
+ writeFileSync,
102
+ ensurePrivateDirectory,
103
+ ensurePrivateFile,
104
+ spawnSync: (...args) => executionBroker.spawnSync(...args),
105
+ tmpdir,
106
+ };
107
+
108
+ /**
109
+ * Open the current prompt in $EDITOR and return the edited text. The editor is
110
+ * always executed as argv (`shell:false`); prompt contents never enter argv or
111
+ * the environment. Temporary files are owner-only and removed in `finally`.
112
+ */
113
+ export function editPromptInExternalEditor(prompt, options = {}) {
114
+ const deps = { ...defaultDeps, ...(options.deps || {}) };
115
+ const resolved = Object.prototype.hasOwnProperty.call(options, "editor")
116
+ ? { command: options.editor, source: "explicit" }
117
+ : resolvePromptEditor(
118
+ options.env || process.env,
119
+ options.platform || process.platform,
120
+ );
121
+ const [executable, ...editorArgs] = parsePromptEditorCommand(
122
+ resolved.command,
123
+ );
124
+ if (!executable) {
125
+ return {
126
+ ok: false,
127
+ capability: "unavailable",
128
+ reason: "No external editor command is configured.",
129
+ };
130
+ }
131
+
132
+ let tempDirectory = null;
133
+ try {
134
+ tempDirectory = deps.mkdtempSync(join(deps.tmpdir(), "cc-prompt-"));
135
+ deps.ensurePrivateDirectory(tempDirectory, {
136
+ applyWindowsAcl: true,
137
+ failIfUnavailable: true,
138
+ });
139
+ const filePath = join(tempDirectory, "prompt.md");
140
+ deps.writeFileSync(filePath, String(prompt || ""), {
141
+ encoding: "utf8",
142
+ mode: PRIVATE_FILE_MODE,
143
+ });
144
+ deps.ensurePrivateFile(filePath, {
145
+ applyWindowsAcl: true,
146
+ failIfUnavailable: true,
147
+ });
148
+
149
+ let result;
150
+ try {
151
+ result = deps.spawnSync(executable, [...editorArgs, filePath], {
152
+ stdio: "inherit",
153
+ windowsHide: false,
154
+ origin: "repl:prompt-editor",
155
+ policy: "allow",
156
+ scope: "editor",
157
+ shell: false,
158
+ });
159
+ } catch (error) {
160
+ return {
161
+ ok: false,
162
+ capability: "unavailable",
163
+ editor: executable,
164
+ reason: `Could not launch ${executable}: ${error.message}`,
165
+ };
166
+ }
167
+ if (!result || result.error || result.signal || result.status !== 0) {
168
+ return {
169
+ ok: false,
170
+ capability: !result || result?.error ? "unavailable" : "failed",
171
+ editor: executable,
172
+ reason:
173
+ result?.error?.message ||
174
+ (result?.signal
175
+ ? `${executable} was terminated by ${result.signal}`
176
+ : null) ||
177
+ `${executable} exited with status ${result?.status}`,
178
+ };
179
+ }
180
+
181
+ const editedStat = deps.lstatSync(filePath);
182
+ if (editedStat.isSymbolicLink()) {
183
+ return {
184
+ ok: false,
185
+ capability: "failed",
186
+ editor: executable,
187
+ reason: "Editor replaced the prompt file with a symbolic link.",
188
+ };
189
+ }
190
+ deps.ensurePrivateFile(filePath, {
191
+ applyWindowsAcl: true,
192
+ failIfUnavailable: true,
193
+ });
194
+
195
+ const byteLength = Number(deps.statSync(filePath).size) || 0;
196
+ const maxBytes = Math.max(
197
+ 1,
198
+ Number(options.maxBytes) || MAX_EDITED_PROMPT_BYTES,
199
+ );
200
+ if (byteLength > maxBytes) {
201
+ return {
202
+ ok: false,
203
+ capability: "failed",
204
+ editor: executable,
205
+ reason: `Edited prompt exceeds ${maxBytes} bytes.`,
206
+ };
207
+ }
208
+ const content = normalizeEditedPrompt(deps.readFileSync(filePath, "utf8"));
209
+ return {
210
+ ok: true,
211
+ capability: "available",
212
+ editor: executable,
213
+ source: resolved.source,
214
+ content,
215
+ changed: content !== normalizeEditedPrompt(prompt),
216
+ };
217
+ } catch (error) {
218
+ return {
219
+ ok: false,
220
+ capability: "unavailable",
221
+ editor: executable,
222
+ reason: `External prompt editor unavailable: ${error.message}`,
223
+ };
224
+ } finally {
225
+ if (tempDirectory) {
226
+ try {
227
+ deps.rmSync(tempDirectory, { recursive: true, force: true });
228
+ } catch {
229
+ // Best-effort cleanup. The directory and file are owner-only.
230
+ }
231
+ }
232
+ }
233
+ }
@@ -0,0 +1,344 @@
1
+ /**
2
+ * Small integration controller for the REPL's prompt-side interaction tools.
3
+ * It keeps slash/key dispatch outside the large agent driver and exposes a
4
+ * narrow seam that readline, IDE hosts, and tests can share.
5
+ */
6
+ import { buildSessionRecap, renderSessionRecap } from "./session-recap.js";
7
+ import { PromptStash, runPromptStashCommand } from "./prompt-stash.js";
8
+ import { editPromptInExternalEditor } from "./prompt-editor.js";
9
+ import {
10
+ PromptSuggestionController,
11
+ renderPromptSuggestions,
12
+ resolvePromptSuggestionsEnabled,
13
+ runPromptSuggestionsCommand,
14
+ } from "./prompt-suggestions.js";
15
+ import {
16
+ matchReplKeybinding,
17
+ validateReplKeybindings,
18
+ } from "./repl-keybindings.js";
19
+ import {
20
+ detectClipboardImageCapability,
21
+ readClipboardImageChip,
22
+ } from "./clipboard-image.js";
23
+ import { layoutTerminalText } from "./terminal-layout.js";
24
+
25
+ function commandArgs(line, command) {
26
+ const text = String(line || "");
27
+ if (text === command) return "";
28
+ return text.startsWith(`${command} `) ? text.slice(command.length + 1) : null;
29
+ }
30
+
31
+ function safeErrorText(value) {
32
+ return String(value || "Interaction failed")
33
+ .split(/\r?\n/)
34
+ .map((line) => line.replace(/[\p{Cc}\p{Cf}]+/gu, " ").trimEnd())
35
+ .join("\n");
36
+ }
37
+
38
+ export const PROMPT_INTERACTION_SLASH_COMMANDS = Object.freeze([
39
+ Object.freeze({
40
+ name: "/recap",
41
+ description: "Show a lightweight recap from the session index",
42
+ }),
43
+ Object.freeze({
44
+ name: "/stash",
45
+ description: "Stash/list/pop/clear draft prompts",
46
+ }),
47
+ Object.freeze({
48
+ name: "/editor",
49
+ description: "Edit a draft prompt in an external editor",
50
+ }),
51
+ Object.freeze({
52
+ name: "/suggestions",
53
+ description: "Control background prompt suggestions",
54
+ }),
55
+ Object.freeze({
56
+ name: "/paste-image",
57
+ description: "Attach a clipboard image when the terminal host supports it",
58
+ }),
59
+ ]);
60
+
61
+ /** Register the interaction surface in the shared slash-command registry. */
62
+ export function registerPromptInteractionCommands(registry, controller) {
63
+ if (typeof registry?.register !== "function") {
64
+ throw new TypeError("a slash command registry is required");
65
+ }
66
+ if (typeof controller?.handleSlash !== "function") {
67
+ throw new TypeError("a prompt interaction controller is required");
68
+ }
69
+ for (const command of PROMPT_INTERACTION_SLASH_COMMANDS) {
70
+ registry.register(command.name, {
71
+ description: command.description,
72
+ handler: (args) => {
73
+ const suffix = String(args || "").trim();
74
+ return controller.handleSlash(
75
+ `${command.name}${suffix ? ` ${suffix}` : ""}`,
76
+ );
77
+ },
78
+ });
79
+ }
80
+ return PROMPT_INTERACTION_SLASH_COMMANDS.map((command) => command.name);
81
+ }
82
+
83
+ export class PromptInteractionController {
84
+ constructor(options = {}) {
85
+ this.readline = options.readline || null;
86
+ this.write =
87
+ options.write || ((text) => process.stdout.write(String(text)));
88
+ this.writeError =
89
+ options.writeError || ((text) => process.stderr.write(String(text)));
90
+ this.refresh =
91
+ options.refresh ||
92
+ (() => {
93
+ this.readline?._refreshLine?.();
94
+ });
95
+ this.getSessionId =
96
+ typeof options.getSessionId === "function"
97
+ ? options.getSessionId
98
+ : () => options.sessionId || null;
99
+ this.screenReader = options.screenReader === true;
100
+ this.getColumns =
101
+ typeof options.getColumns === "function"
102
+ ? options.getColumns
103
+ : () => this.readline?.output?.columns || process.stdout.columns || 80;
104
+ this.stash = options.stash || new PromptStash(options.stashOptions);
105
+ this.editPrompt = options.editPrompt || editPromptInExternalEditor;
106
+ this.buildRecap = options.buildRecap || buildSessionRecap;
107
+ this.renderRecap = options.renderRecap || renderSessionRecap;
108
+ this.persistSuggestionEnabled = options.persistSuggestionEnabled;
109
+ this.clipboardBinding = options.clipboardBinding || null;
110
+ this.clipboardImageChips = [];
111
+
112
+ const validated = validateReplKeybindings(options.keybindings || {});
113
+ this.keybindingDiagnostics = validated.errors.slice();
114
+ this.keybindings = validated.valid
115
+ ? validated
116
+ : validateReplKeybindings({});
117
+
118
+ const enabled = resolvePromptSuggestionsEnabled({
119
+ config: options.config || {},
120
+ env: options.env || process.env,
121
+ });
122
+ this.suggestions =
123
+ options.suggestionController ||
124
+ new PromptSuggestionController({
125
+ enabled,
126
+ generate: options.generateSuggestions,
127
+ debounceMs: options.suggestionDebounceMs ?? 120,
128
+ onUpdate: (suggestions) => this._showSuggestionUpdate(suggestions),
129
+ });
130
+ }
131
+
132
+ _line() {
133
+ return String(this.readline?.line || "");
134
+ }
135
+
136
+ _replaceLine(value) {
137
+ if (!this.readline) return false;
138
+ const text = String(value ?? "");
139
+ this.readline.line = text;
140
+ this.readline.cursor = text.length;
141
+ this.refresh();
142
+ return true;
143
+ }
144
+
145
+ _print(message, { error = false, refresh = false } = {}) {
146
+ if (message) {
147
+ const rawContent = error ? safeErrorText(message) : String(message);
148
+ const content = layoutTerminalText(rawContent, {
149
+ columns: this.getColumns(),
150
+ screenReader: this.screenReader,
151
+ });
152
+ const output = `${content.replace(/\n?$/, "\n")}`;
153
+ (error ? this.writeError : this.write)(output);
154
+ }
155
+ if (refresh) this.refresh();
156
+ }
157
+
158
+ _showSuggestionUpdate(suggestions) {
159
+ if (this.screenReader || !suggestions.length) return;
160
+ this._print(`\n${renderPromptSuggestions(suggestions)}`, { refresh: true });
161
+ }
162
+
163
+ diagnostics() {
164
+ return {
165
+ keybindingErrors: this.keybindingDiagnostics.slice(),
166
+ clipboardImage: detectClipboardImageCapability(this.clipboardBinding),
167
+ suggestions: this.suggestions.status(),
168
+ };
169
+ }
170
+
171
+ /** Returns `{ handled }`; popped/edited prompts stay editable, never submit. */
172
+ async handleSlash(line) {
173
+ try {
174
+ return await this._handleSlash(line);
175
+ } catch (error) {
176
+ const message = `Prompt interaction failed: ${safeErrorText(error.message)}`;
177
+ this._print(message, { error: true });
178
+ return { handled: true, ok: false, action: "error", message };
179
+ }
180
+ }
181
+
182
+ async _handleSlash(line) {
183
+ const recapArgs = commandArgs(line, "/recap");
184
+ if (recapArgs !== null) {
185
+ const sessionId = recapArgs.trim() || this.getSessionId();
186
+ const recap = this.buildRecap(sessionId || "");
187
+ this._print(this.renderRecap(recap));
188
+ return { handled: true, action: "recap", recap };
189
+ }
190
+
191
+ const stashArgs = commandArgs(line, "/stash");
192
+ if (stashArgs !== null) {
193
+ const result = runPromptStashCommand(stashArgs, { stash: this.stash });
194
+ if (result.prompt != null) this._replaceLine(result.prompt);
195
+ this._print(result.message, { error: !result.ok });
196
+ return { handled: true, ...result };
197
+ }
198
+
199
+ let editorArgs = commandArgs(line, "/editor");
200
+ if (editorArgs === null) editorArgs = commandArgs(line, "/edit-prompt");
201
+ if (editorArgs !== null) {
202
+ const seed = editorArgs || this._line();
203
+ const result = this.editPrompt(seed);
204
+ if (result.ok) {
205
+ this._replaceLine(result.content);
206
+ this._print(
207
+ result.changed
208
+ ? "Edited prompt restored to the input buffer."
209
+ : "Editor closed; prompt was unchanged.",
210
+ );
211
+ } else {
212
+ this._print(result.reason, { error: true });
213
+ }
214
+ return { handled: true, action: "editor", ...result };
215
+ }
216
+
217
+ const suggestionArgs = commandArgs(line, "/suggestions");
218
+ if (suggestionArgs !== null) {
219
+ const result = runPromptSuggestionsCommand(suggestionArgs, {
220
+ controller: this.suggestions,
221
+ persistEnabled: this.persistSuggestionEnabled,
222
+ context: optionsContext(this.getSessionId()),
223
+ });
224
+ this._print(result.message, { error: !result.ok });
225
+ return { handled: true, ...result };
226
+ }
227
+
228
+ const imageArgs = commandArgs(line, "/paste-image");
229
+ if (imageArgs !== null) {
230
+ if (imageArgs.trim()) {
231
+ const result = {
232
+ ok: false,
233
+ reason: "Usage: /paste-image (the command takes no arguments)",
234
+ };
235
+ this._print(result.reason, { error: true });
236
+ return { handled: true, action: "paste-image", ...result };
237
+ }
238
+ const result = await readClipboardImageChip(this.clipboardBinding);
239
+ if (result.ok) {
240
+ this.clipboardImageChips.push(result.chip);
241
+ this._print(
242
+ `Image attached from clipboard (${result.mediaType}, ${result.bytes} bytes).`,
243
+ );
244
+ } else {
245
+ this._print(result.reason, { error: true });
246
+ }
247
+ return { handled: true, action: "paste-image", ...result };
248
+ }
249
+
250
+ return { handled: false };
251
+ }
252
+
253
+ /** Handle only declared custom chords. Returns true when consumed. */
254
+ handleKeypress(input, key) {
255
+ try {
256
+ return this._handleKeypress(input, key);
257
+ } catch (error) {
258
+ this._print(
259
+ `Prompt interaction failed: ${safeErrorText(error.message)}`,
260
+ {
261
+ error: true,
262
+ refresh: true,
263
+ },
264
+ );
265
+ return true;
266
+ }
267
+ }
268
+
269
+ _handleKeypress(input, key) {
270
+ const action = matchReplKeybinding(this.keybindings, input, key);
271
+ if (!action) return false;
272
+ if (action === "prompt.edit") {
273
+ const result = this.editPrompt(this._line());
274
+ if (result.ok) this._replaceLine(result.content);
275
+ else this._print(result.reason, { error: true, refresh: true });
276
+ return true;
277
+ }
278
+ if (action === "prompt.stash") {
279
+ const current = this._line();
280
+ if (!current.trim()) {
281
+ this._print("Nothing to stash.", { error: true, refresh: true });
282
+ return true;
283
+ }
284
+ const result = runPromptStashCommand("", {
285
+ stash: this.stash,
286
+ currentPrompt: current,
287
+ });
288
+ this._replaceLine("");
289
+ this._print(result.message, { refresh: true });
290
+ return true;
291
+ }
292
+ if (action === "prompt.pop") {
293
+ const result = runPromptStashCommand("pop", { stash: this.stash });
294
+ if (result.prompt != null) this._replaceLine(result.prompt);
295
+ this._print(result.message, { error: !result.ok, refresh: true });
296
+ return true;
297
+ }
298
+ if (action === "session.recap") {
299
+ const recap = this.buildRecap(this.getSessionId() || "");
300
+ this._print(this.renderRecap(recap), { refresh: true });
301
+ return true;
302
+ }
303
+ if (action === "suggestions.toggle") {
304
+ const enabled = !this.suggestions.status().enabled;
305
+ try {
306
+ this.persistSuggestionEnabled?.(enabled);
307
+ } catch (error) {
308
+ this._print(`Could not update prompt suggestions: ${error.message}`, {
309
+ error: true,
310
+ refresh: true,
311
+ });
312
+ return true;
313
+ }
314
+ this.suggestions.setEnabled(enabled);
315
+ this._print(`Prompt suggestions ${enabled ? "enabled" : "disabled"}.`, {
316
+ refresh: true,
317
+ });
318
+ return true;
319
+ }
320
+ return false;
321
+ }
322
+
323
+ scheduleSuggestions(context = {}) {
324
+ return this.suggestions.schedule({
325
+ ...context,
326
+ sessionId: context.sessionId || this.getSessionId(),
327
+ });
328
+ }
329
+
330
+ takeClipboardImageChips() {
331
+ const chips = this.clipboardImageChips.slice();
332
+ this.clipboardImageChips.length = 0;
333
+ return chips;
334
+ }
335
+
336
+ dispose() {
337
+ this.suggestions.dispose();
338
+ this.clipboardImageChips.length = 0;
339
+ }
340
+ }
341
+
342
+ function optionsContext(sessionId) {
343
+ return { sessionId: sessionId || null };
344
+ }