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
@@ -0,0 +1,299 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ import executionBroker from "./process-execution-broker/index.js";
5
+ import {
6
+ fileStatIdentity,
7
+ sameFileStatIdentity,
8
+ samePathHandleFileIdentity,
9
+ } from "./secure-file-identity.js";
10
+
11
+ const fsp = fs.promises;
12
+ const sha256 = (value) =>
13
+ `sha256:${createHash("sha256").update(value).digest("hex")}`;
14
+ const fail = (code) => {
15
+ throw Object.assign(new Error(code), { goalWorkspaceCode: code });
16
+ };
17
+ const LIMITS = Object.freeze({
18
+ maxFiles: 50_000,
19
+ maxBytes: 512 * 1024 * 1024,
20
+ maxFileBytes: 64 * 1024 * 1024,
21
+ maxMs: 15_000,
22
+ });
23
+
24
+ function inside(root, target) {
25
+ const relative = path.relative(root, target);
26
+ return (
27
+ relative !== ".." &&
28
+ !relative.startsWith(`..${path.sep}`) &&
29
+ !path.isAbsolute(relative)
30
+ );
31
+ }
32
+
33
+ function samePath(left, right) {
34
+ return process.platform === "win32"
35
+ ? left.toLowerCase() === right.toLowerCase()
36
+ : left === right;
37
+ }
38
+
39
+ async function hasGitAncestor(root) {
40
+ for (let current = root; ; current = path.dirname(current)) {
41
+ try {
42
+ await fsp.lstat(path.join(current, ".git"));
43
+ return true;
44
+ } catch (error) {
45
+ if (error.code !== "ENOENT") throw error;
46
+ }
47
+ if (path.dirname(current) === current) return false;
48
+ }
49
+ }
50
+
51
+ function gitFiles(root, maxFiles) {
52
+ // No shell, index writes, filters, hooks, or inherited Git redirection. The
53
+ // broker remains the sole process boundary; no provider credentials needed.
54
+ const env = Object.fromEntries(
55
+ Object.entries(process.env).filter(([key]) =>
56
+ /^(path|systemroot|windir|temp|tmp|home|userprofile)$/i.test(key),
57
+ ),
58
+ );
59
+ const result = executionBroker.spawnSync(
60
+ "git",
61
+ [
62
+ "-c",
63
+ "core.fsmonitor=false",
64
+ "ls-files",
65
+ "-z",
66
+ "--cached",
67
+ "--others",
68
+ "--exclude-standard",
69
+ "--",
70
+ ".",
71
+ ],
72
+ {
73
+ cwd: root,
74
+ shell: false,
75
+ windowsHide: true,
76
+ encoding: "utf8",
77
+ timeout: 5000,
78
+ maxBuffer: 8 * 1024 * 1024,
79
+ origin: "headless-goal:workspace-evidence",
80
+ scope: "headless-goal",
81
+ policy: "allow",
82
+ env: { ...env, GIT_OPTIONAL_LOCKS: "0", GIT_TERMINAL_PROMPT: "0" },
83
+ },
84
+ );
85
+ if (result.error || result.signal || result.status !== 0)
86
+ fail("source-list-unavailable");
87
+ const files = [...new Set(result.stdout.split("\0").filter(Boolean))].sort();
88
+ if (files.length > maxFiles) fail("resource-limit");
89
+ return files;
90
+ }
91
+
92
+ async function directoryFiles(root, check, maxFiles) {
93
+ const files = [];
94
+ let entries = 0;
95
+ const walk = async (relative) => {
96
+ check();
97
+ const dir = await fsp.opendir(path.join(root, relative));
98
+ for await (const entry of dir) {
99
+ check();
100
+ if (++entries > maxFiles) fail("resource-limit");
101
+ const name = path.join(relative, entry.name);
102
+ if (entry.name === ".git") continue;
103
+ if (entry.isDirectory()) await walk(name);
104
+ else files.push(name);
105
+ }
106
+ };
107
+ await walk("");
108
+ return files.sort();
109
+ }
110
+
111
+ /** Read-only content evidence. Git scope is tracked + nonignored files under
112
+ * cwd; artifact reads also cover ignored output files. No Git scope is silently
113
+ * replaced by a smaller directory scan when Git fails. This detects ordinary
114
+ * concurrent changes, not a hostile writer that can perform undetectable ABA.
115
+ */
116
+ export async function captureGoalWorkspace(
117
+ cwd,
118
+ call,
119
+ { signal, limits = {} } = {},
120
+ ) {
121
+ const bounds = { ...LIMITS, ...limits };
122
+ const started = Date.now();
123
+ let rootHandle;
124
+ const check = () => {
125
+ if (signal?.aborted) fail("cancelled");
126
+ if (Date.now() - started > bounds.maxMs) fail("resource-limit");
127
+ };
128
+ try {
129
+ check();
130
+ const artifact = call?.tool === "read_file";
131
+ const workspaceTool = call?.tool === "run_shell";
132
+ if (!artifact && !workspaceTool) fail("tool-scope-unavailable");
133
+ const root = await fsp.realpath(path.resolve(cwd));
134
+ const rootStat = await fsp.stat(root, { bigint: true });
135
+ if (!rootStat.isDirectory()) fail("workspace-unavailable");
136
+ rootHandle = await fsp.open(root, fs.constants.O_RDONLY);
137
+ const rootDevice = (await rootHandle.stat({ bigint: true })).dev;
138
+ const workspaceId = sha256(
139
+ JSON.stringify([
140
+ root,
141
+ String(rootStat.dev),
142
+ String(rootStat.ino),
143
+ String(rootStat.birthtimeNs),
144
+ ]),
145
+ );
146
+ let scope;
147
+ let list;
148
+ if (artifact) {
149
+ if (typeof call.args?.path !== "string" || !call.args.path)
150
+ fail("artifact-path-unavailable");
151
+ const target = path.resolve(root, call.args.path);
152
+ if (!inside(root, target) || target === root) fail("outside-workspace");
153
+ scope = "artifact";
154
+ list = async () => [path.relative(root, target)];
155
+ } else if (await hasGitAncestor(root)) {
156
+ scope = "git-visible-files-under-cwd";
157
+ list = async () => gitFiles(root, bounds.maxFiles);
158
+ } else {
159
+ scope = "directory-files-under-cwd";
160
+ list = () => directoryFiles(root, check, bounds.maxFiles);
161
+ }
162
+ const files = await list();
163
+ check();
164
+ const content = createHash("sha256");
165
+ const freshness = createHash("sha256");
166
+ const identities = [];
167
+ const artifacts = [];
168
+ let totalBytes = 0;
169
+ for (const relative of files) {
170
+ check();
171
+ const target = path.resolve(root, relative);
172
+ if (!inside(root, target)) fail("outside-workspace");
173
+ // Canonical parents must stay within this exact workspace. Symlinks,
174
+ // submodules, special files and unreadable entries are not partial proof.
175
+ let before;
176
+ try {
177
+ before = await fsp.lstat(target, { bigint: true });
178
+ } catch (error) {
179
+ // Deleted tracked files are part of the current source version. A
180
+ // missing requested artifact, however, cannot support completion.
181
+ if (scope !== "git-visible-files-under-cwd" || error.code !== "ENOENT")
182
+ throw error;
183
+ content.update(
184
+ JSON.stringify({ path: relative, missing: true }) + "\n",
185
+ );
186
+ freshness.update(
187
+ JSON.stringify({ path: relative, missing: true }) + "\n",
188
+ );
189
+ identities.push([target, null]);
190
+ continue;
191
+ }
192
+ const canonical = await fsp.realpath(target);
193
+ if (!samePath(canonical, target) || !inside(root, canonical))
194
+ fail("linked-entry");
195
+ if (!before.isFile() || before.nlink !== 1n) fail("unsupported-entry");
196
+ if (before.size > BigInt(bounds.maxFileBytes)) fail("resource-limit");
197
+ totalBytes += Number(before.size);
198
+ if (totalBytes > bounds.maxBytes) fail("resource-limit");
199
+ let handle;
200
+ try {
201
+ handle = await fsp.open(
202
+ target,
203
+ fs.constants.O_RDONLY |
204
+ (fs.constants.O_NOFOLLOW || 0) |
205
+ (fs.constants.O_NONBLOCK || 0),
206
+ );
207
+ const opened = await handle.stat({ bigint: true });
208
+ if (!samePathHandleFileIdentity(before, opened, rootDevice))
209
+ fail("workspace-changed");
210
+ const digest = createHash("sha256");
211
+ const buffer = Buffer.alloc(64 * 1024);
212
+ let size = 0;
213
+ while (true) {
214
+ check();
215
+ const { bytesRead } = await handle.read(
216
+ buffer,
217
+ 0,
218
+ buffer.length,
219
+ null,
220
+ );
221
+ if (bytesRead === 0) break;
222
+ size += bytesRead;
223
+ if (size > Number(before.size)) fail("workspace-changed");
224
+ digest.update(buffer.subarray(0, bytesRead));
225
+ }
226
+ const after = await fsp.lstat(target, { bigint: true });
227
+ if (
228
+ size !== Number(before.size) ||
229
+ !sameFileStatIdentity(before, after) ||
230
+ !samePathHandleFileIdentity(
231
+ after,
232
+ await handle.stat({ bigint: true }),
233
+ rootDevice,
234
+ )
235
+ )
236
+ fail("workspace-changed");
237
+ const entry = {
238
+ path: relative.split(path.sep).join("/"),
239
+ size,
240
+ digest: `sha256:${digest.digest("hex")}`,
241
+ };
242
+ content.update(JSON.stringify(entry) + "\n");
243
+ freshness.update(
244
+ JSON.stringify([entry.path, fileStatIdentity(after)]) + "\n",
245
+ );
246
+ identities.push([target, after]);
247
+ if (artifact) artifacts.push(entry);
248
+ } finally {
249
+ await handle?.close();
250
+ }
251
+ }
252
+ if (JSON.stringify(await list()) !== JSON.stringify(files))
253
+ fail("workspace-changed");
254
+ check();
255
+ for (const [target, stat] of identities) {
256
+ check();
257
+ let current = null;
258
+ try {
259
+ current = await fsp.lstat(target, { bigint: true });
260
+ } catch (error) {
261
+ if (error.code !== "ENOENT") throw error;
262
+ }
263
+ if (
264
+ stat === null
265
+ ? current !== null
266
+ : !current || !sameFileStatIdentity(stat, current)
267
+ )
268
+ fail("workspace-changed");
269
+ }
270
+ const finalRoot = await fsp.stat(root, { bigint: true });
271
+ if (
272
+ (await fsp.realpath(path.resolve(cwd))) !== root ||
273
+ finalRoot.ino !== rootStat.ino ||
274
+ finalRoot.dev !== rootStat.dev ||
275
+ finalRoot.birthtimeNs !== rootStat.birthtimeNs
276
+ )
277
+ fail("workspace-changed");
278
+ check();
279
+ return {
280
+ verified: true,
281
+ scope,
282
+ workspaceId,
283
+ digest: `sha256:${content.digest("hex")}`,
284
+ freshnessDigest: `sha256:${freshness.digest("hex")}`,
285
+ fileCount: files.length,
286
+ totalBytes,
287
+ ...(artifact ? { artifacts } : {}),
288
+ };
289
+ } catch (error) {
290
+ // File/provider text is not a diagnostic channel. Missing/denied/unstable
291
+ // coverage remains unavailable and must not become a positive verdict.
292
+ return {
293
+ verified: false,
294
+ reason: error.goalWorkspaceCode || "workspace-unavailable",
295
+ };
296
+ } finally {
297
+ await rootHandle?.close();
298
+ }
299
+ }
@@ -10,7 +10,7 @@
10
10
  "label": "Volcengine / Doubao (volcengine)",
