chainlesschain 0.162.155 → 0.162.157

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 (194) hide show
  1. package/README.md +1 -1
  2. package/package.json +2 -2
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-Cth_zZeA.js → AIOps-CfMP2Oud.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-zfwA3Oxn.js → ActionButton-Zu0N8BQL.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-FeKc4aU2.js → Analytics-DZTwj5T_.js} +3 -3
  7. package/src/assets/web-panel/assets/AppLayout-CVFJh47v.js +9 -0
  8. package/src/assets/web-panel/assets/Artifacts-BbN5V7au.js +1 -0
  9. package/src/assets/web-panel/assets/Artifacts-CRkepl4t.css +1 -0
  10. package/src/assets/web-panel/assets/{Audit-C2gRq5Qi.js → Audit-BMfiLj7T.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-TeTIFiW-.js → BackgroundAgents-BslPCdGF.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-CLJk3k6i.js → Backup-CQ_fMC1r.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-5ms537NY.js → BaseInput-CsFsARiC.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-4Nr5U9PJ.js → Chat-CwfBobco.js} +6 -6
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-K6Nf3xeN.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-B2Bca5ev.js → Checkbox-DkSyjjPp.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-D6Uysdbv.js → Codegen-B7Fx3zZ6.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-B3XQ8xc7.js → Col-Dzfqn8Ep.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-CqwKtoPz.js → Community-DhHPdzMM.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-BZZINTus.js → Compact-Ct18_8y7.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-Dr3BXkWA.js → Compliance-CY64IqBi.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-rx_x9Wqc.js → Cowork-BYSmWlUl.js} +3 -3
  23. package/src/assets/web-panel/assets/{Cron-BpZr7rHc.js → Cron-_4xtP3Ug.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-CeV5EYVg.js → Crosschain-B4qY-Ycr.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-fe2Qaowz.js → DID-CkCzWkx1.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-Fh_EdWVa.js → Dashboard-C1scT7Ke.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-N1PIwWYf.js → Dropdown-DBnQ2EWd.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-B6vK93Ed.js → EmailListRenderer-C9JhOTq0.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-e3iUZhAg.js → FamilyGuardDashboard-CWXv5RUv.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-uInc9YcN.js → Federation-fYdcbz9W.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-DmQZSX0z.js → FormItemContext-CJqOT3Yj.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-CV_Z8OAo.js → GenericCardRenderer-DGCsHc5K.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-jXAhNN8d.js → Git-EH2K-H0Q.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-Blw1esBB.js → Governance-DJn1X2pR.js} +1 -1
  35. package/src/assets/web-panel/assets/Inference-Dch1E8qd.js +1 -0
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-5xrglMTK.js → KnowledgeGraph-QIur8j8-.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-BGIG9798.js → Logs-DUgHldPg.js} +2 -2
  38. package/src/assets/web-panel/assets/Marketplace-DafrSfvd.js +1 -0
  39. package/src/assets/web-panel/assets/{McpTools-7U8tEhwK.js → McpTools-D2xRbfJx.js} +4 -4
  40. package/src/assets/web-panel/assets/{Memory-BrvboPLE.js → Memory-C6RbVHAo.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-nzcd7d1H.js → MobileBridge-BPtVBKqn.js} +1 -1
  42. package/src/assets/web-panel/assets/{MobileProjects-DETVNKa7.js → MobileProjects-Cuw832cr.js} +1 -1
  43. package/src/assets/web-panel/assets/{Mtc-SZcCYec3.js → Mtc-D6O9fWFa.js} +4 -4
  44. package/src/assets/web-panel/assets/{MtcAudit-Cx_d3N17.js → MtcAudit-CWZcXIH1.js} +5 -5
  45. package/src/assets/web-panel/assets/{Multisig-DtcmSUo-.js → Multisig-DhIBxTFd.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-Dgx2QHl-.js → NLProgramming-wkBFS33e.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-oHTGEHoJ.js → Notes-B09FxncA.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-qKD-IlOl.js → NotificationSettings-oQwtH6-9.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-CiU4Sy1J.js → OrderTableRenderer-iFKeNf6Y.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-BBNXnltP.js → Organization-CsF-NIjz.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-Df2fDbvT.js → Overflow-bLxv9Dqi.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-DUHj6zjO.js → P2P-DVwQtm4q.js} +2 -2
  53. package/src/assets/web-panel/assets/{PdhVaultBrowser-B2nWgdoV.js → PdhVaultBrowser-Bgic3QKm.js} +3 -3
  54. package/src/assets/web-panel/assets/{Permissions-CiW0afny.js → Permissions-as80-9ep.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-cc1mHU_D.js → PersonalDataHub-BGmUw36a.js} +2 -2
  56. package/src/assets/web-panel/assets/{Pipeline-B93zTapU.js → Pipeline-BM96zBxG.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-Db1jXWfd.js → Privacy-BBOzBSWe.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-DFoZ1h9U.js → ProjectInit-GHX41V28.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-BkkUnmYs.js → ProjectSettings-DraqzxKD.js} +2 -2
  60. package/src/assets/web-panel/assets/{Projects-Xa779XLC.js → Projects-BzzdUml4.js} +1 -1
  61. package/src/assets/web-panel/assets/{Providers-DOF01IEN.js → Providers-CSeYNAtW.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-TohRsKd0.js → QrScannerModal-DlzBCdXh.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-DjLcr1ZU.js → QuickAsk-p8iB7od_.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend--Ism6bMx.js → Recommend-DjOVXacd.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-B8CL3YHM.js → RemoteSession-CIGk7gk-.js} +2 -2
  66. package/src/assets/web-panel/assets/Reputation-CjT3M0Di.js +1 -0
  67. package/src/assets/web-panel/assets/{Row-BioxZBBH.js → Row-tw8m6T0c.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-B2LipwH3.js → RssFeed-B47KBx_f.js} +2 -2
  69. package/src/assets/web-panel/assets/Search-D2sx1PBe.js +1 -0
  70. package/src/assets/web-panel/assets/{Security-TibHuJWP.js → Security-JmtL8g7D.js} +3 -3
  71. package/src/assets/web-panel/assets/{Services-DtkuWseW.js → Services-BxrNqjin.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-BIcPQae6.js → Skeleton-udk8L18t.js} +1 -1
  73. package/src/assets/web-panel/assets/Skills-DooLT9of.js +1 -0
  74. package/src/assets/web-panel/assets/{Sla-uUSU185m.js → Sla-ITVZE1xI.js} +1 -1
  75. package/src/assets/web-panel/assets/{SpeechSettings-B7Bgc9mk.js → SpeechSettings-DCkfqY1n.js} +1 -1
  76. package/src/assets/web-panel/assets/{SyncSettings-K-XrJ2s9.js → SyncSettings-CkNlgFjM.js} +2 -2
  77. package/src/assets/web-panel/assets/Tasks-BMAoyCM_.js +1 -0
  78. package/src/assets/web-panel/assets/{Templates-CaFnyGDK.js → Templates-BnrFTlrz.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-C2X0PtEC.js → Tenant-BjNsy3-i.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-CKU5yVsT.js → Terminal-C0gxLL7V.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-8trZeYDC.js → TimelineRenderer-CUtj_KHA.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-BUEEe9US.js → Tokens-DOg61zlq.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-COU97I7Y.js → Trigger-D4ldCewj.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-DNWQChaP.js → Trust-3lk_Zd8j.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-DWX_VtCp.js → UkeySign-kWhFR6Li.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-D9eIDhsp.js → VideoEditing-D3GOFVWg.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-BOnCCgIL.js → Wallet-DzrZfBuh.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-DN4dD-W8.js → WebAuthn-CyVJVp_g.js} +5 -5
  89. package/src/assets/web-panel/assets/{WorkflowEditor-ClvDb_jX.js → WorkflowEditor-i_b0wi9b.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-DIxQ_Eeb.js → chat-DwPCK8I7.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-BOX3WKcP.js → colors-D0vaVqZU.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-Bny82VDi.js → compact-item-Don7nGW2.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-Cnoy3enS.js → createContext-D84R5qy2.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-BBwWehQ7.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-BJ7fkx3F.js → hasIn-BeUqVVKU.js} +1 -1
  96. package/src/assets/web-panel/assets/{icons-DEmcnxBf.js → icons-DG5UD-6K.js} +4 -4
  97. package/src/assets/web-panel/assets/{index-CZ6CHiCQ.js → index-4MkfPLGv.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-7GLXvG8p.js → index-7QUwcGTg.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-C1nHEOFE.js → index-B57al0Z5.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-Kio1ekYg.js → index-BER98o4P.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-D9QEc7Tq.js → index-BNpJf-sf.js} +1 -1
  102. package/src/assets/web-panel/assets/{index--CcGiwAI.js → index-BZ1N07Sp.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BWPey0Uf.js → index-BlfTf0ka.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-B7Fah_BX.js → index-BohrJpBf.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BJ8-oLHI.js → index-Br3SOdER.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-D2qNdrNW.js → index-C0_sKVi7.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CQ-xLCVb.js → index-CAdCTTBC.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DSRIjAWO.js → index-CExWtm98.js} +1 -1
  109. package/src/assets/web-panel/assets/{index--Xb2lq6E.js → index-CL71rIwo.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BDkN6YOI.js → index-CfYRv-zA.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Bk5yST66.js → index-CnnxzIx0.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-2N9Y1cLx.js → index-CrnVEEQO.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CW6n-y1L.js → index-CzT56x-_.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-OaNFXV8N.js → index-D4b5XqIy.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CEPTiBWy.js → index-D84BnuFg.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CZCTan8Q.js → index-D8r7WKk-.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-rn6xd12s.js → index-DA0-EJKx.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BcmXbIwv.js → index-DBzBLX-K.js} +3 -3
  119. package/src/assets/web-panel/assets/{index-C--PPqwi.js → index-DFFzwrNs.js} +1 -1
  120. package/src/assets/web-panel/assets/index-DJ8etkBT.js +1 -0
  121. package/src/assets/web-panel/assets/{index-Ty4w18mR.js → index-DMT8n9vB.js} +4 -4
  122. package/src/assets/web-panel/assets/{index-qOBKrw-g.js → index-DQor_7NF.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CN6emwbq.js → index-DT40zd7K.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-BM0mQhVv.js → index-De85D9Pc.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-ceH9DsAi.js → index-IGGttsCv.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DBhkJqVF.js → index-L73NrmlW.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BbZynivw.js → index-LMo9bBLJ.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Bvheiep2.js → index-MKZrJrP_.js} +1 -1
  129. package/src/assets/web-panel/assets/index-OeaK-zXZ.js +1 -0
  130. package/src/assets/web-panel/assets/{index-DxX8hhmL.js → index-WRw1pM5E.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-B6WoW8DJ.js → index-YKLCotoo.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BP7HFsAK.js → index-hjgrIX5I.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-CnjtAKdw.js → index-m9bn0F1p.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-CEq5Vh0i.js → index-wesQQ2cH.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-B1-h2QrC.js → index-x7VYlV41.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-BmxMBuUZ.js → initDefaultProps-DGeU4vPS.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-DnXNwo2k.js → motion-Dgqj9ab3.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-WnIJwmZN.js → move-BFyEU6Lr.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-DAto-c2w.js → mtc-parser-CueCXXPC.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-BtvW9W0H.js → omit-D2pU5OyE.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-DFqI9-_C.js → pickAttrs-CKTf6zD6.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-Dax6wOK3.js → placementArrow-DieJaGCN.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-BUFWWC83.js → responsiveObserve-Bxr-rmU6.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-DyARyuSz.js → slide-CDEDk3Se.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-BZSDugpi.js → statusUtils-icf2eCTx.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-B7o_K-4R.js → styleChecker-qKvgmBhE.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-Dg7Bg8VG.js → useFlexGapSupport-1_UhiyJZ.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-DQYXo5Rk.js → useFs-CFGLXDWh.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-E8NBAnkq.js → usePersonalDataHub-UafOXvQ6.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-DD71_w1b.js → vnode-BfPqSx79.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-zc9EMd3q.js → zoom-CXsVcRB6.js} +1 -1
  152. package/src/assets/web-panel/index.html +2 -2
  153. package/src/command-manifest.json +22 -1
  154. package/src/commands/agenda.js +228 -0
  155. package/src/commands/agent.js +45 -4
  156. package/src/commands/artifacts.js +161 -0
  157. package/src/commands/batch.js +345 -0
  158. package/src/commands/browse.js +204 -2
  159. package/src/data/changelog.json +13 -2
  160. package/src/gateways/ws/artifact-protocol.js +219 -0
  161. package/src/gateways/ws/message-dispatcher.js +6 -0
  162. package/src/gateways/ws/ws-server.js +32 -0
  163. package/src/index.js +18 -0
  164. package/src/lib/accessibility.js +55 -0
  165. package/src/lib/agent-batch.js +235 -0
  166. package/src/lib/agent-notify.js +66 -0
  167. package/src/lib/agent-schedule-store.js +330 -0
  168. package/src/lib/artifact-store.js +236 -0
  169. package/src/lib/chrome-connector.js +314 -0
  170. package/src/lib/hook-runner.cjs +47 -7
  171. package/src/lib/ide-context.js +84 -0
  172. package/src/lib/permission-rules.cjs +26 -3
  173. package/src/lib/plugin-runtime/scopes.js +12 -0
  174. package/src/lib/safe-mode.js +40 -0
  175. package/src/lib/shell-selector.cjs +203 -0
  176. package/src/lib/skill-loader.js +19 -0
  177. package/src/lib/slash-dispatch.js +34 -0
  178. package/src/repl/agent-repl.js +99 -58
  179. package/src/runtime/agent-core.js +197 -8
  180. package/src/runtime/coding-agent-contract-shared.cjs +156 -0
  181. package/src/runtime/coding-agent-policy.cjs +43 -0
  182. package/src/runtime/headless-stream.js +51 -1
  183. package/src/runtime/policies/agent-policy.js +1 -0
  184. package/src/assets/web-panel/assets/AppLayout-C6WIrDZk.js +0 -9
  185. package/src/assets/web-panel/assets/ChatBubbleRenderer-BFEnA8LN.js +0 -1
  186. package/src/assets/web-panel/assets/Inference-CoK8Ia0Z.js +0 -1
  187. package/src/assets/web-panel/assets/Marketplace-DFqhJMuY.js +0 -1
  188. package/src/assets/web-panel/assets/Reputation-CaRxB3Ep.js +0 -1
  189. package/src/assets/web-panel/assets/Search-BpjLBV8u.js +0 -1
  190. package/src/assets/web-panel/assets/Skills-DoTWIQOX.js +0 -1
  191. package/src/assets/web-panel/assets/Tasks-B3hEXNcI.js +0 -1
  192. package/src/assets/web-panel/assets/devWarning-Dr9dzlQ5.js +0 -1
  193. package/src/assets/web-panel/assets/index-B92M3t6B.js +0 -1
  194. package/src/assets/web-panel/assets/index-d2UcGpK-.js +0 -1
