chainlesschain 0.166.115 → 0.166.118

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 (207) hide show
  1. package/README.md +43 -5
  2. package/package.json +4 -4
  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/.build-hash +1 -1
  6. package/src/assets/web-panel/assets/{AIOps-BsoSoDNb.js → AIOps-BGySwMIP.js} +1 -1
  7. package/src/assets/web-panel/assets/{ActionButton-Dcx7Gm5t.js → ActionButton-Chn7fBLr.js} +1 -1
  8. package/src/assets/web-panel/assets/{Analytics-S1hsBIz3.js → Analytics-ORH7UkGa.js} +3 -3
  9. package/src/assets/web-panel/assets/{AppLayout-B2j067qM.js → AppLayout-8xV4jWjP.js} +5 -5
  10. package/src/assets/web-panel/assets/{Artifacts-D5iGV9ic.js → Artifacts-26SBK-x-.js} +1 -1
  11. package/src/assets/web-panel/assets/{Audit-C8ChVvXu.js → Audit-CtXpqbXg.js} +1 -1
  12. package/src/assets/web-panel/assets/{BackgroundAgents-Cg97AAJS.js → BackgroundAgents-C5zLvQis.js} +1 -1
  13. package/src/assets/web-panel/assets/{Backup-CyxU9IUg.js → Backup-C93xY4vO.js} +1 -1
  14. package/src/assets/web-panel/assets/{BaseInput-CKlWjA8I.js → BaseInput-DpVCHfAn.js} +1 -1
  15. package/src/assets/web-panel/assets/{Chat-C-EqZza6.js → Chat-DM0LblR2.js} +5 -5
  16. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BRFiXKPX.js → ChatBubbleRenderer-unlQUF1T.js} +1 -1
  17. package/src/assets/web-panel/assets/{Checkbox-kkI13tSJ.js → Checkbox-BsAt3cKR.js} +1 -1
  18. package/src/assets/web-panel/assets/{Codegen-NlqEDwHK.js → Codegen-E_kp4KFd.js} +1 -1
  19. package/src/assets/web-panel/assets/{Col-CfepEu79.js → Col-6msR3T6I.js} +1 -1
  20. package/src/assets/web-panel/assets/{Community-BRo0qLXM.js → Community-PyX9c5D-.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compact-BMu8TP0E.js → Compact-7G1bVDSH.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compliance-B7Q3Moef.js → Compliance-DcHN7GlD.js} +1 -1
  23. package/src/assets/web-panel/assets/{Cowork-BVwt7Xmc.js → Cowork-WUIHJYDx.js} +3 -3
  24. package/src/assets/web-panel/assets/{Cron-CgBv20Qy.js → Cron-CWgCbptg.js} +2 -2
  25. package/src/assets/web-panel/assets/{Crosschain-CwcSBJk2.js → Crosschain-BzKZ6roD.js} +1 -1
  26. package/src/assets/web-panel/assets/{DID-d20rCiIm.js → DID-r7zxeItn.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dashboard-PpZaUYpS.js → Dashboard-D3pBiN2H.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dropdown-DjsLdX_Z.js → Dropdown-C4otRJlZ.js} +1 -1
  29. package/src/assets/web-panel/assets/{EmailListRenderer-CaPkrtxn.js → EmailListRenderer-CzDTC8lm.js} +1 -1
  30. package/src/assets/web-panel/assets/{EvolutionSettings-DDY8cQnE.js → EvolutionSettings-DGkXiIs-.js} +1 -1
  31. package/src/assets/web-panel/assets/{FamilyGuardDashboard-VQavMjyj.js → FamilyGuardDashboard-BKdEyuiR.js} +1 -1
  32. package/src/assets/web-panel/assets/{Federation-D0GvKQgI.js → Federation-dsI-xcpf.js} +1 -1
  33. package/src/assets/web-panel/assets/{FormItemContext-Dl_TWHmb.js → FormItemContext-CEEb1fMR.js} +1 -1
  34. package/src/assets/web-panel/assets/{GenericCardRenderer-Bny2uagG.js → GenericCardRenderer-D_mfO3Ts.js} +1 -1
  35. package/src/assets/web-panel/assets/{Git-B01KXq47.js → Git-CBwr2ZI3.js} +2 -2
  36. package/src/assets/web-panel/assets/{Governance-F4c4Vwo1.js → Governance-D-Wy2Jjr.js} +1 -1
  37. package/src/assets/web-panel/assets/{Inference-_025Q-8K.js → Inference-B4Yk_IRx.js} +1 -1
  38. package/src/assets/web-panel/assets/{KnowledgeGraph-DwbTmQb1.js → KnowledgeGraph-DoI7bi6m.js} +1 -1
  39. package/src/assets/web-panel/assets/{Logs-CnNo0hCm.js → Logs-Ce1IiKAj.js} +2 -2
  40. package/src/assets/web-panel/assets/MarkdownRenderer-GND_8y0V.js +1 -0
  41. package/src/assets/web-panel/assets/{Marketplace-Dkz5bv7F.js → Marketplace-CsIEByzK.js} +1 -1
  42. package/src/assets/web-panel/assets/{McpTools-CBtRwDW_.js → McpTools-_DRzjcIn.js} +3 -3
  43. package/src/assets/web-panel/assets/{Memory-Y9jnyTb7.js → Memory-zvLpyi__.js} +2 -2
  44. package/src/assets/web-panel/assets/{MobileBridge-Br1urkOz.js → MobileBridge-DXd1ik2Z.js} +1 -1
  45. package/src/assets/web-panel/assets/{MobileProjects-DnsyuerX.js → MobileProjects-DKh2q-Y9.js} +1 -1
  46. package/src/assets/web-panel/assets/{Mtc-he3ZzieF.js → Mtc-Ct-fhtIx.js} +4 -4
  47. package/src/assets/web-panel/assets/{MtcAudit-BadphAuN.js → MtcAudit-J4zY3Oqk.js} +2 -2
  48. package/src/assets/web-panel/assets/{Multisig-3_pVLymK.js → Multisig-B2HJMCKe.js} +3 -3
  49. package/src/assets/web-panel/assets/{NLProgramming-DmtmHfsI.js → NLProgramming-CwcSmU4q.js} +1 -1
  50. package/src/assets/web-panel/assets/{Notes-CE4L2O55.js → Notes-Da53L6wb.js} +4 -4
  51. package/src/assets/web-panel/assets/{NotificationSettings-B7QmfJn9.js → NotificationSettings-BxhufdrA.js} +1 -1
  52. package/src/assets/web-panel/assets/{OrderTableRenderer-O0wRSyJ0.js → OrderTableRenderer-BoFwohAi.js} +1 -1
  53. package/src/assets/web-panel/assets/{Organization-BrlMSsyT.js → Organization-MIsMrUes.js} +4 -4
  54. package/src/assets/web-panel/assets/{Overflow-CY4ULPrZ.js → Overflow-Dy2P4v3q.js} +1 -1
  55. package/src/assets/web-panel/assets/{P2P-kIANZYKd.js → P2P-CD9Sxn2y.js} +2 -2
  56. package/src/assets/web-panel/assets/{PdhVaultBrowser-DEgB4rvF.js → PdhVaultBrowser-BvBWgfG0.js} +5 -5
  57. package/src/assets/web-panel/assets/{Permissions-CWxywRp5.js → Permissions-CwOlDRis.js} +4 -4
  58. package/src/assets/web-panel/assets/{PersonalDataHub-DAg7iCbr.js → PersonalDataHub-CZYaxEpv.js} +4 -4
  59. package/src/assets/web-panel/assets/{Pipeline-Brc6ONnR.js → Pipeline-kLU7PUbB.js} +1 -1
  60. package/src/assets/web-panel/assets/{Privacy-CcinYTL8.js → Privacy-BVRycSiI.js} +1 -1
  61. package/src/assets/web-panel/assets/{ProjectInit-Bz8XEsom.js → ProjectInit-DP3pr7uJ.js} +2 -2
  62. package/src/assets/web-panel/assets/{ProjectSettings-CsOMlSTZ.js → ProjectSettings-CACaDYjs.js} +2 -2
  63. package/src/assets/web-panel/assets/Projects-CB1k4zTC.js +1 -0
  64. package/src/assets/web-panel/assets/{Providers-CeunOQiH.js → Providers-D7Y9WHRE.js} +1 -1
  65. package/src/assets/web-panel/assets/{QrScannerModal-CN2a2_Fb.js → QrScannerModal-CeP8xzs1.js} +1 -1
  66. package/src/assets/web-panel/assets/{QuickAsk-CVeLif3e.js → QuickAsk-iJVFrhZ2.js} +1 -1
  67. package/src/assets/web-panel/assets/{Recommend-1k9WOEGM.js → Recommend-DmTpnagw.js} +1 -1
  68. package/src/assets/web-panel/assets/{RemoteSession-Q8UCqIMw.js → RemoteSession-C6ek8Uni.js} +2 -2
  69. package/src/assets/web-panel/assets/{Reputation-CkrCgXKM.js → Reputation-CPfwc9de.js} +1 -1
  70. package/src/assets/web-panel/assets/{Row-JFdvuTzi.js → Row-C1wwtSMJ.js} +1 -1
  71. package/src/assets/web-panel/assets/{RssFeed-C74JHCmk.js → RssFeed-BiDJsqaH.js} +3 -3
  72. package/src/assets/web-panel/assets/{Search-DrJiVO1T.js → Search-BF6Aon95.js} +1 -1
  73. package/src/assets/web-panel/assets/{Security-BJzNlSJq.js → Security-Bps0XnV4.js} +3 -3
  74. package/src/assets/web-panel/assets/{Services-D4TLMnJm.js → Services-uf92smGR.js} +2 -2
  75. package/src/assets/web-panel/assets/{Skeleton-cswTDqhh.js → Skeleton-DQd4eVWW.js} +1 -1
  76. package/src/assets/web-panel/assets/{Skills-Bv0rM1BS.js → Skills-DgamiYa5.js} +1 -1
  77. package/src/assets/web-panel/assets/{Sla-D9rE7hNh.js → Sla-CF1IVIrm.js} +1 -1
  78. package/src/assets/web-panel/assets/SpeechSettings-Bzxmjbpc.js +1 -0
  79. package/src/assets/web-panel/assets/{SyncSettings-BwnMG8kq.js → SyncSettings-B8zKauiq.js} +2 -2
  80. package/src/assets/web-panel/assets/{Tasks-wJvU24cB.js → Tasks-DPKV_xSt.js} +1 -1
  81. package/src/assets/web-panel/assets/{Templates-CZbRU3tN.js → Templates-BikeSZIF.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tenant-_jbpFJPZ.js → Tenant-CEaUaDkJ.js} +1 -1
  83. package/src/assets/web-panel/assets/{Terminal-BzNm5WKZ.js → Terminal-ZPgOSQ_q.js} +3 -3
  84. package/src/assets/web-panel/assets/{TimelineRenderer-bmybWjuS.js → TimelineRenderer-DmyB4Udk.js} +1 -1
  85. package/src/assets/web-panel/assets/{Tokens-o1WDcqVQ.js → Tokens-g85Pm5TO.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trigger-BB1D6sIB.js → Trigger-D202hx9a.js} +1 -1
  87. package/src/assets/web-panel/assets/{Trust-CLxdCfy2.js → Trust-DzvQYVFy.js} +1 -1
  88. package/src/assets/web-panel/assets/{UkeySign-B9LS6vS0.js → UkeySign-KRzwddVg.js} +1 -1
  89. package/src/assets/web-panel/assets/{VideoEditing-Bg0-wxjz.js → VideoEditing-IRBXLO2z.js} +1 -1
  90. package/src/assets/web-panel/assets/{Wallet-Bw0G2F6P.js → Wallet-DSf5KPgQ.js} +4 -4
  91. package/src/assets/web-panel/assets/{WebAuthn-irEiNY9b.js → WebAuthn-DNPxLTCc.js} +5 -5
  92. package/src/assets/web-panel/assets/{WorkflowEditor-Bh08FbJs.js → WorkflowEditor-C3wAtVcK.js} +1 -1
  93. package/src/assets/web-panel/assets/{addon-fit-CK6X9sAG.js → addon-fit-CbkjSUJl.js} +1 -1
  94. package/src/assets/web-panel/assets/{chat-De-FPjVT.js → chat-q3XXUtv2.js} +1 -1
  95. package/src/assets/web-panel/assets/{colors-ygdyvinU.js → colors-CF54SNei.js} +1 -1
  96. package/src/assets/web-panel/assets/{compact-item-BQ9jH9KV.js → compact-item-BaRkvZuT.js} +1 -1
  97. package/src/assets/web-panel/assets/{createContext-BFuVSyox.js → createContext-CDR9hsfs.js} +1 -1
  98. package/src/assets/web-panel/assets/devWarning-1LO-NplX.js +1 -0
  99. package/src/assets/web-panel/assets/{hasIn-i19GtR1P.js → hasIn-DlC--S8R.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DS1IwwGL.js → index-B0Ptc7yu.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-B1IsP_JO.js → index-B0V9rgdu.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CWfgeaG4.js → index-BEiUlFKb.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DTY20pWu.js → index-BJO0n1LQ.js} +1 -1
  104. package/src/assets/web-panel/assets/index-BLaJsev4.js +1 -0
  105. package/src/assets/web-panel/assets/index-BLmviChG.js +1 -0
  106. package/src/assets/web-panel/assets/{index-IXkif6J_.js → index-BU5DJqk7.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BVhtukYX.js → index-BY-Tf3OM.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BKlU5VZy.js → index-BZrE0Go8.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Bw5pTpnI.js → index-BizdX2X5.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BGMxK155.js → index-C87Yr3h1.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DVnFgasM.js → index-C9Wypz9e.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-C61w3omz.js → index-CAoG_E-q.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-l5-J0jHx.js → index-CAxSyMrF.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-28DjsABm.js → index-CC5HjNM6.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BPUCvc8i.js → index-CNZQEZ9g.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CpdXhhMY.js → index-CPvIhha6.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DAboGZTw.js → index-CR_wqMGy.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DL7ewjD2.js → index-CSClXoB3.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Bhf-MuUh.js → index-CZ8azVgB.js} +3 -3
  120. package/src/assets/web-panel/assets/{index-BaaydJcC.js → index-Ccc5z8eJ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-B2LieObB.js → index-CeiKbM3a.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-We2nK3ju.js → index-Cl6av3X7.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-m8waSAyv.js → index-CtGfeD7E.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-cDJsyAkI.js → index-Ctid12Gq.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DlwxUZQL.js → index-D0H-N0uG.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BBYiCI1d.js → index-D0vIgprF.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-_9tUBcLm.js → index-D4wUDFRg.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-4HoFz1MA.js → index-DJFipyK7.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Cq9k4-Ws.js → index-DX2REKNp.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DuuOX5u3.js → index-Dc3gD0cw.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DgjLaB7k.js → index-DiQzer2R.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CMNjaSir.js → index-DntKLOs9.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-vXtH3o6O.js → index-Dplhl6gh.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BLMtCKAY.js → index-Dq8q_PWB.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-CXrk8OYO.js → index-IVQdOBNN.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-CBVcGaxk.js → index-Kerduyao.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-BKblSCL9.js → index-W6cLGjpW.js} +1 -1
  138. package/src/assets/web-panel/assets/{index-CgoSgmjK.js → index-qZDNFll9.js} +1 -1
  139. package/src/assets/web-panel/assets/{initDefaultProps-B_EZHeqN.js → initDefaultProps-Ccz7v71u.js} +1 -1
  140. package/src/assets/web-panel/assets/{markdown-Yo_c6Krv.js → markdown-Bq2x0XsR.js} +1 -1
  141. package/src/assets/web-panel/assets/markdown-DUKxbhE4.js +51 -0
  142. package/src/assets/web-panel/assets/{motion-BrVb_Gy1.js → motion-BlCLpVDp.js} +1 -1
  143. package/src/assets/web-panel/assets/{move-CKxVRL_J.js → move-B80G7fLU.js} +1 -1
  144. package/src/assets/web-panel/assets/{mtc-parser-C80rvQ1J.js → mtc-parser-Djw08NJh.js} +1 -1
  145. package/src/assets/web-panel/assets/{omit-De5vD7BR.js → omit-Bg_G1eUr.js} +1 -1
  146. package/src/assets/web-panel/assets/{pickAttrs-BTyEDjth.js → pickAttrs-Df9zYUg2.js} +1 -1
  147. package/src/assets/web-panel/assets/{placementArrow-BWR94AjR.js → placementArrow-DjCDLhJ4.js} +1 -1
  148. package/src/assets/web-panel/assets/{responsiveObserve-1g-Vnibk.js → responsiveObserve--Naz7NgY.js} +1 -1
  149. package/src/assets/web-panel/assets/{slide-Dmg6dYuF.js → slide-CHn3ald-.js} +1 -1
  150. package/src/assets/web-panel/assets/{statusUtils-Ddj6rSab.js → statusUtils-BiGwoIK_.js} +1 -1
  151. package/src/assets/web-panel/assets/{styleChecker-DyP1mPDf.js → styleChecker-Zf2dQx1j.js} +1 -1
  152. package/src/assets/web-panel/assets/{useFlexGapSupport-D3d_0YuY.js → useFlexGapSupport-sLES8nyD.js} +1 -1
  153. package/src/assets/web-panel/assets/{useFs-M3vq-gE2.js → useFs-DV1Hl4qu.js} +1 -1
  154. package/src/assets/web-panel/assets/{usePersonalDataHub-GtP2TgtK.js → usePersonalDataHub-CZXr2Qxg.js} +1 -1
  155. package/src/assets/web-panel/assets/{vnode-BurE2ATQ.js → vnode-e8Eo3Oyl.js} +1 -1
  156. package/src/assets/web-panel/assets/{xterm-BZcWGsqw.js → xterm-zbskxxGA.js} +1 -1
  157. package/src/assets/web-panel/assets/{zoom-Ch-ViiDe.js → zoom-B8A6xKMF.js} +1 -1
  158. package/src/assets/web-panel/index.html +1 -1
  159. package/src/commands/compact.js +7 -2
  160. package/src/data/changelog.json +27 -1
  161. package/src/harness/jsonl-session-store.js +80 -74
  162. package/src/harness/prompt-compressor.js +57 -3
  163. package/src/lib/artifact-store.js +129 -20
  164. package/src/lib/bounded-artifact-file-read.js +128 -46
  165. package/src/lib/context-memory-kernel/context-image-transport.js +248 -0
  166. package/src/lib/context-memory-kernel/jsonl-session-context-port.js +4 -1
  167. package/src/lib/context-memory-kernel/live-compaction.js +40 -10
  168. package/src/lib/context-memory-kernel/message-adapter.js +80 -10
  169. package/src/lib/context-memory-kernel/message-bundle-store.js +1140 -0
  170. package/src/lib/context-memory-kernel/provider-context.js +23 -8
  171. package/src/lib/evolution/agent-evolution-ingress.js +103 -19
  172. package/src/lib/evolution/agent-evolution-runtime-composition.js +65 -27
  173. package/src/lib/evolution/agent-model-projection.js +90 -18
  174. package/src/lib/evolution/evidence-json-text.js +341 -42
  175. package/src/lib/evolution/evolution-artifact-ports.js +1005 -83
  176. package/src/lib/evolution/evolution-evidence-artifact-adapter.js +59 -15
  177. package/src/lib/evolution/evolution-evidence-projector.js +153 -16
  178. package/src/lib/evolution/evolution-evidence-storage-layout.js +115 -0
  179. package/src/lib/evolution/evolution-file-witness.js +7 -3
  180. package/src/lib/evolution/evolution-ledger-file-manifest-catalog.js +6 -2
  181. package/src/lib/evolution/evolution-ledger-file-manifest-head-store.js +6 -2
  182. package/src/lib/evolution/evolution-ledger.js +226 -55
  183. package/src/lib/evolution/evolution-private-storage.js +20 -0
  184. package/src/lib/evolution/evolution-run-ledger-adapter.js +298 -11
  185. package/src/lib/evolution/evolution-windows-directory-durability.js +215 -32
  186. package/src/lib/evolution/local-ui-evolution-runtime.js +3 -38
  187. package/src/lib/evolution/local-ui-signing-authority.js +69 -0
  188. package/src/lib/image-token-estimate.js +59 -0
  189. package/src/lib/ollama-provider-fetch.js +33 -0
  190. package/src/lib/provider-stream.js +14 -13
  191. package/src/lib/read-file-loop-guard.js +7 -4
  192. package/src/lib/session-history-origins.js +94 -35
  193. package/src/lib/session-message-provenance.js +26 -2
  194. package/src/lib/session-runtime-retention.js +10 -1
  195. package/src/lib/session-transcript-history.js +5 -1
  196. package/src/lib/session-transcript-migration.js +67 -12
  197. package/src/lib/storage-failure-cause-codes.js +449 -0
  198. package/src/lib/tool-result-preview.js +276 -0
  199. package/src/runtime/agent-core.js +111 -92
  200. package/src/runtime/headless-stream.js +121 -27
  201. package/src/assets/web-panel/assets/MarkdownRenderer-D8_iZief.js +0 -1
  202. package/src/assets/web-panel/assets/Projects-BeSOM6wi.js +0 -1
  203. package/src/assets/web-panel/assets/SpeechSettings-Bfhvin8B.js +0 -1
  204. package/src/assets/web-panel/assets/devWarning-c2I2Rn4_.js +0 -1
  205. package/src/assets/web-panel/assets/index-CTs4dYcV.js +0 -1
  206. package/src/assets/web-panel/assets/index-DeuvaW15.js +0 -1
  207. package/src/assets/web-panel/assets/markdown-CsiA8-E5.js +0 -50