11
11
  "cliLabel": "Volcengine (火山引擎/豆包)",
12
12
  "baseUrl": "https://ark.cn-beijing.volces.com/api/v3",
13
- "defaultModel": "deepseek-v4-1-flash-260910",
13
+ "defaultModel": "deepseek-v4-1-flash-economy-261017",
14
14
  "needsKey": true,
15
15
  "visionModel": "doubao-seed-2-0-lite-260215"
16
16
  },
@@ -91,6 +91,7 @@ export const BUILT_IN_PROVIDERS = {
91
91
  baseUrl: "https://ark.cn-beijing.volces.com/api/v3",
92
92
  apiKeyEnv: "VOLCENGINE_API_KEY",
93
93
  models: [
94
+ "deepseek-v4-1-flash-economy-261017",
94
95
  "deepseek-v4-1-flash-260910",
95
96
  "deepseek-v4-flash-ga-260731",
96
97
  "deepseek-v4-flash-260425",
@@ -24,7 +24,7 @@ export const TaskType = {
24
24
  */
25
25
  const TASK_MODEL_MAP = {
26
26
  [TaskType.CHAT]: {
27
- volcengine: "deepseek-v4-1-flash-260910",
27
+ volcengine: "deepseek-v4-1-flash-economy-261017",
28
28
  openai: "gpt-4o-mini",
29
29
  anthropic: "claude-sonnet-4-6",
30
30
  deepseek: "deepseek-chat",