@@ -1041,6 +1041,7 @@ async function tryIdeDiffApprovalForEdit(
1041
1041
  hasIdeOpenDiff,
1042
1042
  requestIdeDiffApproval,
1043
1043
  formatReviewComments,
1044
+ summarizeUserAmendments,
1044
1045
  } = await import("../lib/ide-context.js");
1045
1046
  const mcpLike = {
1046
1047
  mcpClient: context.mcpClient,
@@ -1056,15 +1057,22 @@ async function tryIdeDiffApprovalForEdit(
1056
1057
  title: `cc agent: ${name} ${path.basename(proposal.filePath)}`,
1057
1058
  });
1058
1059
  if (verdict?.outcome === "accepted") {
1060
+ // When the reviewer amended the proposal in the diff before accepting,
1061
+ // hand the agent the actual -/+ delta — not just a flag — so its model
1062
+ // of the file matches what was really written (gap #4: the agent
1063
+ // perceives the user's edits).
1064
+ const amendments =
1065
+ verdict.finalText != null && verdict.finalText !== proposal.newContent
1066
+ ? summarizeUserAmendments(proposal.newContent, verdict.finalText)
1067
+ : null;
1059
1068
  return {
1060
1069
  outcome: "accepted",
1061
1070
  result: {
1062
1071
  success: true,
1063
1072
  path: proposal.filePath,
1064
1073
  appliedVia: "ide-diff",
1065
- ...(verdict.finalText != null &&
1066
- verdict.finalText !== proposal.newContent
1067
- ? { userEdited: true }
1074
+ ...(amendments
1075
+ ? { userEdited: true, userAmendments: amendments }
1068
1076
  : {}),
1069
1077
  policy: { decision: "allow", rule, via: "ide-diff" },
1070
1078
  },
@@ -2431,6 +2439,24 @@ async function executeToolInner(
2431
2439
  }
2432
2440
  }
2433
2441
 
2442
+ // P1 #8 Windows/PowerShell first-class: per-call args.shell or the
2443
+ // configured settings `shell.windowsDefault` may route this command
2444
+ // through PowerShell via explicit argv (`powershell.exe -NoProfile
2445
+ // [-ExecutionPolicy <p>] -Command <cmd>`). The unconfigured path keeps
2446
+ // the historical default shell byte-identical (useDefaultShell=true).
2447
+ const { resolveShellInvocation } =
2448
+ await import("../lib/shell-selector.cjs");
2449
+ const shellInv = resolveShellInvocation({
2450
+ command: args.command,
2451
+ requested: args.shell,
2452
+ cwd: args.cwd || cwd,
2453
+ });
2454
+ const shellMeta = shellInv.useDefaultShell
2455
+ ? shellInv.note
2456
+ ? { shell_note: shellInv.note }
2457
+ : {}
2458
+ : { shell: shellInv.kind };
2459
+
2434
2460
  // Background: spawn, register, return a task_id immediately. The agent
2435
2461
  // polls output + completion via check_shell. No timeout — that's the whole
2436
2462
  // point of backgrounding (builds, test suites, dev servers).
@@ -2463,9 +2489,9 @@ async function executeToolInner(
2463
2489
  child: null,
2464
2490
  };
2465
2491
  try {
2466
- const child = spawn(args.command, {
2492
+ const bgSpawnOpts = {
2467
2493
  cwd: task.cwd,
2468
- shell: true,
2494
+ shell: shellInv.useDefaultShell,
2469
2495
  windowsHide: true,
2470
2496
  // Same agent-identity env as the foreground path: CLAUDECODE marks
2471
2497
  // "running under the agent"; the session id correlates work to the
@@ -2484,7 +2510,12 @@ async function executeToolInner(
2484
2510
  // the whole tree (shell + its grandchild command). No-op on Windows
2485
2511
  // where the tree is killed via taskkill /T instead.
2486
2512
  detached: process.platform !== "win32",
2487
- });
2513
+ };
2514
+ // PowerShell route: explicit argv (shell:false above); default route
2515
+ // is the historical spawn(command, {shell:true}) byte-for-byte.
2516
+ const child = shellInv.useDefaultShell
2517
+ ? spawn(args.command, bgSpawnOpts)
2518
+ : spawn(shellInv.file, shellInv.argv, bgSpawnOpts);
2488
2519
  task.child = child;
2489
2520
  if (child.stdout) {
2490
2521
  child.stdout.setEncoding("utf8");
@@ -2532,6 +2563,7 @@ async function executeToolInner(
2532
2563
  task_id: id,
2533
2564
  status: task.status,
2534
2565
  command: task.command,
2566
+ ...shellMeta,
2535
2567
  hint: "Poll output and completion with the check_shell tool using this task_id. Kill long-lived servers with check_shell { task_id, kill: true } when done.",
2536
2568
  shellCommandPolicy: shellPolicy,
2537
2569
  approval: approvalOutcome,
@@ -2630,7 +2662,7 @@ async function executeToolInner(
2630
2662
  }
2631
2663
 
2632
2664
  try {
2633
- const output = execSync(args.command, {
2665
+ const fgExecOpts = {
2634
2666
  cwd: args.cwd || cwd,
2635
2667
  encoding: "utf8",
2636
2668
  timeout: _resolveShellTimeout(args.timeout),
@@ -2649,10 +2681,35 @@ async function executeToolInner(
2649
2681
  }
2650
2682
  : {}),
2651
2683
  },
2652
- });
2684
+ };
2685
+ let output;
2686
+ if (shellInv.useDefaultShell) {
2687
+ output = execSync(args.command, fgExecOpts);
2688
+ } else {
2689
+ // PowerShell route: explicit argv, no intermediate default shell.
2690
+ // Reproduce execSync's contract so the shared catch shapes errors
2691
+ // identically: throw on spawn error; throw an Error carrying
2692
+ // status/stdout/stderr on non-zero exit.
2693
+ const res = spawnSync(shellInv.file, shellInv.argv, {
2694
+ ...fgExecOpts,
2695
+ windowsHide: true,
2696
+ });
2697
+ if (res.error) throw res.error;
2698
+ if (res.status !== 0) {
2699
+ const e = new Error(
2700
+ `Command failed (${shellInv.kind}, exit ${res.status}): ${args.command}`,
2701
+ );
2702
+ e.status = res.status;
2703
+ e.stdout = res.stdout;
2704
+ e.stderr = res.stderr;
2705
+ throw e;
2706
+ }
2707
+ output = res.stdout ?? "";
2708
+ }
2653
2709
  return attachDescriptor(
2654
2710
  {
2655
2711
  stdout: output.substring(0, 30000),
2712
+ ...shellMeta,
2656
2713
  shellCommandPolicy: shellPolicy,
2657
2714
  approval: approvalOutcome,
2658
2715
  },
@@ -2672,6 +2729,7 @@ async function executeToolInner(
2672
2729
  : {}),
2673
2730
  stderr: (err.stderr || "").substring(0, 2000),
2674
2731
  exitCode: err.status,
2732
+ ...shellMeta,
2675
2733
  shellCommandPolicy: shellPolicy,
2676
2734
  approval: approvalOutcome,
2677
2735
  },
@@ -3010,6 +3068,125 @@ async function executeToolInner(
3010
3068
  }
3011
3069
  }
3012
3070
 
3071
+ case "notify": {
3072
+ try {
3073
+ const { sendAgentNotification } =
3074
+ await import("../lib/agent-notify.js");
3075
+ const outcome = await sendAgentNotification({
3076
+ title: args.title,
3077
+ body: args.body,
3078
+ level: args.level,
3079
+ });
3080
+ return attachDescriptor(outcome);
3081
+ } catch (err) {
3082
+ return attachDescriptor({ error: `notify failed: ${err.message}` });
3083
+ }
3084
+ }
3085
+
3086
+ case "schedule": {
3087
+ try {
3088
+ const { AgentScheduleStore } =
3089
+ await import("../lib/agent-schedule-store.js");
3090
+ const { parseDuration } = await import("../lib/loop.js");
3091
+ const store = new AgentScheduleStore();
3092
+ const action = String(args.action || "").toLowerCase();
3093
+ if (action === "wakeup") {
3094
+ if (!args.prompt) {
3095
+ return attachDescriptor({
3096
+ error: "schedule wakeup requires a prompt",
3097
+ });
3098
+ }
3099
+ const delayMs = args.delay ? parseDuration(args.delay) : 0;
3100
+ const entry = store.scheduleWakeup({
3101
+ prompt: args.prompt,
3102
+ delayMs,
3103
+ label: args.label || null,
3104
+ });
3105
+ return attachDescriptor({
3106
+ scheduled: entry,
3107
+ hint: "Run `cc agenda run` (e.g. via cron or `cc loop`) to fire due entries.",
3108
+ });
3109
+ }
3110
+ if (action === "cron") {
3111
+ if (!args.prompt || !args.cron) {
3112
+ return attachDescriptor({
3113
+ error: "schedule cron requires a prompt and a cron expression",
3114
+ });
3115
+ }
3116
+ const entry = store.createCron({
3117
+ prompt: args.prompt,
3118
+ cron: args.cron,
3119
+ label: args.label || null,
3120
+ });
3121
+ return attachDescriptor({ scheduled: entry });
3122
+ }
3123
+ if (action === "monitor") {
3124
+ if (!args.command) {
3125
+ return attachDescriptor({
3126
+ error: "schedule monitor requires a command",
3127
+ });
3128
+ }
3129
+ const intervalMs = args.interval
3130
+ ? parseDuration(args.interval)
3131
+ : 60000;
3132
+ const entry = store.createMonitor({
3133
+ command: args.command,
3134
+ intervalMs,
3135
+ stopWhen: args.stop_when || null,
3136
+ notify: args.notify_title ? { title: args.notify_title } : null,
3137
+ maxChecks: args.max_checks ?? null,
3138
+ label: args.label || null,
3139
+ });
3140
+ return attachDescriptor({ scheduled: entry });
3141
+ }
3142
+ if (action === "list") {
3143
+ return attachDescriptor({ entries: store.list() });
3144
+ }
3145
+ if (action === "cancel") {
3146
+ if (!args.id) {
3147
+ return attachDescriptor({
3148
+ error: "schedule cancel requires an id",
3149
+ });
3150
+ }
3151
+ const removed = store.cancel(args.id);
3152
+ return attachDescriptor({
3153
+ cancelled: removed ? removed.id : null,
3154
+ found: Boolean(removed),
3155
+ });
3156
+ }
3157
+ return attachDescriptor({
3158
+ error: `unknown schedule action "${args.action}". Valid: wakeup, cron, monitor, list, cancel.`,
3159
+ });
3160
+ } catch (err) {
3161
+ return attachDescriptor({ error: `schedule failed: ${err.message}` });
3162
+ }
3163
+ }
3164
+
3165
+ case "publish_artifact": {
3166
+ // P1 #10: copy a finished deliverable into the user's artifact store.
3167
+ // Only METADATA returns to the conversation (the transcript never
3168
+ // carries the file body); `cc artifacts` lists/inspects/cleans.
3169
+ try {
3170
+ const { ArtifactStore } = await import("../lib/artifact-store.js");
3171
+ const store = new ArtifactStore();
3172
+ const entry = store.publish({
3173
+ filePath: path.resolve(cwd, String(args.path || "")),
3174
+ title: args.title,
3175
+ kind: args.kind,
3176
+ ttlDays: args.ttl_days,
3177
+ sessionId: sessionId ? String(sessionId) : null,
3178
+ });
3179
+ return attachDescriptor({
3180
+ published: entry,
3181
+ hint: "The user can browse this with `cc artifacts list` / `cc artifacts show <id>`.",
3182
+ });
3183
+ } catch (err) {
3184
+ return attachDescriptor({
3185
+ error: `publish_artifact failed: ${err.message}`,
3186
+ });
3187
+ }
3188
+ }
3189
+
3013
3190
  case "search_files": {
3014
3191
  // An explicit directory scopes the search to one root; otherwise span
3015
3192
  // cwd plus any --add-dir roots so cross-package searches find matches.
@@ -6342,6 +6519,18 @@ export function formatToolArgs(name, args) {
6342
6519
  return `[${args.role}] ${(args.task || "").substring(0, 60)}`;
6343
6520
  case "search_sessions":
6344
6521
  return `"${(args.query || "").substring(0, 60)}"`;
6522
+ case "notify":
6523
+ return `${args.level || "info"}: ${(args.title || "").substring(0, 50)}`;
6524
+ case "publish_artifact":
6525
+ return `${args.kind || "other"}: ${(args.title || args.path || "").substring(0, 60)}`;
6526
+ case "schedule":
6527
+ return args.action === "cron"
6528
+ ? `cron ${args.cron || ""}`.trim()
6529
+ : args.action === "monitor"
6530
+ ? `monitor ${(args.command || "").substring(0, 40)}`.trim()
6531
+ : args.action === "wakeup"
6532
+ ? `wakeup +${args.delay || "0s"}`
6533
+ : String(args.action || "");
6345
6534
  default:
6346
6535
  return JSON.stringify(args).substring(0, 60);
6347
6536
  }
@@ -238,6 +238,12 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
238
238
  description:
239
239
  "Foreground (synchronous) timeout in milliseconds. Default 60000, max 600000. Ignored when run_in_background is true.",
240
240
  },
241
+ shell: {
242
+ type: "string",
243
+ enum: ["default", "cmd", "powershell", "pwsh"],
244
+ description:
245
+ "Shell to run the command with (optional). default = the platform shell (cmd.exe on Windows, /bin/sh elsewhere) or the configured settings shell.windowsDefault. Use powershell (Windows PowerShell 5.1) or pwsh (PowerShell 7+) when the command uses PowerShell syntax: cmdlets, object pipelines, $variables.",
246
+ },
241
247
  },
242
248
  required: ["command"],
243
249
  },
@@ -849,6 +855,156 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
849
855
  tags: ["tool:search_sessions", "contract:coding-agent", "tier:extension"],
850
856
  },
851
857
  },