@@ -12,6 +12,59 @@ export const EVIDENCE_JSON_POLICY = Object.freeze({
12
12
  numbers: "finite-safe-integers-pii-to-string",
13
13
  });
14
14
 
15
+ export const AGENT_CODE_TEXT_RESULT_TOOLS = Object.freeze([
16
+ "run_code",
17
+ "read_file",
18
+ "run_shell",
19
+ "check_shell",
20
+ "git",
21
+ "search_files",
22
+ ]);
23
+
24
+ export const AGENT_FENCED_CODE_LANGUAGES = Object.freeze([
25
+ "javascript",
26
+ "js",
27
+ "typescript",
28
+ "ts",
29
+ "jsx",
30
+ "tsx",
31
+ "python",
32
+ "py",
33
+ ]);
34
+
35
+ function fencedCodeRanges(text, languages) {
36
+ const ranges = [];
37
+ const fences = /^ {0,3}(`{3,}|~{3,})([^\r\n]*)\r?$/gmu;
38
+ let opening = null;
39
+ for (const match of text.matchAll(fences)) {
40
+ const marker = match[1];
41
+ const info = match[2].trim().toLowerCase();
42
+ if (opening === null) {
43
+ opening = {
44
+ marker,
45
+ supported: languages.includes(info),
46
+ start: match.index + match[0].length,
47
+ };
48
+ } else if (
49
+ marker[0] === opening.marker[0] &&
50
+ marker.length >= opening.marker.length &&
51
+ info === ""
52
+ ) {
53
+ if (opening.supported) ranges.push([opening.start, match.index]);
54
+ opening = null;
55
+ }
56
+ }
57
+ // Unclosed/unknown fences never acquire code semantics.
58
+ return ranges;
59
+ }
60
+
61
+ /* eslint-disable no-control-regex -- Quoted literals exclude unescaped control bytes. */
62
+ const JSON_STRING_PREFIX =
63
+ /^"(?:[^"\\\x00-\x1f]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"/u;
64
+ const CODE_DOUBLE_QUOTED_PREFIX = /^"(?:[^"\\\x00-\x1f]|\\[\s\S])*"/u;
65
+ const CODE_SINGLE_QUOTED_PREFIX = /^'(?:[^'\\\x00-\x1f]|\\[\s\S])*'/u;
66
+ /* eslint-enable no-control-regex */
67
+
15
68
  export function isAgentToolArgumentsPath(path) {
16
69
  return (
17
70
  path.length === 6 &&
@@ -35,15 +88,103 @@ function assignmentKeyBefore(text, start, end) {
35
88
  return keyEnd > index + 1 ? text.slice(index + 1, keyEnd) : undefined;
36
89
  }
37
90
 
38
- export function createEvidenceJsonTextBoundary(fail) {
91
+ export function createEvidenceJsonTextBoundary(
92
+ fail,
93
+ policy = EVIDENCE_JSON_POLICY,
94
+ ) {
39
95
  let nodes = 0;
40
96
  let bytes = 0;
41
- const reject = () => {
42
- throw fail(
43
- "Agent model JSON text is malformed, ambiguous or exceeds its budget",
97
+ const PARSE_FAILURE = Symbol("evidence-json-parse-failure");
98
+ const reject = (
99
+ message = "Agent model JSON text is malformed or ambiguous",
100
+ ) => {
101
+ throw fail(message);
102
+ };
103
+ const rejectParseFailure = (error) => {
104
+ reject(
105
+ error?.[PARSE_FAILURE] === "budget"
106
+ ? "Agent model JSON text exceeds its budget"
107
+ : "Agent model JSON text is malformed or ambiguous",
44
108
  );
45
109
  };
46
- const parser = (text, start) => {
110
+ const parserReject = (kind) => {
111
+ const error = new Error(kind);
112
+ Object.defineProperty(error, PARSE_FAILURE, { value: kind });
113
+ throw error;
114
+ };
115
+ const decodeSourceString = (literal, quote) => {
116
+ let output = "";
117
+ for (let index = 1; index < literal.length - 1; index++) {
118
+ const char = literal[index];
119
+ if (char !== "\\") {
120
+ output += char;
121
+ continue;
122
+ }
123
+ const escaped = literal[++index];
124
+ if (/[0-7]/u.test(escaped ?? "")) {
125
+ const digits = /^[0-7]{1,3}/u.exec(literal.slice(index))[0];
126
+ output += String.fromCodePoint(Number.parseInt(digits, 8));
127
+ index += digits.length - 1;
128
+ continue;
129
+ }
130
+ // Python named Unicode escapes require a Unicode-name database. Refuse
131
+ // them instead of treating an encoded sensitive key/value as plain text.
132
+ if (escaped === "N" && literal[index + 1] === "{")
133
+ return parserReject("syntax");
134
+ const simple = {
135
+ "'": "'",
136
+ '"': '"',
137
+ "\\": "\\",
138
+ b: "\b",
139
+ f: "\f",
140
+ n: "\n",
141
+ r: "\r",
142
+ t: "\t",
143
+ v: "\v",
144
+ 0: "\0",
145
+ };
146
+ if (escaped === quote || Object.hasOwn(simple, escaped)) {
147
+ output += simple[escaped] ?? escaped;
148
+ continue;
149
+ }
150
+ if (escaped === "x" || escaped === "u" || escaped === "U") {
151
+ if (escaped === "u" && literal[index + 1] === "{") {
152
+ const close = literal.indexOf("}", index + 2);
153
+ const digits = close < 0 ? "" : literal.slice(index + 2, close);
154
+ if (/^[0-9a-fA-F]{1,6}$/u.test(digits)) {
155
+ const codePoint = Number.parseInt(digits, 16);
156
+ if (codePoint <= 0x10ffff) {
157
+ output += String.fromCodePoint(codePoint);
158
+ index = close;
159
+ continue;
160
+ }
161
+ }
162
+ }
163
+ const count = escaped === "x" ? 2 : escaped === "u" ? 4 : 8;
164
+ const digits = literal.slice(index + 1, index + 1 + count);
165
+ if (new RegExp(`^[0-9a-fA-F]{${count}}$`, "u").test(digits)) {
166
+ const codePoint = Number.parseInt(digits, 16);
167
+ if (codePoint <= 0x10ffff) {
168
+ output += String.fromCodePoint(codePoint);
169
+ index += count;
170
+ continue;
171
+ }
172
+ }
173
+ output += `\\${escaped}`;
174
+ continue;
175
+ }
176
+ // Keep line continuations and language-specific escapes bounded to the
177
+ // source literal. The decoded value is used only for evidence scanning.
178
+ if (escaped === "\n") continue;
179
+ if (escaped === "\r" && literal[index + 1] === "\n") {
180
+ index++;
181
+ continue;
182
+ }
183
+ output += escaped;
184
+ }
185
+ return output;
186
+ };
187
+ const parser = (text, start, { allowSingleQuotedStrings = false } = {}) => {
47
188
  let index = start;
48
189
  const whitespace = () => {
49
190
  while (/[ \t\r\n]/u.test(text[index] ?? "x")) index++;
@@ -57,21 +198,32 @@ export function createEvidenceJsonTextBoundary(fail) {
57
198
  try {
58
199
  return JSON.parse(text.slice(begin, index));
59
200
  } catch {
60
- return reject();
201
+ if (allowSingleQuotedStrings)
202
+ return decodeSourceString(text.slice(begin, index), '"');
203
+ return parserReject("syntax");
61
204
  }
62
205
  }
63
206
  }
64
- return reject();
207
+ return parserReject("syntax");
208
+ };
209
+ const singleQuotedString = () => {
210
+ const begin = index++;
211
+ while (index < text.length) {
212
+ const char = text[index++];
213
+ if (char === "\\") index++;
214
+ else if (char === "'")
215
+ return decodeSourceString(text.slice(begin, index), "'");
216
+ }
217
+ return parserReject("syntax");
65
218
  };
66
219
  const value = (depth = 0) => {
67
- if (
68
- ++nodes > EVIDENCE_JSON_POLICY.maxNodes ||
69
- depth > EVIDENCE_JSON_POLICY.maxDepth
70
- )
71
- reject();
220
+ if (++nodes > policy.maxNodes || depth > policy.maxDepth)
221
+ parserReject("budget");
72
222
  whitespace();
73
223
  const char = text[index];
74
224
  if (char === '"') return string();
225
+ if (char === "'" && allowSingleQuotedStrings) return singleQuotedString();
226
+ if (char === "'") return parserReject("code-expression");
75
227
  if (char === "{" || char === "[") {
76
228
  const array = char === "[";
77
229
  const end = array ? "]" : "}";
@@ -85,11 +237,19 @@ export function createEvidenceJsonTextBoundary(fail) {
85
237
  while (index < text.length) {
86
238
  let key;
87
239
  if (!array) {
88
- if (text[index] !== '"') reject();
89
- key = string();
90
- if (Object.hasOwn(output, key)) reject();
240
+ if (
241
+ text[index] !== '"' &&
242
+ !(allowSingleQuotedStrings && text[index] === "'")
243
+ )
244
+ parserReject(
245
+ text[index] === "'" || /^[A-Za-z_$]/u.test(text[index] ?? "")
246
+ ? "code-expression"
247
+ : "syntax",
248
+ );
249
+ key = text[index] === "'" ? singleQuotedString() : string();
250
+ if (Object.hasOwn(output, key)) parserReject("ambiguous");
91
251
  whitespace();
92
- if (text[index++] !== ":") reject();
252
+ if (text[index++] !== ":") parserReject("syntax");
93
253
  }
94
254
  const child = value(depth + 1);
95
255
  if (array) output.push(child);
@@ -103,16 +263,34 @@ export function createEvidenceJsonTextBoundary(fail) {
103
263
  index++;
104
264
  return output;
105
265
  }
106
- if (text[index++] !== ",") reject();
266
+ if (text[index] !== ",") {
267
+ // Slices, comprehensions and member/call/arithmetic expressions
268
+ // are source syntax. Missing delimiters and trailing commas stay
269
+ // malformed JSON, including in run_code output.
270
+ parserReject(
271
+ (array && text[index] === ":") ||
272
+ /^[.(+*/?]/u.test(text[index] ?? "") ||
273
+ /^for\b/u.test(text.slice(index))
274
+ ? "code-expression"
275
+ : "syntax",
276
+ );
277
+ }
278
+ index++;
107
279
  whitespace();
108
280
  }
109
- return reject();
281
+ return parserReject("syntax");
110
282
  }
111
283
  const token =
112
284
  /^(?:true|false|null|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)/u.exec(
113
285
  text.slice(index),
114
286
  )?.[0];
115
- if (!token) return reject();
287
+ if (!token) {
288
+ return parserReject(
289
+ /^[A-Za-z_$][A-Za-z0-9_$]*|^\(/u.test(text.slice(index))
290
+ ? "code-expression"
291
+ : "syntax",
292
+ );
293
+ }
116
294
  index += token.length;
117
295
  const parsed = JSON.parse(token);
118
296
  if (
@@ -120,7 +298,7 @@ export function createEvidenceJsonTextBoundary(fail) {
120
298
  (!Number.isFinite(parsed) ||
121
299
  (Number.isInteger(parsed) && !Number.isSafeInteger(parsed)))
122
300
  )
123
- reject();
301
+ parserReject("budget");
124
302
  return parsed;
125
303
  };
126
304
  return {
@@ -130,16 +308,51 @@ export function createEvidenceJsonTextBoundary(fail) {
130
308
  };
131
309
  };
132
310
 
133
- return (text, { layer = 0, objectOnly = false, visit, plain, equal }) => {
311
+ return function scanText(
312
+ text,
313
+ {
314
+ layer = 0,
315
+ objectOnly = false,
316
+ codeText = false,
317
+ fencedCodeLanguages = null,
318
+ visit,
319
+ plain,
320
+ equal,
321
+ },
322
+ ) {
323
+ if (!objectOnly && !codeText && fencedCodeLanguages) {
324
+ const ranges = fencedCodeRanges(text, fencedCodeLanguages);
325
+ if (ranges.length > 0) {
326
+ let output = "";
327
+ let offset = 0;
328
+ const options = { layer, visit, plain, equal };
329
+ for (const [start, end] of ranges) {
330
+ output += scanText(text.slice(offset, start), options);
331
+ output += scanText(text.slice(start, end), {
332
+ ...options,
333
+ codeText: true,
334
+ });
335
+ offset = end;
336
+ }
337
+ return output + scanText(text.slice(offset), options);
338
+ }
339
+ }
134
340
  bytes += Buffer.byteLength(text, "utf8");
135
- if (bytes > EVIDENCE_JSON_POLICY.maxDecodedBytes) reject();
341
+ if (bytes > policy.maxDecodedBytes)
342
+ reject("Agent model JSON text exceeds its budget");
136
343
  const transform = (parsed) => {
137
- if (layer >= EVIDENCE_JSON_POLICY.maxLayers) reject();
344
+ if (layer >= policy.maxLayers)
345
+ reject("Agent model JSON text exceeds its budget");
138
346
  return visit(parsed, layer + 1);
139
347
  };
140
348
  if (objectOnly) {
141
349
  const reader = parser(text, 0);
142
- const parsed = reader.value();
350
+ let parsed;
351
+ try {
352
+ parsed = reader.value();
353
+ } catch (error) {
354
+ rejectParseFailure(error);
355
+ }
143
356
  reader.whitespace();
144
357
  if (
145
358
  reader.end() !== text.length ||
@@ -157,7 +370,7 @@ export function createEvidenceJsonTextBoundary(fail) {
157
370
  // as objects. Ordinary code braces and projection markers are not JSON.
158
371
  let output = "";
159
372
  let plainStart = 0;
160
- for (let index = 0; index < text.length;) {
373
+ for (let index = 0; index < text.length; ) {
161
374
  const char = text[index];
162
375
  const next =
163
376
  char === "{" || char === "["
@@ -173,7 +386,8 @@ export function createEvidenceJsonTextBoundary(fail) {
173
386
  /^\s*(?:-\d|(?:true|false|null)(?=[\s,\]]))/u.test(
174
387
  text.slice(index + 1),
175
388
  )));
176
- if (!container && char !== '"') {
389
+ const quoted = char === '"' || (codeText && char === "'");
390
+ if (!container && !quoted) {
177
391
  index++;
178
392
  continue;
179
393
  }
@@ -181,34 +395,110 @@ export function createEvidenceJsonTextBoundary(fail) {
181
395
  // lexically valid JSON string is a candidate outside JSON containers.
182
396
  if (
183
397
  !container &&
184
- // eslint-disable-next-line no-control-regex -- JSON strings exclude literal U+0000 through U+001F.
185
- !/^"(?:[^"\\\x00-\x1f]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"/u.test(
186
- text.slice(index),
187
- )
398
+ char === '"' &&
399
+ !(codeText
400
+ ? CODE_DOUBLE_QUOTED_PREFIX.test(text.slice(index))
401
+ : JSON_STRING_PREFIX.test(text.slice(index)))
402
+ ) {
403
+ index++;
404
+ continue;
405
+ }
406
+ if (
407
+ codeText &&
408
+ char === "'" &&
409
+ !CODE_SINGLE_QUOTED_PREFIX.test(text.slice(index))
188
410
  ) {
189
411
  index++;
190
412
  continue;
191
413
  }
192
- const reader = parser(text, index);
193
- let parsed = reader.value();
194
- const valueEnd = reader.end();
414
+ const reader = parser(text, index, {
415
+ // A recognized container is always tried as strict JSON first, even
416
+ // inside code. Only an explicit non-JSON token allows literal scanning.
417
+ allowSingleQuotedStrings: codeText && !container,
418
+ });
419
+ let parsed;
420
+ let valueEnd;
421
+ try {
422
+ parsed = reader.value();
423
+ valueEnd = reader.end();
424
+ } catch (error) {
425
+ const kind = error?.[PARSE_FAILURE];
426
+ if (!codeText || kind !== "code-expression") rejectParseFailure(error);
427
+ // Python/JavaScript containers may contain single quotes or expressions.
428
+ // Scan their literals individually, preserving nested strict JSON scans.
429
+ // Keep consumed nodes charged so repeated fallback cannot reset budgets.
430
+ index++;
431
+ continue;
432
+ }
195
433
  reader.whitespace();
196
- const pair = char === '"' && text[reader.end()] === ":";
434
+ let pair = quoted && text[reader.end()] === ":";
435
+ let pairValueEnd;
436
+ const requireSafeExpressionKey = () => {
437
+ // An expression cannot be visited as a decoded JSON value. Preserve
438
+ // the decoded key boundary: otherwise a password list/call expression
439
+ // could expose its string literals when scanning resumes inside it.
440
+ const probe = Object.defineProperty(Object.create(null), parsed, {
441
+ value: "source-expression",
442
+ enumerable: true,
443
+ });
444
+ if (!equal(probe, transform(probe)))
445
+ reject(
446
+ "Agent model code expression under a sensitive key cannot be safely projected",
447
+ );
448
+ };
449
+ if (pair) {
450
+ const rhsStart = reader.end() + 1;
451
+ const codeExpression = codeText
452
+ ? /^\s*([A-Za-z_$][A-Za-z0-9_$]*)/u.exec(text.slice(rhsStart))?.[1]
453
+ : undefined;
454
+ if (
455
+ codeExpression &&
456
+ !["true", "false", "null"].includes(codeExpression)
457
+ ) {
458
+ requireSafeExpressionKey();
459
+ pair = false;
460
+ } else {
461
+ try {
462
+ const rhsContainer = /^[ \t\r\n]*[\[{]/u.test(text.slice(rhsStart));
463
+ const rhs = parser(text, rhsStart, {
464
+ allowSingleQuotedStrings: codeText && !rhsContainer,
465
+ });
466
+ const entry = rhs.value();
467
+ const entryEnd = rhs.end();
468
+ rhs.whitespace();
469
+ if (
470
+ codeText &&
471
+ /^[+\-*/%?.([<>&|^=!"']/u.test(text[rhs.end()] ?? "")
472
+ )
473
+ requireSafeExpressionKey();
474
+ parsed = Object.defineProperty(Object.create(null), parsed, {
475
+ value: entry,
476
+ enumerable: true,
477
+ });
478
+ pairValueEnd = entryEnd;
479
+ } catch (error) {
480
+ const kind = error?.[PARSE_FAILURE];
481
+ if (kind === undefined) throw error;
482
+ if (!codeText || kind !== "code-expression")
483
+ rejectParseFailure(error);
484
+ // In a run_code source/result string, a quoted key followed by a
485
+ // Python/JavaScript expression is code, not a broken JSON pair.
486
+ // Resume the scan at the next literal so any string value still
487
+ // receives key-aware or ordinary secret scanning.
488
+ requireSafeExpressionKey();
489
+ pair = false;
490
+ }
491
+ }
492
+ }
197
493
  const assignmentKey =
198
- char === '"' && !pair
494
+ quoted && !pair
199
495
  ? // Scan backward once; an unanchored greedy key regex would retry at
200
496
  // every offset of a long ordinary prefix before a quoted fragment.
201
497
  assignmentKeyBefore(text, plainStart, index)
202
498
  : undefined;
203
499
  let end = valueEnd;
204
500
  if (pair) {
205
- const rhs = parser(text, reader.end() + 1);
206
- const entry = rhs.value();
207
- parsed = Object.defineProperty(Object.create(null), parsed, {
208
- value: entry,
209
- enumerable: true,
210
- });
211
- end = rhs.end();
501
+ end = pairValueEnd;
212
502
  } else if (assignmentKey) {
213
503
  // Bare assignments followed by a quoted value cross a text/JSON span.
214
504
  // Reuse decoded field rules rather than a second credential-key list.
@@ -218,6 +508,15 @@ export function createEvidenceJsonTextBoundary(fail) {
218
508
  });
219
509
  }
220
510
  const safe = transform(parsed);
511
+ if (
512
+ codeText &&
513
+ assignmentKey &&
514
+ !equal(parsed, safe) &&
515
+ /^\s*[+\-*/%?.([<>&|^=!"']/u.test(text.slice(end))
516
+ )
517
+ reject(
518
+ "Agent model code expression under a sensitive key cannot be safely projected",
519
+ );
221
520
  let replacement = text.slice(index, end);
222
521
  if (!equal(parsed, safe)) {
223
522
  replacement = JSON.stringify(safe);