chainlesschain 0.166.104 → 0.166.105

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 (164) hide show
  1. package/README.md +14 -2
  2. package/package.json +2 -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-Bah3HREy.js → AIOps-CcD-AVDw.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-DY2aeZMc.js → ActionButton-CYy-g36A.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-BFly8Xaa.js → Analytics-DPFDNaBL.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-dp0Zz-JM.js → AppLayout-PVIuRdgN.js} +4 -4
  9. package/src/assets/web-panel/assets/{Artifacts-DcIg09ai.js → Artifacts-BXGD3bM-.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-DkN-lsjZ.js → Audit-Bu5s_4tu.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-BjzgusLx.js → BackgroundAgents-BHmgpnzo.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-CU8S6qu9.js → Backup-C872jURx.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-B1pC2gjL.js → BaseInput-Bh7xO30H.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-B6xFp6gD.js → Chat-DaacK53T.js} +6 -6
  15. package/src/assets/web-panel/assets/{ChatBubbleRenderer-DxNCLZ_X.js → ChatBubbleRenderer-PYrSKMM_.js} +1 -1
  16. package/src/assets/web-panel/assets/{Checkbox-QHw7Vc4U.js → Checkbox-Cnt7_8I2.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-gdecsfjg.js → Codegen-AZRz6kmW.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-B0_JmAmc.js → Col-BtOXzMFt.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-DRCcP5xR.js → Community-BFmFygS7.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-DZtoGzhX.js → Compact-2z5CfKpR.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-BfNTvEnT.js → Compliance-B5hKrPVF.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-CDXTLm84.js → Cowork-CxEyp2ww.js} +3 -3
  23. package/src/assets/web-panel/assets/{Cron-Big35CbN.js → Cron-B-8f9_qF.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-C8ArrAVr.js → Crosschain-XARMOcc4.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-D_77BI2O.js → DID-DwLtEKAe.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-D2SxTzEp.js → Dashboard-Cjw0L_iA.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-mR1-b9ud.js → Dropdown-BBGWIP7l.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-DPl7TE1c.js → EmailListRenderer-DG4kZFkm.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-BxRYLRSH.js → EvolutionSettings-D8vuNDde.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-rnGtXJ5Z.js → FamilyGuardDashboard-COXCzDXI.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-BpxenYK8.js → Federation-Btb-aMhW.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-Cz1kDf6l.js → FormItemContext-TO-E6l6e.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-CGV3KN6U.js → GenericCardRenderer-BWXdJCT0.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-CIRP4UTx.js → Git-B6icGhEv.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-DX4r8Vmt.js → Governance-C5Y__K6S.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-DQKk02Hl.js → Inference-DZGEKnbN.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-DdD6J-By.js → KnowledgeGraph--Kga5yvm.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-DA2w-1_m.js → Logs-BXs3EPKj.js} +2 -2
  39. package/src/assets/web-panel/assets/MarkdownRenderer-BsSiyE-A.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-BsJ6_6KW.js → Marketplace-JSEAu0su.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-_6k30z6u.js → McpTools-BUBifkKP.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-C0_dYY0A.js → Memory-Cb7sE4a-.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-CCTnVqiC.js → MobileBridge-BOzmmNV2.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-RZdxDSwC.js → MobileProjects-ClRlavdF.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-D4Ys8lvX.js → Mtc-DmMWErG1.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-BKTC--a2.js → MtcAudit-DnGkRVXF.js} +2 -2
  47. package/src/assets/web-panel/assets/{Multisig-CGR1qOe1.js → Multisig-C3mzascL.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-hKKD4qWb.js → NLProgramming-CrmMZZ1t.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-pCn7Ec40.js → Notes-4S6uts9Q.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-B9eEJXEs.js → NotificationSettings-gn3UrWwW.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-CmJuhaT2.js → OrderTableRenderer-CDVAlBUf.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-CcQbrnwW.js → Organization-fMlkdgpW.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-HmD4Mn72.js → Overflow-DGwCUPU1.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-B7LIgx5H.js → P2P-BDGcpPmf.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-CXiHnBfX.js → PdhVaultBrowser-CccRPAB9.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-CQRI3y_l.js → Permissions-C33dNECx.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-1EeHmsy5.js → PersonalDataHub-BeqbCStc.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-BFyoIdn8.js → Pipeline-CTmasgbQ.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-BxWthXMF.js → Privacy-ktd37BSp.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-DfigBilu.js → ProjectInit-KOGvQtBX.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-CFmIcVc-.js → ProjectSettings-CUvH_hC6.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-CR7H59v3.js → Projects-BvP_Os-1.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-2ulom-76.js → Providers-C-hmLXlO.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-BwhO07b_.js → QrScannerModal-DzG_rbSL.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-_Wg34OwF.js → QuickAsk-ShwiATg4.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-D_jq6Svg.js → Recommend-DkV8Ruep.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-BlzvEfsa.js → RemoteSession-Ca2dOx_G.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-9CTXHfL4.js → Reputation-DYA5BJ6A.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-DlCYCN-t.js → Row-DvGDgxLS.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-BvlInFCH.js → RssFeed-DbwTBSPw.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-CfaUzKuL.js → Search-C5XAMQ9T.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-bAWgLyve.js → Security-CKWT60Qt.js} +3 -3
  73. package/src/assets/web-panel/assets/{Services-C4LOGACW.js → Services-CZvASlWL.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-Dd0Uwh3_.js → Skeleton-DFkMVqws.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-ZYF1kYCU.js → Skills-hslZ_GyP.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-DpsmIaEo.js → Sla-BLW5rmZ5.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-BBXoJ4yc.js → SpeechSettings-Cn4ffCi5.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-SOnROi2Y.js → SyncSettings-D1K0nJuo.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-HFA_ZlDk.js → Tasks-CCRu0xoN.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-fsK-RCEc.js → Templates-L19GYuS4.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CuqYxamb.js → Tenant-CZ6HE3PF.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-GKlI2R5F.js → Terminal-BiAwzaBT.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-DMDMHLeY.js → TimelineRenderer-DRHSWQT5.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-BoV60rh3.js → Tokens-Cm-XATgh.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CE344-Ws.js → Trigger-BVXtx3kn.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-DENwgkVc.js → Trust-Bb0TmkLJ.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-FrcM7yfm.js → UkeySign-Dbt9R7l0.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-DAY9WaC2.js → VideoEditing-z0-Ti8eJ.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-BuUR5i82.js → Wallet-BZh31tI-.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-nfSQuq85.js → WebAuthn-DQ0yIr5K.js} +4 -4
  91. package/src/assets/web-panel/assets/{WorkflowEditor-DHhPOp9l.js → WorkflowEditor-DCt_yuWG.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-C4nsLzYy.js → chat-BLgtmFeS.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-BwXH0Wjn.js → colors-xU4UH8M1.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-uApFG30S.js → compact-item-C4w4v16T.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-BpyYs4fe.js → createContext-CZM9hAaj.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-BZUZgMkO.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-MXCLi00p.js → hasIn-DvHqEpE7.js} +1 -1
  98. package/src/assets/web-panel/assets/index--_-pNhk0.js +1 -0
  99. package/src/assets/web-panel/assets/{index-BOhjapd5.js → index-55Rkd1KA.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CNjUPfJP.js → index-B0IvKEVO.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DucLR6YX.js → index-B4jIcYSv.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Gz2rGWef.js → index-B64Vf-8H.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-IvgszJ3C.js → index-B6AQ2b5U.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-pgHGBAoF.js → index-BHK3CQHq.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DE4W4vLO.js → index-BHg9NoJ5.js} +3 -3
  106. package/src/assets/web-panel/assets/{index-Dt-nq2eF.js → index-BIWumeQl.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-1LxX2IwJ.js → index-BRhD9RMV.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-nn22NSDK.js → index-BTxhDCtg.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-B7jojVc7.js → index-BaQZvM4m.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CF0bUOP4.js → index-Bf8Wm4ks.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-ChUTKrOq.js → index-Bh14b1k0.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-pCIAE2yS.js → index-BkTKWAgq.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-pRpMLhMt.js → index-BlN5KPq6.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-XHBXtvqp.js → index-C6ZrTSw5.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CwVvk2i7.js → index-C9YnZFv2.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-xLGf7f9K.js → index-CExiTobS.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-C_oOpXhP.js → index-CF9ebAIB.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BaBwXpAp.js → index-CKugxsw3.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Dn12gJJU.js → index-CPC7OGCe.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DLxKx5_J.js → index-CPDw21XY.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CiIpIYhs.js → index-CQEzxnYS.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Daco83me.js → index-CRLP56-W.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CRmNdEk_.js → index-CYrQnkqA.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DffWVpZv.js → index-Cm00787d.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-Btv--Nnt.js → index-CpiuuIww.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-S80LLjdx.js → index-CqDiY-jl.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-ugIUt5TL.js → index-CyV8fNBg.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-D3_tj06B.js → index-DGdLkss8.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BEGMfaOo.js → index-DifMvnMQ.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-61CBBrHE.js → index-Ds1tM734.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DTXi_gQh.js → index-Ds6wKTMh.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-Du01X9N9.js → index-QHmhwgfc.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-WKbnwbKa.js → index-SNV95Zen.js} +1 -1
  134. package/src/assets/web-panel/assets/index-ftwO31cp.js +1 -0
  135. package/src/assets/web-panel/assets/{index-B0P1Z_oa.js → index-n6SAUmmI.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-Dkncxel3.js → index-wYRjvvbl.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-C58CkKEo.js → initDefaultProps-C44ZER6c.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-BLWPO2NV.js → motion-DbNzzScd.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-BgrFMwYp.js → move-BrRrDH2u.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-Cq2AuGzl.js → mtc-parser-DZ_T_Pw8.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-Bb-9L7if.js → omit-5QHHk_V3.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-vLmOxYr1.js → pickAttrs-BdxEl0G2.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-BNySU_dJ.js → placementArrow-CGyD615D.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-xnbwagnm.js → responsiveObserve-QqcWAQmN.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-BccbY5Cn.js → slide-BumQrJ5R.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-DOp9d2-w.js → statusUtils-Pf64olM7.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-Bu1w6ho9.js → styleChecker-DNwm5SQZ.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-ZsUOrVdL.js → useFlexGapSupport-c3gLKs6e.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-C0zpzKtO.js → useFs-TzTd6NDM.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-DO1OdgXK.js → usePersonalDataHub-BP5E_0Fe.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-jTIRyhR5.js → vnode-CVEkRfZU.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-DKvS7-Qs.js → zoom-C18X_8TJ.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/data/changelog.json +13 -0
  155. package/src/lib/coding-task-guidance.js +13 -0
  156. package/src/lib/file-import-diagnostics.js +246 -0
  157. package/src/lib/transport-error-details.js +83 -0
  158. package/src/runtime/agent-core.js +137 -2
  159. package/src/runtime/headless-runner.js +83 -49
  160. package/src/runtime/headless-stream.js +8 -2
  161. package/src/assets/web-panel/assets/MarkdownRenderer-C9aSGETh.js +0 -1
  162. package/src/assets/web-panel/assets/devWarning-Bk6HGn3N.js +0 -1
  163. package/src/assets/web-panel/assets/index-Bb1LPYdi.js +0 -1
  164. package/src/assets/web-panel/assets/index-C-FsTuFG.js +0 -1
@@ -0,0 +1,246 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { parse } from "acorn";
4
+
5
+ export const FILE_IMPORT_LIMITS = Object.freeze({
6
+ contentBytes: 256 * 1024,
7
+ references: 64,
8
+ specifierChars: 512,
9
+ });
10
+
11
+ const JS_EXTENSION = /\.(?:js|mjs|cjs)$/;
12
+
13
+ function inside(root, target) {
14
+ const relative = path.relative(root, target);
15
+ return (
16
+ relative === "" ||
17
+ (!path.isAbsolute(relative) &&
18
+ relative !== ".." &&
19
+ !relative.startsWith(`..${path.sep}`))
20
+ );
21
+ }
22
+
23
+ // Inspect each component before descending. Never stat/realpath a link, read
24
+ // target contents, enumerate directories, or include OS errors in feedback.
25
+ // As with other path-based Node APIs, this is not atomic against directory
26
+ // replacement by another process. The caller supplies its authorized root.
27
+ function inspectPath(root, target) {
28
+ if (!inside(root, target)) return "outside-workspace";
29
+ const components = path
30
+ .relative(root, target)
31
+ .split(path.sep)
32
+ .filter(Boolean);
33
+ let current = root;
34
+ for (let index = -1; index < components.length; index++) {
35
+ if (index >= 0) current = path.join(current, components[index]);
36
+ let stat;
37
+ try {
38
+ stat = fs.lstatSync(current);
39
+ } catch (error) {
40
+ return error?.code === "ENOENT" ? "missing" : "unavailable";
41
+ }
42
+ if (stat.isSymbolicLink()) return "symbolic-link";
43
+ if (index < components.length - 1 && !stat.isDirectory()) {
44
+ return "missing";
45
+ }
46
+ if (index === components.length - 1) {
47
+ return stat.isFile() ? "file" : "not-file";
48
+ }
49
+ }
50
+ return "not-file";
51
+ }
52
+
53
+ function inspectReference(root, target, kind) {
54
+ const state = inspectPath(root, target);
55
+ if (kind !== "require") return state;
56
+ // CommonJS can load directories and append extensions even when a request
57
+ // already has a suffix. Do not claim those uncertain cases are unresolved.
58
+ if (state === "not-file") return "commonjs-resolution";
59
+ if (state === "missing") {
60
+ for (const extension of [".js", ".json", ".node"]) {
61
+ const fallback = inspectPath(root, target + extension);
62
+ if (fallback !== "missing" && fallback !== "not-file") {
63
+ return "commonjs-resolution";
64
+ }
65
+ }
66
+ }
67
+ return state;
68
+ }
69
+
70
+ function parseSource(content, extension) {
71
+ const options = { ecmaVersion: "latest", locations: true };
72
+ if (extension === ".cjs") {
73
+ return parse(content, {
74
+ ...options,
75
+ sourceType: "script",
76
+ allowReturnOutsideFunction: true,
77
+ });
78
+ }
79
+ try {
80
+ return parse(content, { ...options, sourceType: "module" });
81
+ } catch (error) {
82
+ if (extension === ".mjs") throw error;
83
+ return parse(content, {
84
+ ...options,
85
+ sourceType: "script",
86
+ allowReturnOutsideFunction: true,
87
+ });
88
+ }
89
+ }
90
+
91
+ function collectReferences(ast) {
92
+ const references = [];
93
+ const pending = [{ node: ast, parent: null }];
94
+ let uncertainRequire = false;
95
+ let truncated = false;
96
+ while (pending.length) {
97
+ const { node, parent } = pending.pop();
98
+ // Conservative across the whole file: local bindings, assignments, and
99
+ // indirect uses make require's meaning uncertain. Imports remain useful.
100
+ if (
101
+ (node.type === "Identifier" &&
102
+ node.name === "require" &&
103
+ !(parent?.type === "CallExpression" && parent.callee === node)) ||
104
+ node.type === "WithStatement" ||
105
+ (node.type === "CallExpression" && node.callee?.name === "eval")
106
+ ) {
107
+ uncertainRequire = true;
108
+ }
109
+ let source;
110
+ let kind;
111
+ if (
112
+ node.type === "ImportDeclaration" ||
113
+ node.type === "ExportNamedDeclaration" ||
114
+ node.type === "ExportAllDeclaration" ||
115
+ node.type === "ImportExpression"
116
+ ) {
117
+ source = node.source;
118
+ kind = "import";
119
+ } else if (
120
+ node.type === "CallExpression" &&
121
+ !node.optional &&
122
+ node.callee?.type === "Identifier" &&
123
+ node.callee.name === "require" &&
124
+ node.arguments.length === 1
125
+ ) {
126
+ source = node.arguments[0];
127
+ kind = "require";
128
+ }
129
+ if (
130
+ source?.type === "Literal" &&
131
+ typeof source.value === "string" &&
132
+ /^\.{1,2}\//.test(source.value) &&
133
+ JS_EXTENSION.test(source.value) &&
134
+ !/[\\%?#:\u0000-\u001f\u007f]/.test(source.value)
135
+ ) {
136
+ if (references.length < FILE_IMPORT_LIMITS.references) {
137
+ references.push({ source, kind });
138
+ } else {
139
+ truncated = true;
140
+ }
141
+ }
142
+ const children = [];
143
+ for (const value of Object.values(node)) {
144
+ if (value?.type) children.push(value);
145
+ else if (Array.isArray(value)) {
146
+ for (const child of value) if (child?.type) children.push(child);
147
+ }
148
+ }
149
+ for (let index = children.length - 1; index >= 0; index--) {
150
+ pending.push({ node: children[index], parent: node });
151
+ }
152
+ }
153
+ return { references, uncertainRequire, truncated };
154
+ }
155
+
156
+ /**
157
+ * Best-effort feedback after an authorized write. Only explicit JS relative
158
+ * runtime references are checked, using supplied content and metadata inside
159
+ * workspaceRoot. This does not run code, resolve packages, or prove tests pass.
160
+ * Missing/inaccessible inputs and unsupported syntax never throw to the writer.
161
+ * line/column are one-based. uncheckedReferences never disclose resolved paths.
162
+ */
163
+ export function collectFileImportDiagnostics(input) {
164
+ const result = {
165
+ status: "skipped",
166
+ diagnostics: [],
167
+ checkedReferences: 0,
168
+ uncheckedReferences: [],
169
+ truncated: false,
170
+ };
171
+ const skip = (reason) => ({ ...result, reason });
172
+ try {
173
+ const { filePath, content, workspaceRoot } = input ?? {};
174
+ if (
175
+ typeof filePath !== "string" ||
176
+ !filePath ||
177
+ filePath.length > 4096 ||
178
+ typeof workspaceRoot !== "string" ||
179
+ !workspaceRoot ||
180
+ workspaceRoot.length > 4096 ||
181
+ !path.isAbsolute(workspaceRoot) ||
182
+ typeof content !== "string"
183
+ ) {
184
+ return skip("invalid-input");
185
+ }
186
+ if (!JS_EXTENSION.test(filePath)) return skip("unsupported-file");
187
+ if (
188
+ content.length > FILE_IMPORT_LIMITS.contentBytes ||
189
+ Buffer.byteLength(content, "utf8") > FILE_IMPORT_LIMITS.contentBytes
190
+ ) {
191
+ return skip("content-limit");
192
+ }
193
+ const root = path.resolve(workspaceRoot);
194
+ const file = path.resolve(root, filePath);
195
+ if (!inside(root, file)) return skip("outside-workspace");
196
+ const fileState = inspectPath(root, file);
197
+ if (fileState !== "file") return skip(fileState);
198
+ let ast;
199
+ try {
200
+ ast = parseSource(content, path.extname(file));
201
+ } catch {
202
+ return skip("unsupported-syntax");
203
+ }
204
+ const { references, uncertainRequire, truncated } = collectReferences(ast);
205
+ result.status = "checked";
206
+ result.truncated = truncated;
207
+ for (const { source, kind } of references) {
208
+ const location = {
209
+ specifier: source.value.slice(0, FILE_IMPORT_LIMITS.specifierChars),
210
+ line: source.loc.start.line,
211
+ column: source.loc.start.column + 1,
212
+ };
213
+ let state;
214
+ if (source.value.length > FILE_IMPORT_LIMITS.specifierChars) {
215
+ state = "specifier-limit";
216
+ } else if (kind === "require" && uncertainRequire) {
217
+ state = "uncertain-require";
218
+ } else {
219
+ state = inspectReference(
220
+ root,
221
+ path.resolve(path.dirname(file), source.value),
222
+ kind,
223
+ );
224
+ }
225
+ if (state === "file" || state === "missing" || state === "not-file") {
226
+ result.checkedReferences++;
227
+ if (state !== "file") {
228
+ result.diagnostics.push({
229
+ source: "relative-import",
230
+ code: "UNRESOLVED_RELATIVE_IMPORT",
231
+ severity: "error",
232
+ filePath: file,
233
+ ...location,
234
+ message: `Relative import ${JSON.stringify(location.specifier)} does not point to an existing file from this file's directory. Verify the importing file's location before running tests.`,
235
+ });
236
+ }
237
+ } else {
238
+ result.uncheckedReferences.push({ ...location, reason: state });
239
+ }
240
+ }
241
+ return result;
242
+ } catch {
243
+ // Do not allow optional feedback to turn a completed mutation into failure.
244
+ return skip("unavailable");
245
+ }
246
+ }
@@ -0,0 +1,83 @@
1
+ import { types } from "node:util";
2
+
3
+ const NAMES = new Set([
4
+ "Error",
5
+ "TypeError",
6
+ "AggregateError",
7
+ "AbortError",
8
+ "TimeoutError",
9
+ "ConnectTimeoutError",
10
+ "HeadersTimeoutError",
11
+ "BodyTimeoutError",
12
+ "SocketError",
13
+ "RequestAbortedError",
14
+ "ClientDestroyedError",
15
+ "ClientClosedError",
16
+ ]);
17
+ const CODES = new Set([
18
+ "ECONNRESET",
19
+ "ECONNREFUSED",
20
+ "ENOTFOUND",
21
+ "EAI_AGAIN",
22
+ "ETIMEDOUT",
23
+ "EHOSTUNREACH",
24
+ "ENETUNREACH",
25
+ "EPIPE",
26
+ "ERR_TLS_CERT_ALTNAME_INVALID",
27
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
28
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
29
+ "CERT_HAS_EXPIRED",
30
+ "ABORT_ERR",
31
+ "UND_ERR_SOCKET",
32
+ "UND_ERR_CONNECT_TIMEOUT",
33
+ "UND_ERR_HEADERS_TIMEOUT",
34
+ "UND_ERR_BODY_TIMEOUT",
35
+ "UND_ERR_ABORTED",
36
+ "UND_ERR_DESTROYED",
37
+ "UND_ERR_CLOSED",
38
+ "UND_ERR_REQ_CONTENT_LENGTH_MISMATCH",
39
+ "UND_ERR_RES_CONTENT_LENGTH_MISMATCH",
40
+ ]);
41
+
42
+ // Never invoke accessors, coercion hooks or Proxy traps. Native Error.name is
43
+ // inherited, so inspect a bounded number of prototype data descriptors.
44
+ function data(object, key) {
45
+ for (let depth = 0; depth < 4 && object !== null; depth++) {
46
+ if (typeof object !== "object" || types.isProxy(object)) return undefined;
47
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
48
+ if (descriptor) return "value" in descriptor ? descriptor.value : undefined;
49
+ object = Object.getPrototypeOf(object);
50
+ }
51
+ return undefined;
52
+ }
53
+
54
+ /** Optional diagnostic projection only: no messages, endpoints or request data. */
55
+ export function transportErrorDetails(error) {
56
+ try {
57
+ const name = data(error, "name");
58
+ const code = data(error, "code");
59
+ let causeCode;
60
+ const seen = new Set([error]);
61
+ let cause = error;
62
+ for (let depth = 0; depth < 4; depth++) {
63
+ cause = data(cause, "cause");
64
+ if (!cause || seen.has(cause)) break;
65
+ seen.add(cause);
66
+ const value = data(cause, "code");
67
+ if (CODES.has(value)) {
68
+ causeCode = value;
69
+ break;
70
+ }
71
+ }
72
+ if (!CODES.has(code) && !causeCode) return undefined;
73
+ return {
74
+ kind: "transport",
75
+ ...(NAMES.has(name) ? { name } : {}),
76
+ ...(CODES.has(code) ? { code } : {}),
77
+ ...(causeCode ? { causeCode } : {}),
78
+ };
79
+ } catch {
80
+ // Diagnostics must never replace the original error or exit outcome.
81
+ return undefined;
82
+ }
83
+ }
@@ -49,6 +49,7 @@ import { ReadFileLoopGuard } from "../lib/read-file-loop-guard.js";
49
49
  import { gitToolInputError } from "../lib/git-tool-input.js";
50
50
  import { shellOutputPage, shellOutputPreview } from "../lib/shell-output.js";
51
51
  import { DIAGNOSTIC_WORKFLOW_GUIDANCE } from "../lib/diagnostic-workflow.js";
52
+ import { CODING_TASK_QUALITY_GUIDANCE } from "../lib/coding-task-guidance.js";
52
53
  import { RemoteReadLoopGuard } from "../lib/remote-read-loop-guard.js";
53
54
  import {
54
55
  isPrActionRequest,
@@ -1167,6 +1168,8 @@ export function getBaseSystemPrompt(cwd) {
1167
1168
  You have access to tools that let you read files, write files, edit files, run shell commands, and search the codebase. When the user asks you to do something, USE THE TOOLS to actually do it — don't just describe what should be done.
1168
1169
 
1169
1170
  Key behaviors:
1171
+ ${CODING_TASK_QUALITY_GUIDANCE}
1172
+
1170
1173
  - A new user message may arrive before the previous task finishes. Incorporate corrections and added requests while preserving unfinished authorized work, unless the user cancels or replaces it. Use the completed tool results already in history; do not restart the investigation.
1171
1174
  - When asked to modify code, read the file first, then edit it
1172
1175
  - When asked to create something, use write_file to create it
@@ -4927,19 +4930,63 @@ export async function _withPostEditDiagnostics(
4927
4930
  cwd,
4928
4931
  additionalDirectories,
4929
4932
  managedCheckpoint = false,
4933
+ writtenContent = null,
4930
4934
  ) {
4935
+ // Parsing the bytes we just wrote is safe even when starting a language
4936
+ // server is forbidden. Feed definite local import mistakes back in the same
4937
+ // tool result; a successful write still means persistence, not test success.
4938
+ let enriched = result;
4939
+ if (
4940
+ result?.success === true &&
4941
+ typeof writtenContent === "string" &&
4942
+ /\.(?:js|mjs|cjs)$/i.test(filePath) &&
4943
+ process.env.CC_EDIT_DIAGNOSTICS !== "0"
4944
+ ) {
4945
+ try {
4946
+ const root = pickRootForFile(
4947
+ path.resolve(cwd || process.cwd(), filePath),
4948
+ workspaceRootsFor(cwd, additionalDirectories),
4949
+ );
4950
+ if (root) {
4951
+ const { collectFileImportDiagnostics } = await import(
4952
+ "../lib/file-import-diagnostics.js"
4953
+ );
4954
+ const checked = collectFileImportDiagnostics({
4955
+ filePath,
4956
+ content: writtenContent,
4957
+ workspaceRoot: root,
4958
+ });
4959
+ if (checked.diagnostics.length) {
4960
+ enriched = {
4961
+ ...result,
4962
+ newDiagnostics: [
4963
+ ...(result.newDiagnostics || []),
4964
+ ...checked.diagnostics.slice(0, 8),
4965
+ ],
4966
+ };
4967
+ }
4968
+ }
4969
+ } catch {
4970
+ // Optional diagnostics must not turn a persisted edit into a failed one.
4971
+ }
4972
+ }
4931
4973
  // A cold language server is a long-lived child process. Starting one inside
4932
4974
  // a managed workspace transaction would keep a writer bound past tool
4933
4975
  // settlement and make commit/rollback unverifiable. Managed edits therefore
4934
4976
  // skip this best-effort enrichment; callers can request diagnostics after the
4935
4977
  // checkpoint has sealed.
4936
- if (managedCheckpoint) return result;
4978
+ if (managedCheckpoint) return enriched;
4937
4979
  const newDiagnostics = await _postEditDiagnostics(
4938
4980
  filePath,
4939
4981
  cwd,
4940
4982
  additionalDirectories,
4941
4983
  );
4942
- return newDiagnostics ? { ...result, newDiagnostics } : result;
4984
+ return newDiagnostics
4985
+ ? {
4986
+ ...enriched,
4987
+ newDiagnostics: [...(enriched.newDiagnostics || []), ...newDiagnostics],
4988
+ }
4989
+ : enriched;
4943
4990
  }
4944
4991
 
4945
4992
  // ─── Lazy subtree instruction injection (large-monorepo lever) ─────────────
@@ -5791,6 +5838,7 @@ async function executeToolInner(
5791
5838
  cwd,
5792
5839
  additionalDirectories,
5793
5840
  managedCheckpoint || hermeticExecution,
5841
+ args.content,
5794
5842
  ),
5795
5843
  filePath,
5796
5844
  cwd,
@@ -5992,6 +6040,7 @@ async function executeToolInner(
5992
6040
  cwd,
5993
6041
  additionalDirectories,
5994
6042
  managedCheckpoint || hermeticExecution,
6043
+ newContent,
5995
6044
  ),
5996
6045
  filePath,
5997
6046
  cwd,
@@ -6094,6 +6143,7 @@ async function executeToolInner(
6094
6143
  cwd,
6095
6144
  additionalDirectories,
6096
6145
  managedCheckpoint || hermeticExecution,
6146
+ result.content,
6097
6147
  ),
6098
6148
  filePath,
6099
6149
  cwd,
@@ -14622,6 +14672,53 @@ export async function* agentLoop(messages, options) {
14622
14672
  options.hostResourceBudget || new HostResourceBudget();
14623
14673
  const taskProgressTracker =
14624
14674
  options.taskProgressTracker || new TaskProgressTracker();
14675
+ // A subtree preflight is deliberately not an executed mutation. Keep this
14676
+ // obligation outside transcript compaction and never replay it automatically.
14677
+ const pendingSubtreeMutations = new Map();
14678
+ let subtreeMutationReprompted = false;
14679
+ const recordSubtreeMutation = (tool, args, result) => {
14680
+ if (!GUARDED_FILE_MUTATION_TOOLS.has(tool)) return;
14681
+ if (!args || typeof args !== "object" || Array.isArray(args)) return;
14682
+ // Invalid tool arguments/results must retain their existing error path;
14683
+ // bookkeeping must not introduce a new exception or completion verdict.
14684
+ const requestedPaths = fileMutationPaths(tool, args);
14685
+ if (
14686
+ !requestedPaths.length ||
14687
+ requestedPaths.some((target) => typeof target !== "string")
14688
+ )
14689
+ return;
14690
+ const targets = [
14691
+ ...new Set(
14692
+ requestedPaths.map((target) =>
14693
+ path.resolve(options.cwd || process.cwd(), target),
14694
+ ),
14695
+ ),
14696
+ ].sort();
14697
+ // These tools are alternative ways to deliver content to the same target.
14698
+ // A successful explicit replacement must settle a deferred edit (and vice
14699
+ // versa); move/delete/notebook effects retain their distinct obligations.
14700
+ const effect = ["write_file", "edit_file", "edit_file_hashed"].includes(tool)
14701
+ ? "file-content"
14702
+ : tool;
14703
+ const key = JSON.stringify([effect, targets]);
14704
+ if (
14705
+ result?.policy?.via === "subtree-instructions" &&
14706
+ result.policy.decision === "deferred" &&
14707
+ result.mutationPerformed === false
14708
+ ) {
14709
+ pendingSubtreeMutations.set(key, { tool, targets });
14710
+ } else if (
14711
+ result &&
14712
+ !result.error &&
14713
+ result.success === true &&
14714
+ result.isError !== true &&
14715
+ result.policy?.decision !== "deny" &&
14716
+ result.policy?.decision !== "deferred" &&
14717
+ result.mutationPerformed !== false
14718
+ ) {
14719
+ pendingSubtreeMutations.delete(key);
14720
+ }
14721
+ };
14625
14722
  const signal = options.signal || null;
14626
14723
  const workflowEffectId = _normalizeWorkflowEffectId(options.workflowEffectId);
14627
14724
  // Optional OpenTelemetry recorder (TelemetryRecorder). When present, the loop
@@ -16397,6 +16494,42 @@ export async function* agentLoop(messages, options) {
16397
16494
  }
16398
16495
  continue;
16399
16496
  }
16497
+ if (pendingSubtreeMutations.size) {
16498
+ const pending = [...pendingSubtreeMutations.values()];
16499
+ if (!subtreeMutationReprompted && budget.remaining() > 0) {
16500
+ subtreeMutationReprompted = true;
16501
+ messages.push({ role: "assistant", content: msg.content || "" });
16502
+ messages.push({
16503
+ role: "user",
16504
+ content:
16505
+ "Runtime status: these mutations were deferred before any effect: " +
16506
+ JSON.stringify(pending) +
16507
+ ". Review the authoritative subtree instructions already returned. " +
16508
+ "If still authorized and appropriate, explicitly issue the required tool call. " +
16509
+ "Do not bypass rules or perform a prohibited write. Otherwise report the unfinished work and its blocker. " +
16510
+ "A promise to retry does not execute the mutation.",
16511
+ });
16512
+ yield {
16513
+ type: "iteration-warning",
16514
+ message:
16515
+ "Subtree-deferred mutations remain unexecuted; one recovery turn requested.",
16516
+ };
16517
+ continue;
16518
+ }
16519
+ yield {
16520
+ type: "response-complete",
16521
+ content:
16522
+ (msg.content ? msg.content + "\n\n" : "") +
16523
+ "Incomplete: subtree-deferred mutations remain unexecuted.",
16524
+ };
16525
+ yield {
16526
+ type: "run-ended",
16527
+ runId,
16528
+ reason: "deferred-mutation-unresolved",
16529
+ pendingMutations: pending,
16530
+ };
16531
+ return;
16532
+ }
16400
16533
  // Surface the final answer's extended-thinking reasoning (Anthropic, when
16401
16534
  // --think is on) so non-streaming consumers (the REPL) can show it. The
16402
16535
  // streaming path forwards reasoning live via onThinking instead.
@@ -16638,6 +16771,7 @@ export async function* agentLoop(messages, options) {
16638
16771
  } = await promise;
16639
16772
  if (fatalError) throw fatalError;
16640
16773
  throwIfAborted(signal);
16774
+ recordSubtreeMutation(call.function.name, toolArgs, toolResult);
16641
16775
  const taskAdvanced = taskProgressTracker.record(
16642
16776
  call.function.name,
16643
16777
  toolResult,
@@ -17181,6 +17315,7 @@ export async function* agentLoop(messages, options) {
17181
17315
  // context — but tell the model when we cut it (no more silent
17182
17316
  // mid-content slice). See MAX_TOOL_RESULT_CHARS / capToolResultString.
17183
17317
  const resultStr = toolResultForModel(toolName, toolResult, messages);
17318
+ recordSubtreeMutation(toolName, toolArgs, toolResult);
17184
17319
  const taskAdvanced = taskProgressTracker.record(
17185
17320
  toolName,
17186
17321
  toolResult,