858
+ {
859
+ name: "notify",
860
+ title: "Send Notification",
861
+ kind: "notify",
862
+ tier: "extension",
863
+ description:
864
+ "Push a notification to the user's configured channels (Telegram / WeCom / DingTalk / Feishu) and/or a paired mobile device. Use for long-running tasks: report completion, flag that you need a human decision, or surface an error. Best-effort: reports which channels delivered.",
865
+ inputSchema: {
866
+ type: "object",
867
+ properties: {
868
+ title: { type: "string", description: "Short notification title" },
869
+ body: { type: "string", description: "Notification body text" },
870
+ level: {
871
+ type: "string",
872
+ enum: ["info", "success", "failure"],
873
+ description: "Severity (default: info)",
874
+ },
875
+ },
876
+ required: ["title"],
877
+ },
878
+ ...TOOL_POLICY_METADATA.notify,
879
+ permissions: {
880
+ level: "standard",
881
+ scopes: ["network:notify"],
882
+ },
883
+ telemetry: {
884
+ category: "notify",
885
+ tags: ["tool:notify", "contract:coding-agent", "tier:extension"],
886
+ },
887
+ },
888
+ {
889
+ name: "schedule",
890
+ title: "Schedule / Monitor",
891
+ kind: "schedule",
892
+ tier: "extension",
893
+ description:
894
+ "Set up work that outlives this turn (persisted for `cc agenda run` to execute). Actions: `wakeup` — run a prompt once after a delay; `cron` — run a prompt on a 5-field cron schedule; `monitor` — run a shell command every interval and notify when its output matches a regex; `list` — show scheduled items; `cancel` — remove one by id.",
895
+ inputSchema: {
896
+ type: "object",
897
+ properties: {
898
+ action: {
899
+ type: "string",
900
+ enum: ["wakeup", "cron", "monitor", "list", "cancel"],
901
+ description: "What to do",
902
+ },
903
+ prompt: {
904
+ type: "string",
905
+ description:
906
+ "For wakeup/cron: the agent prompt to run (via `cc agent -p`) when it fires",
907
+ },
908
+ delay: {
909
+ type: "string",
910
+ description:
911
+ "For wakeup: how long from now before it fires (e.g. 30s, 5m, 1h)",
912
+ },
913
+ cron: {
914
+ type: "string",
915
+ description:
916
+ 'For cron: a 5-field cron expression, e.g. "0 9 * * 1" (09:00 every Monday)',
917
+ },
918
+ command: {
919
+ type: "string",
920
+ description: "For monitor: the shell command to run each interval",
921
+ },
922
+ interval: {
923
+ type: "string",
924
+ description:
925
+ "For monitor: how often to run the command (e.g. 30s, 5m)",
926
+ },
927
+ stop_when: {
928
+ type: "string",
929
+ description:
930
+ "For monitor: a regex; when the command output matches, the monitor fires its notification and stops",
931
+ },
932
+ notify_title: {
933
+ type: "string",
934
+ description: "For monitor: notification title sent when it matches",
935
+ },
936
+ max_checks: {
937
+ type: "number",
938
+ description:
939
+ "For monitor: give up after this many checks (optional safety cap)",
940
+ },
941
+ label: {
942
+ type: "string",
943
+ description: "Optional human label for list/cancel",
944
+ },
945
+ id: {
946
+ type: "string",
947
+ description: "For cancel: the schedule entry id to remove",
948
+ },
949
+ },
950
+ required: ["action"],
951
+ },
952
+ ...TOOL_POLICY_METADATA.schedule,
953
+ permissions: {
954
+ level: "standard",
955
+ scopes: ["schedule:write"],
956
+ },
957
+ telemetry: {
958
+ category: "schedule",
959
+ tags: ["tool:schedule", "contract:coding-agent", "tier:extension"],
960
+ },
961
+ },
962
+ {
963
+ name: "publish_artifact",
964
+ title: "Publish Artifact",
965
+ kind: "artifact",
966
+ tier: "extension",
967
+ description:
968
+ "Publish a finished deliverable file (Markdown report, patch, screenshot, test log, findings JSON) as a durable artifact the user can find later with `cc artifacts`. The file is copied into the user's artifact store with metadata; only the metadata enters the conversation. Use at the END of a task for its key outputs — not for intermediate scratch files.",
969
+ inputSchema: {
970
+ type: "object",
971
+ properties: {
972
+ path: {
973
+ type: "string",
974
+ description:
975
+ "Path of the file to publish (relative to cwd or absolute)",
976
+ },
977
+ title: {
978
+ type: "string",
979
+ description: "Human title for the artifact (default: the file name)",
980
+ },
981
+ kind: {
982
+ type: "string",
983
+ enum: ["report", "patch", "screenshot", "log", "data", "other"],
984
+ description: "What kind of deliverable this is (default: other)",
985
+ },
986
+ ttl_days: {
987
+ type: "number",
988
+ description:
989
+ "Days to retain before `cc artifacts clean` may remove it (default 30)",
990
+ },
991
+ },
992
+ required: ["path"],
993
+ },
994
+ ...TOOL_POLICY_METADATA.publish_artifact,
995
+ permissions: {
996
+ level: "standard",
997
+ scopes: ["filesystem:read", "artifact:write"],
998
+ },
999
+ telemetry: {
1000
+ category: "artifact",
1001
+ tags: [
1002
+ "tool:publish_artifact",
1003
+ "contract:coding-agent",
1004
+ "tier:extension",
1005
+ ],
1006
+ },
1007
+ },
852
1008
  ]);
