chainlesschain 0.166.128 → 0.166.130

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 (177) hide show
  1. package/README.md +24 -4
  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-BmGA5zXX.js → AIOps-o-rFKEYL.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-B7WXwoF0.js → ActionButton-Dzv1ReHF.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-IvJG43B5.js → Analytics-Bt7H_jrh.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-DWY017_e.js → AppLayout-CgynsRFP.js} +5 -5
  9. package/src/assets/web-panel/assets/Artifacts-gghOGDyE.js +1 -0
  10. package/src/assets/web-panel/assets/{Audit-CD9sTnBN.js → Audit-DBXn-AZ6.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-J6gg5z0U.js → BackgroundAgents--dxPftKa.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-D7ik3lse.js → Backup-D9Zf_2tH.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-MrDd5zcz.js → BaseInput-DDTOjovq.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-DbxRqGiK.js → Chat-2ETqdBLn.js} +6 -6
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-DSg2Xs8G.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-CditB77B.js → Checkbox-B5uzaLLP.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-Ds0UZWZG.js → Codegen-4ieEEIwt.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-CZlj1XI2.js → Col-D3I2kUGu.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-j4B2SoT6.js → Community-DeYxFMJb.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-BuKQutaO.js → Compact-5GigOmb8.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-DAgDyS-p.js → Compliance-DLVjbVUh.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-DX2-I6V3.js → Cowork-DfUKa0T5.js} +3 -3
  23. package/src/assets/web-panel/assets/{Cron-dJpc-FxX.js → Cron-_RpktpO5.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-7m8euM3v.js → Crosschain-7x6xdbwH.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-CLoYoCe1.js → DID-ccVhToC1.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-DR1rRMb7.js → Dashboard-DhygcaoK.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-BsKhCfvH.js → Dropdown-DFplwXK7.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-BAGexzJu.js → EmailListRenderer-Bm01soCN.js} +1 -1
  29. package/src/assets/web-panel/assets/EvolutionSettings-C4v--DkD.js +1 -0
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BIpueefy.js → FamilyGuardDashboard-ChQXDBA3.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-BluNep6d.js → Federation-C0yomE-M.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-CerdM3am.js → FormItemContext-DtT3ZEZK.js} +1 -1
  33. package/src/assets/web-panel/assets/GenericCardRenderer-DgITtFRv.js +1 -0
  34. package/src/assets/web-panel/assets/{Git-CEE0cGmf.js → Git-CCY42R8S.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-Bc-XNDhM.js → Governance-N66Bwvqg.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-CiBzXyZ-.js → Inference-BkbPuR_2.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-CV2IiyuN.js → KnowledgeGraph-B3PibXdA.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-fbQYKuSz.js → Logs-CUtNB_N6.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-B73ZyMRI.js → MarkdownRenderer-D-V4dOe3.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-C5utdpxZ.js → Marketplace-DLNJb6Nr.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-CPE4SaF3.js → McpTools-2zGjJb5K.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-DTFDszzk.js → Memory-9rNZ1EvR.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-DxqPmTzP.js → MobileBridge-Cw7sAAgn.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-CwcK8l2y.js → MobileProjects-8XACrqqy.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-DrjECLGO.js → Mtc-mg02JNy-.js} +4 -4
  46. package/src/assets/web-panel/assets/{MtcAudit-4IURCa-3.js → MtcAudit-B1Vkhj2l.js} +5 -5
  47. package/src/assets/web-panel/assets/{Multisig-CggLV1Cp.js → Multisig-BQEeA7GG.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-DkOQJT73.js → NLProgramming-BIbkjZV3.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-Dodcva6s.js → Notes-DIwhkZNY.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-CQ3HeTs6.js → NotificationSettings-Cj9175ce.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-pT2nzmIO.js → OrderTableRenderer-IfNpXT2R.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-B6HFsIfU.js → Organization-DPFp6G9o.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-G9dju55N.js → Overflow-ky9UfGv4.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-C1BCE155.js → P2P-tXck8GLq.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-BFAxXn5D.js → PdhVaultBrowser-DSvpQl9k.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-DWg7cw9Q.js → Permissions-CKPkdLj-.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-BQxuOQOO.js → PersonalDataHub-DnqXc12l.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-C3Gse9Ne.js → Pipeline-BKjFU_kd.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-Dcsjx6Oi.js → Privacy-ChC-J5Tn.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-DeYlnXJQ.js → ProjectInit-ByFZG9sY.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-D7kbZ_K7.js → ProjectSettings-Bbv1Kiw-.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-C5m3NGzM.js → Projects-QYyGW31-.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-oT6jy83z.js → Providers-CJLnWw0r.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-NZ11GEBa.js → QrScannerModal-er_HkLCI.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-CtQU4Tx0.js → QuickAsk-DoXU0np9.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-3CoXYu3O.js → Recommend-DCo_vuaf.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-C2d4LzBM.js → RemoteSession-CLuL925Z.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-WZQHrGwl.js → Reputation-CNNCA_-M.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-ChiqY7Hg.js → Row-Vu4j631i.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-Cjwl2Kum.js → RssFeed-C18B4xiy.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-DRDMZxTF.js → Search-DxiqccE2.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-D0y4LlQ4.js → Security-Droe_hHI.js} +3 -3
  73. package/src/assets/web-panel/assets/{Services-ChpkqWm0.js → Services-CwmmyXzq.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-D3WGZ8yO.js → Skeleton-CrFs6rUL.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-Bv_7HaUW.js → Skills-Dp-d2miK.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-crZMKyX0.js → Sla-2DFXVbK4.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-ByWn5XDZ.js → SpeechSettings-Cdd9lCoy.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings--R55vxvj.js → SyncSettings-CxQhcYSk.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-BZA_Via_.js → Tasks-BHWVRfXx.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-9eJ9yY8Q.js → Templates-DNFk3a5_.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CfWX2jqj.js → Tenant-B6X6dPo8.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-CUXUF4kL.js → Terminal-BuUNoLGM.js} +2 -2
  83. package/src/assets/web-panel/assets/TimelineRenderer-DThrBYj8.js +1 -0
  84. package/src/assets/web-panel/assets/{Tokens-CvyrdLH6.js → Tokens-CA_u4Blu.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-MNRl_YNr.js → Trigger-CXrW4Nry.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-BHOXK-Mp.js → Trust-DHcLpNy3.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-Bz1oZNyQ.js → UkeySign-B_fni4C2.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-DlqmXyZv.js → VideoEditing-g9nf2EhS.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-Dg1rnqEG.js → Wallet-C8pOjIve.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-DJtGeaOk.js → WebAuthn-BaKNjxZt.js} +3 -3
  91. package/src/assets/web-panel/assets/{WorkflowEditor-DJPubjX5.js → WorkflowEditor-CX030Wb1.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-BWweDuIV.js → chat-BpJsXlTK.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-BX5ViADF.js → colors-CUNg0-fh.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-Df8MLbXp.js → compact-item-C3tFHnhu.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-C0FDTwdV.js → createContext-B8rTvO61.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-B4_IVU_n.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-PpL6GdNk.js → hasIn-CU6RIciB.js} +1 -1
  98. package/src/assets/web-panel/assets/index--6BUI55w.js +1 -0
  99. package/src/assets/web-panel/assets/{index-DGLbojjx.js → index-111hR8WZ.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BF0ERucU.js → index-1L0tt7G2.js} +1 -1
  101. package/src/assets/web-panel/assets/index-5Q1bepcM.js +1 -0
  102. package/src/assets/web-panel/assets/{index-DwZkBGXd.js → index-6EwPIfXu.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-C0PqPK-8.js → index-B10Ia2KL.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-FAZH69my.js → index-B1SLBLli.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BWSCphaT.js → index-B8_VQAav.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-itNn6pW1.js → index-BG4zuFf0.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-iif2A1eL.js → index-BJjEAoDb.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DFtzEEYe.js → index-BMuPJra-.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-B982oUKN.js → index-BOCjph-k.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-B8-pSyP7.js → index-BOlAutGy.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-C8wl7Ica.js → index-BPWJw4Ji.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-UXM5vpt4.js → index-BpBaOWmV.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-7VyVOEf7.js → index-BzhobTgZ.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-R0LQ3fgq.js → index-CDlHvQtw.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-ChV82mzs.js → index-CEIoRm_c.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-B3K1uZ7R.js → index-CLQjdKmE.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-B4UxFB2N.js → index-CPF7Vqri.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DddQd0_V.js → index-CPmgKQcl.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CxY_U5RT.js → index-CcpMHPWd.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-D5Ei75Wt.js → index-Cyksnofp.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DxJqyIP8.js → index-CyyhilXV.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-P1ERNJla.js → index-D4njcYFw.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-Cj00JSqq.js → index-Dc9pcin6.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Cf86RSQk.js → index-DfAC55QA.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DBzaRg4E.js → index-DgNCfwvg.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-NdEUFm32.js → index-DvfhIBNZ.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-Beh1kLwx.js → index-Hbzd9WeI.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-D_6XIMVV.js → index-IiS7WoUl.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-C2JU-gdS.js → index-K2Uqqkr1.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Dy8K2laU.js → index-KgR1f2Gq.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-C9FOwTgX.js → index-X6e0cGRU.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BeFhy4BX.js → index-Xa6TlaD7.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-Cm7vZvA3.js → index-YczWc2_0.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BMIEWinN.js → index-h_ANnbR8.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-CmMzB4C-.js → index-k7QsBwyo.js} +3 -3
  136. package/src/assets/web-panel/assets/{index-C9N1u8jV.js → index-lo9rgpyj.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-DeMthvi4.js → initDefaultProps-FI8D7E2x.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-_7kbkzE0.js → motion-B1hpJYSD.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-gCI04pLw.js → move-Vl1vUReW.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-D5UWHv2U.js → mtc-parser-6Cu2aFME.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-CDCZcqeS.js → omit-VRKL8iSO.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-DGMDLi3S.js → pickAttrs-DZfWsOe0.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-C-3vC1Vh.js → placementArrow-qmcOUc4W.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-vdoYucvi.js → responsiveObserve-BLB6SsSw.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-B62FhgyZ.js → slide-41jdYeSH.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-DCLlfnym.js → statusUtils-Yn8OQ5ey.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-CGvQ4LRR.js → styleChecker-4CEwz9Zd.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-BqkGoKwe.js → useFlexGapSupport-BClv53kR.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-Bkr_nU3q.js → useFs-Bugo8HuF.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-CYxMIUEq.js → usePersonalDataHub-B-q2ElB0.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-sAbcY1FX.js → vnode-ejVeFJ0x.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-Dm2pLrXi.js → zoom-DM1y_KKP.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/constants.js +1 -1
  155. package/src/data/changelog.json +26 -0
  156. package/src/lib/codex-app-server-adapter.js +36 -22
  157. package/src/lib/codex-app-server-support.js +91 -0
  158. package/src/lib/coding-change-review-context.js +258 -0
  159. package/src/lib/coding-task-guidance.js +3 -0
  160. package/src/lib/context-memory-kernel/provider-context.js +22 -12
  161. package/src/lib/goal-assess.js +4 -1
  162. package/src/lib/goal-check-evidence.js +77 -9
  163. package/src/lib/goal-model-call.js +107 -0
  164. package/src/lib/goal-workspace-evidence.js +299 -0
  165. package/src/lib/llm-onboarding-catalog.json +1 -1
  166. package/src/lib/llm-providers.js +1 -0
  167. package/src/lib/task-model-selector.js +1 -1
  168. package/src/runtime/agent-core.js +152 -41
  169. package/src/runtime/headless-runner.js +201 -107
  170. package/src/assets/web-panel/assets/Artifacts-BOyohM_-.js +0 -1
  171. package/src/assets/web-panel/assets/ChatBubbleRenderer-DbeJAwMg.js +0 -1
  172. package/src/assets/web-panel/assets/EvolutionSettings-BqYYmC01.js +0 -1
  173. package/src/assets/web-panel/assets/GenericCardRenderer-DXh4tOjU.js +0 -1
  174. package/src/assets/web-panel/assets/TimelineRenderer-77y9bkYN.js +0 -1
  175. package/src/assets/web-panel/assets/devWarning-BgM5vq1s.js +0 -1
  176. package/src/assets/web-panel/assets/index-Bl-HTXWn.js +0 -1
  177. package/src/assets/web-panel/assets/index-Cxf0YfM5.js +0 -1
@@ -69,6 +69,7 @@ import {
69
69
  CODING_TASK_QUALITY_GUIDANCE,
70
70
  CODING_CHANGE_REVIEW_PROMPT,
71
71
  } from "../lib/coding-task-guidance.js";
72
+ import { CodingChangeReviewContext } from "../lib/coding-change-review-context.js";
72
73
  import { RemoteReadLoopGuard } from "../lib/remote-read-loop-guard.js";
73
74
  import {
74
75
  isPrActionRequest,
@@ -13580,6 +13581,31 @@ const _CHECKPOINT_READ_ONLY = new Set([
13580
13581
  "search_sessions",
13581
13582
  ]);
13582
13583
 
13584
+ function isCheckpointReadOnly(toolContext, toolName, toolArgs) {
13585
+ if (_CHECKPOINT_READ_ONLY.has(toolName)) return true;
13586
+ if (
13587
+ toolName !== "git" ||
13588
+ toolContext.externalToolExecutors?.git ||
13589
+ !isReadOnlyGitCommand(toolArgs?.command)
13590
+ )
13591
+ return false;
13592
+ const command = normalizeGitCommand(toolArgs.command);
13593
+ if (gitToolInputError(command)) return false;
13594
+ // Read commands can explicitly write output or invoke external drivers.
13595
+ // Keep their recovery snapshot, including abbreviated long options.
13596
+ const args = tokenizeShellWords(command).slice(1);
13597
+ const separator = args.indexOf("--");
13598
+ return !(separator < 0 ? args : args.slice(0, separator)).some((arg) => {
13599
+ const option = arg.split("=", 1)[0];
13600
+ return (
13601
+ option.startsWith("--") &&
13602
+ ["--output", "--ext-diff", "--textconv"].some((flag) =>
13603
+ flag.startsWith(option),
13604
+ )
13605
+ );
13606
+ });
13607
+ }
13608
+
13583
13609
  // Rolling cap on auto-checkpoints per agent session — the engine prunes the
13584
13610
  // oldest beyond this so a long run can't accumulate unbounded refs.
13585
13611
  const MAX_AUTO_CHECKPOINTS_PER_SESSION = 100;
@@ -13602,7 +13628,7 @@ function _loadCheckpointStore() {
13602
13628
  */
13603
13629
  async function _autoCheckpointBeforeTool(toolContext, toolName, toolArgs) {
13604
13630
  if (!toolContext?.autoCheckpoint) return null;
13605
- if (_CHECKPOINT_READ_ONLY.has(toolName)) return null;
13631
+ if (isCheckpointReadOnly(toolContext, toolName, toolArgs)) return null;
13606
13632
  const cwd = toolContext.cwd || process.cwd();
13607
13633
  try {
13608
13634
  const store = await _loadCheckpointStore();
@@ -14714,8 +14740,9 @@ export async function* agentLoop(messages, options) {
14714
14740
  const { HostResourceBudget } = await import("../lib/host-resource-budget.js");
14715
14741
  const hostResourceBudget =
14716
14742
  options.hostResourceBudget || new HostResourceBudget();
14717
- const taskProgressTracker =
14743
+ let taskProgressTracker =
14718
14744
  options.taskProgressTracker || new TaskProgressTracker();
14745
+ const hostTaskProgressTracker = taskProgressTracker;
14719
14746
  // A subtree preflight is deliberately not an executed mutation. Keep this
14720
14747
  // obligation outside transcript compaction and never replay it automatically.
14721
14748
  const pendingSubtreeMutations = new Map();
@@ -14723,6 +14750,22 @@ export async function* agentLoop(messages, options) {
14723
14750
  let hasFileContentChanges = false;
14724
14751
  // Headless outer turns share this object; a new user turn gets a fresh one.
14725
14752
  const changeReviewState = options._changeReviewState || { requested: false };
14753
+ let independentReviewContext = null;
14754
+ let independentReviewSetupError = null;
14755
+ const appendMessages = (...entries) => {
14756
+ // Keep complete review tool groups in both the durable conversation and a
14757
+ // separate request journal. Canonical compaction cannot restore author
14758
+ // rationale to this journal or remove its current file observations.
14759
+ independentReviewContext?.record(...entries);
14760
+ messages.push(...entries);
14761
+ };
14762
+ const recordTaskProgress = (...args) => {
14763
+ const advanced = taskProgressTracker.record(...args);
14764
+ if (taskProgressTracker !== hostTaskProgressTracker) {
14765
+ hostTaskProgressTracker.record(...args);
14766
+ }
14767
+ return advanced;
14768
+ };
14726
14769
  const recordSubtreeMutation = (tool, args, result) => {
14727
14770
  if (!GUARDED_FILE_MUTATION_TOOLS.has(tool)) return;
14728
14771
  if (!args || typeof args !== "object" || Array.isArray(args)) return;
@@ -14788,6 +14831,23 @@ export async function* agentLoop(messages, options) {
14788
14831
  { cwd: options.cwd || process.cwd() },
14789
14832
  );
14790
14833
  const hermeticExecution = options.hermeticExecution === true;
14834
+ if (options.reviewChanges === true && hermeticExecution) {
14835
+ if (changeReviewState.independentReviewPending === true) {
14836
+ const error = new Error(
14837
+ "An interrupted independent review cannot resume from author history; the task remains incomplete.",
14838
+ );
14839
+ error.code = "CC_CHANGE_REVIEW_RECONSTRUCTION_REQUIRED";
14840
+ throw error;
14841
+ }
14842
+ try {
14843
+ independentReviewContext = new CodingChangeReviewContext(messages);
14844
+ } catch (error) {
14845
+ // An explanation without writes still keeps its old behavior. If a
14846
+ // mutation later arms review, stop before an extra call rather than
14847
+ // silently falling back to the author's summarized context.
14848
+ independentReviewSetupError = error;
14849
+ }
14850
+ }
14791
14851
  if (
14792
14852
  fileMutationScope &&
14793
14853
  (options.exactToolNames !== true || !hermeticExecution)
@@ -15191,8 +15251,8 @@ export async function* agentLoop(messages, options) {
15191
15251
  // one-shot guard means a model that keeps returning empty turns completes
15192
15252
  // rather than looping forever (the iteration budget is the hard backstop).
15193
15253
  let emptyThinkingReprompted = false;
15194
- const readFileLoopGuard = new ReadFileLoopGuard();
15195
- const remoteReadLoopGuard = new RemoteReadLoopGuard();
15254
+ let readFileLoopGuard = new ReadFileLoopGuard();
15255
+ let remoteReadLoopGuard = new RemoteReadLoopGuard();
15196
15256
  const prActionTask = isPrActionRequest(messages);
15197
15257
  // Keep an explicit user-requested PR close action alive even if the
15198
15258
  // conversation is compacted down to tool evidence. It is guidance only;
@@ -15302,7 +15362,11 @@ export async function* agentLoop(messages, options) {
15302
15362
  // threshold. Settlement persists a bounded resume checkpoint before the
15303
15363
  // live array changes; the earlier hash-chained result events remain the
15304
15364
  // durable evidence for audit/recovery.
15305
- if (options.runtimeResultRetention !== false && messages.length > 32) {
15365
+ if (
15366
+ !independentReviewContext?.active &&
15367
+ options.runtimeResultRetention !== false &&
15368
+ messages.length > 32
15369
+ ) {
15306
15370
  const retentionConfig =
15307
15371
  options.runtimeResultRetention &&
15308
15372
  typeof options.runtimeResultRetention === "object"
@@ -15370,6 +15434,7 @@ export async function* agentLoop(messages, options) {
15370
15434
  // dangling call; `preserveToolPairs` then guarantees compaction never
15371
15435
  // orphans a tool result. Best-effort — a failure never aborts the run.
15372
15436
  if (
15437
+ !independentReviewContext?.active &&
15373
15438
  options.autoCompact !== false &&
15374
15439
  !automaticCompactionSettlementBlocked &&
15375
15440
  messages.length > 4
@@ -15915,7 +15980,7 @@ export async function* agentLoop(messages, options) {
15915
15980
  // SubagentStop hooks are best-effort
15916
15981
  }
15917
15982
  }
15918
- messages.push(
15983
+ appendMessages(
15919
15984
  markRuntimeOnlySessionMessage({
15920
15985
  role: "user",
15921
15986
  content: _backgroundSubAgentResultText(entry),
@@ -15950,7 +16015,10 @@ export async function* agentLoop(messages, options) {
15950
16015
  // Turn-scoped context injection (open-agents prepareCall parity).
15951
16016
  // prepareCall runs fresh each iteration and returns an ephemeral
15952
16017
  // system-message supplement that is NOT persisted to messages history.
15953
- let callMessages = messages;
16018
+ const requestMessages = independentReviewContext?.active
16019
+ ? independentReviewContext.project()
16020
+ : messages;
16021
+ let callMessages = requestMessages;
15954
16022
  // Give a looping model a turn focused on search/action rather than another
15955
16023
  // whole-file request. This changes discovery for one request only; runtime
15956
16024
  // permissions are untouched and ordinary reads return on the next turn.
@@ -16021,7 +16089,9 @@ export async function* agentLoop(messages, options) {
16021
16089
  }
16022
16090
  : effectiveToolOptions;
16023
16091
  const readContext = [
16024
- options.getTaskWorklogContext?.(),
16092
+ independentReviewContext?.active
16093
+ ? null
16094
+ : options.getTaskWorklogContext?.(),
16025
16095
  readFileLoopGuard.findingsHint,
16026
16096
  readFileLoopGuard.progressHint,
16027
16097
  remoteReadLoopGuard.findingsHint,
@@ -16031,11 +16101,11 @@ export async function* agentLoop(messages, options) {
16031
16101
  // Preserve the last conversational turn and never split a tool call
16032
16102
  // from its results. Source data must neither become system authority
16033
16103
  // nor create an assistant prefill / a new generic user request.
16034
- const resultIndex = messages.findLastIndex(
16104
+ const resultIndex = requestMessages.findLastIndex(
16035
16105
  (message) => message.role === "tool",
16036
16106
  );
16037
16107
  if (resultIndex >= 0) {
16038
- const result = messages[resultIndex];
16108
+ const result = requestMessages[resultIndex];
16039
16109
  const original =
16040
16110
  typeof result.content === "string"
16041
16111
  ? result.content
@@ -16052,15 +16122,17 @@ export async function* agentLoop(messages, options) {
16052
16122
  }
16053
16123
  // Enrich only the ephemeral copy. This preserves signed assistant
16054
16124
  // thinking blocks, the last tool result, and the persisted transcript.
16055
- callMessages = messages.map((message, index) =>
16125
+ callMessages = requestMessages.map((message, index) =>
16056
16126
  index === resultIndex ? { ...result, content } : message,
16057
16127
  );
16058
16128
  } else {
16059
16129
  // Full compaction can leave only the pinned request. Reiterate that
16060
16130
  // exact request after the source data, not a replacement objective.
16061
- const request = messages.findLast((message) => message.role === "user");
16131
+ const request = requestMessages.findLast(
16132
+ (message) => message.role === "user",
16133
+ );
16062
16134
  callMessages = [
16063
- ...messages,
16135
+ ...requestMessages,
16064
16136
  ...readContext.map((content) => ({ role: "assistant", content })),
16065
16137
  {
16066
16138
  role: "user",
@@ -16228,6 +16300,9 @@ export async function* agentLoop(messages, options) {
16228
16300
  callMessages,
16229
16301
  {
16230
16302
  ...options,
16303
+ ...(independentReviewContext?.active
16304
+ ? { contextMemoryRecall: false }
16305
+ : {}),
16231
16306
  contextMemoryToolDefinitions:
16232
16307
  getProviderToolDefinitions(iterationToolOptions),
16233
16308
  contextMemoryTrustedSystemIndexes,
@@ -16243,6 +16318,15 @@ export async function* agentLoop(messages, options) {
16243
16318
  }
16244
16319
  }
16245
16320
 
16321
+ if (independentReviewContext?.active) {
16322
+ try {
16323
+ independentReviewContext.assertRequirementsPreserved(callMessages);
16324
+ } catch (error) {
16325
+ error.code = "CC_CHANGE_REVIEW_CONTEXT_LOST";
16326
+ throw error;
16327
+ }
16328
+ }
16329
+
16246
16330
  const modelIdAttrs = recorder
16247
16331
  ? buildTelemetryAttributes({
16248
16332
  turnId: `${runId}:t${budget.consumed}`,
@@ -16476,6 +16560,16 @@ export async function* agentLoop(messages, options) {
16476
16560
  };
16477
16561
  }
16478
16562
  throwIfAborted(signal);
16563
+ if (
16564
+ independentReviewContext?.active &&
16565
+ changeReviewState.usageKnown === false
16566
+ ) {
16567
+ const error = new Error(
16568
+ "Change review stopped with unknown provider usage; the task remains incomplete.",
16569
+ );
16570
+ error.code = "CC_CHANGE_REVIEW_USAGE_UNKNOWN";
16571
+ throw error;
16572
+ }
16479
16573
 
16480
16574
  if (!msg) {
16481
16575
  await _awaitBackgroundUsageSettlement(
@@ -16573,7 +16667,7 @@ export async function* agentLoop(messages, options) {
16573
16667
  );
16574
16668
  _throwBackgroundUsageFailureState(backgroundUsageFailureState);
16575
16669
  throwIfAborted(signal);
16576
- messages.push(
16670
+ appendMessages(
16577
16671
  markRuntimeOnlySessionMessage({
16578
16672
  role: "assistant",
16579
16673
  content: msg.content || "",
@@ -16583,7 +16677,7 @@ export async function* agentLoop(messages, options) {
16583
16677
  backgroundSubAgents,
16584
16678
  )) {
16585
16679
  _throwBackgroundSubAgentUsageFailure(entry);
16586
- messages.push(
16680
+ appendMessages(
16587
16681
  markRuntimeOnlySessionMessage({
16588
16682
  role: "user",
16589
16683
  content:
@@ -16615,13 +16709,13 @@ export async function* agentLoop(messages, options) {
16615
16709
  const pending = [...pendingSubtreeMutations.values()];
16616
16710
  if (!subtreeMutationReprompted && budget.remaining() > 0) {
16617
16711
  subtreeMutationReprompted = true;
16618
- messages.push(
16712
+ appendMessages(
16619
16713
  markRuntimeOnlySessionMessage({
16620
16714
  role: "assistant",
16621
16715
  content: msg.content || "",
16622
16716
  }),
16623
16717
  );
16624
- messages.push(
16718
+ appendMessages(
16625
16719
  markRuntimeOnlySessionMessage({
16626
16720
  role: "user",
16627
16721
  content:
@@ -16665,17 +16759,31 @@ export async function* agentLoop(messages, options) {
16665
16759
  budget.hasRemaining()
16666
16760
  ) {
16667
16761
  throwIfAborted(signal);
16762
+ if (independentReviewSetupError) throw independentReviewSetupError;
16668
16763
  changeReviewState.requested = true;
16669
- messages.push(
16764
+ const reviewPrompt = markRuntimeOnlySessionMessage({
16765
+ role: "user",
16766
+ content: CODING_CHANGE_REVIEW_PROMPT,
16767
+ });
16768
+ appendMessages(
16670
16769
  markRuntimeOnlySessionMessage({
16671
16770
  role: "assistant",
16672
16771
  content: msg.content || "",
16673
16772
  }),
16674
- markRuntimeOnlySessionMessage({
16675
- role: "user",
16676
- content: CODING_CHANGE_REVIEW_PROMPT,
16677
- }),
16773
+ reviewPrompt,
16678
16774
  );
16775
+ if (independentReviewContext) {
16776
+ independentReviewContext.activate(reviewPrompt);
16777
+ changeReviewState.independentReviewPending = true;
16778
+ // These are phase-local discovery hints, not permission or spend
16779
+ // authorities. Fresh inspection must not inherit author assertions,
16780
+ // old visible file pages, or a pause caused by author exploration.
16781
+ readFileLoopGuard = new ReadFileLoopGuard();
16782
+ remoteReadLoopGuard = new RemoteReadLoopGuard();
16783
+ taskProgressTracker = new TaskProgressTracker();
16784
+ toolContext.readFileLoopGuard = readFileLoopGuard;
16785
+ lastTaskProgressIntervention = null;
16786
+ }
16679
16787
  yield {
16680
16788
  type: "iteration-warning",
16681
16789
  message: "Reviewing changed files against the task before finishing.",
@@ -16703,10 +16811,10 @@ export async function* agentLoop(messages, options) {
16703
16811
  const _contentEmpty = !String(msg.content || "").trim();
16704
16812
  if (_contentEmpty && _thinking && !emptyThinkingReprompted) {
16705
16813
  emptyThinkingReprompted = true;
16706
- messages.push(
16814
+ appendMessages(
16707
16815
  markRuntimeOnlySessionMessage({ role: "assistant", content: "" }),
16708
16816
  );
16709
- messages.push(
16817
+ appendMessages(
16710
16818
  markRuntimeOnlySessionMessage({
16711
16819
  role: "user",
16712
16820
  content:
@@ -16770,13 +16878,13 @@ export async function* agentLoop(messages, options) {
16770
16878
  }
16771
16879
  if (stopOutcome && stopOutcome.decision === "block") {
16772
16880
  stopHookActive = true;
16773
- messages.push(
16881
+ appendMessages(
16774
16882
  markRuntimeOnlySessionMessage({
16775
16883
  role: "assistant",
16776
16884
  content: msg.content || "",
16777
16885
  }),
16778
16886
  );
16779
- messages.push(
16887
+ appendMessages(
16780
16888
  markRuntimeOnlySessionMessage({
16781
16889
  role: "user",
16782
16890
  content:
@@ -16792,6 +16900,9 @@ export async function* agentLoop(messages, options) {
16792
16900
  continue;
16793
16901
  }
16794
16902
  }
16903
+ if (independentReviewContext?.active) {
16904
+ changeReviewState.independentReviewPending = false;
16905
+ }
16795
16906
  yield { type: "run-ended", runId, reason: "complete" };
16796
16907
  return;
16797
16908
  }
@@ -16815,7 +16926,7 @@ export async function* agentLoop(messages, options) {
16815
16926
  }
16816
16927
 
16817
16928
  // Add assistant message with tool calls
16818
- messages.push(msg);
16929
+ appendMessages(msg);
16819
16930
  readFileLoopGuard.startBatch();
16820
16931
 
16821
16932
  // Concurrent READ-ONLY batch (latency optimization). When every call in the
@@ -16935,7 +17046,7 @@ export async function* agentLoop(messages, options) {
16935
17046
  if (fatalError) throw fatalError;
16936
17047
  throwIfAborted(signal);
16937
17048
  recordSubtreeMutation(call.function.name, toolArgs, toolResult);
16938
- const taskAdvanced = taskProgressTracker.record(
17049
+ const taskAdvanced = recordTaskProgress(
16939
17050
  call.function.name,
16940
17051
  toolResult,
16941
17052
  toolArgs,
@@ -16968,7 +17079,7 @@ export async function* agentLoop(messages, options) {
16968
17079
  const resultStr = toolResultForModel(
16969
17080
  call.function.name,
16970
17081
  toolResult,
16971
- messages,
17082
+ requestMessages,
16972
17083
  );
16973
17084
  const toolContent = warningMsg
16974
17085
  ? `${resultStr}\n\n${warningMsg}`
@@ -16995,7 +17106,7 @@ export async function* agentLoop(messages, options) {
16995
17106
  toolResult,
16996
17107
  );
16997
17108
  if (nestedOutcomeUnknown) throw nestedOutcomeUnknown;
16998
- messages.push({
17109
+ appendMessages({
16999
17110
  role: "tool",
17000
17111
  content: toolContent,
17001
17112
  tool_call_id: call.id,
@@ -17052,7 +17163,7 @@ export async function* agentLoop(messages, options) {
17052
17163
  tool_use_id: call?.id || null,
17053
17164
  turn_id: `${runId}:t${budget.consumed}`,
17054
17165
  };
17055
- messages.push({
17166
+ appendMessages({
17056
17167
  role: "tool",
17057
17168
  content: `Error: ${reason}.`,
17058
17169
  tool_call_id: call?.id,
@@ -17111,12 +17222,7 @@ export async function* agentLoop(messages, options) {
17111
17222
  readFileLoopGuard.record(
17112
17223
  toolName,
17113
17224
  earlyAuthorityDenial,
17114
- taskProgressTracker.record(
17115
- toolName,
17116
- earlyAuthorityDenial,
17117
- toolArgs,
17118
- runId,
17119
- ),
17225
+ recordTaskProgress(toolName, earlyAuthorityDenial, toolArgs, runId),
17120
17226
  );
17121
17227
  const resultStr = capToolResultString(
17122
17228
  safeStringifyToolResult(earlyAuthorityDenial),
@@ -17152,7 +17258,7 @@ export async function* agentLoop(messages, options) {
17152
17258
  permission_decision_id: decision?.id || null,
17153
17259
  permission_decision: decision,
17154
17260
  };
17155
- messages.push({
17261
+ appendMessages({
17156
17262
  role: "tool",
17157
17263
  content: resultStr,
17158
17264
  tool_call_id: call.id,
@@ -17198,6 +17304,7 @@ export async function* agentLoop(messages, options) {
17198
17304
  try {
17199
17305
  managedCheckpointHandle = beginManagedToolCheckpoint({
17200
17306
  enabled: toolContext.managedCheckpoint === true,
17307
+ readOnly: isCheckpointReadOnly(toolContext, toolName, toolArgs),
17201
17308
  broker,
17202
17309
  workspaceRoot: toolContext.cwd || process.cwd(),
17203
17310
  stateDir: toolContext.managedCheckpointStateDir || undefined,
@@ -17477,9 +17584,13 @@ export async function* agentLoop(messages, options) {
17477
17584
  // Cap an individual tool result so one giant output can't blow the
17478
17585
  // context — but tell the model when we cut it (no more silent
17479
17586
  // mid-content slice). See MAX_TOOL_RESULT_CHARS / capToolResultString.
17480
- const resultStr = toolResultForModel(toolName, toolResult, messages);
17587
+ const resultStr = toolResultForModel(
17588
+ toolName,
17589
+ toolResult,
17590
+ requestMessages,
17591
+ );
17481
17592
  recordSubtreeMutation(toolName, toolArgs, toolResult);
17482
- const taskAdvanced = taskProgressTracker.record(
17593
+ const taskAdvanced = recordTaskProgress(
17483
17594
  toolName,
17484
17595
  toolResult,
17485
17596
  toolArgs,
@@ -17519,7 +17630,7 @@ export async function* agentLoop(messages, options) {
17519
17630
  );
17520
17631
  if (nestedOutcomeUnknown) throw nestedOutcomeUnknown;
17521
17632
 
17522
- messages.push({
17633
+ appendMessages({
17523
17634
  role: "tool",
17524
17635
  content: toolContent,
17525
17636
  tool_call_id: call.id,