chainlesschain 0.162.162 → 0.162.164

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 (237) hide show
  1. package/package.json +3 -1
  2. package/src/assets/web-panel/assets/{AIOps-ClI2ALgv.js → AIOps-BqRkaHGb.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-BDjRcJaK.js → ActionButton-DWO7OZLC.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DikSRsaT.js → Analytics-C5oaVezM.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-9mLhMFmz.js → AppLayout-CsUESDoZ.js} +3 -3
  6. package/src/assets/web-panel/assets/{Artifacts-BSr88BrH.js → Artifacts-Dragqu5k.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-CdvyimOF.js → Audit-CQsaHctY.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-D3_hCedh.js → BackgroundAgents-DdG1jNSM.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-Cyvv9RHf.js → Backup-DN6sjK4z.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-BZM14kt8.js → BaseInput-Cxm_ZTCl.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-DrQSokVz.js → Chat-DVXGmA56.js} +6 -6
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-HwJR-C6B.js → ChatBubbleRenderer-BdaCL_iE.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-bFLYeWMV.js → Checkbox-DEc4vD_A.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-7mN7xJXT.js → Codegen-CKiTcv36.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-DAB5ZWm7.js → Col-Br9UUNN0.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-B_1TymaK.js → Community-NeUH_70T.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-Bq1uSWLJ.js → Compact-BqR-z2Df.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-CyiE1jEe.js → Compliance-DcWB_SgZ.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-Cpk0D7vm.js → Cowork-BfhgcudF.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-d_Lv3rdB.js → Cron-LaU29LgD.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-DMqhHjMR.js → Crosschain-B2ZB9uwW.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-Br-oPuBw.js → DID-BuHl38A2.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-CfLW_RaP.js → Dashboard-m627yqvZ.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-DZnTOExV.js → Dropdown-C7bxF8F5.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-DHIUHDv1.js → EmailListRenderer-DPLPQzLp.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Bw3t3myu.js → FamilyGuardDashboard-cOiH6ike.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-D9cpQPAY.js → Federation-Bvkzg88z.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-Jdczr9Mr.js → FormItemContext-BTsiA7h_.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-BT8ZMpC5.js → GenericCardRenderer-BGnVE5qu.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-DjARip2b.js → Git-DS_j6r25.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-BgWbSRcj.js → Governance-CKRG3Rsl.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-CfouJciM.js → Inference-DW8INoNQ.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-50l7mrAr.js → KnowledgeGraph-BhEYeFhC.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-rq50H84B.js → Logs-wqi0uxuR.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-DUPIEdQH.js → MarkdownRenderer-DS8dE8ty.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-BYgPDmHU.js → Marketplace-CMlTuPLT.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-5DVgcFdx.js → McpTools-CSx4m5JJ.js} +3 -3
  38. package/src/assets/web-panel/assets/{Memory-B70LPk7f.js → Memory-vnQCUy-_.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-De8ssA5Y.js → MobileBridge-BV2NA742.js} +1 -1
  40. package/src/assets/web-panel/assets/MobileProjects-Bw0k8e1B.js +1 -0
  41. package/src/assets/web-panel/assets/{Mtc-RJsOTsIA.js → Mtc-CzK_FPB1.js} +2 -2
  42. package/src/assets/web-panel/assets/{MtcAudit-Crh-6BEK.js → MtcAudit-Cb7G9oL3.js} +5 -5
  43. package/src/assets/web-panel/assets/{Multisig-wuoR5l3x.js → Multisig-qJxlUyzr.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-U2Mji4fZ.js → NLProgramming-DqaBJ7Te.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-CdTZAyDH.js → Notes-CwhTJkRi.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-C-FucWE7.js → NotificationSettings-YDs4Fal4.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-DCYFTeaI.js → OrderTableRenderer-CvEALpq7.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-an3OF85L.js → Organization-CEmQm9n8.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-C-1vmYFe.js → Overflow-zby_P_LA.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-Cwh47xKg.js → P2P-DsmDNFNT.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-Dm38GT0k.js → PdhVaultBrowser-FWwFlZGF.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-DS2Y8awD.js → Permissions-DuzQ6me5.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-BQNziA0I.js → PersonalDataHub-DZbeN613.js} +3 -3
  54. package/src/assets/web-panel/assets/{Pipeline-DF85L1ue.js → Pipeline-CoNSVAUS.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-BuLornF-.js → Privacy-OYJEAaMC.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-C3Y31IwX.js → ProjectInit-CWIapV--.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-BCPiI8aD.js → ProjectSettings-CX8xMxZn.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-BZ6s4k6g.js → Projects-BLCN8YyY.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-D3Wp022X.js → Providers-BV_sxp75.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-CUJfQkH4.js → QrScannerModal-BTnRrHRp.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-UAc0EO8l.js → QuickAsk-D1KZg018.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-BaxKupcs.js → Recommend-COm5cuNg.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-C75NNnXZ.js → RemoteSession-0saWEkYI.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-BVXynZAk.js → Reputation-Dr7iKLS2.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-C5MRZ0bi.js → Row-C1vpPBcr.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-DAKkEYka.js → RssFeed-CxlWrtNj.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-DvWv9YOA.js → Search-BT2V8dPN.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-B5peafW1.js → Security-bm9V3c5k.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-UQmvPEaG.js → Services-CocH1yyX.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-C3bhWpuF.js → Skeleton-DHItlMdd.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-DfkKf9_H.js → Skills-C59sLc4w.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-DqMSjlBM.js → Sla-Crj4BMc8.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-C-WbxWUX.js → SpeechSettings-DX4KFceY.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-CYuHZ4N2.js → SyncSettings-BD_iwQLr.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-CyeAyB9d.js → Tasks-BmCTzYsH.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-BTCeQnpq.js → Templates-BGUaxZYl.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-BifQuA9Y.js → Tenant-BS0tJx2O.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-Bx_9Bocf.js → Terminal--tHSAsld.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-BX0RFCOm.js → TimelineRenderer-D9-MFxS4.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-CGHrCmUS.js → Tokens-CiCB485f.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-DlqaY4SO.js → Trigger-SmCFuW_l.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-DfOmj-ay.js → Trust-DkK3Rqe0.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-B72jH5fE.js → UkeySign-CDM4LGdB.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-BT-63fqv.js → VideoEditing-IDB7DJXt.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-Dsul3sHr.js → Wallet-Bikj5cmt.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-Izkwwdgy.js → WebAuthn-C9abWlAw.js} +2 -2
  87. package/src/assets/web-panel/assets/{WorkflowEditor-D3FHSiH1.js → WorkflowEditor-DrbRKVky.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-CmVz5z3U.js → chat-CccCSDQf.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-CuLgyJBp.js → colors-CXObXLhb.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-Ml1YkXpw.js → compact-item-B5kfYAxC.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-BvjJ48bs.js → createContext-DmiPBfip.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-CvKrADNa.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-DVC0157C.js → hasIn-Q6lYteAc.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-C229ABfy.js → index-25Wlqps4.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-Ck_52dz_.js → index-33U29UNV.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-QXzlT9KD.js → index-4oXBDczR.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-4SBta3d7.js → index-BGYXvMc5.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-B0S8NzO6.js → index-BJCCa0s_.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DJyN28Et.js → index-BJJ5DhKI.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DC_OI9H2.js → index-BLOzViJ6.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-C_XuRgGn.js → index-BRrbUMoG.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-wvb_FtaV.js → index-BUFpT17Q.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-KMqhcF7l.js → index-BkRDiqGc.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-vG4XSJ1d.js → index-BsfvW6my.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DYXHFr4r.js → index-By-kfPED.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DuGszaWY.js → index-BzFTcQsc.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CXkJH-lK.js → index-C2FXdboq.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Dt5KMjwJ.js → index-C5XOlTHN.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-4wcgvPoF.js → index-CLhBDS2w.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-C_H_S-DY.js → index-CMq7UeoT.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BydjdZnl.js → index-CVMTWNKl.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BjHBpRYZ.js → index-Caghi-yL.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Bzr0rB5T.js → index-CdB6FuSH.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BbPtzB8M.js → index-CoK8-kWQ.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BUt8kTIB.js → index-CsO3GUAY.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-C_vRgTl9.js → index-CwZBa20Z.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DukDVXCv.js → index-D-kASucw.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BbepULSc.js → index-D8eBw7vW.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BfuKP4qe.js → index-D9wgifk4.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BiC6dQZG.js → index-DAYCTc07.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CmFNvNLZ.js → index-DF6Q8l2h.js} +1 -1
  122. package/src/assets/web-panel/assets/index-DTdFUWc_.js +1 -0
  123. package/src/assets/web-panel/assets/{index-KjgKdZe-.js → index-DgTLApS9.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-BpFJHiTv.js → index-DgxVJ8pg.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-Cw0Rjy87.js → index-DlJvIqoR.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CFYVQMvu.js → index-Dw4eHfsG.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CudmwNBV.js → index-Rh-ytwow.js} +3 -3
  128. package/src/assets/web-panel/assets/{index-DDGaOWBV.js → index-StAEt2pq.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-D3lD5qap.js → index-bzfw951k.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BzG-x9p4.js → index-fSUMbMvv.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-B_EvG_GW.js → index-tFHy5Wol.js} +1 -1
  132. package/src/assets/web-panel/assets/index-zQ0M_kz-.js +1 -0
  133. package/src/assets/web-panel/assets/{initDefaultProps-BDgd2YZ8.js → initDefaultProps-BNq7X72N.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-ErtrXdYe.js → motion-DOf9viTc.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-_GPPNCgs.js → move-CRHTcW4x.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-DRLL-8V2.js → mtc-parser-Cyoozgm2.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-p86sl023.js → omit-6-TjFNru.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-BTu7cMLH.js → pickAttrs-DlUmO1zi.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-BEKz6Isr.js → placementArrow-CFOL8mIR.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-Ck42c9MP.js → responsiveObserve-BtaFK5zd.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-1CEvuPsB.js → slide-BIbc2bur.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-BDfdx1GJ.js → statusUtils-BXX9d6-w.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-B4K46m5w.js → styleChecker-BGv10Bpn.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-DoIVpJNq.js → useFlexGapSupport-bKnKT8tw.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-DdAWi-ln.js → useFs-FY4IL4jn.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-iUu6k8dx.js → usePersonalDataHub-Bwl9TEgu.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-DZz4R6Tw.js → vnode-BM3OHxAT.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-DXlf9sA3.js → zoom-D1fbFiHB.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/commands/agenda.js +320 -32
  151. package/src/commands/agent.js +105 -11
  152. package/src/commands/context.js +125 -14
  153. package/src/commands/doctor.js +85 -1
  154. package/src/commands/hook.js +181 -7
  155. package/src/commands/plugin.js +456 -1
  156. package/src/commands/review.js +363 -2
  157. package/src/commands/session.js +191 -0
  158. package/src/commands/team.js +19 -1
  159. package/src/data/changelog.json +10 -4
  160. package/src/gateways/ws/remote-session-protocol.js +39 -0
  161. package/src/gateways/ws/session-protocol.js +55 -2
  162. package/src/gateways/ws/ws-agent-handler.js +50 -0
  163. package/src/harness/jsonl-session-store.js +60 -0
  164. package/src/harness/worktree-isolator.js +140 -5
  165. package/src/lib/agent-schedule-store.js +318 -10
  166. package/src/lib/agent-team/team-worktree.js +37 -2
  167. package/src/lib/agent-tool-admission.js +125 -0
  168. package/src/lib/app-preview.js +360 -0
  169. package/src/lib/async-hook-supervisor.cjs +54 -0
  170. package/src/lib/capability-manifest.js +319 -0
  171. package/src/lib/capability-negotiation.js +23 -12
  172. package/src/lib/channels/channel-manager.js +54 -2
  173. package/src/lib/cli-context-engineering.js +9 -2
  174. package/src/lib/context-breakdown.js +116 -0
  175. package/src/lib/diagnostic-bundle.js +230 -0
  176. package/src/lib/doctor-checkup.js +275 -4
  177. package/src/lib/execution-location.js +286 -0
  178. package/src/lib/headless-manifest.js +13 -40
  179. package/src/lib/hook-event-log.cjs +193 -0
  180. package/src/lib/hook-stats-store.cjs +197 -0
  181. package/src/lib/idempotency.js +109 -0
  182. package/src/lib/interaction-adapter.js +34 -4
  183. package/src/lib/json-schema-output.js +46 -12
  184. package/src/lib/json-schema-validate.js +143 -3
  185. package/src/lib/jsonl-session-store.js +1 -0
  186. package/src/lib/lsp/__tests__/lsp-manager.test.js +58 -0
  187. package/src/lib/lsp/lsp-manager.js +56 -0
  188. package/src/lib/monitor-event.js +290 -0
  189. package/src/lib/operation-fingerprint.js +217 -0
  190. package/src/lib/plugin-runtime/bin.js +37 -0
  191. package/src/lib/plugin-runtime/capabilities.js +19 -0
  192. package/src/lib/plugin-runtime/capability-consent.js +203 -0
  193. package/src/lib/plugin-runtime/hooks.js +37 -0
  194. package/src/lib/plugin-runtime/lsp.js +38 -0
  195. package/src/lib/plugin-runtime/mcp.js +40 -0
  196. package/src/lib/plugin-runtime/monitors.js +37 -0
  197. package/src/lib/plugin-runtime/plugin-options.js +151 -0
  198. package/src/lib/plugin-runtime/policy.js +62 -0
  199. package/src/lib/plugin-runtime/scopes.js +20 -4
  200. package/src/lib/pr-automation-policy.js +224 -0
  201. package/src/lib/project-instructions.js +128 -0
  202. package/src/lib/remote-approval-bridge.js +66 -13
  203. package/src/lib/repl-goal.js +132 -0
  204. package/src/lib/repl-rewind.js +153 -0
  205. package/src/lib/review-comment-anchor.js +241 -0
  206. package/src/lib/review-pipeline.js +46 -7
  207. package/src/lib/runtime-checkup.js +221 -0
  208. package/src/lib/schedule-planner.js +17 -1
  209. package/src/lib/secret-scan.js +409 -0
  210. package/src/lib/session-branch.js +0 -0
  211. package/src/lib/settings-hook-events.cjs +13 -0
  212. package/src/lib/settings-loader.cjs +42 -0
  213. package/src/lib/side-effect-ledger-store.js +88 -0
  214. package/src/lib/side-effect-ledger.js +401 -0
  215. package/src/lib/skill-loader.js +32 -0
  216. package/src/lib/skill-path-scope.js +63 -0
  217. package/src/lib/sub-agent-context.js +110 -9
  218. package/src/lib/sub-agent-registry.js +19 -0
  219. package/src/lib/subagent-inheritance.js +112 -0
  220. package/src/lib/telemetry/span-recorder.js +17 -4
  221. package/src/lib/terminal-context.js +195 -0
  222. package/src/lib/turn-binding-store.js +119 -0
  223. package/src/lib/unattended-action-policy.js +182 -0
  224. package/src/lib/worktree-cleanup-safety.js +138 -0
  225. package/src/lib/worktree-isolator.js +8 -0
  226. package/src/lib/worktree-sparse.js +131 -0
  227. package/src/repl/agent-repl.js +280 -30
  228. package/src/repl/permission-tier.js +28 -0
  229. package/src/runtime/agent-core.js +565 -21
  230. package/src/runtime/coding-agent-contract-shared.cjs +60 -1
  231. package/src/runtime/diagnostics.js +60 -0
  232. package/src/runtime/headless-runner.js +393 -1
  233. package/src/runtime/headless-stream.js +60 -1
  234. package/src/assets/web-panel/assets/MobileProjects-D10VISps.js +0 -1
  235. package/src/assets/web-panel/assets/devWarning-DhiGrbsh.js +0 -1
  236. package/src/assets/web-panel/assets/index-B7a1TrU6.js +0 -1
  237. package/src/assets/web-panel/assets/index-C2B1KRja.js +0 -1
@@ -116,6 +116,7 @@ import { describeAskContext, raceLocalAndRemote } from "./remote-approval.js";
116
116
  import {
117
117
  parsePermissionTier,
118
118
  parsePermissionModeArg,
119
+ permissionModeForTier,
119
120
  describeTier,
120
121
  nextTier,
121
122
  } from "./permission-tier.js";
@@ -460,6 +461,10 @@ export async function startAgentRepl(options = {}) {
460
461
  // tier but additionally activates the autoMode.decisions classifier wrapper
461
462
  // (when settings customize it) — gateTierFor() maps mode → real gate tier.
462
463
  let _sessionTier = "strict";
464
+ // `/goal <condition>`: an optional SESSION completion condition. When set, the
465
+ // condition is evaluated + reported after each turn (interactive — no auto
466
+ // re-drive; that autonomous loop is headless-only). null = no session goal.
467
+ let _sessionGoal = null;
463
468
  const gateTierFor = (mode) =>
464
469
  mode === "auto" ? "trusted" : mode === "dontAsk" ? "strict" : mode;
465
470
  // dontAsk (headless parity, interactive form): anything that would prompt
@@ -1581,6 +1586,7 @@ export async function startAgentRepl(options = {}) {
1581
1586
  "/exit",
1582
1587
  "/export",
1583
1588
  "/fast",
1589
+ "/goal",
1584
1590
  "/help",
1585
1591
  "/hooks",
1586
1592
  "/ide",
@@ -2182,7 +2188,10 @@ export async function startAgentRepl(options = {}) {
2182
2188
  ` ${chalk.cyan("/export")} Save this conversation to a Markdown file (/export [path])`,
2183
2189
  );
2184
2190
  logger.log(
2185
- ` ${chalk.cyan("/rewind")} Rewind to an earlier turn (double-Esc lists); ${chalk.cyan("/rewind clear")} restores a /clear`,
2191
+ ` ${chalk.cyan("/rewind")} Rewind to an earlier turn (double-Esc lists); ${chalk.cyan("/rewind <n> --files|--conversation")} scopes it; ${chalk.cyan("/rewind <n> --branch")} forks a session; ${chalk.cyan("/rewind clear")} restores a /clear`,
2192
+ );
2193
+ logger.log(
2194
+ ` ${chalk.cyan("/goal <cond>")} Set a session goal checked after each turn (exit-zero:/file-exists:/contains:/regex:/text); ${chalk.cyan("/goal")} shows, ${chalk.cyan("/goal clear")} drops`,
2186
2195
  );
2187
2196
  logger.log(
2188
2197
  ` ${chalk.cyan("/cd <dir>")} Change working directory mid-session (completion/memory follow)`,
@@ -3009,9 +3018,19 @@ export async function startAgentRepl(options = {}) {
3009
3018
  pickCheckpointForTurn,
3010
3019
  pruneMarksAfter,
3011
3020
  restoreClearedConversation,
3021
+ buildRewindPlan,
3022
+ renderRewindWarnings,
3023
+ buildBranchPlan,
3024
+ renderBranchPlan,
3025
+ parseRewindArg,
3026
+ RESTORE_SCOPE,
3012
3027
  } = await import("../lib/repl-rewind.js");
3013
3028
  const arg = trimmed.slice("/rewind".length).trim();
3014
- if (arg === "clear" || arg === "undo-clear") {
3029
+ // Parse the turn number + optional restore scope (--conversation /
3030
+ // --files / --both). Claude-Code parity: a rewind can restore the
3031
+ // conversation only, the files only, or both.
3032
+ const parsed = parseRewindArg(arg);
3033
+ if (parsed.command === "clear") {
3015
3034
  // Restore the conversation stashed by /clear (Claude-Code 2.1.191).
3016
3035
  const r = restoreClearedConversation(
3017
3036
  messages,
@@ -3034,13 +3053,86 @@ export async function startAgentRepl(options = {}) {
3034
3053
  prompt();
3035
3054
  return;
3036
3055
  }
3037
- if (!arg) {
3056
+ if (parsed.command === "branch") {
3057
+ // "从这里分支" (P0-3's fourth restore action): fork a NEW independent
3058
+ // session that keeps history up to the chosen turn and diverges from
3059
+ // there. The origin session is NEVER truncated (preservesParent), so
3060
+ // the live conversation continues unchanged.
3061
+ const targetTurn = listUserTurns(messages, { limit: 1000 }).find(
3062
+ (t) => t.n === parsed.n,
3063
+ );
3064
+ if (!targetTurn) {
3065
+ logger.error(`No such turn: ${parsed.n} — run /rewind to list.`);
3066
+ } else if (!sessionId) {
3067
+ logger.error(
3068
+ "Branch needs a persisted session — none is active yet.",
3069
+ );
3070
+ } else {
3071
+ const turnIndex = targetTurn.index;
3072
+ const plan = buildBranchPlan(
3073
+ messages,
3074
+ _checkpointMarks,
3075
+ turnIndex,
3076
+ {
3077
+ parentSessionId: sessionId,
3078
+ writeIntent: parsed.writeIntent,
3079
+ },
3080
+ );
3081
+ if (!plan || !plan.branchSessionId) {
3082
+ logger.error("Could not plan a branch from that turn.");
3083
+ } else {
3084
+ try {
3085
+ const { createBranchSession } =
3086
+ await import("../harness/jsonl-session-store.js");
3087
+ const res = createBranchSession({
3088
+ branchSessionId: plan.branchSessionId,
3089
+ parentSessionId: sessionId,
3090
+ parentTurnId: plan.parentTurnId,
3091
+ messages: messages.slice(0, turnIndex),
3092
+ meta: { title: `Branch of ${sessionId}` },
3093
+ });
3094
+ logger.log(
3095
+ chalk.green(
3096
+ res.created
3097
+ ? `🌿 branched to ${res.branchSessionId} — ${res.messages} message(s) kept; parent ${sessionId} untouched`
3098
+ : `🌿 branch ${res.branchSessionId} already exists; parent ${sessionId} untouched`,
3099
+ ),
3100
+ );
3101
+ for (const line of renderBranchPlan(plan))
3102
+ logger.log(chalk.yellow(line));
3103
+ logger.log(
3104
+ chalk.gray(
3105
+ ` resume it with cc agent --resume ${res.branchSessionId}` +
3106
+ (plan.requiresWorktree
3107
+ ? " (write task → branch into an isolated worktree)"
3108
+ : ""),
3109
+ ),
3110
+ );
3111
+ } catch (e) {
3112
+ logger.error(`branch failed: ${e.message}`);
3113
+ }
3114
+ }
3115
+ }
3116
+ prompt();
3117
+ return;
3118
+ }
3119
+ if (parsed.command === "list") {
3038
3120
  logger.log(chalk.bold("\nRewind — pick a user turn (newest first):"));
3039
3121
  logger.log(renderTurnList(listUserTurns(messages)));
3040
3122
  const fileHint = _checkpointMarks.length
3041
3123
  ? " (restores files to that point too — checkpoints are on)"
3042
3124
  : " (conversation only — start with --checkpoint / git to also rewind files)";
3043
3125
  logger.log(chalk.gray(`Usage: /rewind <n>${fileHint}`));
3126
+ logger.log(
3127
+ chalk.gray(
3128
+ " scope: /rewind <n> --conversation | --files | --both (default)",
3129
+ ),
3130
+ );
3131
+ logger.log(
3132
+ chalk.gray(
3133
+ " branch: /rewind <n> --branch [--write] forks an independent session (parent kept)",
3134
+ ),
3135
+ );
3044
3136
  if (_clearedConversation) {
3045
3137
  logger.log(
3046
3138
  chalk.gray(
@@ -3049,30 +3141,67 @@ export async function startAgentRepl(options = {}) {
3049
3141
  );
3050
3142
  }
3051
3143
  } else {
3052
- const res = rewindToTurn(messages, arg);
3053
- if (!res) {
3054
- logger.error(`No such turn: ${arg} — run /rewind to list.`);
3144
+ const scope = parsed.scope;
3145
+ const rewindConversation = scope !== RESTORE_SCOPE.FILES;
3146
+ const restoreFiles = scope !== RESTORE_SCOPE.CONVERSATION;
3147
+ // Snapshot + locate the target turn BEFORE any truncation:
3148
+ // buildRewindPlan needs the turn still present to bind its checkpoint,
3149
+ // and a files-only rewind keeps the conversation intact entirely.
3150
+ const preRewind = messages.slice();
3151
+ const targetTurn = listUserTurns(messages, { limit: 1000 }).find(
3152
+ (t) => t.n === parsed.n,
3153
+ );
3154
+ if (!targetTurn) {
3155
+ logger.error(`No such turn: ${parsed.n} — run /rewind to list.`);
3055
3156
  } else {
3056
- logger.log(
3057
- chalk.yellow(
3058
- `⎌ rewound — dropped ${res.removed} message(s); edit and resend below`,
3059
- ),
3060
- );
3061
- // Claude-Code parity: rewind restores files too. Match the dropped
3062
- // turn to the snapshot taken just before it first mutated the tree,
3063
- // then offer to roll the working tree back to it (undoable — the
3064
- // restore takes its own safety checkpoint first).
3065
- const cp = pickCheckpointForTurn(_checkpointMarks, res.index);
3066
- pruneMarksAfter(_checkpointMarks, res.index);
3157
+ const turnIndex = targetTurn.index;
3158
+ // 1) Conversation rewind (skipped for files-only).
3159
+ if (rewindConversation) {
3160
+ const res = rewindToTurn(messages, parsed.n);
3161
+ logger.log(
3162
+ chalk.yellow(
3163
+ `⎌ rewound — dropped ${res.removed} message(s); edit and resend below`,
3164
+ ),
3165
+ );
3166
+ } else {
3167
+ logger.log(
3168
+ chalk.yellow("⎌ files-only rewind — conversation left intact"),
3169
+ );
3170
+ }
3171
+ // 2) Coverage-aware honesty for the CHOSEN scope (P1 turn/checkpoint
3172
+ // binding): print what a restore can and cannot promise — a shell/
3173
+ // external side-effect → PARTIAL, no checkpoint → files can't be
3174
+ // restored, and a scope-specific conversation/files drift. Derived
3175
+ // from the REPL's existing marks (no new agent-loop events);
3176
+ // best-effort so the advisory never blocks the rewind itself.
3177
+ try {
3178
+ const plan = buildRewindPlan(
3179
+ preRewind,
3180
+ _checkpointMarks,
3181
+ turnIndex,
3182
+ scope,
3183
+ );
3184
+ for (const line of renderRewindWarnings(plan))
3185
+ logger.log(chalk.yellow(line));
3186
+ } catch {
3187
+ /* advisory only — a rewind must never fail over its own warning */
3188
+ }
3189
+ // 3) File restore (skipped for conversation-only). Match the turn to
3190
+ // the snapshot taken just before it first mutated the tree, then
3191
+ // offer to roll the working tree back to it (undoable — the restore
3192
+ // takes its own safety checkpoint first). Prune dropped-turn marks
3193
+ // only when the conversation was actually truncated.
3194
+ const cp = restoreFiles
3195
+ ? pickCheckpointForTurn(_checkpointMarks, turnIndex)
3196
+ : null;
3197
+ if (rewindConversation)
3198
+ pruneMarksAfter(_checkpointMarks, turnIndex);
3067
3199
  if (cp) {
3068
3200
  const q = (p) => new Promise((r) => rl.question(p, r));
3069
- const ans = (
3070
- await q(
3071
- chalk.yellow(
3072
- ` Also restore files to before this turn? (checkpoint ${cp.id}) [Y/n] `,
3073
- ),
3074
- )
3075
- )
3201
+ const promptText = rewindConversation
3202
+ ? ` Also restore files to before this turn? (checkpoint ${cp.id}) [Y/n] `
3203
+ : ` Restore files to before this turn? (checkpoint ${cp.id}) [Y/n] `;
3204
+ const ans = (await q(chalk.yellow(promptText)))
3076
3205
  .trim()
3077
3206
  .toLowerCase();
3078
3207
  if (ans === "" || ans === "y" || ans === "yes") {
@@ -3089,7 +3218,7 @@ export async function startAgentRepl(options = {}) {
3089
3218
  );
3090
3219
  } catch (e) {
3091
3220
  logger.error(
3092
- ` file restore skipped: ${e.message} (conversation already rewound)`,
3221
+ ` file restore skipped: ${e.message}${rewindConversation ? " (conversation already rewound)" : ""}`,
3093
3222
  );
3094
3223
  }
3095
3224
  } else {
@@ -3099,9 +3228,19 @@ export async function startAgentRepl(options = {}) {
3099
3228
  ),
3100
3229
  );
3101
3230
  }
3231
+ } else if (restoreFiles && scope === RESTORE_SCOPE.FILES) {
3232
+ logger.log(
3233
+ chalk.gray(
3234
+ " no checkpoint captured for that turn — nothing to restore",
3235
+ ),
3236
+ );
3102
3237
  }
3103
3238
  prompt();
3104
- if (res.text) rl.write(res.text);
3239
+ // Prefill the input line with the turn's text only when the
3240
+ // conversation was rewound (edit-and-resend); files-only leaves the
3241
+ // conversation and the prompt untouched.
3242
+ if (rewindConversation && typeof targetTurn.content === "string")
3243
+ rl.write(targetTurn.content);
3105
3244
  return;
3106
3245
  }
3107
3246
  }
@@ -3406,7 +3545,9 @@ export async function startAgentRepl(options = {}) {
3406
3545
  if (!_asyncHookSupervisor) {
3407
3546
  const { AsyncHookSupervisor } =
3408
3547
  await import("../lib/async-hook-supervisor.cjs");
3409
- _asyncHookSupervisor = new AsyncHookSupervisor();
3548
+ _asyncHookSupervisor = new AsyncHookSupervisor({
3549
+ persistStats: true,
3550
+ });
3410
3551
  }
3411
3552
  dispatchAsyncHooks(_settingsHooks, "ConfigChange", payload, {
3412
3553
  cwd,
@@ -3533,6 +3674,35 @@ export async function startAgentRepl(options = {}) {
3533
3674
  }
3534
3675
 
3535
3676
  // Stats
3677
+ if (trimmed === "/goal" || trimmed.startsWith("/goal ")) {
3678
+ // Session completion condition (distinct from `cc goal` OKR): set / show /
3679
+ // clear a condition that is evaluated + reported after each turn.
3680
+ try {
3681
+ const rg = await import("../lib/repl-goal.js");
3682
+ const cmd = rg.parseGoalCommand(trimmed.slice("/goal".length));
3683
+ if (cmd.action === "clear") {
3684
+ if (_sessionGoal) {
3685
+ _sessionGoal = null;
3686
+ logger.log(chalk.gray("◎ session goal cleared."));
3687
+ } else {
3688
+ logger.log(chalk.gray("No session goal to clear."));
3689
+ }
3690
+ } else if (cmd.action === "status") {
3691
+ for (const l of rg.renderGoalStatus(_sessionGoal))
3692
+ logger.log(chalk.gray(l));
3693
+ } else {
3694
+ // set — createReplGoal throws on a malformed spec (caught below).
3695
+ _sessionGoal = rg.createReplGoal(cmd.spec, { now: () => Date.now() });
3696
+ for (const l of rg.renderGoalStart(_sessionGoal))
3697
+ logger.log(chalk.cyan(l));
3698
+ }
3699
+ } catch (err) {
3700
+ logger.error(`/goal: ${err.message}`);
3701
+ }
3702
+ prompt();
3703
+ return;
3704
+ }
3705
+
3536
3706
  if (trimmed === "/stats") {
3537
3707
  if (contextEngine) {
3538
3708
  const stats = contextEngine.getStats();
@@ -4753,7 +4923,9 @@ export async function startAgentRepl(options = {}) {
4753
4923
  if (!_asyncHookSupervisor) {
4754
4924
  const { AsyncHookSupervisor } =
4755
4925
  await import("../lib/async-hook-supervisor.cjs");
4756
- _asyncHookSupervisor = new AsyncHookSupervisor();
4926
+ _asyncHookSupervisor = new AsyncHookSupervisor({
4927
+ persistStats: true,
4928
+ });
4757
4929
  }
4758
4930
  dispatchAsyncHooks(
4759
4931
  _settingsHooks,
@@ -5040,7 +5212,7 @@ export async function startAgentRepl(options = {}) {
5040
5212
  if (_settingsHooks && !_asyncHookSupervisor) {
5041
5213
  const { AsyncHookSupervisor } =
5042
5214
  await import("../lib/async-hook-supervisor.cjs");
5043
- _asyncHookSupervisor = new AsyncHookSupervisor();
5215
+ _asyncHookSupervisor = new AsyncHookSupervisor({ persistStats: true });
5044
5216
  }
5045
5217
  const {
5046
5218
  content: response,
@@ -5102,6 +5274,17 @@ export async function startAgentRepl(options = {}) {
5102
5274
  denialLog: _recentDenials,
5103
5275
  persistRecentDenials: true,
5104
5276
  permissionMode: _sessionTier,
5277
+ // Seed the subagent-contract CEILING with the interactive session's
5278
+ // CURRENT approval tier (mapped back to a permission mode) so a spawned
5279
+ // sub-agent inherits/tightens from it (tighten-only), mirroring the
5280
+ // headless runner. An autopilot session hands children bypassPermissions
5281
+ // (→ allow confirmer); a mid-session Shift+Tab / `/permissions` change is
5282
+ // reflected because `_sessionTier` is read per turn. A strict session
5283
+ // resolves children to "default" exactly as before (byte-identical — the
5284
+ // previous absent ceiling also yielded "default").
5285
+ subAgentContract: {
5286
+ permissionMode: permissionModeForTier(_sessionTier),
5287
+ },
5105
5288
  prepareCall,
5106
5289
  approvalGate: _approvalGate,
5107
5290
  permissionRules: _permissionRules,
@@ -5161,6 +5344,71 @@ export async function startAgentRepl(options = {}) {
5161
5344
  if (used > 0) _ctxUsedTokens = used;
5162
5345
  }
5163
5346
 
5347
+ // /goal (session completion condition): evaluate this turn's answer and
5348
+ // report met / not-yet / dropped. Deterministic conditions (exit-zero /
5349
+ // file-exists / contains / regex) run inline; a model condition reuses the
5350
+ // session model as an independent judge. Interactive → REPORT only, never
5351
+ // auto re-drive (that autonomous loop is headless-only). Best-effort — an
5352
+ // eval failure never disturbs the turn.
5353
+ if (_sessionGoal && !_sessionGoal.done) {
5354
+ try {
5355
+ const rg = await import("../lib/repl-goal.js");
5356
+ const fsMod = await import("node:fs");
5357
+ const cpMod = await import("node:child_process");
5358
+ const judge = async (cond, { finalText }) => {
5359
+ const { chatWithTools } = await import("../runtime/agent-core.js");
5360
+ const { firstBalancedJson } =
5361
+ await import("../lib/json-schema-output.js");
5362
+ const p =
5363
+ `Judge whether this coding session met a completion condition.\n` +
5364
+ `Condition: ${cond.text || cond.source}\n\n` +
5365
+ `Latest assistant output:\n${String(finalText || "").slice(0, 2000)}\n\n` +
5366
+ `Reply with STRICT JSON only: {"met": true|false, "reason": "<short>"}.`;
5367
+ const jr = await chatWithTools([{ role: "user", content: p }], {
5368
+ model: activeModel,
5369
+ provider,
5370
+ baseUrl,
5371
+ apiKey,
5372
+ enabledToolNames: [],
5373
+ });
5374
+ const text = jr?.message?.content || "";
5375
+ let met = false;
5376
+ let reason = "model judge returned no verdict";
5377
+ const block = firstBalancedJson(text, "{");
5378
+ if (block) {
5379
+ try {
5380
+ const parsed = JSON.parse(block);
5381
+ met = parsed.met === true;
5382
+ reason =
5383
+ typeof parsed.reason === "string" && parsed.reason.trim()
5384
+ ? parsed.reason.trim()
5385
+ : met
5386
+ ? "condition met"
5387
+ : "condition not met";
5388
+ } catch {
5389
+ /* a non-JSON verdict stays unmet */
5390
+ }
5391
+ }
5392
+ return { met, reason, evidence: { kind: "model" } };
5393
+ };
5394
+ const { decision, events, done } = await rg.evaluateReplGoalTurn(
5395
+ _sessionGoal,
5396
+ response || "",
5397
+ {
5398
+ cwd: process.cwd(),
5399
+ spawnSync: cpMod.spawnSync,
5400
+ existsSync: fsMod.existsSync,
5401
+ judge,
5402
+ },
5403
+ );
5404
+ for (const l of rg.renderGoalVerdict(decision, events))
5405
+ logger.log(chalk.cyan(l));
5406
+ if (done) _sessionGoal = null; // completed or exhausted → drop
5407
+ } catch (err) {
5408
+ logger.verbose(`/goal eval skipped: ${err.message}`);
5409
+ }
5410
+ }
5411
+
5164
5412
  // Fire AssistantResponse hook with rewrite/suppress support
5165
5413
  const responseDirective = await fireAssistantResponse(
5166
5414
  _hookDb,
@@ -5306,7 +5554,9 @@ export async function startAgentRepl(options = {}) {
5306
5554
  if (!_asyncHookSupervisor) {
5307
5555
  const { AsyncHookSupervisor } =
5308
5556
  await import("../lib/async-hook-supervisor.cjs");
5309
- _asyncHookSupervisor = new AsyncHookSupervisor();
5557
+ _asyncHookSupervisor = new AsyncHookSupervisor({
5558
+ persistStats: true,
5559
+ });
5310
5560
  }
5311
5561
  dispatchAsyncHooks(
5312
5562
  _settingsHooks,
@@ -72,6 +72,34 @@ export function parsePermissionModeArg(arg) {
72
72
  return tier ? { tier, auto: false, dontAsk: false } : null;
73
73
  }
74
74
 
75
+ /**
76
+ * Inverse of the tier mapping: turn a live REPL session tier back into a
77
+ * subagent-contract permission MODE, so a spawned sub-agent inherits/tightens
78
+ * from the interactive session's CURRENT approval tier (its run-mode ceiling).
79
+ * Lossy on the restrictive end (strict ← default/manual/plan) — "default" is the
80
+ * safe representative and resolves identically for a child — but the PERMISSIVE
81
+ * end (autopilot → bypassPermissions) is exact, which is what lets a bypass
82
+ * session hand its children the allow confirmer. `auto`/`dontAsk` carry through.
83
+ *
84
+ * @param {string} tier strict | trusted | autopilot | auto | dontAsk
85
+ * @returns {"default"|"acceptEdits"|"bypassPermissions"|"auto"|"dontAsk"}
86
+ */
87
+ export function permissionModeForTier(tier) {
88
+ switch (tier) {
89
+ case "autopilot":
90
+ return "bypassPermissions";
91
+ case "trusted":
92
+ return "acceptEdits";
93
+ case "auto":
94
+ return "auto";
95
+ case "dontAsk":
96
+ return "dontAsk";
97
+ case "strict":
98
+ default:
99
+ return "default";
100
+ }
101
+ }
102
+
75
103
  /** One-line description of what a tier auto-approves. */
76
104
  export function describeTier(tier) {
77
105
  switch (tier) {