853
1009
 
854
1010
  const CODING_AGENT_MVP_TOOL_NAMES = Object.freeze(
@@ -261,6 +261,49 @@ const TOOL_POLICY_METADATA = Object.freeze({
261
261
  approvalFlow: "auto",
262
262
  isReadOnly: true,
263
263
  },
264
+ // Sends an outbound notification to the user's own channels/device. No
265
+ // workspace mutation and no un-gated shell; blocked in plan mode (an
266
+ // external side effect) but otherwise auto — it targets the user, not a
267
+ // third party.
268
+ notify: {
269
+ riskLevel: RISK_LEVELS.LOW,
270
+ category: TOOL_CATEGORIES.WRITE,
271
+ availableInPlanMode: false,
272
+ planModeBehavior: "blocked",
273
+ requiresPlanApproval: false,
274
+ requiresConfirmation: false,
275
+ approvalFlow: "auto",
276
+ isReadOnly: false,
277
+ },
278
+ // Persists a wakeup/cron/monitor entry for `cc agenda run` to execute later.
279
+ // Writing the schedule is itself harmless (a JSONL row under the user's
280
+ // config dir); the eventual `cc agent`/shell run is gated when the agenda
281
+ // consumer executes it. Blocked in plan mode (schedules future side effects).
282
+ schedule: {
283
+ riskLevel: RISK_LEVELS.LOW,
284
+ category: TOOL_CATEGORIES.WRITE,
285
+ availableInPlanMode: false,
286
+ planModeBehavior: "blocked",
287
+ requiresPlanApproval: false,
288
+ requiresConfirmation: false,
289
+ approvalFlow: "auto",
290
+ isReadOnly: false,
291
+ },
292
+ // Copies a finished deliverable (report/patch/screenshot/log) into the
293
+ // user's own ~/.chainlesschain/artifacts store with metadata. Reads a
294
+ // workspace file, writes only under the user's config dir — no third-party
295
+ // egress. Blocked in plan mode (publishing is a side effect of DONE work,
296
+ // not analysis).
297
+ publish_artifact: {
298
+ riskLevel: RISK_LEVELS.LOW,
299
+ category: TOOL_CATEGORIES.WRITE,
300
+ availableInPlanMode: false,
301
+ planModeBehavior: "blocked",
302
+ requiresPlanApproval: false,
303
+ requiresConfirmation: false,
304
+ approvalFlow: "auto",
305
+ isReadOnly: false,
306
+ },
264
307
  });
