chainlesschain 0.166.127 → 0.166.129

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 (183) hide show
  1. package/README.md +25 -1
  2. package/package.json +1 -1
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/assets/{AIOps-DkSOwKNn.js → AIOps-CjPaaF2r.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-CaYSnkeR.js → ActionButton-_zlP_Z6z.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-D8kEgXLP.js → Analytics-C7X31L8l.js} +2 -2
  8. package/src/assets/web-panel/assets/{AppLayout-D43FaO4a.js → AppLayout-BmYa34Se.js} +3 -3
  9. package/src/assets/web-panel/assets/{Artifacts-DfxY2Gqs.js → Artifacts-B_YKNjlp.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-0ogv1Zu5.js → Audit-5JsI67XQ.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-BhLnn-Gw.js → BackgroundAgents-BL3QbzvS.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-D4591rlk.js → Backup-BRmg-gTa.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-gK1PjPDZ.js → BaseInput-DNE7mT3K.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-CCDmOYwg.js → Chat-OYwAopdM.js} +5 -5
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-Dtxw3Wgt.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-DG4PRH9M.js → Checkbox-nMgYkH8H.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-DtJxGiSg.js → Codegen-B9G2ngLI.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-4wGBC25p.js → Col-i0owJaGP.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-dOCSc8t-.js → Community-B3Ta0mI_.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-Du4kXsyN.js → Compact-DDXrvvm-.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-BbI5XMcz.js → Compliance-Bn4Uq6U1.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-CbQRpyiK.js → Cowork-CO5NKD6r.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-CtWy2bMC.js → Cron-ByjNese0.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-CzdM5hF6.js → Crosschain-BN1FUYyi.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-CcBboBJN.js → DID-CUFX5RL3.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-I7m0oCeC.js → Dashboard-D_2FDPBP.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-CKIy2Ikn.js → Dropdown-lGOMtIzb.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-BNuxCq89.js → EmailListRenderer-DA3Qf1S2.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-BeBovLZs.js → EvolutionSettings-DLcnicCr.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-QThmET-n.js → FamilyGuardDashboard-BPOSaIN1.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-Bqf7YYlV.js → Federation-DzJUCQq8.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-DZAM28ve.js → FormItemContext-DVx1XNKx.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-DunXFYML.js → GenericCardRenderer-BkqzO_lh.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-BgwOjaMf.js → Git-Dr_rdT_j.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-B1za4wCP.js → Governance-DyVkZddw.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-DMPqX1oN.js → Inference-IN2YDd4v.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-ChDn3okr.js → KnowledgeGraph-Ceiy4n6N.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-BQoPB6-O.js → Logs-d7pIEAX2.js} +2 -2
  39. package/src/assets/web-panel/assets/MarkdownRenderer-DmSl0MNI.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-DZXEaPpe.js → Marketplace-uVE7U14g.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-CZbVOFaG.js → McpTools-DUfBM--y.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-Cl3T8asu.js → Memory-6gkcR02J.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-DK_ayU9I.js → MobileBridge-Cl6ys2O9.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-DEWAA2gT.js → MobileProjects-5P8jN4gf.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-z-XAWzMh.js → Mtc-DtiT1Kol.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-CX7qJvQS.js → MtcAudit-DZz8iiTE.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-DiQlKgxx.js → Multisig-DFH3-fBJ.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-Ciuxcu00.js → NLProgramming-BYNuDOt-.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-BAvqNw_6.js → Notes-BCY4jgYy.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-DkHDTslA.js → NotificationSettings-Bk2ltghU.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer--WZdD2oV.js → OrderTableRenderer-OdeXEGAn.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-Bv6bMLCe.js → Organization-CY4_mSiV.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-Bwoz_oq1.js → Overflow-CaRUAOY_.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-De7T0ZeB.js → P2P-Bd96rBWQ.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-Dblr2x25.js → PdhVaultBrowser-JjnExxan.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-C-jAt-cg.js → Permissions-CW1PUJB0.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-yXeXDMgf.js → PersonalDataHub-BNn9alTk.js} +3 -3
  58. package/src/assets/web-panel/assets/{Pipeline-C8CYoLOa.js → Pipeline-01_PBiUu.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-B-gwnOGT.js → Privacy-BP4DlVGb.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-CbNjHiBV.js → ProjectInit-CAMnQj4n.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-BMUY0GCP.js → ProjectSettings-DKxV5On_.js} +2 -2
  62. package/src/assets/web-panel/assets/Projects-B_4kRnM8.js +1 -0
  63. package/src/assets/web-panel/assets/{Providers-K_tlWkON.js → Providers-DeqqZyUv.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-2RSZDzJI.js → QrScannerModal-fFkycCT4.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-mhbcQRMI.js → QuickAsk-Ln6qQidy.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-BXm0uG0q.js → Recommend-DeENA-y0.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-xhOpmNZG.js → RemoteSession-CRxSYxo4.js} +3 -3
  68. package/src/assets/web-panel/assets/{Reputation-CwbCWB-3.js → Reputation-B2kU2F0l.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-BdAjmDBO.js → Row-lV_nLlFq.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-Cq4LZ9WU.js → RssFeed-Df21mCdF.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-C_I6B-4l.js → Search-8_Dz4qU9.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-CdH6mzL-.js → Security-Cl5-PEcp.js} +3 -3
  73. package/src/assets/web-panel/assets/{Services-CWu1wqtS.js → Services-C5qgCqA7.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-daw9DiVM.js → Skeleton-ASRgSh_Y.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-CmurIxkM.js → Skills-DWx01ZJ7.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-cETA5aPO.js → Sla-I2gbgtW8.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-B1llZgu3.js → SpeechSettings-BqTikzfe.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-DufZ-B2q.js → SyncSettings-D3zCpBFV.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-PfRLKTFY.js → Tasks-DjMWII45.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-DGtz-vT8.js → Templates-Cq7qDnHX.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-JeKYLN0b.js → Tenant-DEasKDpQ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-BiMsF2Y0.js → Terminal-J6fLkTzi.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-DhcBAGPg.js → TimelineRenderer-CNvWrWN-.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-DpIg-0ju.js → Tokens-BSgHJCKH.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-DreKHxyb.js → Trigger-DgGU_D0o.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-D7ByQvBQ.js → Trust-BANlv-uB.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-OudyQByy.js → UkeySign-qh8GPRsU.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-BhU6nzCF.js → VideoEditing-DBiGTB4H.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-BCEpB6E0.js → Wallet-DMUFR7cL.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-DwjAM5Mr.js → WebAuthn-DP9nQQzW.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor-ChQqlAmY.js → WorkflowEditor-DT_6jDkL.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-CzUKWqTy.js → chat-C_kELmV6.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-D3Y_Pvu4.js → colors-DE-ZxAv_.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-ByyPRfkA.js → compact-item-BowulLDi.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-Dt5PF6VI.js → createContext-DCh8oMBQ.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-BVvJAp91.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-BuIaEKuC.js → hasIn-Be7mK-iw.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BO29sPX8.js → index-3Ql7xQLn.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CFXZ9lbO.js → index-4KkYmFy5.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DHzVIQLX.js → index-6OluUVJJ.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DxVLI-Iu.js → index-Ao-LXr-d.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-COsjgjvP.js → index-B-3EDOlf.js} +1 -1
  103. package/src/assets/web-panel/assets/index-B7IhCfsh.js +1 -0
  104. package/src/assets/web-panel/assets/{index-CCBm8_o4.js → index-BDIIR8g6.js} +1 -1
  105. package/src/assets/web-panel/assets/index-BMrbe_Ey.js +1 -0
  106. package/src/assets/web-panel/assets/{index-BFQGN97S.js → index-BdzVLz-c.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CmrfHS36.js → index-BlzMqaWB.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-GyTOYTFg.js → index-BwY31W-u.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CAfX0VyL.js → index-C2pCquZC.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BdvZNMNm.js → index-CKmC6ugN.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CgPKUSe4.js → index-CL2hAUWh.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BmVY2f7I.js → index-CUXfwAhF.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Di78LDr8.js → index-CXvy8HrM.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DpAqy6Co.js → index-C_VnSUjh.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DSXjiZAV.js → index-CecGCLWI.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-D51wU4q-.js → index-Ck6MYKVN.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-gg5zO3aD.js → index-Cvy4vdVW.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-1YgdY0Vq.js → index-CwJfLNqv.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-NFqKQquS.js → index-D3lOYd9_.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CDTS4qJm.js → index-DEDVYN7D.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BwlY7Yap.js → index-DLCzaLH4.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BcqZAAr5.js → index-DMDaGPxG.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DWW5svXU.js → index-DMKo49Um.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CByWkXdO.js → index-DN1AT3FH.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-EtrWRKu2.js → index-DOebEvgn.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-D7QSTEjb.js → index-DPX3N4T8.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-F-T8AHeo.js → index-DSRKtgJg.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-B600riYP.js → index-DSqZBvQM.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BSWTyRhI.js → index-DbrQO1p9.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-huWw0XBb.js → index-DjC2TJeH.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Dlec7Sr4.js → index-LVrxqU88.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CZX4_hGp.js → index-OH54KMLN.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DSgroT-P.js → index-Qx8cTReg.js} +3 -3
  134. package/src/assets/web-panel/assets/{index-BztqxXMP.js → index-_cYsz4df.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-Cb7MzML-.js → index-lN916819.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-_oJnnOnZ.js → index-nLHTuHoT.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-Bny6G13G.js → initDefaultProps-BNhziAal.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-DRhRj_uM.js → motion-fUkbJz38.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-D0wKnhYr.js → move-rFx211Cl.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-BXXSTJBk.js → mtc-parser-CEP1wN3R.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-d8t9Yze4.js → omit-DacHd_Zm.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-nyB6BMe6.js → pickAttrs-Dqp58Ep2.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-CSFyBNA2.js → placementArrow-Cv6Rm0pV.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-DYmiKhJa.js → responsiveObserve-rNE0p9ZW.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-D4KZSRmt.js → slide-C97JxD4S.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-BcrcPeFm.js → statusUtils-Cxk1gV9M.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-BFgOb1vz.js → styleChecker-CbtKKsPo.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-DQ5qSQlN.js → useFlexGapSupport-CQATs2JQ.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-Cafq069l.js → useFs-6c7qrpE_.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-DTma9Ary.js → usePersonalDataHub-OjxtBGe7.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-HvC2-bE9.js → vnode-CSlXfUSh.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-AZxADWXu.js → zoom-Cc1qKiSZ.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +1 -1
  155. package/src/commands/agent.js +29 -0
  156. package/src/commands/setup.js +35 -10
  157. package/src/constants.js +15 -89
  158. package/src/data/changelog.json +27 -1
  159. package/src/lib/bm25-search.js +6 -3
  160. package/src/lib/codex-app-server-adapter.js +36 -22
  161. package/src/lib/codex-app-server-support.js +91 -0
  162. package/src/lib/coding-change-review-context.js +258 -0
  163. package/src/lib/coding-task-guidance.js +9 -1
  164. package/src/lib/context-memory-kernel/memory-query-index.js +35 -17
  165. package/src/lib/context-memory-kernel/provider-context.js +22 -12
  166. package/src/lib/goal-check-evidence.js +159 -0
  167. package/src/lib/goal-condition-engine.js +24 -2
  168. package/src/lib/llm-connection-probe.js +48 -4
  169. package/src/lib/llm-onboarding-catalog.json +131 -0
  170. package/src/lib/skill-retrieval-router.js +2 -1
  171. package/src/lib/skill-search-tokenizer.js +143 -0
  172. package/src/repl/agent-repl.js +8 -4
  173. package/src/runtime/agent-core.js +207 -42
  174. package/src/runtime/headless-runner.js +138 -66
  175. package/src/runtime/headless-stream.js +1 -0
  176. package/src/runtime/mcp-tool-search-ranking.js +142 -0
  177. package/src/runtime/mcp-tool-search.js +198 -60
  178. package/src/assets/web-panel/assets/ChatBubbleRenderer-CnpWe3dp.js +0 -1
  179. package/src/assets/web-panel/assets/MarkdownRenderer-uS1yHX12.js +0 -1
  180. package/src/assets/web-panel/assets/Projects-DpCaWXv6.js +0 -1
  181. package/src/assets/web-panel/assets/devWarning-BgSxkkQ3.js +0 -1
  182. package/src/assets/web-panel/assets/index-D5v6roiB.js +0 -1
  183. package/src/assets/web-panel/assets/index-DgXZCvH5.js +0 -1
@@ -65,7 +65,11 @@ import {
65
65
  copyHostToolOutputIdentity,
66
66
  } from "../lib/tool-result-preview.js";
67
67
  import { DIAGNOSTIC_WORKFLOW_GUIDANCE } from "../lib/diagnostic-workflow.js";
68
- import { CODING_TASK_QUALITY_GUIDANCE } from "../lib/coding-task-guidance.js";
68
+ import {
69
+ CODING_TASK_QUALITY_GUIDANCE,
70
+ CODING_CHANGE_REVIEW_PROMPT,
71
+ } from "../lib/coding-task-guidance.js";
72
+ import { CodingChangeReviewContext } from "../lib/coding-change-review-context.js";
69
73
  import { RemoteReadLoopGuard } from "../lib/remote-read-loop-guard.js";
70
74
  import {
71
75
  isPrActionRequest,
@@ -198,7 +202,11 @@ import {
198
202
  toOllamaMessages,
199
203
  imageUrlBlockToAnthropic,
200
204
  } from "../lib/image-input.js";
201
- import { executeToolSearch, gateDeferredMcpCall } from "./mcp-tool-search.js";
205
+ import {
206
+ executeToolSearch,
207
+ gateDeferredMcpCall,
208
+ projectMcpToolDefinitions,
209
+ } from "./mcp-tool-search.js";
202
210
  import {
203
211
  emitHooksV2Event,
204
212
  executeHooksV2Event,
@@ -9669,7 +9677,9 @@ async function executeToolInner(
9669
9677
  // local — same risk class as list_skills, so no approval gate.
9670
9678
  if (localToolExecutor?.kind === "tool-search") {
9671
9679
  return attachDescriptor(
9672
- executeToolSearch(localToolExecutor.registry, args || {}),
9680
+ executeToolSearch(localToolExecutor.registry, args || {}, {
9681
+ allowedToolNames: effectiveAllowedToolNames,
9682
+ }),
9673
9683
  );
9674
9684
  }
9675
9685
 
@@ -12010,6 +12020,13 @@ function getEffectiveToolDefinitions(options = {}) {
12010
12020
  });
12011
12021
  }
12012
12022
 
12023
+ function getProviderToolDefinitions(options = {}) {
12024
+ return projectMcpToolDefinitions(
12025
+ getEffectiveToolDefinitions(options),
12026
+ options.externalToolExecutors,
12027
+ );
12028
+ }
12029
+
12013
12030
  const PROVIDER_REQUEST_ID_RE = /^[\x21-\x7e]{1,512}$/;
12014
12031
 
12015
12032
  function _normalizeProviderRequestId(value) {
@@ -12109,7 +12126,7 @@ export async function chatWithTools(rawMessages, options) {
12109
12126
  options.providerRequestId,
12110
12127
  );
12111
12128
 
12112
- let tools = getEffectiveToolDefinitions(options);
12129
+ let tools = getProviderToolDefinitions(options);
12113
12130
  if (Array.isArray(options.contextMemorySelectedToolNames)) {
12114
12131
  const selected = new Set(options.contextMemorySelectedToolNames);
12115
12132
  tools = tools.filter((tool) => selected.has(tool?.function?.name));
@@ -14698,12 +14715,32 @@ export async function* agentLoop(messages, options) {
14698
14715
  const { HostResourceBudget } = await import("../lib/host-resource-budget.js");
14699
14716
  const hostResourceBudget =
14700
14717
  options.hostResourceBudget || new HostResourceBudget();
14701
- const taskProgressTracker =
14718
+ let taskProgressTracker =
14702
14719
  options.taskProgressTracker || new TaskProgressTracker();
14720
+ const hostTaskProgressTracker = taskProgressTracker;
14703
14721
  // A subtree preflight is deliberately not an executed mutation. Keep this
14704
14722
  // obligation outside transcript compaction and never replay it automatically.
14705
14723
  const pendingSubtreeMutations = new Map();
14706
14724
  let subtreeMutationReprompted = false;
14725
+ let hasFileContentChanges = false;
14726
+ // Headless outer turns share this object; a new user turn gets a fresh one.
14727
+ const changeReviewState = options._changeReviewState || { requested: false };
14728
+ let independentReviewContext = null;
14729
+ let independentReviewSetupError = null;
14730
+ const appendMessages = (...entries) => {
14731
+ // Keep complete review tool groups in both the durable conversation and a
14732
+ // separate request journal. Canonical compaction cannot restore author
14733
+ // rationale to this journal or remove its current file observations.
14734
+ independentReviewContext?.record(...entries);
14735
+ messages.push(...entries);
14736
+ };
14737
+ const recordTaskProgress = (...args) => {
14738
+ const advanced = taskProgressTracker.record(...args);
14739
+ if (taskProgressTracker !== hostTaskProgressTracker) {
14740
+ hostTaskProgressTracker.record(...args);
14741
+ }
14742
+ return advanced;
14743
+ };
14707
14744
  const recordSubtreeMutation = (tool, args, result) => {
14708
14745
  if (!GUARDED_FILE_MUTATION_TOOLS.has(tool)) return;
14709
14746
  if (!args || typeof args !== "object" || Array.isArray(args)) return;
@@ -14747,6 +14784,7 @@ export async function* agentLoop(messages, options) {
14747
14784
  result.mutationPerformed !== false
14748
14785
  ) {
14749
14786
  pendingSubtreeMutations.delete(key);
14787
+ if (effect === "file-content") hasFileContentChanges = true;
14750
14788
  }
14751
14789
  };
14752
14790
  const signal = options.signal || null;
@@ -14768,6 +14806,23 @@ export async function* agentLoop(messages, options) {
14768
14806
  { cwd: options.cwd || process.cwd() },
14769
14807
  );
14770
14808
  const hermeticExecution = options.hermeticExecution === true;
14809
+ if (options.reviewChanges === true && hermeticExecution) {
14810
+ if (changeReviewState.independentReviewPending === true) {
14811
+ const error = new Error(
14812
+ "An interrupted independent review cannot resume from author history; the task remains incomplete.",
14813
+ );
14814
+ error.code = "CC_CHANGE_REVIEW_RECONSTRUCTION_REQUIRED";
14815
+ throw error;
14816
+ }
14817
+ try {
14818
+ independentReviewContext = new CodingChangeReviewContext(messages);
14819
+ } catch (error) {
14820
+ // An explanation without writes still keeps its old behavior. If a
14821
+ // mutation later arms review, stop before an extra call rather than
14822
+ // silently falling back to the author's summarized context.
14823
+ independentReviewSetupError = error;
14824
+ }
14825
+ }
14771
14826
  if (
14772
14827
  fileMutationScope &&
14773
14828
  (options.exactToolNames !== true || !hermeticExecution)
@@ -15171,8 +15226,8 @@ export async function* agentLoop(messages, options) {
15171
15226
  // one-shot guard means a model that keeps returning empty turns completes
15172
15227
  // rather than looping forever (the iteration budget is the hard backstop).
15173
15228
  let emptyThinkingReprompted = false;
15174
- const readFileLoopGuard = new ReadFileLoopGuard();
15175
- const remoteReadLoopGuard = new RemoteReadLoopGuard();
15229
+ let readFileLoopGuard = new ReadFileLoopGuard();
15230
+ let remoteReadLoopGuard = new RemoteReadLoopGuard();
15176
15231
  const prActionTask = isPrActionRequest(messages);
15177
15232
  // Keep an explicit user-requested PR close action alive even if the
15178
15233
  // conversation is compacted down to tool evidence. It is guidance only;
@@ -15282,7 +15337,11 @@ export async function* agentLoop(messages, options) {
15282
15337
  // threshold. Settlement persists a bounded resume checkpoint before the
15283
15338
  // live array changes; the earlier hash-chained result events remain the
15284
15339
  // durable evidence for audit/recovery.
15285
- if (options.runtimeResultRetention !== false && messages.length > 32) {
15340
+ if (
15341
+ !independentReviewContext?.active &&
15342
+ options.runtimeResultRetention !== false &&
15343
+ messages.length > 32
15344
+ ) {
15286
15345
  const retentionConfig =
15287
15346
  options.runtimeResultRetention &&
15288
15347
  typeof options.runtimeResultRetention === "object"
@@ -15350,6 +15409,7 @@ export async function* agentLoop(messages, options) {
15350
15409
  // dangling call; `preserveToolPairs` then guarantees compaction never
15351
15410
  // orphans a tool result. Best-effort — a failure never aborts the run.
15352
15411
  if (
15412
+ !independentReviewContext?.active &&
15353
15413
  options.autoCompact !== false &&
15354
15414
  !automaticCompactionSettlementBlocked &&
15355
15415
  messages.length > 4
@@ -15895,7 +15955,7 @@ export async function* agentLoop(messages, options) {
15895
15955
  // SubagentStop hooks are best-effort
15896
15956
  }
15897
15957
  }
15898
- messages.push(
15958
+ appendMessages(
15899
15959
  markRuntimeOnlySessionMessage({
15900
15960
  role: "user",
15901
15961
  content: _backgroundSubAgentResultText(entry),
@@ -15930,7 +15990,10 @@ export async function* agentLoop(messages, options) {
15930
15990
  // Turn-scoped context injection (open-agents prepareCall parity).
15931
15991
  // prepareCall runs fresh each iteration and returns an ephemeral
15932
15992
  // system-message supplement that is NOT persisted to messages history.
15933
- let callMessages = messages;
15993
+ const requestMessages = independentReviewContext?.active
15994
+ ? independentReviewContext.project()
15995
+ : messages;
15996
+ let callMessages = requestMessages;
15934
15997
  // Give a looping model a turn focused on search/action rather than another
15935
15998
  // whole-file request. This changes discovery for one request only; runtime
15936
15999
  // permissions are untouched and ordinary reads return on the next turn.
@@ -16001,7 +16064,9 @@ export async function* agentLoop(messages, options) {
16001
16064
  }
16002
16065
  : effectiveToolOptions;
16003
16066
  const readContext = [
16004
- options.getTaskWorklogContext?.(),
16067
+ independentReviewContext?.active
16068
+ ? null
16069
+ : options.getTaskWorklogContext?.(),
16005
16070
  readFileLoopGuard.findingsHint,
16006
16071
  readFileLoopGuard.progressHint,
16007
16072
  remoteReadLoopGuard.findingsHint,
@@ -16011,11 +16076,11 @@ export async function* agentLoop(messages, options) {
16011
16076
  // Preserve the last conversational turn and never split a tool call
16012
16077
  // from its results. Source data must neither become system authority
16013
16078
  // nor create an assistant prefill / a new generic user request.
16014
- const resultIndex = messages.findLastIndex(
16079
+ const resultIndex = requestMessages.findLastIndex(
16015
16080
  (message) => message.role === "tool",
16016
16081
  );
16017
16082
  if (resultIndex >= 0) {
16018
- const result = messages[resultIndex];
16083
+ const result = requestMessages[resultIndex];
16019
16084
  const original =
16020
16085
  typeof result.content === "string"
16021
16086
  ? result.content
@@ -16032,15 +16097,17 @@ export async function* agentLoop(messages, options) {
16032
16097
  }
16033
16098
  // Enrich only the ephemeral copy. This preserves signed assistant
16034
16099
  // thinking blocks, the last tool result, and the persisted transcript.
16035
- callMessages = messages.map((message, index) =>
16100
+ callMessages = requestMessages.map((message, index) =>
16036
16101
  index === resultIndex ? { ...result, content } : message,
16037
16102
  );
16038
16103
  } else {
16039
16104
  // Full compaction can leave only the pinned request. Reiterate that
16040
16105
  // exact request after the source data, not a replacement objective.
16041
- const request = messages.findLast((message) => message.role === "user");
16106
+ const request = requestMessages.findLast(
16107
+ (message) => message.role === "user",
16108
+ );
16042
16109
  callMessages = [
16043
- ...messages,
16110
+ ...requestMessages,
16044
16111
  ...readContext.map((content) => ({ role: "assistant", content })),
16045
16112
  {
16046
16113
  role: "user",
@@ -16208,8 +16275,11 @@ export async function* agentLoop(messages, options) {
16208
16275
  callMessages,
16209
16276
  {
16210
16277
  ...options,
16278
+ ...(independentReviewContext?.active
16279
+ ? { contextMemoryRecall: false }
16280
+ : {}),
16211
16281
  contextMemoryToolDefinitions:
16212
- getEffectiveToolDefinitions(iterationToolOptions),
16282
+ getProviderToolDefinitions(iterationToolOptions),
16213
16283
  contextMemoryTrustedSystemIndexes,
16214
16284
  },
16215
16285
  );
@@ -16223,6 +16293,15 @@ export async function* agentLoop(messages, options) {
16223
16293
  }
16224
16294
  }
16225
16295
 
16296
+ if (independentReviewContext?.active) {
16297
+ try {
16298
+ independentReviewContext.assertRequirementsPreserved(callMessages);
16299
+ } catch (error) {
16300
+ error.code = "CC_CHANGE_REVIEW_CONTEXT_LOST";
16301
+ throw error;
16302
+ }
16303
+ }
16304
+
16226
16305
  const modelIdAttrs = recorder
16227
16306
  ? buildTelemetryAttributes({
16228
16307
  turnId: `${runId}:t${budget.consumed}`,
@@ -16237,15 +16316,29 @@ export async function* agentLoop(messages, options) {
16237
16316
  "model",
16238
16317
  budget.consumed,
16239
16318
  );
16319
+ // A review may replace the first completion. Keep streaming transport but
16320
+ // discard live text/thinking in this opt-in mode; only the accepted final
16321
+ // response is published. This avoids concatenating drafts in IDE clients
16322
+ // without buffering unbounded provider output or changing the protocol.
16323
+ const outputOptions =
16324
+ options.reviewChanges === true
16325
+ ? {
16326
+ ...iterationToolOptions,
16327
+ onToken:
16328
+ typeof options.onToken === "function" ? () => {} : undefined,
16329
+ onThinking:
16330
+ typeof options.onThinking === "function" ? () => {} : undefined,
16331
+ }
16332
+ : iterationToolOptions;
16240
16333
  const plannedProviderOptions = canonicalProviderContext?.plan
16241
16334
  ? {
16242
- ...iterationToolOptions,
16335
+ ...outputOptions,
16243
16336
  contextEngine: null,
16244
16337
  contextMemoryPreplanned: true,
16245
16338
  contextMemorySelectedToolNames:
16246
16339
  canonicalProviderContext.selectedToolNames,
16247
16340
  }
16248
- : iterationToolOptions;
16341
+ : outputOptions;
16249
16342
  const requestOptions = providerRequestId
16250
16343
  ? { ...plannedProviderOptions, providerRequestId }
16251
16344
  : plannedProviderOptions;
@@ -16258,6 +16351,23 @@ export async function* agentLoop(messages, options) {
16258
16351
  ? { ...requestOptions, evolutionIngress }
16259
16352
  : requestOptions),
16260
16353
  };
16354
+ const originalExtraTools = requestOptions.extraToolDefinitions;
16355
+ if (Array.isArray(originalExtraTools)) {
16356
+ const projectedExtraTools = projectMcpToolDefinitions(
16357
+ originalExtraTools,
16358
+ requestOptions.externalToolExecutors,
16359
+ );
16360
+ if (projectedExtraTools !== originalExtraTools) {
16361
+ const admittedNames = new Set(
16362
+ getEffectiveToolDefinitions(requestOptions).map(
16363
+ (tool) => tool.function.name,
16364
+ ),
16365
+ );
16366
+ providerCallOptions.extraToolDefinitions = projectedExtraTools.filter(
16367
+ (tool) => admittedNames.has(tool.function.name),
16368
+ );
16369
+ }
16370
+ }
16261
16371
  const modelUsageCall = {
16262
16372
  type: "model-usage-started",
16263
16373
  callId: _newModelUsageCallId("model"),
@@ -16414,6 +16524,7 @@ export async function* agentLoop(messages, options) {
16414
16524
  contextWindow: requestContextWindow,
16415
16525
  };
16416
16526
  } else {
16527
+ changeReviewState.usageKnown = false;
16417
16528
  yield {
16418
16529
  type: "model-usage-unknown",
16419
16530
  callId: modelUsageCall.callId,
@@ -16424,6 +16535,16 @@ export async function* agentLoop(messages, options) {
16424
16535
  };
16425
16536
  }
16426
16537
  throwIfAborted(signal);
16538
+ if (
16539
+ independentReviewContext?.active &&
16540
+ changeReviewState.usageKnown === false
16541
+ ) {
16542
+ const error = new Error(
16543
+ "Change review stopped with unknown provider usage; the task remains incomplete.",
16544
+ );
16545
+ error.code = "CC_CHANGE_REVIEW_USAGE_UNKNOWN";
16546
+ throw error;
16547
+ }
16427
16548
 
16428
16549
  if (!msg) {
16429
16550
  await _awaitBackgroundUsageSettlement(
@@ -16521,7 +16642,7 @@ export async function* agentLoop(messages, options) {
16521
16642
  );
16522
16643
  _throwBackgroundUsageFailureState(backgroundUsageFailureState);
16523
16644
  throwIfAborted(signal);
16524
- messages.push(
16645
+ appendMessages(
16525
16646
  markRuntimeOnlySessionMessage({
16526
16647
  role: "assistant",
16527
16648
  content: msg.content || "",
@@ -16531,7 +16652,7 @@ export async function* agentLoop(messages, options) {
16531
16652
  backgroundSubAgents,
16532
16653
  )) {
16533
16654
  _throwBackgroundSubAgentUsageFailure(entry);
16534
- messages.push(
16655
+ appendMessages(
16535
16656
  markRuntimeOnlySessionMessage({
16536
16657
  role: "user",
16537
16658
  content:
@@ -16563,13 +16684,13 @@ export async function* agentLoop(messages, options) {
16563
16684
  const pending = [...pendingSubtreeMutations.values()];
16564
16685
  if (!subtreeMutationReprompted && budget.remaining() > 0) {
16565
16686
  subtreeMutationReprompted = true;
16566
- messages.push(
16687
+ appendMessages(
16567
16688
  markRuntimeOnlySessionMessage({
16568
16689
  role: "assistant",
16569
16690
  content: msg.content || "",
16570
16691
  }),
16571
16692
  );
16572
- messages.push(
16693
+ appendMessages(
16573
16694
  markRuntimeOnlySessionMessage({
16574
16695
  role: "user",
16575
16696
  content:
@@ -16602,6 +16723,48 @@ export async function* agentLoop(messages, options) {
16602
16723
  };
16603
16724
  return;
16604
16725
  }
16726
+ // Opt-in review uses the same loop, tools, usage settlement and budget.
16727
+ // Never emit a provisional completion or turn this self-check into an
16728
+ // acceptance verdict. Failed/deferred writes do not arm the review.
16729
+ if (
16730
+ options.reviewChanges === true &&
16731
+ hasFileContentChanges &&
16732
+ !changeReviewState.requested &&
16733
+ changeReviewState.usageKnown !== false &&
16734
+ budget.hasRemaining()
16735
+ ) {
16736
+ throwIfAborted(signal);
16737
+ if (independentReviewSetupError) throw independentReviewSetupError;
16738
+ changeReviewState.requested = true;
16739
+ const reviewPrompt = markRuntimeOnlySessionMessage({
16740
+ role: "user",
16741
+ content: CODING_CHANGE_REVIEW_PROMPT,
16742
+ });
16743
+ appendMessages(
16744
+ markRuntimeOnlySessionMessage({
16745
+ role: "assistant",
16746
+ content: msg.content || "",
16747
+ }),
16748
+ reviewPrompt,
16749
+ );
16750
+ if (independentReviewContext) {
16751
+ independentReviewContext.activate(reviewPrompt);
16752
+ changeReviewState.independentReviewPending = true;
16753
+ // These are phase-local discovery hints, not permission or spend
16754
+ // authorities. Fresh inspection must not inherit author assertions,
16755
+ // old visible file pages, or a pause caused by author exploration.
16756
+ readFileLoopGuard = new ReadFileLoopGuard();
16757
+ remoteReadLoopGuard = new RemoteReadLoopGuard();
16758
+ taskProgressTracker = new TaskProgressTracker();
16759
+ toolContext.readFileLoopGuard = readFileLoopGuard;
16760
+ lastTaskProgressIntervention = null;
16761
+ }
16762
+ yield {
16763
+ type: "iteration-warning",
16764
+ message: "Reviewing changed files against the task before finishing.",
16765
+ };
16766
+ continue;
16767
+ }
16605
16768
  // Surface the final answer's extended-thinking reasoning (Anthropic, when
16606
16769
  // --think is on) so non-streaming consumers (the REPL) can show it. The
16607
16770
  // streaming path forwards reasoning live via onThinking instead.
@@ -16623,10 +16786,10 @@ export async function* agentLoop(messages, options) {
16623
16786
  const _contentEmpty = !String(msg.content || "").trim();
16624
16787
  if (_contentEmpty && _thinking && !emptyThinkingReprompted) {
16625
16788
  emptyThinkingReprompted = true;
16626
- messages.push(
16789
+ appendMessages(
16627
16790
  markRuntimeOnlySessionMessage({ role: "assistant", content: "" }),
16628
16791
  );
16629
- messages.push(
16792
+ appendMessages(
16630
16793
  markRuntimeOnlySessionMessage({
16631
16794
  role: "user",
16632
16795
  content:
@@ -16690,13 +16853,13 @@ export async function* agentLoop(messages, options) {
16690
16853
  }
16691
16854
  if (stopOutcome && stopOutcome.decision === "block") {
16692
16855
  stopHookActive = true;
16693
- messages.push(
16856
+ appendMessages(
16694
16857
  markRuntimeOnlySessionMessage({
16695
16858
  role: "assistant",
16696
16859
  content: msg.content || "",
16697
16860
  }),
16698
16861
  );
16699
- messages.push(
16862
+ appendMessages(
16700
16863
  markRuntimeOnlySessionMessage({
16701
16864
  role: "user",
16702
16865
  content:
@@ -16712,6 +16875,9 @@ export async function* agentLoop(messages, options) {
16712
16875
  continue;
16713
16876
  }
16714
16877
  }
16878
+ if (independentReviewContext?.active) {
16879
+ changeReviewState.independentReviewPending = false;
16880
+ }
16715
16881
  yield { type: "run-ended", runId, reason: "complete" };
16716
16882
  return;
16717
16883
  }
@@ -16735,7 +16901,7 @@ export async function* agentLoop(messages, options) {
16735
16901
  }
16736
16902
 
16737
16903
  // Add assistant message with tool calls
16738
- messages.push(msg);
16904
+ appendMessages(msg);
16739
16905
  readFileLoopGuard.startBatch();
16740
16906
 
16741
16907
  // Concurrent READ-ONLY batch (latency optimization). When every call in the
@@ -16855,7 +17021,7 @@ export async function* agentLoop(messages, options) {
16855
17021
  if (fatalError) throw fatalError;
16856
17022
  throwIfAborted(signal);
16857
17023
  recordSubtreeMutation(call.function.name, toolArgs, toolResult);
16858
- const taskAdvanced = taskProgressTracker.record(
17024
+ const taskAdvanced = recordTaskProgress(
16859
17025
  call.function.name,
16860
17026
  toolResult,
16861
17027
  toolArgs,
@@ -16888,7 +17054,7 @@ export async function* agentLoop(messages, options) {
16888
17054
  const resultStr = toolResultForModel(
16889
17055
  call.function.name,
16890
17056
  toolResult,
16891
- messages,
17057
+ requestMessages,
16892
17058
  );
16893
17059
  const toolContent = warningMsg
16894
17060
  ? `${resultStr}\n\n${warningMsg}`
@@ -16915,7 +17081,7 @@ export async function* agentLoop(messages, options) {
16915
17081
  toolResult,
16916
17082
  );
16917
17083
  if (nestedOutcomeUnknown) throw nestedOutcomeUnknown;
16918
- messages.push({
17084
+ appendMessages({
16919
17085
  role: "tool",
16920
17086
  content: toolContent,
16921
17087
  tool_call_id: call.id,
@@ -16972,7 +17138,7 @@ export async function* agentLoop(messages, options) {
16972
17138
  tool_use_id: call?.id || null,
16973
17139
  turn_id: `${runId}:t${budget.consumed}`,
16974
17140
  };
16975
- messages.push({
17141
+ appendMessages({
16976
17142
  role: "tool",
16977
17143
  content: `Error: ${reason}.`,
16978
17144
  tool_call_id: call?.id,
@@ -17031,12 +17197,7 @@ export async function* agentLoop(messages, options) {
17031
17197
  readFileLoopGuard.record(
17032
17198
  toolName,
17033
17199
  earlyAuthorityDenial,
17034
- taskProgressTracker.record(
17035
- toolName,
17036
- earlyAuthorityDenial,
17037
- toolArgs,
17038
- runId,
17039
- ),
17200
+ recordTaskProgress(toolName, earlyAuthorityDenial, toolArgs, runId),
17040
17201
  );
17041
17202
  const resultStr = capToolResultString(
17042
17203
  safeStringifyToolResult(earlyAuthorityDenial),
@@ -17072,7 +17233,7 @@ export async function* agentLoop(messages, options) {
17072
17233
  permission_decision_id: decision?.id || null,
17073
17234
  permission_decision: decision,
17074
17235
  };
17075
- messages.push({
17236
+ appendMessages({
17076
17237
  role: "tool",
17077
17238
  content: resultStr,
17078
17239
  tool_call_id: call.id,
@@ -17397,9 +17558,13 @@ export async function* agentLoop(messages, options) {
17397
17558
  // Cap an individual tool result so one giant output can't blow the
17398
17559
  // context — but tell the model when we cut it (no more silent
17399
17560
  // mid-content slice). See MAX_TOOL_RESULT_CHARS / capToolResultString.
17400
- const resultStr = toolResultForModel(toolName, toolResult, messages);
17561
+ const resultStr = toolResultForModel(
17562
+ toolName,
17563
+ toolResult,
17564
+ requestMessages,
17565
+ );
17401
17566
  recordSubtreeMutation(toolName, toolArgs, toolResult);
17402
- const taskAdvanced = taskProgressTracker.record(
17567
+ const taskAdvanced = recordTaskProgress(
17403
17568
  toolName,
17404
17569
  toolResult,
17405
17570
  toolArgs,
@@ -17439,7 +17604,7 @@ export async function* agentLoop(messages, options) {
17439
17604
  );
17440
17605
  if (nestedOutcomeUnknown) throw nestedOutcomeUnknown;
17441
17606
 
17442
- messages.push({
17607
+ appendMessages({
17443
17608
  role: "tool",
17444
17609
  content: toolContent,
17445
17610
  tool_call_id: call.id,