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
@@ -42,7 +42,10 @@ import {
42
42
  resolvePermissionPromptTool,
43
43
  makePermissionPromptConfirmer,
44
44
  } from "./mcp-config.js";
45
- import { maybeApplyToolSearch } from "./mcp-tool-search.js";
45
+ import {
46
+ maybeApplyToolSearch,
47
+ projectMcpToolDefinitions,
48
+ } from "./mcp-tool-search.js";
46
49
  import { IterationBudget } from "../lib/iteration-budget.js";
47
50
  import { HostResourceBudget } from "../lib/host-resource-budget.js";
48
51
  import {
@@ -169,6 +172,19 @@ export const _goalProcessDeps = {
169
172
  export const RUNTIME_LEDGER_PERSISTENCE_FAILURE_MESSAGE =
170
173
  "CC_RUNTIME_USAGE_LEDGER_FAILED: runtime usage telemetry was not durably persisted";
171
174
 
175
+ export const GOAL_CHECKPOINT_FAILURE_CODE = "CC_GOAL_CHECKPOINT_FAILED";
176
+ export const GOAL_CHECKPOINT_FAILURE_MESSAGE =
177
+ `${GOAL_CHECKPOINT_FAILURE_CODE}: goal state could not be safely saved or restored; ` +
178
+ "verify prior effects and usage before continuing; for an interrupted goal, " +
179
+ "resume with --goal-recovery-reviewed only after that review";
180
+
181
+ function goalCheckpointFailure(cause, phase) {
182
+ const error = new Error(GOAL_CHECKPOINT_FAILURE_MESSAGE, { cause });
183
+ error.code = GOAL_CHECKPOINT_FAILURE_CODE;
184
+ error.goalCheckpointPhase = phase;
185
+ return error;
186
+ }
187
+
172
188
  export function resolveHeadlessMeteredSessionId(persist, sessionId) {
173
189
  return persist && sessionId ? sessionId : null;
174
190
  }
@@ -230,6 +246,12 @@ import {
230
246
  runtimeToolCallId,
231
247
  } from "../lib/runtime-usage-ledger.js";
232
248
  import { runMeteredDirectModelCall } from "../lib/direct-model-usage.js";
249
+ import {
250
+ GoalCheckEvidence,
251
+ buildGoalJudgePrompt,
252
+ usableGoalEvidence,
253
+ validateGoalJudgeVerdict,
254
+ } from "../lib/goal-check-evidence.js";
233
255
  import { resolveTeamMessageToolBundle } from "../lib/agent-team/team-message-tools.js";
234
256
  import { normalizeDecisionMode } from "../lib/decision-layer/contracts.js";
235
257
  import { createSkillDecisionRuntime } from "../lib/decision-layer/runtime.js";
@@ -2640,7 +2662,10 @@ async function runAgentHeadlessInWorkspace(
2640
2662
  }
2641
2663
  try {
2642
2664
  store.appendEvent(sessionId, "context_sources", {
2643
- mcp: (mcp?.extraToolDefinitions || []).map((definition) => ({
2665
+ mcp: projectMcpToolDefinitions(
2666
+ mcp?.extraToolDefinitions || [],
2667
+ mcp?.externalToolExecutors,
2668
+ ).map((definition) => ({
2644
2669
  function: {
2645
2670
  name: definition?.function?.name || null,
2646
2671
  description: definition?.function?.description || "",
@@ -2970,6 +2995,8 @@ async function runAgentHeadlessInWorkspace(
2970
2995
  exactToolNames: options.exactToolNames === true,
2971
2996
  fileMutationScope,
2972
2997
  hermeticExecution,
2998
+ reviewChanges: options.reviewChanges === true,
2999
+ _changeReviewState: { requested: false },
2973
3000
  iterationBudget: budget,
2974
3001
  toolAdmission: hermeticExecution ? null : options.toolAdmission || null,
2975
3002
  unattendedActionPolicy: hermeticExecution
@@ -3363,17 +3390,25 @@ async function runAgentHeadlessInWorkspace(
3363
3390
  let _goalHelpers = null;
3364
3391
  let _goalTokensSeen = 0; // per-turn usage deltas (engine totals == run total)
3365
3392
  let _goalCostSeen = 0;
3393
+ let goalSetupFailure = null;
3394
+ let goalRecoveryReviewed = false;
3395
+ const goalEvidence = options.goalCondition
3396
+ ? new GoalCheckEvidence({ readOnlyTools: READ_ONLY_TOOLS })
3397
+ : null;
3366
3398
  // Model-judged conditions reuse the run's own model as an independent
3367
3399
  // evaluator (mirrors --goal-assess). Overridable via deps for tests.
3368
3400
  const _defaultGoalJudge = async (cond, transcript) => {
3401
+ if (!usableGoalEvidence(transcript.goalEvidence).length) {
3402
+ return {
3403
+ met: false,
3404
+ reason:
3405
+ "No current successful tool evidence; run an explicit check for the goal condition",
3406
+ evidence: { kind: "model", source: "current-turn-tools", toolIds: [] },
3407
+ };
3408
+ }
3369
3409
  const { chatWithTools } = await import("./agent-core.js");
3370
3410
  const { firstBalancedJson } = await import("../lib/json-schema-output.js");
3371
- const judgePrompt =
3372
- `You are judging whether a coding session met a completion condition.\n` +
3373
- `Condition: ${cond.text || cond.source}\n\n` +
3374
- `Latest assistant output:\n${String(transcript.finalText || "").slice(0, 2000)}\n\n` +
3375
- `Reply with STRICT JSON only, for example: {"met": false, "reason": "<short>"}. ` +
3376
- `Set met to true only when the condition is satisfied; otherwise false.`;
3411
+ const judgePrompt = buildGoalJudgePrompt(cond, transcript);
3377
3412
  const r = await runMeteredDirectModelCall({
3378
3413
  sessionId: resolveHeadlessMeteredSessionId(persist, sessionId),
3379
3414
  persist: persist
@@ -3394,37 +3429,33 @@ async function runAgentHeadlessInWorkspace(
3394
3429
  }),
3395
3430
  });
3396
3431
  const text = r?.message?.content || "";
3397
- let met = false;
3398
- let reason = "model judge returned no verdict";
3432
+ let verdict = null;
3399
3433
  const block = firstBalancedJson(text, "{");
3400
3434
  if (block) {
3401
3435
  try {
3402
- const parsed = JSON.parse(block);
3403
- met = parsed.met === true;
3404
- if (typeof parsed.reason === "string" && parsed.reason.trim())
3405
- reason = parsed.reason.trim();
3406
- else reason = met ? "condition met" : "condition not met";
3436
+ verdict = JSON.parse(block);
3407
3437
  } catch {
3408
3438
  /* tolerant: a non-JSON verdict stays unmet */
3409
3439
  }
3410
3440
  }
3411
- return {
3412
- met,
3413
- reason,
3414
- evidence: { kind: "model", raw: text.slice(0, 200) },
3415
- };
3441
+ return validateGoalJudgeVerdict(verdict, transcript.goalEvidence);
3416
3442
  };
3417
- // Persist the engine snapshot as a hash-chained `goal_snapshot` session event
3418
- // (best-effort, only when persisting). Re-read on --resume so an unfinished
3419
- // goal continues across processes with its outerTurns/tokens/cost/startedAtMs
3420
- // intact. rebuildMessages ignores this event type, so it never pollutes model
3421
- // context. Defined here so the outer loop can call it after each evaluate().
3422
- const persistGoalSnapshot = () => {
3443
+ // A running checkpoint precedes model/tool effects; an evaluated checkpoint
3444
+ // precedes publishing the decision. An interrupted running phase requires
3445
+ // reconciliation on resume instead of silently replaying the old goal state.
3446
+ const persistGoalSnapshot = (phase, failurePhase = "after-model") => {
3423
3447
  if (!persist || !goalEngine) return;
3424
3448
  try {
3425
- store.appendEvent(sessionId, "goal_snapshot", goalEngine.snapshot());
3426
- } catch {
3427
- // best-effort — never fail the run over persistence
3449
+ store.appendEvent(sessionId, "goal_snapshot", {
3450
+ ...goalEngine.snapshot(),
3451
+ checkpoint: {
3452
+ schema: "chainlesschain.goal-checkpoint/v1",
3453
+ phase,
3454
+ ...(goalRecoveryReviewed ? { recoveryReviewed: true } : {}),
3455
+ },
3456
+ });
3457
+ } catch (error) {
3458
+ throw goalCheckpointFailure(error, failurePhase);
3428
3459
  }
3429
3460
  };
3430
3461
  if (options.goalCondition) {
@@ -3442,17 +3473,41 @@ async function runAgentHeadlessInWorkspace(
3442
3473
  try {
3443
3474
  const event = store.findLatestEvent(resumeId, "goal_snapshot");
3444
3475
  const snap = event?.data;
3476
+ if (
3477
+ event &&
3478
+ (!snap?.state ||
3479
+ typeof snap.state.done !== "boolean" ||
3480
+ (snap.checkpoint != null &&
3481
+ (snap.checkpoint.schema !==
3482
+ "chainlesschain.goal-checkpoint/v1" ||
3483
+ !["ready", "running", "evaluated"].includes(
3484
+ snap.checkpoint.phase,
3485
+ ))))
3486
+ ) {
3487
+ throw goalCheckpointFailure(null, "before-model");
3488
+ }
3489
+ if (snap?.checkpoint?.phase === "running") {
3490
+ if (options.goalRecoveryReviewed !== true)
3491
+ throw goalCheckpointFailure(null, "before-model");
3492
+ goalRecoveryReviewed = true;
3493
+ }
3445
3494
  if (snap && snap.state && snap.state.done !== true) {
3446
3495
  restoredSnap = snap;
3447
3496
  }
3448
- } catch {
3449
- restoredSnap = null; // unreadable transcript → start fresh
3497
+ } catch (error) {
3498
+ throw error?.code === GOAL_CHECKPOINT_FAILURE_CODE
3499
+ ? error
3500
+ : goalCheckpointFailure(error, "before-model");
3450
3501
  }
3451
3502
  }
3452
3503
  if (restoredSnap) {
3453
- goalEngine = eng.GoalConditionEngine.fromSnapshot(restoredSnap, {
3454
- now: goalNow,
3455
- });
3504
+ try {
3505
+ goalEngine = eng.GoalConditionEngine.fromSnapshot(restoredSnap, {
3506
+ now: goalNow,
3507
+ });
3508
+ } catch (error) {
3509
+ throw goalCheckpointFailure(error, "before-model");
3510
+ }
3456
3511
  } else {
3457
3512
  goalEngine = new eng.GoalConditionEngine({
3458
3513
  condition: options.goalCondition,
@@ -3471,13 +3526,14 @@ async function runAgentHeadlessInWorkspace(
3471
3526
  GOAL_DECISION: eng.GOAL_DECISION,
3472
3527
  };
3473
3528
  const started = goalEngine.start();
3529
+ persistGoalSnapshot("ready", "before-model");
3474
3530
  emitStream({
3475
3531
  type: started.type,
3476
3532
  condition: started.condition,
3477
3533
  budget: started.budget,
3478
3534
  resumed: Boolean(restoredSnap),
3535
+ ...(goalRecoveryReviewed ? { recovery_reviewed: true } : {}),
3479
3536
  });
3480
- persistGoalSnapshot(); // checkpoint the starting/restored state
3481
3537
  if (isText)
3482
3538
  writeErr(
3483
3539
  ` ◎ goal-condition ${restoredSnap ? "resumed" : "active"}: ` +
@@ -3486,10 +3542,15 @@ async function runAgentHeadlessInWorkspace(
3486
3542
  `${goalEngine.budget.maxOuterTurns})\n`,
3487
3543
  );
3488
3544
  } catch (err) {
3489
- // A bad spec should have been rejected at the command layer; fail-open so
3490
- // a malformed condition never aborts an otherwise-valid run.
3491
- goalEngine = null;
3492
- if (isText) writeErr(` goal-condition ignored: ${err.message}\n`);
3545
+ if (err?.code === GOAL_CHECKPOINT_FAILURE_CODE) {
3546
+ // Surface through the main failure/cleanup path before any agent call.
3547
+ goalSetupFailure = err;
3548
+ } else {
3549
+ // A bad spec should have been rejected at the command layer; fail-open so
3550
+ // a malformed condition never aborts an otherwise-valid run.
3551
+ goalEngine = null;
3552
+ if (isText) writeErr(` goal-condition ignored: ${err.message}\n`);
3553
+ }
3493
3554
  }
3494
3555
  }
3495
3556
 
@@ -3522,8 +3583,11 @@ async function runAgentHeadlessInWorkspace(
3522
3583
  let loopFailureOutcome = null;
3523
3584
  let cleanupFailure = null;
3524
3585
  try {
3586
+ if (goalSetupFailure) throw goalSetupFailure;
3525
3587
  while (true) {
3526
3588
  sessionHostLease?.assert?.();
3589
+ persistGoalSnapshot("running", "before-model");
3590
+ goalEvidence?.beginTurn();
3527
3591
  // P1 turn→checkpoint binding: one drain of the loop = one turn. Anchor
3528
3592
  // the conversation offset before the model sees the new user turn. A
3529
3593
  // `--worktree` run stamps its isolation worktree (branch name, threaded
@@ -3586,6 +3650,7 @@ async function runAgentHeadlessInWorkspace(
3586
3650
  args: event.args,
3587
3651
  };
3588
3652
  toolCalls.push(toolCall);
3653
+ goalEvidence?.started(toolCall);
3589
3654
  toolStartedAt.set(
3590
3655
  telemetryToolId,
3591
3656
  deps.now ? deps.now() : Date.now(),
@@ -3713,6 +3778,7 @@ async function runAgentHeadlessInWorkspace(
3713
3778
  if (policyEvent) emitStream(policyEvent);
3714
3779
  }
3715
3780
  if (settledCall) {
3781
+ goalEvidence?.settled(settledCall, event.result, Boolean(err));
3716
3782
  settledCall.is_error = Boolean(err);
3717
3783
  settledCall.durationMs =
3718
3784
  event.result?.toolTelemetryRecord?.durationMs ??
@@ -4069,6 +4135,7 @@ async function runAgentHeadlessInWorkspace(
4069
4135
  prompt: options.prompt,
4070
4136
  finalText,
4071
4137
  toolCalls,
4138
+ goalEvidence: goalEvidence.snapshot(),
4072
4139
  });
4073
4140
  }
4074
4141
  } catch (err) {
@@ -4082,6 +4149,8 @@ async function runAgentHeadlessInWorkspace(
4082
4149
  }
4083
4150
 
4084
4151
  const { decision, events } = goalEngine.evaluate(evaluation);
4152
+ // Publish only after the decision and accumulated usage are durable.
4153
+ persistGoalSnapshot("evaluated");
4085
4154
  for (const ev of events) {
4086
4155
  emitStream(ev);
4087
4156
  if (isText) {
@@ -4097,10 +4166,6 @@ async function runAgentHeadlessInWorkspace(
4097
4166
  );
4098
4167
  }
4099
4168
  }
4100
- // Checkpoint the post-evaluate state (outerTurns incremented, and
4101
- // done/outcome on a terminal decision) so a crash or Ctrl-C between here
4102
- // and the next turn still resumes at the right point.
4103
- persistGoalSnapshot();
4104
4169
  if (decision === _goalHelpers.GOAL_DECISION.CONTINUE) {
4105
4170
  messages.push(
4106
4171
  markRuntimeOnlySessionMessage({
@@ -4119,6 +4184,8 @@ async function runAgentHeadlessInWorkspace(
4119
4184
  );
4120
4185
  continue; // re-drive: run another outer turn
4121
4186
  }
4187
+ if (decision === _goalHelpers.GOAL_DECISION.EXHAUSTED)
4188
+ endReason = "goal-exhausted";
4122
4189
  // complete | exhausted → fall through to the break below.
4123
4190
  }
4124
4191
  break;
@@ -4126,13 +4193,16 @@ async function runAgentHeadlessInWorkspace(
4126
4193
  } catch (err) {
4127
4194
  const runtimeLedgerPersistenceFailed =
4128
4195
  err?.runtimeLedgerPersistence === true;
4129
- const persistence = runtimeLedgerPersistenceFailed
4196
+ const goalCheckpointFailed = err?.code === GOAL_CHECKPOINT_FAILURE_CODE;
4197
+ const persistenceFailed =
4198
+ runtimeLedgerPersistenceFailed || goalCheckpointFailed;
4199
+ const persistence = persistenceFailed
4130
4200
  ? projectSessionPersistenceFailure(
4131
4201
  createSessionPersistenceFailure(err, {
4132
4202
  sessionId,
4133
4203
  operation: "append-event",
4134
4204
  }),
4135
- { phase: "after-model" },
4205
+ { phase: err.goalCheckpointPhase || "after-model" },
4136
4206
  )
4137
4207
  : null;
4138
4208
  if (persistence) {
@@ -4146,17 +4216,19 @@ async function runAgentHeadlessInWorkspace(
4146
4216
  err?.code === "CC_SESSION_BUDGET_EXHAUSTED" ||
4147
4217
  err?.code === "CC_SESSION_BUDGET_USAGE_UNKNOWN" ||
4148
4218
  options.sessionBudget?.signal?.aborted === true;
4149
- const message = runtimeLedgerPersistenceFailed
4150
- ? RUNTIME_LEDGER_PERSISTENCE_FAILURE_MESSAGE
4151
- : err?.code === "CC_SESSION_BUDGET_USAGE_UNKNOWN"
4152
- ? err.message
4153
- : sessionBudgetFailed
4154
- ? sessionBudgetAdmissionError(
4155
- options.sessionBudget?.reason?.() || err?.budgetReason,
4156
- "run",
4157
- ).message
4158
- : err?.message || String(err);
4159
- const errorSubtype = runtimeLedgerPersistenceFailed
4219
+ const message = goalCheckpointFailed
4220
+ ? GOAL_CHECKPOINT_FAILURE_MESSAGE
4221
+ : runtimeLedgerPersistenceFailed
4222
+ ? RUNTIME_LEDGER_PERSISTENCE_FAILURE_MESSAGE
4223
+ : err?.code === "CC_SESSION_BUDGET_USAGE_UNKNOWN"
4224
+ ? err.message
4225
+ : sessionBudgetFailed
4226
+ ? sessionBudgetAdmissionError(
4227
+ options.sessionBudget?.reason?.() || err?.budgetReason,
4228
+ "run",
4229
+ ).message
4230
+ : err?.message || String(err);
4231
+ const errorSubtype = persistenceFailed
4160
4232
  ? "error_persistence"
4161
4233
  : sessionBudgetFailed
4162
4234
  ? "error_session_budget"
@@ -4166,9 +4238,7 @@ async function runAgentHeadlessInWorkspace(
4166
4238
  const diagnosticFields = transportDetails
4167
4239
  ? { error_details: transportDetails }
4168
4240
  : {
4169
- ...(runtimeLedgerPersistenceFailed && err.code
4170
- ? { code: err.code }
4171
- : {}),
4241
+ ...(persistenceFailed && err.code ? { code: err.code } : {}),
4172
4242
  ...(persistence ? { persistence } : {}),
4173
4243
  };
4174
4244
  if (isStream) {
@@ -4204,13 +4274,11 @@ async function runAgentHeadlessInWorkspace(
4204
4274
  // "the model call failed" from "the run itself errored" (1).
4205
4275
  loopFailureOutcome = {
4206
4276
  exitCode:
4207
- runtimeLedgerPersistenceFailed || sessionBudgetFailed
4208
- ? 1
4209
- : classifyLoopError(err),
4277
+ persistenceFailed || sessionBudgetFailed ? 1 : classifyLoopError(err),
4210
4278
  result: message,
4211
4279
  isError: true,
4212
4280
  ...(persistence ? { persistence } : {}),
4213
- ...(runtimeLedgerPersistenceFailed && err.code ? { code: err.code } : {}),
4281
+ ...(persistenceFailed && err.code ? { code: err.code } : {}),
4214
4282
  };
4215
4283
  } finally {
4216
4284
  // Capture body-cache hits/misses caused by list_skills/run_skill during the
@@ -4380,18 +4448,22 @@ async function runAgentHeadlessInWorkspace(
4380
4448
  const exhausted =
4381
4449
  endReason === "budget-exhausted" || endReason === "max_turns";
4382
4450
  const costStopped = endReason === "cost-budget-exhausted";
4451
+ const goalExhausted = endReason === "goal-exhausted";
4383
4452
  let isError =
4384
4453
  exhausted ||
4385
4454
  costStopped ||
4455
+ goalExhausted ||
4386
4456
  endReason === "no-response" ||
4387
4457
  endReason === "deferred-mutation-unresolved";
4388
4458
  let subtype = exhausted
4389
4459
  ? "error_max_turns"
4390
4460
  : costStopped
4391
4461
  ? "error_max_budget"
4392
- : isError
4393
- ? "error"
4394
- : "success";
4462
+ : goalExhausted
4463
+ ? "error_goal_condition"
4464
+ : isError
4465
+ ? "error"
4466
+ : "success";
4395
4467
  const durationMs = (deps.now ? deps.now() : Date.now()) - startedAt;
4396
4468
  let persistenceFailure = null;
4397
4469
  let sessionPersistenceCode = null;
@@ -3862,6 +3862,7 @@ async function runAgentHeadlessStreamInWorkspace(
3862
3862
  };
3863
3863
  const loopOptionsBase = {
3864
3864
  ...(evolutionIngress === null ? {} : { evolutionIngress }),
3865
+ reviewChanges: options.reviewChanges === true,
3865
3866
  model,
3866
3867
  provider,
3867
3868
  // Extended thinking (Anthropic; opt-in via --think/--ultrathink).
@@ -0,0 +1,142 @@
1
+ // Keyword ranking only: admission, schema loading and executor generations
2
+ // remain owned by mcp-tool-search.js. No provider or embedding calls.
3
+ const segmenter = new Intl.Segmenter("zh", { granularity: "word" });
4
+ const documents = new WeakMap();
5
+ const stopWords = new Set([
6
+ "a",
7
+ "an",
8
+ "the",
9
+ "to",
10
+ "of",
11
+ "for",
12
+ "in",
13
+ "on",
14
+ "with",
15
+ "and",
16
+ "please",
17
+ "help",
18
+ "me",
19
+ "how",
20
+ "can",
21
+ "i",
22
+ "请",
23
+ "请问",
24
+ "帮",
25
+ "帮我",
26
+ "我",
27
+ "我要",
28
+ "需要",
29
+ "如何",
30
+ "怎么",
31
+ "一下",
32
+ "一个",
33
+ "的",
34
+ "在",
35
+ "中",
36
+ "和",
37
+ "并",
38
+ "给",
39
+ "为",
40
+ "从",
41
+ "将",
42
+ "把",
43
+ "进行",
44
+ "可以",
45
+ "使用",
46
+ ]);
47
+
48
+ const normalize = (text) => text.normalize("NFKC").toLowerCase();
49
+
50
+ export function compileMcpToolSearchQuery(query) {
51
+ const scoring = new Set();
52
+ const required = new Set();
53
+ const chunks = normalize(query)
54
+ .split(/[\s,,、;;!?!?。::]+/u)
55
+ .filter(Boolean);
56
+ for (const chunk of chunks) {
57
+ if (!chunk) continue;
58
+ if (chunk.startsWith("+") && chunk.length > 1) {
59
+ // A required name fragment is literal, never split or stop-word filtered.
60
+ required.add(chunk.slice(1));
61
+ scoring.add(chunk.slice(1));
62
+ } else if (/\p{Script=Han}/u.test(chunk)) {
63
+ for (const part of segmenter.segment(chunk)) {
64
+ if (part.isWordLike && !stopWords.has(part.segment))
65
+ scoring.add(part.segment);
66
+ }
67
+ } else if (
68
+ (!stopWords.has(chunk) || chunks.length === 1) &&
69
+ /[\p{L}\p{N}]/u.test(chunk)
70
+ ) {
71
+ scoring.add(chunk);
72
+ }
73
+ }
74
+ return { scoring: [...scoring], required: [...required] };
75
+ }
76
+
77
+ function documentFor(name, entry) {
78
+ const description = String(entry.definition?.function?.description || "");
79
+ const cached = documents.get(entry);
80
+ if (cached?.name === name && cached.description === description)
81
+ return cached;
82
+ // Preserve exact identifier fragments and expose camel-case word boundaries
83
+ // for natural-language queries such as "read file" against readFile.
84
+ const words = name.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
85
+ const document = {
86
+ name,
87
+ description,
88
+ lowerName: normalize(name),
89
+ nameWords: words === name ? null : normalize(words),
90
+ lowerDescription: normalize(description),
91
+ };
92
+ documents.set(entry, document);
93
+ return document;
94
+ }
95
+
96
+ function compare(left, right) {
97
+ return (
98
+ right.score - left.score ||
99
+ (left.name < right.name ? -1 : left.name > right.name ? 1 : 0)
100
+ );
101
+ }
102
+
103
+ export function rankMcpToolSearchEntries(entries, query, maxResults) {
104
+ const { scoring, required } = compileMcpToolSearchQuery(query);
105
+ if (!scoring.length) return [];
106
+ const results = [];
107
+ for (const [name, entry] of entries) {
108
+ if (entry.stale === true) continue;
109
+ const doc = documentFor(name, entry);
110
+ if (required.some((term) => !doc.lowerName.includes(term))) continue;
111
+ let coverage = 0,
112
+ nameHits = 0,
113
+ descriptionHits = 0;
114
+ for (const term of scoring) {
115
+ const inName =
116
+ doc.lowerName.includes(term) || Boolean(doc.nameWords?.includes(term));
117
+ const inDescription = doc.lowerDescription.includes(term);
118
+ if (inName || inDescription) coverage++;
119
+ if (inName) nameHits++;
120
+ if (inDescription) descriptionHits++;
121
+ }
122
+ if (!coverage) continue;
123
+ // Intent coverage wins over repetition of one broad word. At equal
124
+ // coverage retain the existing 3:1 name/description preference.
125
+ const score =
126
+ coverage * (scoring.length * 4 + 1) + nameHits * 3 + descriptionHits;
127
+ const result = { name, entry, score };
128
+ // Keep only top K, rather than allocating and sorting every matching tool.
129
+ let low = 0,
130
+ high = results.length;
131
+ while (low < high) {
132
+ const mid = (low + high) >>> 1;
133
+ if (compare(result, results[mid]) < 0) high = mid;
134
+ else low = mid + 1;
135
+ }
136
+ if (low < maxResults) {
137
+ results.splice(low, 0, result);
138
+ if (results.length > maxResults) results.pop();
139
+ }
140
+ }
141
+ return results;
142
+ }