265
308
 
266
309
  function normalizeGitCommand(command) {
@@ -181,6 +181,47 @@ export function planSnapshot(pm) {
181
181
  }
182
182
  return { active: pm.isActive(), state: pm.state || null, items, risk };
183
183
  }
184
+
185
+ const MAX_PLAN_REVIEW_SNAPSHOT_CHARS = 24000;
186
+
187
+ function planReviewFromInput(obj) {
188
+ const review =
189
+ obj && obj.review && typeof obj.review === "object" ? obj.review : null;
190
+ const snapshot =
191
+ typeof obj?.snapshot === "string"
192
+ ? obj.snapshot
193
+ : typeof review?.snapshot === "string"
194
+ ? review.snapshot
195
+ : "";
196
+ if (!snapshot.trim()) return null;
197
+ const text =
198
+ snapshot.length > MAX_PLAN_REVIEW_SNAPSHOT_CHARS
199
+ ? snapshot.slice(0, MAX_PLAN_REVIEW_SNAPSHOT_CHARS) +
200
+ `\n\n[review snapshot truncated: ${snapshot.length - MAX_PLAN_REVIEW_SNAPSHOT_CHARS} chars omitted]`
201
+ : snapshot;
202
+ return {
203
+ action: String(review?.action || obj.action || "").toLowerCase(),
204
+ reviewedAt:
205
+ typeof review?.reviewedAt === "string" ? review.reviewedAt : null,
206
+ conversationId:
207
+ typeof review?.conversationId === "string" ? review.conversationId : null,
208
+ snapshot: text,
209
+ };
210
+ }
211
+
212
+ function planReviewSystemMessage(review) {
213
+ if (!review?.snapshot) return null;
214
+ const meta = [
215
+ review.action ? `action=${review.action}` : null,
216
+ review.reviewedAt ? `reviewedAt=${review.reviewedAt}` : null,
217
+ review.conversationId ? `conversationId=${review.conversationId}` : null,
218
+ ]
219
+ .filter(Boolean)
220
+ .join(" ");
221
+ return (
222
+ "[PLAN REVIEW SNAPSHOT]" + (meta ? ` ${meta}` : "") + "\n" + review.snapshot
223
+ );
224
+ }
184
225
  import { withQuietStdout } from "./quiet-stdout.js";
185
226
 
186
227
  /**
@@ -199,7 +240,9 @@ export function parseInputEvent(line) {
199
240
  // {"type":"plan","action":"enter"|"approve"|"reject"}
200
241
  if (obj && typeof obj === "object" && obj.type === "plan") {
201
242
  const action = String(obj.action || "").toLowerCase();
202
- return action ? { plan: action } : null;
243
+ if (!action) return null;
244
+ const planReview = planReviewFromInput(obj);
245
+ return planReview ? { plan: action, planReview } : { plan: action };
203
246
  }
204
247
  // Turn interrupt (panel Stop / Claude-Code Esc parity): aborts the
205
248
  // in-flight turn without ending the conversation. {"type":"interrupt"}
@@ -1304,6 +1347,13 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1304
1347
  // exits plan mode. Every control answers with a `plan_update` event.
1305
1348
  if (parsed.plan) {
1306
1349
  const pm = getPlanModeManager();
1350
+ const reviewMessage =
1351
+ parsed.plan === "approve" || parsed.plan === "reject"
1352
+ ? planReviewSystemMessage(parsed.planReview)
1353
+ : null;
1354
+ if (reviewMessage) {
1355
+ messages.push({ role: "system", content: reviewMessage });
1356
+ }
1307
1357
  if (parsed.plan === "enter") {
1308
1358
  if (!pm.isActive()) {
1309
1359
  pm.enterPlanMode({ title: "Agent Plan" });
@@ -55,6 +55,7 @@ export function resolveAgentPolicy({
55
55
  fallbackModels: overrides.fallbackModels,
56
56
  pdh: overrides.pdh,
57
57
  outputStyle: overrides.outputStyle,
58
+ disableSlashCommands: overrides.disableSlashCommands === true,
58
59
  };
59
60
  }
60
61