@ic-reactor/mcp 0.0.0-stage → 0.0.0

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 (1041) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +108 -0
  2. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.yml +77 -0
  4. package/.github/actions/setup-rust-wasm/action.yml +25 -0
  5. package/.github/dependabot.yml +107 -0
  6. package/.github/workflows/auth-latest.yml +67 -0
  7. package/.github/workflows/b3pay-site.yml +49 -0
  8. package/.github/workflows/ci.yml +430 -0
  9. package/.github/workflows/codeql.yml +41 -0
  10. package/.github/workflows/dependency-review.yml +68 -0
  11. package/.github/workflows/docs-check.yml +98 -0
  12. package/.github/workflows/docs.yml +265 -0
  13. package/.github/workflows/e2e.yml +90 -0
  14. package/.github/workflows/examples-published.yml +97 -0
  15. package/.github/workflows/release.yml +326 -0
  16. package/.husky/pre-commit +12 -0
  17. package/.prettierignore +109 -0
  18. package/.prettierrc +6 -0
  19. package/AGENTS.md +103 -0
  20. package/CHANGELOG.md +3268 -0
  21. package/CLAUDE.md +93 -0
  22. package/CNAME +1 -0
  23. package/CODE_OF_CONDUCT.md +7 -0
  24. package/CONTRIBUTING.md +433 -0
  25. package/LICENSE +21 -0
  26. package/README.md +2 -2
  27. package/SECURITY.md +74 -0
  28. package/b3pay-module.json +194 -0
  29. package/docs/.remarkrc.json +10 -0
  30. package/docs/README.md +64 -0
  31. package/docs/astro.config.mjs +205 -0
  32. package/docs/favicon.svg +15 -0
  33. package/docs/package.json +39 -0
  34. package/docs/public/favicon.svg +15 -0
  35. package/docs/public/ic-reactor-social-card.png +0 -0
  36. package/docs/scripts/b3pay-static.mjs +22 -0
  37. package/docs/scripts/check-example-docs.mjs +214 -0
  38. package/docs/scripts/check-links.mjs +212 -0
  39. package/docs/scripts/fix-dist-links.js +125 -0
  40. package/docs/scripts/fix-frontmatter.js +71 -0
  41. package/docs/scripts/remove-redundant-h1.cjs +48 -0
  42. package/docs/scripts/rewrite-typedoc-links.js +110 -0
  43. package/docs/scripts/split-index.js +69 -0
  44. package/docs/src/assets/ic-reactor-hero-dark.svg +23 -0
  45. package/docs/src/assets/ic-reactor-hero-light.svg +23 -0
  46. package/docs/src/assets/ic-reactor-lockup-dark.svg +15 -0
  47. package/docs/src/assets/ic-reactor-lockup-light.svg +15 -0
  48. package/docs/src/assets/ic-reactor-mark-dark.svg +14 -0
  49. package/docs/src/assets/ic-reactor-mark-light.svg +14 -0
  50. package/docs/src/assets/layers/candid-core-layer-icon-dark.svg +4 -0
  51. package/docs/src/assets/layers/candid-core-layer-icon-light.svg +4 -0
  52. package/docs/src/assets/layers/candid-profile-layer-icon-dark.svg +4 -0
  53. package/docs/src/assets/layers/candid-profile-layer-icon-light.svg +4 -0
  54. package/docs/src/assets/layers/ic-reactor-layer-icon-dark.svg +4 -0
  55. package/docs/src/assets/layers/ic-reactor-layer-icon-light.svg +4 -0
  56. package/docs/src/components/LibraryCards.astro +172 -0
  57. package/docs/src/components/LibraryIcon.astro +28 -0
  58. package/docs/src/components/SiteTitle.astro +241 -0
  59. package/docs/src/content/docs/404.mdx +19 -0
  60. package/docs/src/content/docs/build/agent-tools.mdx +593 -0
  61. package/docs/src/content/docs/build/icrc1-wallet.mdx +619 -0
  62. package/docs/src/content/docs/build/ssr-per-user.mdx +552 -0
  63. package/docs/src/content/docs/examples/canister-studio.mdx +95 -0
  64. package/docs/src/content/docs/examples/icrc-ledger.mdx +45 -0
  65. package/docs/src/content/docs/examples/index.mdx +38 -0
  66. package/docs/src/content/docs/examples/next-ssr.mdx +73 -0
  67. package/docs/src/content/docs/examples/node-agent-tool.mdx +80 -0
  68. package/docs/src/content/docs/examples/vite-wallet.mdx +71 -0
  69. package/docs/src/content/docs/guides/auth.mdx +1181 -0
  70. package/docs/src/content/docs/guides/client.mdx +551 -0
  71. package/docs/src/content/docs/guides/deploy.mdx +180 -0
  72. package/docs/src/content/docs/guides/errors.mdx +475 -0
  73. package/docs/src/content/docs/guides/getting-started.mdx +620 -0
  74. package/docs/src/content/docs/guides/reads.mdx +586 -0
  75. package/docs/src/content/docs/guides/ssr.mdx +529 -0
  76. package/docs/src/content/docs/guides/testing.mdx +401 -0
  77. package/docs/src/content/docs/guides/values.mdx +261 -0
  78. package/docs/src/content/docs/guides/vite-plugin.mdx +690 -0
  79. package/docs/src/content/docs/guides/writes.mdx +572 -0
  80. package/docs/src/content/docs/ic-reactor/index.mdx +167 -0
  81. package/docs/src/content/docs/index.mdx +65 -0
  82. package/docs/src/content/docs/migrating-from-3.mdx +535 -0
  83. package/docs/src/content/docs/packages/core.mdx +186 -0
  84. package/docs/src/content/docs/packages/mcp.mdx +163 -0
  85. package/docs/src/content/docs/packages/react.mdx +207 -0
  86. package/docs/src/content/docs/packages/vite-plugin.mdx +73 -0
  87. package/docs/src/content/docs/versioning.mdx +104 -0
  88. package/docs/src/content.config.ts +7 -0
  89. package/docs/src/styles/custom.css +189 -0
  90. package/docs/tsconfig.typedoc.json +26 -0
  91. package/docs/typedoc-entry.ts +17 -0
  92. package/docs/typedoc.json +37 -0
  93. package/e2e/Cargo.lock +646 -0
  94. package/e2e/Cargo.toml +3 -0
  95. package/e2e/README.md +101 -0
  96. package/e2e/frontends/build.mjs +94 -0
  97. package/e2e/frontends/index.html +10 -0
  98. package/e2e/global-setup.ts +65 -0
  99. package/e2e/icp.yaml +38 -0
  100. package/e2e/package.json +40 -0
  101. package/e2e/setup.ts +6 -0
  102. package/e2e/src/actor/Cargo.toml +14 -0
  103. package/e2e/src/actor/hello_actor.did +10 -0
  104. package/e2e/src/actor/src/lib.rs +73 -0
  105. package/e2e/src/calls.test.ts +132 -0
  106. package/e2e/src/declarations/hello_actor.envelope.json +175 -0
  107. package/e2e/src/declarations/hello_actor.ts +15 -0
  108. package/e2e/src/errors.test.ts +107 -0
  109. package/e2e/src/frontend-headers.test.ts +253 -0
  110. package/e2e/src/identity.test.ts +61 -0
  111. package/e2e/src/react.test.tsx +59 -0
  112. package/e2e/src/replica.ts +70 -0
  113. package/e2e/src/vite-env.test.ts +108 -0
  114. package/e2e/test.sh +47 -0
  115. package/e2e/tsconfig.json +20 -0
  116. package/e2e/tsconfig.typecheck.json +9 -0
  117. package/e2e/vitest.config.ts +22 -0
  118. package/eslint.config.mjs +100 -0
  119. package/evals/PREREGISTRATION.md +1346 -0
  120. package/evals/README.md +756 -0
  121. package/evals/conditions/thin/condition.json +8 -0
  122. package/evals/conditions/thin/docs/candid-core-cli.README.md +90 -0
  123. package/evals/conditions/thin/docs/candid-core-schema.README.md +339 -0
  124. package/evals/conditions/thin/package.json +25 -0
  125. package/evals/conditions/thin/starter/src/generated/icrc1.ts +57 -0
  126. package/evals/conditions/thin-guide/condition.json +10 -0
  127. package/evals/conditions/thin-guide/docs/llms.txt +292 -0
  128. package/evals/conditions/v3/condition.json +9 -0
  129. package/evals/conditions/v3/docs/ic-reactor-core.llms.txt +232 -0
  130. package/evals/conditions/v3/docs/ic-reactor-react.llms.txt +280 -0
  131. package/evals/conditions/v3/docs/llms-full.txt +1053 -0
  132. package/evals/conditions/v3/package.json +26 -0
  133. package/evals/conditions/v3/starter/src/declarations/icrc1.did.d.ts +95 -0
  134. package/evals/conditions/v3/starter/src/declarations/icrc1.did.js +140 -0
  135. package/evals/conditions/v4/PORTING.md +384 -0
  136. package/evals/conditions/v4/README.md +106 -0
  137. package/evals/conditions/v4/condition.json +5 -0
  138. package/evals/conditions/v4/docs/llms.txt +323 -0
  139. package/evals/conditions/v4/package.json +27 -0
  140. package/evals/conditions/v4/starter/src/generated/icrc1.ts +78 -0
  141. package/evals/conditions/v4-proto/condition.json +6 -0
  142. package/evals/conditions/v4-proto/docs/llms.txt +291 -0
  143. package/evals/conditions/v4-proto/lib/SHIM-NOTES.md +20 -0
  144. package/evals/conditions/v4-proto/lib/package.json +27 -0
  145. package/evals/conditions/v4-proto/lib/src/client.ts +471 -0
  146. package/evals/conditions/v4-proto/lib/src/errors.ts +214 -0
  147. package/evals/conditions/v4-proto/lib/src/index.ts +36 -0
  148. package/evals/conditions/v4-proto/lib/src/principal.ts +175 -0
  149. package/evals/conditions/v4-proto/lib/src/service.ts +69 -0
  150. package/evals/conditions/v4-proto/lib/src/types.ts +174 -0
  151. package/evals/conditions/v4-proto/lib/test/runtime.test.ts +170 -0
  152. package/evals/conditions/v4-proto/lib/test/tsconfig.json +10 -0
  153. package/evals/conditions/v4-proto/lib/test/types.test-d.ts +145 -0
  154. package/evals/conditions/v4-proto/lib/test/vitest.config.mjs +8 -0
  155. package/evals/conditions/v4-proto/lib/tsconfig.json +17 -0
  156. package/evals/conditions/v4-proto/package.json +26 -0
  157. package/evals/conditions/v4-proto/starter/src/generated/icrc1.service.ts +19 -0
  158. package/evals/conditions/v4-proto/starter/src/generated/icrc1.ts +57 -0
  159. package/evals/drive.mjs +1221 -0
  160. package/evals/gate.mjs +161 -0
  161. package/evals/harness/aggregate.mjs +534 -0
  162. package/evals/harness/aggregate.test.mjs +344 -0
  163. package/evals/harness/assemble.mjs +216 -0
  164. package/evals/harness/assemble.test.mjs +143 -0
  165. package/evals/harness/auth.mjs +91 -0
  166. package/evals/harness/check-docs.mjs +157 -0
  167. package/evals/harness/declarations/icrc1.did.d.ts +95 -0
  168. package/evals/harness/declarations/icrc1.did.js +140 -0
  169. package/evals/harness/drive-auth.test.mjs +584 -0
  170. package/evals/harness/drive.test.mjs +509 -0
  171. package/evals/harness/fake-auth.ts +67 -0
  172. package/evals/harness/fake-ledger.ts +178 -0
  173. package/evals/harness/gate-plan.mjs +104 -0
  174. package/evals/harness/gate-plan.test.mjs +243 -0
  175. package/evals/harness/icrc1.did +88 -0
  176. package/evals/harness/judge.mjs +63 -0
  177. package/evals/harness/judge.test.mjs +81 -0
  178. package/evals/harness/leak-scan.mjs +1373 -0
  179. package/evals/harness/leak-scan.test.mjs +1300 -0
  180. package/evals/harness/probes/amounts.ts +14 -0
  181. package/evals/harness/probes/node-tool.probe.ts +48 -0
  182. package/evals/harness/probes/probe.mjs +149 -0
  183. package/evals/harness/probes/react-wallet.probe.ts +96 -0
  184. package/evals/harness/public/support/auth.ts +38 -0
  185. package/evals/harness/public/support/fake-replica.d.ts +28 -0
  186. package/evals/harness/public/support/fake-replica.js +434 -0
  187. package/evals/harness/public/support/ledger.idl.d.ts +95 -0
  188. package/evals/harness/public/support/ledger.idl.js +140 -0
  189. package/evals/harness/public/support/world.ts +179 -0
  190. package/evals/harness/runs.mjs +139 -0
  191. package/evals/harness/sandbox.mjs +88 -0
  192. package/evals/harness/sandbox.test.mjs +134 -0
  193. package/evals/harness/ship.mjs +264 -0
  194. package/evals/harness/ship.test.mjs +552 -0
  195. package/evals/harness/world.ts +291 -0
  196. package/evals/package.json +26 -0
  197. package/evals/pnpm-lock.yaml +1537 -0
  198. package/evals/pnpm-workspace.yaml +12 -0
  199. package/evals/results/2026-09-30T14-22-05-924Z/pilot.json +384 -0
  200. package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.json +404 -0
  201. package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.rescored.json +404 -0
  202. package/evals/results/2026-09-30T14-22-05-924Z/plan.json +240 -0
  203. package/evals/results/2026-09-30T14-22-05-924Z/summary.json +1800 -0
  204. package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.json +1843 -0
  205. package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.rescored.json +2100 -0
  206. package/evals/results/2026-09-30T15-48-23-343Z/pilot.json +404 -0
  207. package/evals/results/2026-09-30T15-48-23-343Z/pilot.rescored.json +404 -0
  208. package/evals/results/2026-09-30T15-48-23-343Z/plan.json +242 -0
  209. package/evals/results/2026-09-30T15-48-23-343Z/summary.json +1843 -0
  210. package/evals/results/2026-09-30T15-48-23-343Z/summary.rescored.json +2195 -0
  211. package/evals/results/2026-10-03-beta1-gate/pilot.json +162 -0
  212. package/evals/results/2026-10-03-beta1-gate/plan.json +141 -0
  213. package/evals/results/2026-10-03-beta1-gate/summary.json +983 -0
  214. package/evals/results/2026-10-05-ga-gate/contaminated-run.json +55 -0
  215. package/evals/results/2026-10-05-ga-gate/pilot.json +162 -0
  216. package/evals/results/2026-10-05-ga-gate/plan.json +457 -0
  217. package/evals/results/2026-10-05-ga-gate/summary.json +1037 -0
  218. package/evals/results/2026-10-05-ga-gate/summary.rescanned.json +1037 -0
  219. package/evals/results/README.md +31 -0
  220. package/evals/runs-pilot.log +150 -0
  221. package/evals/runs-pilot2.log +150 -0
  222. package/evals/score.mjs +256 -0
  223. package/evals/setup.mjs +547 -0
  224. package/evals/tasks/node-tool/faulty/thin-accepts-exponent/meta.json +5 -0
  225. package/evals/tasks/node-tool/faulty/thin-accepts-exponent/src/index.ts +121 -0
  226. package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/meta.json +5 -0
  227. package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/src/index.ts +116 -0
  228. package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/meta.json +9 -0
  229. package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/src/index.ts +118 -0
  230. package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/meta.json +5 -0
  231. package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/src/index.ts +118 -0
  232. package/evals/tasks/node-tool/faulty/thin-ignores-root-key/meta.json +5 -0
  233. package/evals/tasks/node-tool/faulty/thin-ignores-root-key/src/index.ts +117 -0
  234. package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/meta.json +9 -0
  235. package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/src/index.ts +119 -0
  236. package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/meta.json +9 -0
  237. package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/src/index.ts +118 -0
  238. package/evals/tasks/node-tool/faulty/thin-number-amount/meta.json +10 -0
  239. package/evals/tasks/node-tool/faulty/thin-number-amount/src/index.ts +117 -0
  240. package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/meta.json +5 -0
  241. package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/src/index.ts +120 -0
  242. package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/meta.json +5 -0
  243. package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/src/index.ts +118 -0
  244. package/evals/tasks/node-tool/faulty/v3-retry-call-errors/meta.json +11 -0
  245. package/evals/tasks/node-tool/faulty/v3-retry-call-errors/src/index.ts +149 -0
  246. package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/meta.json +5 -0
  247. package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/src/index.ts +71 -0
  248. package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/meta.json +9 -0
  249. package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/src/index.ts +84 -0
  250. package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/meta.json +9 -0
  251. package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/src/index.ts +72 -0
  252. package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/meta.json +5 -0
  253. package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/src/index.ts +72 -0
  254. package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/meta.json +5 -0
  255. package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/src/index.ts +84 -0
  256. package/evals/tasks/node-tool/hidden/node-tool.test.ts +312 -0
  257. package/evals/tasks/node-tool/prompt.md +55 -0
  258. package/evals/tasks/node-tool/prompt.minimal.md +30 -0
  259. package/evals/tasks/node-tool/solutions/thin/reference/src/index.ts +118 -0
  260. package/evals/tasks/node-tool/solutions/thin/reference-module-scope/src/index.ts +145 -0
  261. package/evals/tasks/node-tool/solutions/thin-guide/reference/src/index.ts +118 -0
  262. package/evals/tasks/node-tool/solutions/thin-guide/reference-module-scope/src/index.ts +145 -0
  263. package/evals/tasks/node-tool/solutions/v3/reference/src/index.ts +140 -0
  264. package/evals/tasks/node-tool/solutions/v3/reference-module-scope/src/index.ts +153 -0
  265. package/evals/tasks/node-tool/solutions/v4/reference/src/index.ts +84 -0
  266. package/evals/tasks/node-tool/solutions/v4/reference-module-scope/src/index.ts +105 -0
  267. package/evals/tasks/node-tool/solutions/v4-proto/reference/src/index.ts +72 -0
  268. package/evals/tasks/node-tool/solutions/v4-proto/reference-module-scope/src/index.ts +87 -0
  269. package/evals/tasks/node-tool/starter/src/contract.ts +31 -0
  270. package/evals/tasks/node-tool/starter/src/index.ts +7 -0
  271. package/evals/tasks/node-tool/starter/test/smoke.test.ts +22 -0
  272. package/evals/tasks/node-tool/starter/tsconfig.json +17 -0
  273. package/evals/tasks/node-tool/task.json +63 -0
  274. package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/meta.json +5 -0
  275. package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/src/Wallet.tsx +216 -0
  276. package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/meta.json +5 -0
  277. package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/src/Wallet.tsx +212 -0
  278. package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/meta.json +5 -0
  279. package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/src/Wallet.tsx +210 -0
  280. package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/meta.json +8 -0
  281. package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/src/Wallet.tsx +213 -0
  282. package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/meta.json +9 -0
  283. package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/src/Wallet.tsx +213 -0
  284. package/evals/tasks/react-wallet/faulty/thin-number-balance/meta.json +5 -0
  285. package/evals/tasks/react-wallet/faulty/thin-number-balance/src/Wallet.tsx +213 -0
  286. package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/meta.json +5 -0
  287. package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/src/Wallet.tsx +254 -0
  288. package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/meta.json +5 -0
  289. package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/src/Wallet.tsx +215 -0
  290. package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/meta.json +5 -0
  291. package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/src/Wallet.tsx +214 -0
  292. package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/meta.json +5 -0
  293. package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/src/Wallet.tsx +224 -0
  294. package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/meta.json +12 -0
  295. package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/src/Wallet.tsx +225 -0
  296. package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/meta.json +11 -0
  297. package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/src/Wallet.tsx +182 -0
  298. package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/meta.json +5 -0
  299. package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/src/Wallet.tsx +160 -0
  300. package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/meta.json +5 -0
  301. package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/src/Wallet.tsx +166 -0
  302. package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/meta.json +5 -0
  303. package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/src/Wallet.tsx +161 -0
  304. package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/meta.json +5 -0
  305. package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/src/Wallet.tsx +163 -0
  306. package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/meta.json +12 -0
  307. package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/src/Wallet.tsx +162 -0
  308. package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/meta.json +5 -0
  309. package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/src/Wallet.tsx +163 -0
  310. package/evals/tasks/react-wallet/faulty/v4-retry-spread/meta.json +12 -0
  311. package/evals/tasks/react-wallet/faulty/v4-retry-spread/src/Wallet.tsx +163 -0
  312. package/evals/tasks/react-wallet/faulty/v4-status-not-idle/meta.json +5 -0
  313. package/evals/tasks/react-wallet/faulty/v4-status-not-idle/src/Wallet.tsx +162 -0
  314. package/evals/tasks/react-wallet/hidden/react-wallet.test.ts +536 -0
  315. package/evals/tasks/react-wallet/prompt.md +88 -0
  316. package/evals/tasks/react-wallet/prompt.minimal.md +51 -0
  317. package/evals/tasks/react-wallet/solutions/thin/reference/src/Wallet.tsx +213 -0
  318. package/evals/tasks/react-wallet/solutions/thin/reference-module-scope/src/Wallet.tsx +227 -0
  319. package/evals/tasks/react-wallet/solutions/thin-guide/reference/src/Wallet.tsx +213 -0
  320. package/evals/tasks/react-wallet/solutions/thin-guide/reference-module-scope/src/Wallet.tsx +227 -0
  321. package/evals/tasks/react-wallet/solutions/v3/reference/src/Wallet.tsx +224 -0
  322. package/evals/tasks/react-wallet/solutions/v3/reference-module-scope/src/Wallet.tsx +230 -0
  323. package/evals/tasks/react-wallet/solutions/v4/reference/src/Wallet.tsx +160 -0
  324. package/evals/tasks/react-wallet/solutions/v4/reference-module-scope/src/Wallet.tsx +178 -0
  325. package/evals/tasks/react-wallet/solutions/v4-proto/reference/src/Wallet.tsx +161 -0
  326. package/evals/tasks/react-wallet/solutions/v4-proto/reference-module-scope/src/Wallet.tsx +161 -0
  327. package/evals/tasks/react-wallet/starter/src/Wallet.tsx +12 -0
  328. package/evals/tasks/react-wallet/starter/src/auth.ts +16 -0
  329. package/evals/tasks/react-wallet/starter/src/config.ts +14 -0
  330. package/evals/tasks/react-wallet/starter/src/ii-auth.ts +43 -0
  331. package/evals/tasks/react-wallet/starter/src/main.tsx +15 -0
  332. package/evals/tasks/react-wallet/starter/test/smoke.test.ts +34 -0
  333. package/evals/tasks/react-wallet/starter/tsconfig.json +18 -0
  334. package/evals/tasks/react-wallet/task.json +84 -0
  335. package/examples/canister-studio/.stackblitzrc +4 -0
  336. package/examples/canister-studio/README.md +183 -0
  337. package/examples/canister-studio/did/ckbtc_minter.did +806 -0
  338. package/examples/canister-studio/did/icp_ledger.did +586 -0
  339. package/examples/canister-studio/did/icrc1.did +88 -0
  340. package/examples/canister-studio/package.json +45 -0
  341. package/examples/canister-studio/scripts/smoke.ts +188 -0
  342. package/examples/canister-studio/src/calls/CacheKeyPanel.tsx +104 -0
  343. package/examples/canister-studio/src/calls/ConfirmWrite.tsx +265 -0
  344. package/examples/canister-studio/src/calls/ErrorPanel.test.tsx +113 -0
  345. package/examples/canister-studio/src/calls/ErrorPanel.tsx +214 -0
  346. package/examples/canister-studio/src/calls/MethodRunner.test.tsx +354 -0
  347. package/examples/canister-studio/src/calls/MethodRunner.tsx +57 -0
  348. package/examples/canister-studio/src/calls/ReadRunner.tsx +244 -0
  349. package/examples/canister-studio/src/calls/ResendPanel.tsx +165 -0
  350. package/examples/canister-studio/src/calls/ShareLink.tsx +59 -0
  351. package/examples/canister-studio/src/calls/WriteRunner.test.tsx +678 -0
  352. package/examples/canister-studio/src/calls/WriteRunner.tsx +670 -0
  353. package/examples/canister-studio/src/calls/dedupe.ts +189 -0
  354. package/examples/canister-studio/src/calls/error-info.ts +168 -0
  355. package/examples/canister-studio/src/calls/history.test.ts +284 -0
  356. package/examples/canister-studio/src/calls/history.ts +287 -0
  357. package/examples/canister-studio/src/calls/kinds.ts +68 -0
  358. package/examples/canister-studio/src/calls/prepare.ts +32 -0
  359. package/examples/canister-studio/src/calls/query-options.ts +30 -0
  360. package/examples/canister-studio/src/calls/read.ts +47 -0
  361. package/examples/canister-studio/src/calls/readback.ts +100 -0
  362. package/examples/canister-studio/src/calls/record.ts +123 -0
  363. package/examples/canister-studio/src/calls/safe-calls.test.ts +299 -0
  364. package/examples/canister-studio/src/calls/share.ts +46 -0
  365. package/examples/canister-studio/src/calls/testing/doubles.tsx +108 -0
  366. package/examples/canister-studio/src/calls/testing/fixtures.ts +185 -0
  367. package/examples/canister-studio/src/calls/useCanisterHandle.ts +35 -0
  368. package/examples/canister-studio/src/canisters/ckbtc_minter.envelope.json +4228 -0
  369. package/examples/canister-studio/src/canisters/ckbtc_minter.ts +868 -0
  370. package/examples/canister-studio/src/canisters/icp_ledger.envelope.json +3454 -0
  371. package/examples/canister-studio/src/canisters/icp_ledger.ts +584 -0
  372. package/examples/canister-studio/src/canisters/icrc1.envelope.json +840 -0
  373. package/examples/canister-studio/src/canisters/icrc1.ts +78 -0
  374. package/examples/canister-studio/src/components/ActionButton.tsx +32 -0
  375. package/examples/canister-studio/src/components/AppHeader.tsx +83 -0
  376. package/examples/canister-studio/src/components/AppShell.tsx +29 -0
  377. package/examples/canister-studio/src/components/AuthButton.tsx +79 -0
  378. package/examples/canister-studio/src/components/Badge.tsx +79 -0
  379. package/examples/canister-studio/src/components/CanisterHeader.tsx +200 -0
  380. package/examples/canister-studio/src/components/CanisterJump.tsx +130 -0
  381. package/examples/canister-studio/src/components/Card.tsx +64 -0
  382. package/examples/canister-studio/src/components/Code.tsx +101 -0
  383. package/examples/canister-studio/src/components/CopyButton.tsx +126 -0
  384. package/examples/canister-studio/src/components/Disclosure.tsx +34 -0
  385. package/examples/canister-studio/src/components/EmptyState.tsx +34 -0
  386. package/examples/canister-studio/src/components/MethodList.test.tsx +137 -0
  387. package/examples/canister-studio/src/components/MethodList.tsx +244 -0
  388. package/examples/canister-studio/src/components/Notice.tsx +36 -0
  389. package/examples/canister-studio/src/components/ProvenanceBadge.tsx +44 -0
  390. package/examples/canister-studio/src/components/RouteError.tsx +42 -0
  391. package/examples/canister-studio/src/components/SectionBoundary.tsx +76 -0
  392. package/examples/canister-studio/src/components/Spinner.tsx +33 -0
  393. package/examples/canister-studio/src/components/Tabs.tsx +96 -0
  394. package/examples/canister-studio/src/components/canister/CanisterLoadFailure.test.tsx +56 -0
  395. package/examples/canister-studio/src/components/canister/CanisterLoadFailure.tsx +165 -0
  396. package/examples/canister-studio/src/components/canister/CanisterNotFound.tsx +59 -0
  397. package/examples/canister-studio/src/components/canister/CanisterPending.tsx +33 -0
  398. package/examples/canister-studio/src/components/canister/MethodOverview.tsx +93 -0
  399. package/examples/canister-studio/src/components/canister/MethodWorkspace.test.tsx +201 -0
  400. package/examples/canister-studio/src/components/canister/MethodWorkspace.tsx +187 -0
  401. package/examples/canister-studio/src/components/canister/shared-call.test.ts +186 -0
  402. package/examples/canister-studio/src/components/canister/shared-call.ts +133 -0
  403. package/examples/canister-studio/src/components/canister/shared-link-loader.test.ts +116 -0
  404. package/examples/canister-studio/src/components/canister/use-canister-page.ts +44 -0
  405. package/examples/canister-studio/src/components/canister/workspace-key.test.ts +27 -0
  406. package/examples/canister-studio/src/components/canister/workspace-key.ts +36 -0
  407. package/examples/canister-studio/src/components/canister-id-input.ts +69 -0
  408. package/examples/canister-studio/src/components/canister-names.ts +11 -0
  409. package/examples/canister-studio/src/components/download.ts +34 -0
  410. package/examples/canister-studio/src/components/fallbacks.tsx +33 -0
  411. package/examples/canister-studio/src/components/helpers.test.ts +107 -0
  412. package/examples/canister-studio/src/components/history/HistoryList.tsx +284 -0
  413. package/examples/canister-studio/src/components/home/FeaturedLedger.tsx +149 -0
  414. package/examples/canister-studio/src/components/home/OpenCanister.tsx +99 -0
  415. package/examples/canister-studio/src/components/home/featured.test.tsx +92 -0
  416. package/examples/canister-studio/src/components/home/featured.ts +64 -0
  417. package/examples/canister-studio/src/components/interface/CandidTab.tsx +38 -0
  418. package/examples/canister-studio/src/components/interface/CompatReport.tsx +92 -0
  419. package/examples/canister-studio/src/components/interface/CompatibilityTab.tsx +190 -0
  420. package/examples/canister-studio/src/components/interface/ProjectTab.tsx +196 -0
  421. package/examples/canister-studio/src/components/interface/TypeScriptTab.tsx +114 -0
  422. package/examples/canister-studio/src/components/interface/tools.test.tsx +169 -0
  423. package/examples/canister-studio/src/components/modes.ts +31 -0
  424. package/examples/canister-studio/src/components/playground/MethodPicker.tsx +67 -0
  425. package/examples/canister-studio/src/components/playground/PlaygroundForms.tsx +112 -0
  426. package/examples/canister-studio/src/components/playground/PlaygroundTools.tsx +219 -0
  427. package/examples/canister-studio/src/components/playground/sample.ts +43 -0
  428. package/examples/canister-studio/src/components/playground/target.test.tsx +86 -0
  429. package/examples/canister-studio/src/components/primitives.test.tsx +121 -0
  430. package/examples/canister-studio/src/components/provenance.ts +38 -0
  431. package/examples/canister-studio/src/components/route-render.test.tsx +71 -0
  432. package/examples/canister-studio/src/components/use-task.ts +56 -0
  433. package/examples/canister-studio/src/components/wallet/BalancePanel.tsx +110 -0
  434. package/examples/canister-studio/src/components/wallet/LedgerSummary.tsx +63 -0
  435. package/examples/canister-studio/src/components/wallet/MinterPanel.tsx +255 -0
  436. package/examples/canister-studio/src/components/wallet/SendPanel.test.tsx +297 -0
  437. package/examples/canister-studio/src/components/wallet/SendPanel.tsx +446 -0
  438. package/examples/canister-studio/src/components/wallet/ledgers.test.ts +36 -0
  439. package/examples/canister-studio/src/components/wallet/ledgers.ts +111 -0
  440. package/examples/canister-studio/src/forms/JsonPanel.tsx +157 -0
  441. package/examples/canister-studio/src/forms/MethodForm.test.tsx +369 -0
  442. package/examples/canister-studio/src/forms/MethodForm.tsx +368 -0
  443. package/examples/canister-studio/src/forms/TypedForm.tsx +55 -0
  444. package/examples/canister-studio/src/forms/context.ts +62 -0
  445. package/examples/canister-studio/src/forms/convert.ts +131 -0
  446. package/examples/canister-studio/src/forms/edge.test.ts +252 -0
  447. package/examples/canister-studio/src/forms/engine.test.ts +358 -0
  448. package/examples/canister-studio/src/forms/engine.ts +1492 -0
  449. package/examples/canister-studio/src/forms/fields/BytesField.tsx +210 -0
  450. package/examples/canister-studio/src/forms/fields/Field.tsx +106 -0
  451. package/examples/canister-studio/src/forms/fields/FieldShell.tsx +101 -0
  452. package/examples/canister-studio/src/forms/fields/Group.tsx +74 -0
  453. package/examples/canister-studio/src/forms/fields/ListField.tsx +256 -0
  454. package/examples/canister-studio/src/forms/fields/Segmented.tsx +78 -0
  455. package/examples/canister-studio/src/forms/fields/TimestampField.tsx +108 -0
  456. package/examples/canister-studio/src/forms/fields/UnitsField.tsx +119 -0
  457. package/examples/canister-studio/src/forms/fields/composites.tsx +389 -0
  458. package/examples/canister-studio/src/forms/fields/leaves.tsx +350 -0
  459. package/examples/canister-studio/src/forms/fields.test.tsx +396 -0
  460. package/examples/canister-studio/src/forms/helpers.test.ts +225 -0
  461. package/examples/canister-studio/src/forms/hints.ts +128 -0
  462. package/examples/canister-studio/src/forms/json.ts +119 -0
  463. package/examples/canister-studio/src/forms/parsing.test.ts +217 -0
  464. package/examples/canister-studio/src/forms/useMethodForm.ts +251 -0
  465. package/examples/canister-studio/src/interface/browser.test.ts +23 -0
  466. package/examples/canister-studio/src/interface/browser.ts +153 -0
  467. package/examples/canister-studio/src/interface/cache.ts +68 -0
  468. package/examples/canister-studio/src/interface/cli-cache.test.ts +155 -0
  469. package/examples/canister-studio/src/interface/cli-cache.ts +125 -0
  470. package/examples/canister-studio/src/interface/compile.server.test.ts +198 -0
  471. package/examples/canister-studio/src/interface/compile.server.ts +262 -0
  472. package/examples/canister-studio/src/interface/compile.test.ts +108 -0
  473. package/examples/canister-studio/src/interface/compile.ts +305 -0
  474. package/examples/canister-studio/src/interface/docs.test.ts +75 -0
  475. package/examples/canister-studio/src/interface/docs.ts +100 -0
  476. package/examples/canister-studio/src/interface/functions.test.ts +42 -0
  477. package/examples/canister-studio/src/interface/functions.ts +200 -0
  478. package/examples/canister-studio/src/interface/live-candid.server.ts +91 -0
  479. package/examples/canister-studio/src/interface/live-loader.test.ts +515 -0
  480. package/examples/canister-studio/src/interface/live-loader.ts +364 -0
  481. package/examples/canister-studio/src/interface/load.test.ts +328 -0
  482. package/examples/canister-studio/src/interface/load.ts +249 -0
  483. package/examples/canister-studio/src/interface/read-candid.test.ts +185 -0
  484. package/examples/canister-studio/src/interface/read-candid.ts +233 -0
  485. package/examples/canister-studio/src/interface/server-result.ts +42 -0
  486. package/examples/canister-studio/src/interface/typed.ts +68 -0
  487. package/examples/canister-studio/src/interface/types.ts +121 -0
  488. package/examples/canister-studio/src/lib/format.test.ts +107 -0
  489. package/examples/canister-studio/src/lib/format.ts +139 -0
  490. package/examples/canister-studio/src/lib/hex.test.ts +43 -0
  491. package/examples/canister-studio/src/lib/hex.ts +33 -0
  492. package/examples/canister-studio/src/lib/ids.test.ts +70 -0
  493. package/examples/canister-studio/src/lib/ids.ts +93 -0
  494. package/examples/canister-studio/src/lib/reactor.test.ts +55 -0
  495. package/examples/canister-studio/src/lib/reactor.ts +55 -0
  496. package/examples/canister-studio/src/lib/registry.test.ts +74 -0
  497. package/examples/canister-studio/src/lib/registry.ts +238 -0
  498. package/examples/canister-studio/src/lib/schema.ts +148 -0
  499. package/examples/canister-studio/src/routeTree.gen.ts +227 -0
  500. package/examples/canister-studio/src/router.test.ts +290 -0
  501. package/examples/canister-studio/src/router.tsx +127 -0
  502. package/examples/canister-studio/src/routes/__root.tsx +58 -0
  503. package/examples/canister-studio/src/routes/canister.$canisterId.index.tsx +172 -0
  504. package/examples/canister-studio/src/routes/canister.$canisterId.interface.tsx +98 -0
  505. package/examples/canister-studio/src/routes/canister.$canisterId.tsx +91 -0
  506. package/examples/canister-studio/src/routes/history.tsx +55 -0
  507. package/examples/canister-studio/src/routes/index.tsx +169 -0
  508. package/examples/canister-studio/src/routes/playground.tsx +286 -0
  509. package/examples/canister-studio/src/routes/safety.tsx +57 -0
  510. package/examples/canister-studio/src/routes/wallet.tsx +213 -0
  511. package/examples/canister-studio/src/safety/LabTransferForm.tsx +84 -0
  512. package/examples/canister-studio/src/safety/RequestLog.tsx +79 -0
  513. package/examples/canister-studio/src/safety/SafetyLab.test.tsx +89 -0
  514. package/examples/canister-studio/src/safety/SafetyLab.tsx +140 -0
  515. package/examples/canister-studio/src/safety/ScenarioCard.tsx +262 -0
  516. package/examples/canister-studio/src/safety/lab-run.ts +283 -0
  517. package/examples/canister-studio/src/safety/mock-ledger.test.ts +99 -0
  518. package/examples/canister-studio/src/safety/mock-ledger.ts +263 -0
  519. package/examples/canister-studio/src/safety/scenarios.test.ts +157 -0
  520. package/examples/canister-studio/src/safety/scenarios.ts +924 -0
  521. package/examples/canister-studio/src/styles.css +3453 -0
  522. package/examples/canister-studio/src/styles.test.ts +46 -0
  523. package/examples/canister-studio/src/values/CallPreview.test.tsx +86 -0
  524. package/examples/canister-studio/src/values/CallPreview.tsx +148 -0
  525. package/examples/canister-studio/src/values/ErrValueView.tsx +66 -0
  526. package/examples/canister-studio/src/values/Inspector.tsx +133 -0
  527. package/examples/canister-studio/src/values/ReplyView.test.tsx +341 -0
  528. package/examples/canister-studio/src/values/ReplyView.tsx +164 -0
  529. package/examples/canister-studio/src/values/candid-text.test.ts +516 -0
  530. package/examples/canister-studio/src/values/candid-text.ts +479 -0
  531. package/examples/canister-studio/src/values/hints.ts +58 -0
  532. package/examples/canister-studio/src/values/json.test.ts +66 -0
  533. package/examples/canister-studio/src/values/json.ts +31 -0
  534. package/examples/canister-studio/src/values/leaves.tsx +309 -0
  535. package/examples/canister-studio/src/values/schema.test.ts +123 -0
  536. package/examples/canister-studio/src/values/schema.ts +78 -0
  537. package/examples/canister-studio/src/values/test-router.tsx +21 -0
  538. package/examples/canister-studio/src/values/tree.tsx +670 -0
  539. package/examples/canister-studio/src/values/use-sha256.ts +29 -0
  540. package/examples/canister-studio/tsconfig.json +20 -0
  541. package/examples/canister-studio/vite.config.ts +50 -0
  542. package/examples/canister-studio/vitest.config.ts +20 -0
  543. package/examples/icrc-ledger/.stackblitzrc +4 -0
  544. package/examples/icrc-ledger/README.md +100 -0
  545. package/examples/icrc-ledger/ckbtc_minter.did +12 -0
  546. package/examples/icrc-ledger/icp_ledger.did +147 -0
  547. package/examples/icrc-ledger/icrc1.did +88 -0
  548. package/examples/icrc-ledger/index.html +13 -0
  549. package/examples/icrc-ledger/package.json +40 -0
  550. package/examples/icrc-ledger/scripts/smoke.ts +151 -0
  551. package/examples/icrc-ledger/src/App.tsx +71 -0
  552. package/examples/icrc-ledger/src/ErrorPanel.tsx +105 -0
  553. package/examples/icrc-ledger/src/MainnetTab.tsx +450 -0
  554. package/examples/icrc-ledger/src/SandboxTab.test.tsx +379 -0
  555. package/examples/icrc-ledger/src/SandboxTab.tsx +761 -0
  556. package/examples/icrc-ledger/src/blocks.test.ts +247 -0
  557. package/examples/icrc-ledger/src/blocks.ts +140 -0
  558. package/examples/icrc-ledger/src/canisters/ckbtc_minter.envelope.json +96 -0
  559. package/examples/icrc-ledger/src/canisters/ckbtc_minter.ts +16 -0
  560. package/examples/icrc-ledger/src/canisters/icp_ledger.envelope.json +690 -0
  561. package/examples/icrc-ledger/src/canisters/icp_ledger.ts +223 -0
  562. package/examples/icrc-ledger/src/canisters/icrc1.envelope.json +840 -0
  563. package/examples/icrc-ledger/src/canisters/icrc1.ts +78 -0
  564. package/examples/icrc-ledger/src/format.test.ts +41 -0
  565. package/examples/icrc-ledger/src/format.ts +68 -0
  566. package/examples/icrc-ledger/src/ledger.ts +15 -0
  567. package/examples/icrc-ledger/src/main.tsx +10 -0
  568. package/examples/icrc-ledger/src/minter.ts +16 -0
  569. package/examples/icrc-ledger/src/sandbox.test.ts +464 -0
  570. package/examples/icrc-ledger/src/sandbox.ts +281 -0
  571. package/examples/icrc-ledger/src/styles.css +391 -0
  572. package/examples/icrc-ledger/src/transfer-form.test.ts +62 -0
  573. package/examples/icrc-ledger/src/transfer-form.ts +97 -0
  574. package/examples/icrc-ledger/tsconfig.json +19 -0
  575. package/examples/icrc-ledger/vite.config.ts +44 -0
  576. package/examples/icrc-ledger/vitest.config.ts +12 -0
  577. package/examples/next-ssr/.stackblitzrc +4 -0
  578. package/examples/next-ssr/README.md +112 -0
  579. package/examples/next-ssr/icrc1.did +88 -0
  580. package/examples/next-ssr/next.config.ts +10 -0
  581. package/examples/next-ssr/package.json +41 -0
  582. package/examples/next-ssr/scripts/smoke.ts +169 -0
  583. package/examples/next-ssr/src/app/account/CertifiedBalances.tsx +58 -0
  584. package/examples/next-ssr/src/app/account/account.test.tsx +165 -0
  585. package/examples/next-ssr/src/app/account/page.tsx +82 -0
  586. package/examples/next-ssr/src/app/api/balance/[ledger]/[principal]/route.ts +10 -0
  587. package/examples/next-ssr/src/app/globals.css +278 -0
  588. package/examples/next-ssr/src/app/layout.tsx +34 -0
  589. package/examples/next-ssr/src/app/page.tsx +46 -0
  590. package/examples/next-ssr/src/app/providers.browser.test.tsx +127 -0
  591. package/examples/next-ssr/src/app/providers.test.tsx +73 -0
  592. package/examples/next-ssr/src/app/providers.tsx +60 -0
  593. package/examples/next-ssr/src/canisters/icrc1.envelope.json +840 -0
  594. package/examples/next-ssr/src/canisters/icrc1.ts +78 -0
  595. package/examples/next-ssr/src/components/BalanceTable.tsx +43 -0
  596. package/examples/next-ssr/src/components/LedgerCard.test.tsx +96 -0
  597. package/examples/next-ssr/src/components/LedgerCard.tsx +230 -0
  598. package/examples/next-ssr/src/components/LedgerError.tsx +32 -0
  599. package/examples/next-ssr/src/components/LedgerSections.tsx +22 -0
  600. package/examples/next-ssr/src/components/MyBalances.test.tsx +253 -0
  601. package/examples/next-ssr/src/components/MyBalances.tsx +129 -0
  602. package/examples/next-ssr/src/components/SessionBadge.tsx +18 -0
  603. package/examples/next-ssr/src/components/hydration.test.tsx +259 -0
  604. package/examples/next-ssr/src/components/server-data.ts +10 -0
  605. package/examples/next-ssr/src/format.ts +46 -0
  606. package/examples/next-ssr/src/ledgers.ts +38 -0
  607. package/examples/next-ssr/src/server/balance-route.test.ts +151 -0
  608. package/examples/next-ssr/src/server/balance-route.ts +157 -0
  609. package/examples/next-ssr/src/server/error-summary.test.ts +34 -0
  610. package/examples/next-ssr/src/server/error-summary.ts +37 -0
  611. package/examples/next-ssr/src/server/parse-owner.test.ts +39 -0
  612. package/examples/next-ssr/src/server/parse-owner.ts +34 -0
  613. package/examples/next-ssr/src/server/prefetch-ledgers.test.ts +137 -0
  614. package/examples/next-ssr/src/server/prefetch-ledgers.ts +70 -0
  615. package/examples/next-ssr/src/server/read-balances.test.ts +103 -0
  616. package/examples/next-ssr/src/server/read-balances.ts +78 -0
  617. package/examples/next-ssr/src/server/request-client.rsc.test.tsx +110 -0
  618. package/examples/next-ssr/src/server/request-client.ts +24 -0
  619. package/examples/next-ssr/src/testing/mock-ledgers.ts +115 -0
  620. package/examples/next-ssr/src/testing/react-server-dom-turbopack.d.ts +15 -0
  621. package/examples/next-ssr/src/testing/setup.ts +10 -0
  622. package/examples/next-ssr/tsconfig.json +31 -0
  623. package/examples/next-ssr/vitest.config.ts +59 -0
  624. package/examples/node-agent-tool/.stackblitzrc +4 -0
  625. package/examples/node-agent-tool/README.md +165 -0
  626. package/examples/node-agent-tool/icp.yaml +11 -0
  627. package/examples/node-agent-tool/icrc1.did +88 -0
  628. package/examples/node-agent-tool/package.json +32 -0
  629. package/examples/node-agent-tool/src/canisters/icrc1.envelope.json +840 -0
  630. package/examples/node-agent-tool/src/canisters/icrc1.ts +78 -0
  631. package/examples/node-agent-tool/src/cli.test.ts +64 -0
  632. package/examples/node-agent-tool/src/cli.ts +23 -0
  633. package/examples/node-agent-tool/src/command-line.ts +159 -0
  634. package/examples/node-agent-tool/src/commands/balance.ts +73 -0
  635. package/examples/node-agent-tool/src/commands/demo.test.ts +51 -0
  636. package/examples/node-agent-tool/src/commands/demo.ts +359 -0
  637. package/examples/node-agent-tool/src/commands/info.ts +69 -0
  638. package/examples/node-agent-tool/src/commands/reads.test.ts +133 -0
  639. package/examples/node-agent-tool/src/commands/resend.test.ts +363 -0
  640. package/examples/node-agent-tool/src/commands/transfer.test.ts +313 -0
  641. package/examples/node-agent-tool/src/commands/transfer.ts +415 -0
  642. package/examples/node-agent-tool/src/commands/watch.test.ts +159 -0
  643. package/examples/node-agent-tool/src/commands/watch.ts +135 -0
  644. package/examples/node-agent-tool/src/commands/whoami.ts +36 -0
  645. package/examples/node-agent-tool/src/context.ts +20 -0
  646. package/examples/node-agent-tool/src/dispatch.ts +70 -0
  647. package/examples/node-agent-tool/src/failure.test.ts +59 -0
  648. package/examples/node-agent-tool/src/failure.ts +176 -0
  649. package/examples/node-agent-tool/src/identity.test.ts +242 -0
  650. package/examples/node-agent-tool/src/identity.ts +228 -0
  651. package/examples/node-agent-tool/src/input.ts +110 -0
  652. package/examples/node-agent-tool/src/ledgers.test.ts +74 -0
  653. package/examples/node-agent-tool/src/ledgers.ts +62 -0
  654. package/examples/node-agent-tool/src/mock-ledger.ts +211 -0
  655. package/examples/node-agent-tool/src/network.test.ts +128 -0
  656. package/examples/node-agent-tool/src/network.ts +101 -0
  657. package/examples/node-agent-tool/src/output.test.ts +208 -0
  658. package/examples/node-agent-tool/src/output.ts +163 -0
  659. package/examples/node-agent-tool/src/run.ts +73 -0
  660. package/examples/node-agent-tool/src/test-kit.ts +167 -0
  661. package/examples/node-agent-tool/tsconfig.json +18 -0
  662. package/examples/node-agent-tool/vitest.config.ts +8 -0
  663. package/examples/vite-wallet/.stackblitzrc +4 -0
  664. package/examples/vite-wallet/Cargo.lock +646 -0
  665. package/examples/vite-wallet/Cargo.toml +5 -0
  666. package/examples/vite-wallet/README.md +107 -0
  667. package/examples/vite-wallet/backend/Cargo.toml +12 -0
  668. package/examples/vite-wallet/backend/backend.did +37 -0
  669. package/examples/vite-wallet/backend/src/lib.rs +133 -0
  670. package/examples/vite-wallet/icp.yaml +44 -0
  671. package/examples/vite-wallet/index.html +13 -0
  672. package/examples/vite-wallet/ledger.did +54 -0
  673. package/examples/vite-wallet/package.json +46 -0
  674. package/examples/vite-wallet/public/.ic-assets.json5 +26 -0
  675. package/examples/vite-wallet/scripts/faucet-args.test.ts +30 -0
  676. package/examples/vite-wallet/scripts/faucet-args.ts +41 -0
  677. package/examples/vite-wallet/scripts/faucet.ts +41 -0
  678. package/examples/vite-wallet/src/AddressBook.test.tsx +191 -0
  679. package/examples/vite-wallet/src/AddressBook.tsx +147 -0
  680. package/examples/vite-wallet/src/App.tsx +53 -0
  681. package/examples/vite-wallet/src/Balance.test.tsx +57 -0
  682. package/examples/vite-wallet/src/Balance.tsx +58 -0
  683. package/examples/vite-wallet/src/EnvironmentPanel.test.tsx +83 -0
  684. package/examples/vite-wallet/src/EnvironmentPanel.tsx +103 -0
  685. package/examples/vite-wallet/src/ErrorNote.tsx +70 -0
  686. package/examples/vite-wallet/src/Profile.test.tsx +145 -0
  687. package/examples/vite-wallet/src/Profile.tsx +92 -0
  688. package/examples/vite-wallet/src/SendIcp.test.tsx +231 -0
  689. package/examples/vite-wallet/src/SendIcp.tsx +244 -0
  690. package/examples/vite-wallet/src/SendToContact.test.tsx +113 -0
  691. package/examples/vite-wallet/src/SendToContact.tsx +102 -0
  692. package/examples/vite-wallet/src/SignIn.test.tsx +106 -0
  693. package/examples/vite-wallet/src/SignIn.tsx +120 -0
  694. package/examples/vite-wallet/src/Wallet.test.tsx +89 -0
  695. package/examples/vite-wallet/src/account-switch.test.tsx +108 -0
  696. package/examples/vite-wallet/src/auth/dev-accounts.test.ts +113 -0
  697. package/examples/vite-wallet/src/auth/dev-accounts.ts +216 -0
  698. package/examples/vite-wallet/src/auth/local-page.test.ts +28 -0
  699. package/examples/vite-wallet/src/auth/local-page.ts +20 -0
  700. package/examples/vite-wallet/src/auth/wallet-auth.test.ts +159 -0
  701. package/examples/vite-wallet/src/auth/wallet-auth.ts +131 -0
  702. package/examples/vite-wallet/src/canisters/backend.envelope.json +275 -0
  703. package/examples/vite-wallet/src/canisters/backend.ts +58 -0
  704. package/examples/vite-wallet/src/canisters/ledger.envelope.json +451 -0
  705. package/examples/vite-wallet/src/canisters/ledger.ts +56 -0
  706. package/examples/vite-wallet/src/client.ts +45 -0
  707. package/examples/vite-wallet/src/main.tsx +18 -0
  708. package/examples/vite-wallet/src/optimistic-contacts.ts +113 -0
  709. package/examples/vite-wallet/src/refusal.ts +17 -0
  710. package/examples/vite-wallet/src/styles.css +282 -0
  711. package/examples/vite-wallet/src/test/test-wallet.tsx +322 -0
  712. package/examples/vite-wallet/src/token.ts +50 -0
  713. package/examples/vite-wallet/src/transfer.test.ts +178 -0
  714. package/examples/vite-wallet/src/transfer.ts +110 -0
  715. package/examples/vite-wallet/src/use-canisters.ts +49 -0
  716. package/examples/vite-wallet/tsconfig.json +19 -0
  717. package/examples/vite-wallet/vite.config.ts +47 -0
  718. package/examples/vite-wallet/vitest.config.ts +17 -0
  719. package/package.json +9 -4
  720. package/packages/core/.size-limit.js +47 -0
  721. package/packages/core/LICENSE +21 -0
  722. package/packages/core/README.md +84 -0
  723. package/packages/core/llms.txt +610 -0
  724. package/packages/core/package.json +89 -0
  725. package/packages/core/src/call.ts +961 -0
  726. package/packages/core/src/canister.ts +259 -0
  727. package/packages/core/src/client.ts +2061 -0
  728. package/packages/core/src/errors.ts +1079 -0
  729. package/packages/core/src/hydration.ts +239 -0
  730. package/packages/core/src/index.ts +23 -0
  731. package/packages/core/src/keys.ts +108 -0
  732. package/packages/core/src/management.ts +138 -0
  733. package/packages/core/src/network.ts +1020 -0
  734. package/packages/core/src/options.ts +1000 -0
  735. package/packages/core/src/runtime.ts +50 -0
  736. package/packages/core/src/testing/fake-replica.ts +1166 -0
  737. package/packages/core/src/testing/index.ts +16 -0
  738. package/packages/core/src/testing/test-auth.ts +340 -0
  739. package/packages/core/src/testing/test-client.ts +559 -0
  740. package/packages/core/src/types.ts +541 -0
  741. package/packages/core/src/units.ts +299 -0
  742. package/packages/core/src/version.ts +4 -0
  743. package/packages/core/tests/canister-helpers.ts +187 -0
  744. package/packages/core/tests/canister-id.test.ts +158 -0
  745. package/packages/core/tests/canister-unwrap.test.ts +94 -0
  746. package/packages/core/tests/canister.test-d.ts +406 -0
  747. package/packages/core/tests/canister.test.ts +1921 -0
  748. package/packages/core/tests/client-account-change.test.ts +131 -0
  749. package/packages/core/tests/client-agents.test.ts +402 -0
  750. package/packages/core/tests/client-auth-network.test.ts +719 -0
  751. package/packages/core/tests/client-disposed.test.ts +403 -0
  752. package/packages/core/tests/client-helpers.ts +136 -0
  753. package/packages/core/tests/client-hydration.test.ts +166 -0
  754. package/packages/core/tests/client-pinned.test.ts +626 -0
  755. package/packages/core/tests/client-session.test.ts +348 -0
  756. package/packages/core/tests/client.test-d.ts +181 -0
  757. package/packages/core/tests/client.test.ts +1162 -0
  758. package/packages/core/tests/encode.test.ts +171 -0
  759. package/packages/core/tests/env-canister-id.test.ts +666 -0
  760. package/packages/core/tests/env-cookie-copies.test.ts +182 -0
  761. package/packages/core/tests/error-guard.test.ts +222 -0
  762. package/packages/core/tests/errors.test-d.ts +280 -0
  763. package/packages/core/tests/errors.test.ts +1359 -0
  764. package/packages/core/tests/fixtures/README.md +28 -0
  765. package/packages/core/tests/fixtures/accounts.did +21 -0
  766. package/packages/core/tests/fixtures/accounts.envelope.json +367 -0
  767. package/packages/core/tests/fixtures/accounts.ts +26 -0
  768. package/packages/core/tests/fixtures/archive.did +31 -0
  769. package/packages/core/tests/fixtures/archive.envelope.json +259 -0
  770. package/packages/core/tests/fixtures/archive.ts +55 -0
  771. package/packages/core/tests/fixtures/icrc1.did +88 -0
  772. package/packages/core/tests/fixtures/icrc1.envelope.json +840 -0
  773. package/packages/core/tests/fixtures/icrc1.ts +78 -0
  774. package/packages/core/tests/fixtures/management.did +724 -0
  775. package/packages/core/tests/fixtures/management.envelope.json +4455 -0
  776. package/packages/core/tests/fixtures/management.ts +486 -0
  777. package/packages/core/tests/fixtures/shapes.did +33 -0
  778. package/packages/core/tests/fixtures/shapes.envelope.json +440 -0
  779. package/packages/core/tests/fixtures/shapes.ts +56 -0
  780. package/packages/core/tests/fixtures/skippable.did +15 -0
  781. package/packages/core/tests/fixtures/skippable.envelope.json +182 -0
  782. package/packages/core/tests/fixtures/skippable.ts +33 -0
  783. package/packages/core/tests/func.test.ts +154 -0
  784. package/packages/core/tests/identity-attributes.test.ts +214 -0
  785. package/packages/core/tests/keys.test.ts +289 -0
  786. package/packages/core/tests/management.test.ts +206 -0
  787. package/packages/core/tests/network-helpers.ts +121 -0
  788. package/packages/core/tests/network.test-d.ts +78 -0
  789. package/packages/core/tests/network.test.ts +1051 -0
  790. package/packages/core/tests/options.test.ts +1594 -0
  791. package/packages/core/tests/redirect-sign-in.test.ts +393 -0
  792. package/packages/core/tests/resend.test-d.ts +81 -0
  793. package/packages/core/tests/resend.test.ts +723 -0
  794. package/packages/core/tests/skip.test-d.ts +125 -0
  795. package/packages/core/tests/testing-entry.test.ts +73 -0
  796. package/packages/core/tests/testing-fake-replica.test.ts +1242 -0
  797. package/packages/core/tests/testing-test-auth.test-d.ts +84 -0
  798. package/packages/core/tests/testing-test-auth.test.ts +483 -0
  799. package/packages/core/tests/testing-test-client.test-d.ts +184 -0
  800. package/packages/core/tests/testing-test-client.test.ts +1272 -0
  801. package/packages/core/tests/time-realm.test.ts +63 -0
  802. package/packages/core/tests/time.test.ts +238 -0
  803. package/packages/core/tests/traps/README.md +39 -0
  804. package/packages/core/tests/traps/anonymous-write.test.ts +145 -0
  805. package/packages/core/tests/traps/classification-table.test.ts +256 -0
  806. package/packages/core/tests/traps/err-arm.test.ts +144 -0
  807. package/packages/core/tests/traps/fetch-spy.ts +39 -0
  808. package/packages/core/tests/traps/invalidation-after-write.test.ts +178 -0
  809. package/packages/core/tests/traps/ledger.ts +248 -0
  810. package/packages/core/tests/traps/root-key-off-local.test.ts +130 -0
  811. package/packages/core/tests/traps/stale-data-across-users.test.ts +173 -0
  812. package/packages/core/tests/traps/unresolved-name.test.ts +155 -0
  813. package/packages/core/tests/traps/update-as-query.test.ts +244 -0
  814. package/packages/core/tests/traps/update-not-resent.test.ts +126 -0
  815. package/packages/core/tests/traps/update-resent-when-never-delivered.test.ts +159 -0
  816. package/packages/core/tests/traps.test-d.ts +476 -0
  817. package/packages/core/tests/units.test-d.ts +118 -0
  818. package/packages/core/tests/units.test.ts +634 -0
  819. package/packages/core/tsconfig.json +19 -0
  820. package/packages/core/tsconfig.typecheck.json +16 -0
  821. package/packages/core/vitest.config.ts +13 -0
  822. package/packages/mcp/LICENSE +21 -0
  823. package/packages/mcp/README.md +189 -0
  824. package/packages/mcp/package.json +62 -0
  825. package/packages/mcp/src/candid/candid-text.test.ts +455 -0
  826. package/packages/mcp/src/candid/candid-text.ts +501 -0
  827. package/packages/mcp/src/candid/contract.test.ts +398 -0
  828. package/packages/mcp/src/candid/formats.ts +155 -0
  829. package/packages/mcp/src/candid/hex.ts +29 -0
  830. package/packages/mcp/src/candid/json-schema.test.ts +758 -0
  831. package/packages/mcp/src/candid/json-schema.ts +454 -0
  832. package/packages/mcp/src/candid/json.test.ts +1207 -0
  833. package/packages/mcp/src/candid/json.ts +1053 -0
  834. package/packages/mcp/src/candid/schema-walk.ts +189 -0
  835. package/packages/mcp/src/candid/type-text.test.ts +179 -0
  836. package/packages/mcp/src/candid/type-text.ts +238 -0
  837. package/packages/mcp/src/cli.ts +134 -0
  838. package/packages/mcp/src/identity.ts +188 -0
  839. package/packages/mcp/src/interface/cache.test.ts +48 -0
  840. package/packages/mcp/src/interface/cache.ts +68 -0
  841. package/packages/mcp/src/interface/cli-cache.test.ts +150 -0
  842. package/packages/mcp/src/interface/cli-cache.ts +122 -0
  843. package/packages/mcp/src/interface/compile-worker.test.ts +246 -0
  844. package/packages/mcp/src/interface/compile-worker.ts +290 -0
  845. package/packages/mcp/src/interface/compile.test.ts +155 -0
  846. package/packages/mcp/src/interface/compile.ts +281 -0
  847. package/packages/mcp/src/interface/docs.test.ts +105 -0
  848. package/packages/mcp/src/interface/docs.ts +86 -0
  849. package/packages/mcp/src/interface/fixtures/icrc1.did +88 -0
  850. package/packages/mcp/src/interface/hex.ts +8 -0
  851. package/packages/mcp/src/interface/ids.test.ts +71 -0
  852. package/packages/mcp/src/interface/ids.ts +87 -0
  853. package/packages/mcp/src/interface/loader.test.ts +804 -0
  854. package/packages/mcp/src/interface/loader.ts +519 -0
  855. package/packages/mcp/src/interface/read-candid.test.ts +300 -0
  856. package/packages/mcp/src/interface/read-candid.ts +259 -0
  857. package/packages/mcp/src/interface/types.ts +113 -0
  858. package/packages/mcp/src/network.ts +122 -0
  859. package/packages/mcp/src/options.ts +149 -0
  860. package/packages/mcp/src/server/approval.ts +159 -0
  861. package/packages/mcp/src/server/naming.ts +43 -0
  862. package/packages/mcp/src/server/results.ts +102 -0
  863. package/packages/mcp/src/server/server.ts +797 -0
  864. package/packages/mcp/src/server/tools.ts +116 -0
  865. package/packages/mcp/src/usage.ts +40 -0
  866. package/packages/mcp/tests/approval.test.ts +60 -0
  867. package/packages/mcp/tests/identity.test.ts +234 -0
  868. package/packages/mcp/tests/naming.test.ts +62 -0
  869. package/packages/mcp/tests/options.test.ts +140 -0
  870. package/packages/mcp/tests/server.test.ts +997 -0
  871. package/packages/mcp/tsconfig.json +19 -0
  872. package/packages/mcp/tsconfig.typecheck.json +10 -0
  873. package/packages/mcp/vitest.config.ts +10 -0
  874. package/packages/react/LICENSE +21 -0
  875. package/packages/react/README.md +328 -0
  876. package/packages/react/llms.txt +95 -0
  877. package/packages/react/package.json +95 -0
  878. package/packages/react/src/index.tsx +678 -0
  879. package/packages/react/tests/abandoned-render.test.tsx +816 -0
  880. package/packages/react/tests/auth.test.tsx +315 -0
  881. package/packages/react/tests/caller-keys.test.tsx +2334 -0
  882. package/packages/react/tests/client-time.test.ts +40 -0
  883. package/packages/react/tests/entry.test.ts +52 -0
  884. package/packages/react/tests/helpers.tsx +291 -0
  885. package/packages/react/tests/hydration.test.tsx +262 -0
  886. package/packages/react/tests/ownership.test.tsx +260 -0
  887. package/packages/react/tests/provider.server.test.tsx +169 -0
  888. package/packages/react/tests/query-client.test.tsx +107 -0
  889. package/packages/react/tests/strict-mode.test.tsx +288 -0
  890. package/packages/react/tests/suspense.test-d.tsx +357 -0
  891. package/packages/react/tests/two-query-cores.test.tsx +135 -0
  892. package/packages/react/tests/types.test-d.tsx +63 -0
  893. package/packages/react/tsconfig.json +23 -0
  894. package/packages/react/tsconfig.test.json +8 -0
  895. package/packages/react/tsconfig.typecheck.json +16 -0
  896. package/packages/react/vitest.config.ts +39 -0
  897. package/packages/vite-plugin/LICENSE +21 -0
  898. package/packages/vite-plugin/README.md +532 -0
  899. package/packages/vite-plugin/package.json +76 -0
  900. package/packages/vite-plugin/src/describe-value.test.ts +43 -0
  901. package/packages/vite-plugin/src/describe-value.ts +167 -0
  902. package/packages/vite-plugin/src/dev-environment.test.ts +747 -0
  903. package/packages/vite-plugin/src/dev-environment.ts +510 -0
  904. package/packages/vite-plugin/src/env.ts +431 -0
  905. package/packages/vite-plugin/src/fetch.ts +348 -0
  906. package/packages/vite-plugin/src/file-identity.ts +106 -0
  907. package/packages/vite-plugin/src/generate.ts +691 -0
  908. package/packages/vite-plugin/src/index.test.ts +1243 -0
  909. package/packages/vite-plugin/src/index.ts +2565 -0
  910. package/packages/vite-plugin/src/interface.ts +339 -0
  911. package/packages/vite-plugin/src/local-host.ts +34 -0
  912. package/packages/vite-plugin/src/options.ts +641 -0
  913. package/packages/vite-plugin/src/principal-text.test.ts +87 -0
  914. package/packages/vite-plugin/src/principal-text.ts +98 -0
  915. package/packages/vite-plugin/tests/close.test.ts +141 -0
  916. package/packages/vite-plugin/tests/environment-mode.test.ts +136 -0
  917. package/packages/vite-plugin/tests/fake-ic.ts +214 -0
  918. package/packages/vite-plugin/tests/fetch-sdk.test.ts +27 -0
  919. package/packages/vite-plugin/tests/fetch.test.ts +1196 -0
  920. package/packages/vite-plugin/tests/fixtures/fake-cli/bin.js +90 -0
  921. package/packages/vite-plugin/tests/fixtures/fake-cli/package.json +8 -0
  922. package/packages/vite-plugin/tests/fixtures/icrc1.did +88 -0
  923. package/packages/vite-plugin/tests/generation.test.ts +1036 -0
  924. package/packages/vite-plugin/tests/icp-command.test.ts +194 -0
  925. package/packages/vite-plugin/tests/icp-timeout.test.ts +83 -0
  926. package/packages/vite-plugin/tests/no-process-exit.test.ts +83 -0
  927. package/packages/vite-plugin/tests/on-generated.test.ts +323 -0
  928. package/packages/vite-plugin/tests/output-collision.test.ts +329 -0
  929. package/packages/vite-plugin/tests/package.test.ts +62 -0
  930. package/packages/vite-plugin/tests/project.test.ts +2993 -0
  931. package/packages/vite-plugin/tests/support.ts +339 -0
  932. package/packages/vite-plugin/tests/timeout.test.ts +107 -0
  933. package/packages/vite-plugin/tsconfig.json +23 -0
  934. package/packages/vite-plugin/tsconfig.typecheck.json +16 -0
  935. package/packages/vite-plugin/vitest.config.ts +9 -0
  936. package/pnpm-workspace.yaml +23 -0
  937. package/scripts/ai-context-files.js +72 -0
  938. package/scripts/assemble-docs-site.mjs +485 -0
  939. package/scripts/assemble-docs-site.test.mjs +568 -0
  940. package/scripts/build-examples.js +58 -0
  941. package/scripts/check-ai-context.js +963 -0
  942. package/scripts/check-ai-context.test.mjs +811 -0
  943. package/scripts/check-exports.mjs +767 -0
  944. package/scripts/check-exports.test.mjs +1136 -0
  945. package/scripts/check-snippets/ambient.d.ts +428 -0
  946. package/scripts/check-snippets/app/generated/backend.did +7 -0
  947. package/scripts/check-snippets/app/generated/backend.ts +15 -0
  948. package/scripts/check-snippets/app/generated/icrc1.did +88 -0
  949. package/scripts/check-snippets/app/generated/icrc1.ts +78 -0
  950. package/scripts/check-snippets/app/globals.ts +26 -0
  951. package/scripts/check-snippets/docs/guides/App.tsx +21 -0
  952. package/scripts/check-snippets/docs/guides/app/providers.tsx +23 -0
  953. package/scripts/check-snippets/docs/guides/auth-client.ts +47 -0
  954. package/scripts/check-snippets/docs/guides/canisters/backend.ts +3 -0
  955. package/scripts/check-snippets/docs/guides/canisters/icrc1.ts +3 -0
  956. package/scripts/check-snippets/docs/guides/components/LedgerCard.tsx +26 -0
  957. package/scripts/check-snippets/docs/guides/components/shell.tsx +11 -0
  958. package/scripts/check-snippets/docs/guides/components/sign-in-page.tsx +29 -0
  959. package/scripts/check-snippets/docs/guides/components/slow-section.tsx +5 -0
  960. package/scripts/check-snippets/docs/guides/generated/accounts.ts +95 -0
  961. package/scripts/check-snippets/docs/guides/generated/ckbtc_minter.ts +40 -0
  962. package/scripts/check-snippets/docs/guides/generated/icp_ledger.ts +267 -0
  963. package/scripts/check-snippets/docs/guides/ledger.ts +10 -0
  964. package/scripts/check-snippets/docs/guides/server/request-client.ts +8 -0
  965. package/scripts/check-snippets.mjs +993 -0
  966. package/scripts/check-snippets.test.mjs +338 -0
  967. package/scripts/check-stack.mjs +501 -0
  968. package/scripts/check-stack.test.mjs +800 -0
  969. package/scripts/clean-node-modules.js +67 -0
  970. package/scripts/example-projects.js +58 -0
  971. package/scripts/export-budget.mjs +145 -0
  972. package/scripts/faults.json +6749 -0
  973. package/scripts/lib/fault-workspace.mjs +210 -0
  974. package/scripts/lib/io.mjs +29 -0
  975. package/scripts/lib/io.test.mjs +38 -0
  976. package/scripts/lib/markdown-fences.mjs +56 -0
  977. package/scripts/lib/markdown-fences.test.mjs +84 -0
  978. package/scripts/lib/package-exports.mjs +54 -0
  979. package/scripts/lib/package-exports.test.mjs +66 -0
  980. package/scripts/lib/release-pr-steps.mjs +47 -0
  981. package/scripts/release-tag.mjs +95 -0
  982. package/scripts/release-tag.test.mjs +278 -0
  983. package/scripts/release-workflow.test.mjs +98 -0
  984. package/scripts/release.js +167 -0
  985. package/scripts/release.test.mjs +347 -0
  986. package/scripts/removed-v3-names.js +125 -0
  987. package/scripts/size-app/.size-limit.js +90 -0
  988. package/scripts/size-app/core.js +3 -0
  989. package/scripts/size-app/package.json +24 -0
  990. package/scripts/size-app/react.js +4 -0
  991. package/scripts/size-app.test.mjs +73 -0
  992. package/scripts/sync-ai-context-versions.js +102 -0
  993. package/scripts/sync-example-versions.js +151 -0
  994. package/scripts/test-examples-published.mjs +1585 -0
  995. package/scripts/test-examples-published.test.mjs +1586 -0
  996. package/scripts/traps/any-method-vars-not-a-list.json +5 -0
  997. package/scripts/traps/canister-method-unknown.json +5 -0
  998. package/scripts/traps/client-says-who-calls-once.json +5 -0
  999. package/scripts/traps/client-says-who-calls.json +5 -0
  1000. package/scripts/traps/err-only-on-canister-err.json +14 -0
  1001. package/scripts/traps/format-units-refuses-missing-value.json +5 -0
  1002. package/scripts/traps/format-units-refuses-number.json +5 -0
  1003. package/scripts/traps/format-units-unknown-option.json +5 -0
  1004. package/scripts/traps/guard-err-is-the-methods.json +5 -0
  1005. package/scripts/traps/guard-false-keeps-every-kind.json +5 -0
  1006. package/scripts/traps/internals-not-exported.json +9 -0
  1007. package/scripts/traps/network-refuses-unknown-name.json +5 -0
  1008. package/scripts/traps/never-err-has-no-type.json +5 -0
  1009. package/scripts/traps/options-method-unknown.json +5 -0
  1010. package/scripts/traps/options-vars-wrong-type.json +5 -0
  1011. package/scripts/traps/parse-units-refuses-number.json +5 -0
  1012. package/scripts/traps/parse-units-unknown-option.json +5 -0
  1013. package/scripts/traps/principal-is-not-plain-text.json +14 -0
  1014. package/scripts/traps/query-options-refuses-oneway.json +5 -0
  1015. package/scripts/traps/query-options-refuses-update.json +5 -0
  1016. package/scripts/traps/refuse-next-unknown-option.json +5 -0
  1017. package/scripts/traps/resend-key-reads-the-methods-arg.json +5 -0
  1018. package/scripts/traps/resend-states-its-dedupe-key.json +5 -0
  1019. package/scripts/traps/suspense-refuses-argument-skip.json +5 -0
  1020. package/scripts/traps/suspense-refuses-skippable-read.json +5 -0
  1021. package/scripts/traps/suspense-refuses-vars-skip-fits.json +5 -0
  1022. package/scripts/traps/test-handler-method-unknown.json +5 -0
  1023. package/scripts/traps/test-handler-nat-is-bigint.json +5 -0
  1024. package/scripts/traps/test-handler-takes-the-domain-value.json +5 -0
  1025. package/scripts/traps/vars-of-two-arguments-are-the-tuple.json +5 -0
  1026. package/scripts/typecheck-examples.js +122 -0
  1027. package/scripts/verify-faults.mjs +375 -0
  1028. package/scripts/verify-faults.test.mjs +402 -0
  1029. package/scripts/verify-package-artifacts.mjs +590 -0
  1030. package/scripts/verify-peer-floors.js +399 -0
  1031. package/scripts/verify-peer-floors.test.mjs +422 -0
  1032. package/scripts/verify-test-fails-rules.mjs +104 -0
  1033. package/scripts/verify-test-fails-rules.test.mjs +215 -0
  1034. package/scripts/verify-test-fails.js +371 -0
  1035. package/scripts/verify-traps.mjs +505 -0
  1036. package/scripts/verify-traps.test.mjs +521 -0
  1037. package/scripts/verify-typescript-floor.js +239 -0
  1038. package/skill-packages/ic-reactor/SKILL.md +103 -0
  1039. package/stack.json +8 -0
  1040. package/tsconfig.base.json +23 -0
  1041. package/tsconfig.json +8 -0
@@ -0,0 +1,1221 @@
1
+ #!/usr/bin/env node
2
+ // Run driver for the agent matrix. NOT EXECUTED by the harness author: the
3
+ // matrix needs a budget decision. `--dry-run` prints the plan.
4
+ //
5
+ // node evals/drive.mjs --n 20 --model <model> [--task t]... [--condition c]...
6
+ // [--jobs 4] [--timeout-min 30] [--max-turns 60] [--seed 1]
7
+ // [--prompt explicit|minimal] [--effort <level>] [--oauth-token-file <f>]
8
+ // [--mode sandboxed|tsc-only] [--sandbox-allow <dir>]... [--agent-cmd <tpl>]
9
+ // [--retries 2] [--out <dir>] [--resume <dir>] [--pilot] [--margin 0.1] [--dry-run]
10
+ // node evals/drive.mjs --aggregate <results dir> [--rescan] [--rescore] [--pilot] [--margin 0.1]
11
+ //
12
+ // --rescan re-audits each stored transcript with the current leak scanner;
13
+ // --rescore re-scores each stored solution with the current hidden tests and
14
+ // task.json (no agent is launched), under the prompt variant its run used.
15
+ // Either writes summary.<rescanned|rescored>.json (and pilot.…json) beside
16
+ // the originals, which are never changed; --rescore also writes each run's
17
+ // score.rescored.json beside its score.json.
18
+ //
19
+ // --prompt picks the prompt variant (harness/assemble.mjs PROMPT_VARIANTS):
20
+ // `explicit` (default) states the safety rules; `minimal` gives only the
21
+ // product and its public contract. Every record carries it; variants are
22
+ // never pooled.
23
+ //
24
+ // Phase 1, agents. Runs are ordered round-robin — every round has one run of
25
+ // every task × condition cell, in a seeded shuffle — so conditions interleave
26
+ // in time instead of running in cell blocks. For each run it
27
+ // 1. builds a private run directory under a fresh 0700 batch directory in
28
+ // the OS temp dir (refused if inside the repository): work/ (the starter,
29
+ // that condition's docs only, a clean copy of the condition's shipped
30
+ // node_modules, git-initialised), home/ (a clean HOME and
31
+ // CLAUDE_CONFIG_DIR, so the host's ~/.claude — settings, memory, MCP
32
+ // servers, OAuth login — is not visible) and tmp/ (TMPDIR);
33
+ // 2. launches ONE headless agent in work/ with the rendered prompt (identical
34
+ // across conditions but for the library line), inside the OS sandbox
35
+ // (harness/sandbox.mjs: file contents outside the run and the toolchain
36
+ // unreadable, nothing outside the run writable), with a wall-clock
37
+ // timeout; the only host values passed are PATH and exactly one
38
+ // credential (harness/auth.mjs), which is how the agent authenticates;
39
+ // 3. audits the transcript (harness/leak-scan.mjs, a second line behind the
40
+ // sandbox, and the only one for the network, which the sandbox leaves
41
+ // open): a successful tool call reaching outside the run or using the
42
+ // network marks the run contaminated;
43
+ // 4. records the agent's exit (normal / max_turns / timeout / error /
44
+ // no_result), turns, tokens and cost from the transcript, and copies
45
+ // work/ (minus node_modules) to the results directory.
46
+ // A run that throws is recorded as a harness error and retried (--retries).
47
+ //
48
+ // Phase 2, scoring — only after every agent run has ended, so no agent is
49
+ // alive while hidden tests exist anywhere on disk. score.mjs works in its own
50
+ // 0700 directory. A scoring harness error is retried, then excluded and
51
+ // counted (never scored as 0).
52
+ //
53
+ // Phase 3, aggregation (harness/aggregate.mjs): per task × model × condition,
54
+ // never pooling models; primary metric the fraction of runs with zero safety
55
+ // violations (Wilson; Newcombe for differences), secondary mean requirements
56
+ // met; main result without contaminated runs, intent-to-treat with them.
57
+ // `--pilot` (5 runs per cell by default) adds variance, minutes/turns/tokens
58
+ // per run, ceiling/floor warnings and the runs needed for `--margin`.
59
+ //
60
+ // --resume <dir> continues a batch: runs with agent.json are not re-run, runs
61
+ // without score.json are scored. A run excluded as a harness error has no
62
+ // agent.json, so it is run again and scored. A new batch refuses an --out
63
+ // directory that already holds files: it would take that directory's records
64
+ // for its own runs.
65
+ //
66
+ // ASSUMED AGENT CLI (override with --agent-cmd): Claude Code headless,
67
+ // claude -p "$(cat {prompt})" --output-format stream-json --verbose
68
+ // --model {model} --permission-mode acceptEdits --max-turns {maxTurns}
69
+ // --allowedTools "{allowedTools}" --disallowedTools "WebFetch,WebSearch"
70
+ // --strict-mcp-config
71
+ // Placeholders: {prompt}, {model}, {maxTurns}, {allowedTools}, {task},
72
+ // {condition} (the last two are for stub agents in harness tests). The
73
+ // transcript must be stream-json for the audit and the exit/turn/token record.
74
+ import { spawn } from "node:child_process"
75
+ import {
76
+ cpSync,
77
+ existsSync,
78
+ mkdirSync,
79
+ readFileSync,
80
+ readdirSync,
81
+ rmSync,
82
+ statSync,
83
+ writeFileSync,
84
+ } from "node:fs"
85
+ import { join, resolve } from "node:path"
86
+ import { pathToFileURL } from "node:url"
87
+ import { isDeepStrictEqual } from "node:util"
88
+ import {
89
+ CONDITIONS,
90
+ DEFAULT_CONDITIONS,
91
+ EVALS,
92
+ TASKS,
93
+ PROMPT_VARIANTS,
94
+ conditionDocDirs,
95
+ renderPrompt,
96
+ taskSpec,
97
+ } from "./harness/assemble.mjs"
98
+ import {
99
+ aggregate,
100
+ pilotReport,
101
+ printPilot,
102
+ printSummary,
103
+ round,
104
+ } from "./harness/aggregate.mjs"
105
+ import { scanTranscript, transcriptCwd } from "./harness/leak-scan.mjs"
106
+ import { describeV4Source, v4Source } from "./harness/ship.mjs"
107
+ import {
108
+ agentEnv,
109
+ makeBatchDir,
110
+ prepareBareRun,
111
+ prepareRun,
112
+ REPO,
113
+ } from "./harness/runs.mjs"
114
+ import {
115
+ AUTH_VARS,
116
+ MISSING_AUTH_MESSAGE,
117
+ redact,
118
+ resolveAuth,
119
+ secretsOf,
120
+ } from "./harness/auth.mjs"
121
+ import {
122
+ cliInstallDir,
123
+ nodeInstallDir,
124
+ sandboxAvailable,
125
+ sandboxPrefix,
126
+ } from "./harness/sandbox.mjs"
127
+
128
+ export const ALLOWED_TOOLS = {
129
+ sandboxed:
130
+ "Read,Edit,Write,Glob,Grep,Bash(npx tsc:*),Bash(npx vitest:*),Bash(node:*),Bash(ls:*),Bash(cat:*)",
131
+ "tsc-only": "Read,Edit,Write,Glob,Grep,Bash(npx tsc:*),Bash(ls:*)",
132
+ }
133
+
134
+ export const DEFAULT_AGENT_CMD =
135
+ 'claude -p "$(cat {prompt})" --output-format stream-json --verbose --model {model} {effortFlag}' +
136
+ "--permission-mode acceptEdits --max-turns {maxTurns} " +
137
+ '--allowedTools "{allowedTools}" --disallowedTools "WebFetch,WebSearch" ' +
138
+ "--strict-mcp-config"
139
+
140
+ /**
141
+ * The preflight: one tiny call in the same isolated environment and sandbox
142
+ * as a real run, which must succeed before any agent run starts.
143
+ */
144
+ export const PREFLIGHT_CMD =
145
+ "claude -p 'Reply with the single word: ok' --output-format stream-json --verbose " +
146
+ "--model {model} {effortFlag}--max-turns 1 " +
147
+ '--disallowedTools "WebFetch,WebSearch" --strict-mcp-config'
148
+
149
+ // The credential, resolved once (harness/auth.mjs). Kept out of `args`, which
150
+ // is written to plan.json: only its kind and source are recorded.
151
+ let AUTH
152
+
153
+ // ---------------------------------------------------------------- arguments
154
+ function parseArgs(argv) {
155
+ const args = {
156
+ tasks: [],
157
+ conditions: [],
158
+ n: 0,
159
+ model: undefined,
160
+ effort: undefined,
161
+ oauthTokenFile: undefined,
162
+ preflight: false,
163
+ preflightCmd: PREFLIGHT_CMD,
164
+ jobs: undefined,
165
+ timeoutMin: 30,
166
+ maxTurns: 60,
167
+ seed: 1,
168
+ mode: undefined,
169
+ prompt: "explicit",
170
+ sandboxAllow: [],
171
+ agentCmd: DEFAULT_AGENT_CMD,
172
+ customCmd: false,
173
+ retries: 2,
174
+ rateLimitRetries: 4,
175
+ rateLimitBackoffMin: 5,
176
+ rateLimitMaxWaitMin: 300,
177
+ out: undefined,
178
+ resume: undefined,
179
+ pilot: false,
180
+ margin: 0.1,
181
+ dryRun: false,
182
+ aggregate: undefined,
183
+ estMinutes: 12,
184
+ }
185
+ for (let i = 0; i < argv.length; i += 1) {
186
+ const flag = argv[i]
187
+ const value = () => {
188
+ const v = argv[++i]
189
+ if (v === undefined) throw new Error(`${flag} needs a value`)
190
+ return v
191
+ }
192
+ switch (flag) {
193
+ case "--task":
194
+ args.tasks.push(value())
195
+ break
196
+ case "--condition":
197
+ args.conditions.push(value())
198
+ break
199
+ case "--n":
200
+ args.n = Number(value())
201
+ break
202
+ case "--model":
203
+ args.model = value()
204
+ break
205
+ case "--effort":
206
+ args.effort = value()
207
+ break
208
+ case "--oauth-token-file":
209
+ args.oauthTokenFile = resolve(value())
210
+ break
211
+ case "--preflight":
212
+ args.preflight = true
213
+ break
214
+ case "--preflight-cmd":
215
+ // For harness tests: a stub in place of the real CLI call.
216
+ args.preflightCmd = value()
217
+ break
218
+ case "--jobs":
219
+ args.jobs = Number(value())
220
+ break
221
+ case "--rate-limit-retries":
222
+ args.rateLimitRetries = Number(value())
223
+ break
224
+ case "--rate-limit-backoff-min":
225
+ args.rateLimitBackoffMin = Number(value())
226
+ break
227
+ case "--rate-limit-max-wait-min":
228
+ args.rateLimitMaxWaitMin = Number(value())
229
+ break
230
+ case "--timeout-min":
231
+ args.timeoutMin = Number(value())
232
+ break
233
+ case "--max-turns":
234
+ args.maxTurns = Number(value())
235
+ break
236
+ case "--seed":
237
+ args.seed = Number(value())
238
+ break
239
+ case "--mode":
240
+ args.mode = value()
241
+ break
242
+ case "--prompt":
243
+ args.prompt = value()
244
+ args.promptGiven = true
245
+ break
246
+ case "--sandbox-allow":
247
+ args.sandboxAllow.push(value())
248
+ break
249
+ case "--agent-cmd":
250
+ args.agentCmd = value()
251
+ args.customCmd = true
252
+ break
253
+ case "--retries":
254
+ args.retries = Number(value())
255
+ break
256
+ case "--out":
257
+ args.out = value()
258
+ break
259
+ case "--resume":
260
+ args.resume = value()
261
+ break
262
+ case "--pilot":
263
+ args.pilot = true
264
+ break
265
+ case "--margin":
266
+ args.margin = Number(value())
267
+ break
268
+ case "--est-minutes":
269
+ args.estMinutes = Number(value())
270
+ break
271
+ case "--dry-run":
272
+ args.dryRun = true
273
+ break
274
+ case "--aggregate":
275
+ args.aggregate = value()
276
+ break
277
+ case "--rescan":
278
+ args.rescan = true
279
+ break
280
+ case "--rescore":
281
+ args.rescore = true
282
+ break
283
+ default:
284
+ throw new Error(`unknown argument ${flag}`)
285
+ }
286
+ }
287
+ if (args.tasks.length === 0) args.tasks = [...TASKS]
288
+ if (args.conditions.length === 0) args.conditions = [...DEFAULT_CONDITIONS]
289
+ for (const t of args.tasks) taskSpec(t)
290
+ for (const c of args.conditions) {
291
+ if (!CONDITIONS.includes(c)) throw new Error(`unknown condition ${c}`)
292
+ }
293
+ if (!PROMPT_VARIANTS.includes(args.prompt)) {
294
+ throw new Error(`--prompt is one of ${PROMPT_VARIANTS.join(", ")}`)
295
+ }
296
+ if (args.pilot && args.n === 0) args.n = 5
297
+ args.mode ??= sandboxAvailable() ? "sandboxed" : undefined
298
+ if (args.effort !== undefined && !/^[a-z]+$/.test(args.effort)) {
299
+ throw new Error(`--effort takes a level name such as low, medium or high`)
300
+ }
301
+ if (!args.aggregate && !args.resume && !args.preflight) {
302
+ if (!(args.n >= 1))
303
+ throw new Error("--n <runs per cell> is required (or --pilot)")
304
+ if (!args.mode) {
305
+ throw new Error(
306
+ "no OS sandbox is available here: agents cannot be allowed to run node/vitest. " +
307
+ "Pass --mode tsc-only for the documented fallback (type-check feedback only)."
308
+ )
309
+ }
310
+ if (!["sandboxed", "tsc-only"].includes(args.mode))
311
+ throw new Error("--mode is sandboxed or tsc-only")
312
+ if (args.mode === "sandboxed" && !sandboxAvailable()) {
313
+ throw new Error(
314
+ "--mode sandboxed needs sandbox-exec (macOS); use --mode tsc-only"
315
+ )
316
+ }
317
+ if (!args.dryRun && !args.model) {
318
+ throw new Error(
319
+ "--model is required for a real run (an owner decision; see README)"
320
+ )
321
+ }
322
+ }
323
+ resolveCredential(args)
324
+ if (
325
+ (args.preflight || (!args.aggregate && !args.dryRun)) &&
326
+ !args.customCmd &&
327
+ !AUTH
328
+ ) {
329
+ throw new Error(MISSING_AUTH_MESSAGE)
330
+ }
331
+ if (
332
+ (args.preflight || (!args.aggregate && !args.resume && !args.dryRun)) &&
333
+ !args.model
334
+ ) {
335
+ throw new Error("--model is required (an owner decision; see README)")
336
+ }
337
+ // A subscription is rate-limited per account: fewer agents at a time.
338
+ args.jobs ??= args.auth === "oauth" ? 2 : 4
339
+ return args
340
+ }
341
+
342
+ /**
343
+ * Resolves the credential once — `--oauth-token-file`, then
344
+ * CLAUDE_CODE_OAUTH_TOKEN, then ANTHROPIC_API_KEY — and records its kind and
345
+ * source (never its value) in `args`. A custom --agent-cmd (a stub agent in
346
+ * harness tests) may run without one.
347
+ */
348
+ function resolveCredential(args) {
349
+ AUTH = resolveAuth(process.env, { tokenFile: args.oauthTokenFile })
350
+ args.auth = AUTH?.kind ?? "none"
351
+ args.authSource = AUTH
352
+ ? AUTH.source === "file"
353
+ ? "--oauth-token-file"
354
+ : AUTH.name
355
+ : "none"
356
+ }
357
+
358
+ // ---------------------------------------------------------------- planning
359
+ function rng(seed) {
360
+ let s = seed >>> 0
361
+ return () => {
362
+ s = (s + 0x6d2b79f5) >>> 0
363
+ let t = s
364
+ t = Math.imul(t ^ (t >>> 15), t | 1)
365
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61)
366
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296
367
+ }
368
+ }
369
+
370
+ /** Round-robin over cells, each round in a seeded shuffle. */
371
+ /**
372
+ * Refuses to resume a batch whose v4 packages are no longer the ones it was
373
+ * planned with: `saved` is plan.json's `v4Source`, `current` what
374
+ * `.ship/v4/source.json` holds now. A run of the batch and the scoring read
375
+ * `.ship/v4` and `conditions/v4/node_modules`, so after `setup.mjs` rebuilt
376
+ * them from another source, the runs still to come would test other
377
+ * packages than the plan names. A plan from before v4Source was recorded
378
+ * (`saved` undefined) is let through.
379
+ */
380
+ /**
381
+ * Refuses a real v4 batch, new or resumed, when setup has recorded no source
382
+ * for the v4 packages (`.ship/v4/source.json`, from a setup run that predates
383
+ * it, or none): its runs would test packages nobody can identify, and
384
+ * Addendum 4 requires plan.json's `v4Source` to name them. A dry run only
385
+ * prints the gap.
386
+ */
387
+ export function refuseMissingV4Source(source, { dryRun }) {
388
+ if (source || dryRun) return
389
+ throw new Error(
390
+ "no .ship/v4/source.json: the v4 packages this batch would test are not identified. " +
391
+ "Run `node setup.mjs --v4-from ...` first."
392
+ )
393
+ }
394
+
395
+ export function refuseChangedV4Source(saved, current) {
396
+ if (saved === undefined || isDeepStrictEqual(saved, current)) return
397
+ throw new Error(
398
+ `--resume: this batch was planned with the v4 packages from ${describeV4Source(saved)}, ` +
399
+ `but .ship/v4 now holds ${describeV4Source(current)}. ` +
400
+ "Rebuild the planned source with `node setup.mjs --v4-from ...` before resuming."
401
+ )
402
+ }
403
+
404
+ export function plan({ tasks, conditions, n, seed }) {
405
+ const random = rng(seed)
406
+ const cells = tasks.flatMap((task) =>
407
+ conditions.map((condition) => ({ task, condition }))
408
+ )
409
+ const runs = []
410
+ for (let i = 1; i <= n; i += 1) {
411
+ const round = [...cells]
412
+ for (let j = round.length - 1; j > 0; j -= 1) {
413
+ const k = Math.floor(random() * (j + 1))
414
+ ;[round[j], round[k]] = [round[k], round[j]]
415
+ }
416
+ for (const cell of round) runs.push({ ...cell, i })
417
+ }
418
+ return runs
419
+ }
420
+
421
+ const runDirOf = (outDir, run) =>
422
+ join(outDir, run.task, run.condition, String(run.i).padStart(3, "0"))
423
+
424
+ function agentCommand(
425
+ args,
426
+ { promptFile, runRoot },
427
+ run,
428
+ template = args.agentCmd
429
+ ) {
430
+ const shq = (s) => `'${String(s).replace(/'/g, "'\\''")}'`
431
+ const inner = template
432
+ .replaceAll("{prompt}", shq(promptFile))
433
+ .replaceAll("{model}", shq(args.model ?? "<model: owner decision>"))
434
+ .replaceAll("{maxTurns}", String(args.maxTurns))
435
+ .replaceAll(
436
+ "{effortFlag}",
437
+ args.effort ? `--effort ${shq(args.effort)} ` : ""
438
+ )
439
+ .replaceAll("{allowedTools}", ALLOWED_TOOLS[args.mode])
440
+ .replaceAll("{task}", run?.task ?? "<task>")
441
+ .replaceAll("{condition}", run?.condition ?? "<condition>")
442
+ if (!sandboxAvailable())
443
+ return { argv: ["sh", "-c", inner], sandboxed: false }
444
+ const readOnly = [
445
+ nodeInstallDir(),
446
+ cliInstallDir("claude"),
447
+ ...args.sandboxAllow,
448
+ ]
449
+ const prefix = runRoot
450
+ ? sandboxPrefix({ runRoot, readOnly })
451
+ : ["sandbox-exec", "-f", "<run>/sandbox.sb"]
452
+ return { argv: [...prefix, "sh", "-c", inner], sandboxed: true }
453
+ }
454
+
455
+ // ---------------------------------------------------------------- phase 1
456
+ function spawnAgent(argv, { cwd, env, timeoutMs, logBase }) {
457
+ return new Promise((resolvePromise) => {
458
+ const child = spawn(argv[0], argv.slice(1), {
459
+ cwd,
460
+ env,
461
+ stdio: ["ignore", "pipe", "pipe"],
462
+ })
463
+ let out = ""
464
+ let err = ""
465
+ let timedOut = false
466
+ child.stdout.on("data", (d) => (out += d))
467
+ child.stderr.on("data", (d) => (err += d))
468
+ const timer = setTimeout(() => {
469
+ timedOut = true
470
+ child.kill("SIGKILL")
471
+ }, timeoutMs)
472
+ const onAbort = () => child.kill("SIGKILL")
473
+ batchAbort.signal.addEventListener("abort", onAbort, { once: true })
474
+ child.on("close", (code, signal) => {
475
+ clearTimeout(timer)
476
+ batchAbort.signal.removeEventListener("abort", onAbort)
477
+ writeFileSync(`${logBase}.stdout`, redact(out))
478
+ writeFileSync(`${logBase}.stderr`, redact(err))
479
+ resolvePromise({ code, signal, out, err, timedOut })
480
+ })
481
+ })
482
+ }
483
+
484
+ // A usage or rate limit, as the CLI reports one. ASSUMED (from the CLI's
485
+ // documented stream-json shape and its observed error texts, not verified
486
+ // against 2.1.285): a subscription limit ends the run with an error `result`
487
+ // whose text reads like "Claude AI usage limit reached|<reset epoch>" or
488
+ // "... limit reached ... resets ...", and an API limit as
489
+ // "API Error: 429 ... rate_limit_error" or "overloaded_error". Only error
490
+ // results, top-level `error` fields and the CLI's stderr are inspected — the
491
+ // agent's own prose in this task talks about HTTP 429 all the time — and a
492
+ // successful result is never a rate limit.
493
+ // Sign-in failures, measured on CLI 2.1.285: with an isolated config
494
+ // directory and no credential a run returns subtype "success", is_error true,
495
+ // result "Not logged in · Please run /login". Also: api_error_status 401/403.
496
+ const SIGN_IN =
497
+ /not logged in|\/login\b|invalid api key|oauth token (has )?(expired|revoked)|authentication (failed|error)|unauthori[sz]ed/i
498
+ const SIGN_IN_STATUS = new Set([401, 403])
499
+ const LIMIT_STATUS = new Set([429, 529])
500
+
501
+ const RATE_LIMIT =
502
+ /usage limit|limit reached|rate[_ ]?limit|too many requests|\b429\b|overloaded(_error)?|\b529\b/i
503
+
504
+ /**
505
+ * Exit reason, turns, tokens and cost from the stream-json `result` message.
506
+ * `rateLimitedUntil` is the reset time (ms) when the limit message names one.
507
+ */
508
+ export function agentOutcome(stdout, { timedOut, stderr = "" }) {
509
+ let result
510
+ const errorTexts = []
511
+ for (const line of stdout.split("\n")) {
512
+ const l = line.trim()
513
+ if (!l.startsWith("{")) continue
514
+ try {
515
+ const msg = JSON.parse(l)
516
+ if (msg.type === "result") result = msg
517
+ if (msg.type === "error" || msg.error !== undefined) {
518
+ errorTexts.push(JSON.stringify(msg.error ?? msg))
519
+ }
520
+ } catch {
521
+ // not JSON
522
+ }
523
+ }
524
+ const failed = result
525
+ ? result.is_error === true || result.subtype !== "success"
526
+ : true
527
+ if (result && failed && typeof result.result === "string") {
528
+ errorTexts.push(result.result)
529
+ }
530
+ if (failed) errorTexts.push(stderr)
531
+ const status = failed ? result?.api_error_status : undefined
532
+ const signInText = errorTexts.find((t) => SIGN_IN.test(t))
533
+ const signIn =
534
+ !timedOut && (SIGN_IN_STATUS.has(status) || signInText !== undefined)
535
+ const limitText =
536
+ errorTexts.find((t) => RATE_LIMIT.test(t)) ??
537
+ (LIMIT_STATUS.has(status) ? `api_error_status ${status}` : undefined)
538
+ const epoch = limitText && /\|(\d{10})\b/.exec(limitText)
539
+ const exit = signIn
540
+ ? "sign_in_error"
541
+ : !timedOut && limitText
542
+ ? "rate_limited"
543
+ : timedOut
544
+ ? "timeout"
545
+ : !result
546
+ ? "no_result"
547
+ : result.subtype === "success" && result.is_error !== true
548
+ ? "normal"
549
+ : result.subtype === "error_max_turns"
550
+ ? "max_turns"
551
+ : "error"
552
+ const usage = result?.usage ?? {}
553
+ return {
554
+ exit,
555
+ turns: result?.num_turns ?? null,
556
+ tokens: {
557
+ input: usage.input_tokens ?? null,
558
+ output: usage.output_tokens ?? null,
559
+ cacheRead: usage.cache_read_input_tokens ?? null,
560
+ cacheCreation: usage.cache_creation_input_tokens ?? null,
561
+ },
562
+ costUsd: result?.total_cost_usd ?? null,
563
+ resultText:
564
+ typeof result?.result === "string" ? result.result.slice(0, 500) : null,
565
+ apiErrorStatus: result?.api_error_status ?? null,
566
+ ...(exit === "sign_in_error"
567
+ ? {
568
+ signInMessage: String(
569
+ signInText ?? `api_error_status ${status}`
570
+ ).slice(0, 300),
571
+ }
572
+ : {}),
573
+ ...(exit === "rate_limited"
574
+ ? {
575
+ rateLimitedUntil: epoch ? Number(epoch[1]) * 1000 : null,
576
+ rateLimitMessage: String(limitText).slice(0, 300),
577
+ }
578
+ : {}),
579
+ }
580
+ }
581
+
582
+ /** The CLI could not sign in: the whole batch stops at once. */
583
+ export class SignInError extends Error {}
584
+
585
+ /** Stops every agent run of the batch (a sign-in failure). */
586
+ const batchAbort = new AbortController()
587
+
588
+ /** A run the account's usage or rate limit stopped: a harness error, not a result. */
589
+ export class RateLimited extends Error {
590
+ constructor(message, until) {
591
+ super(message)
592
+ this.until = until
593
+ }
594
+ }
595
+
596
+ /** Replaces credential values in every text file under `dir`. */
597
+ function redactTree(dir, secrets) {
598
+ if (secrets.length === 0) return
599
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
600
+ const p = join(dir, entry.name)
601
+ if (entry.isDirectory()) redactTree(p, secrets)
602
+ else if (entry.isFile()) {
603
+ const text = readFileSync(p, "latin1")
604
+ if (secrets.some((s) => text.includes(s))) {
605
+ writeFileSync(p, redact(text, secrets), "latin1")
606
+ }
607
+ }
608
+ }
609
+ }
610
+
611
+ async function agentRun(args, batchDir, outDir, run) {
612
+ const dir = runDirOf(outDir, run)
613
+ mkdirSync(dir, { recursive: true })
614
+ const prepared = prepareRun({
615
+ batchDir,
616
+ ...run,
617
+ mode: args.mode,
618
+ prompt: args.prompt,
619
+ })
620
+ const { argv, sandboxed } = agentCommand(args, prepared, run)
621
+ const started = Date.now()
622
+ const auth = AUTH
623
+ const agent = await spawnAgent(argv, {
624
+ cwd: prepared.work,
625
+ env: agentEnv(prepared, auth),
626
+ timeoutMs: args.timeoutMin * 60_000,
627
+ logBase: join(dir, "agent"),
628
+ })
629
+ const minutes = (Date.now() - started) / 60_000
630
+ const outcome = agentOutcome(agent.out, { ...agent, stderr: agent.err })
631
+ if (batchAbort.signal.aborted) {
632
+ // Killed because another run could not sign in: not a result.
633
+ rmSync(prepared.runRoot, { recursive: true, force: true })
634
+ throw new SignInError("the batch was stopped")
635
+ }
636
+ if (outcome.exit === "sign_in_error") {
637
+ rmSync(prepared.runRoot, { recursive: true, force: true })
638
+ throw new SignInError(redact(outcome.signInMessage ?? "not signed in"))
639
+ }
640
+ if (outcome.exit === "rate_limited") {
641
+ // Keep the attempt's logs for the record; the run itself is retried.
642
+ for (const ext of ["stdout", "stderr"]) {
643
+ cpSync(
644
+ join(dir, `agent.${ext}`),
645
+ join(dir, `rate-limited-${Date.now()}.${ext}`)
646
+ )
647
+ }
648
+ rmSync(prepared.runRoot, { recursive: true, force: true })
649
+ throw new RateLimited(
650
+ redact(outcome.rateLimitMessage ?? "rate limited"),
651
+ outcome.rateLimitedUntil
652
+ )
653
+ }
654
+ const audit = scanTranscript(agent.out, { runDir: prepared.work })
655
+ cpSync(prepared.work, join(dir, "solution"), {
656
+ recursive: true,
657
+ filter: (src) =>
658
+ !src.startsWith(join(prepared.work, "node_modules")) &&
659
+ !src.endsWith("/.git"),
660
+ })
661
+ redactTree(join(dir, "solution"), secretsOf())
662
+ const meta = {
663
+ task: run.task,
664
+ condition: run.condition,
665
+ run: run.i,
666
+ model: args.model,
667
+ effort: args.effort ?? "default",
668
+ prompt: args.prompt,
669
+ auth: auth?.kind ?? "none",
670
+ seed: args.seed,
671
+ mode: args.mode,
672
+ sandboxed,
673
+ agent: {
674
+ ...outcome,
675
+ minutes: round(minutes),
676
+ code: agent.code,
677
+ signal: agent.signal,
678
+ },
679
+ contaminated: audit.contaminated,
680
+ audit: {
681
+ auditable: audit.auditable,
682
+ toolCalls: audit.toolCalls,
683
+ attempts: audit.attempts,
684
+ violations: audit.violations.slice(0, 20),
685
+ persistedReads: audit.persistedReads.slice(0, 20),
686
+ },
687
+ }
688
+ writeFileSync(
689
+ join(dir, "agent.json"),
690
+ redact(JSON.stringify(meta, null, 2)) + "\n"
691
+ )
692
+ rmSync(prepared.runRoot, { recursive: true, force: true })
693
+ return meta
694
+ }
695
+
696
+ async function pool(items, jobs, fn) {
697
+ let next = 0
698
+ const worker = async () => {
699
+ while (next < items.length && !batchAbort.signal.aborted) {
700
+ await fn(items[next++])
701
+ }
702
+ }
703
+ await Promise.all(Array.from({ length: Math.max(1, jobs) }, worker))
704
+ }
705
+
706
+ // ---------------------------------------------------------------- phase 2
707
+ function scoreOnce(run, dir, prompt = "explicit") {
708
+ return new Promise((resolvePromise) => {
709
+ const child = spawn(
710
+ process.execPath,
711
+ [
712
+ join(EVALS, "score.mjs"),
713
+ "--task",
714
+ run.task,
715
+ "--condition",
716
+ run.condition,
717
+ "--solution",
718
+ join(dir, "solution"),
719
+ "--prompt",
720
+ prompt,
721
+ ],
722
+ { cwd: EVALS, stdio: ["ignore", "pipe", "pipe"] }
723
+ )
724
+ let out = ""
725
+ let err = ""
726
+ child.stdout.on("data", (d) => (out += d))
727
+ child.stderr.on("data", (d) => (err += d))
728
+ child.on("close", (code) => resolvePromise({ code, out, err }))
729
+ })
730
+ }
731
+
732
+ async function scoreRun(args, outDir, run) {
733
+ const dir = runDirOf(outDir, run)
734
+ const meta = JSON.parse(readFileSync(join(dir, "agent.json"), "utf8"))
735
+ let score
736
+ let lastError = ""
737
+ for (let attempt = 0; attempt <= args.retries && !score; attempt += 1) {
738
+ const r = await scoreOnce(run, dir, meta.prompt ?? args.prompt)
739
+ if (r.code === 0) score = JSON.parse(r.out)
740
+ else lastError = redact(`score.mjs exit ${r.code}: ${r.err.slice(-2000)}`)
741
+ }
742
+ const record = score
743
+ ? { ...score, ...meta }
744
+ : { ...meta, harnessError: lastError, harnessKind: "scoring" }
745
+ delete record.details
746
+ writeFileSync(
747
+ join(dir, "score.json"),
748
+ redact(JSON.stringify(record, null, 2)) + "\n"
749
+ )
750
+ return record
751
+ }
752
+
753
+ function loadRecords(dir) {
754
+ const records = []
755
+ const walk = (d) => {
756
+ for (const entry of readdirSync(d, { withFileTypes: true })) {
757
+ const p = join(d, entry.name)
758
+ if (entry.isDirectory() && entry.name !== "solution") walk(p)
759
+ else if (entry.name === "score.json")
760
+ records.push({ ...JSON.parse(readFileSync(p, "utf8")), _dir: d })
761
+ }
762
+ }
763
+ walk(dir)
764
+ return records
765
+ }
766
+
767
+ /**
768
+ * Re-audits every run from its stored transcript with the current scanner
769
+ * (the run directory it names in its init message), in memory: the records
770
+ * on disk are not changed.
771
+ */
772
+ function rescan(records) {
773
+ let changed = 0
774
+ const out = records.map((r) => {
775
+ const transcript = r._dir && join(r._dir, "agent.stdout")
776
+ if (!transcript || !existsSync(transcript) || r.harnessError) return r
777
+ const text = readFileSync(transcript, "utf8")
778
+ const runDir = transcriptCwd(text)
779
+ if (!runDir) return r
780
+ const audit = scanTranscript(text, { runDir })
781
+ if (audit.contaminated !== Boolean(r.contaminated)) changed += 1
782
+ return {
783
+ ...r,
784
+ contaminatedAtRun: Boolean(r.contaminated),
785
+ contaminated: audit.contaminated,
786
+ audit: {
787
+ auditable: audit.auditable,
788
+ toolCalls: audit.toolCalls,
789
+ attempts: audit.attempts,
790
+ violations: audit.violations.slice(0, 20),
791
+ persistedReads: audit.persistedReads.slice(0, 20),
792
+ },
793
+ }
794
+ })
795
+ process.stdout.write(
796
+ `rescan: ${out.length} runs re-audited from their transcripts; contamination changed in ${changed}; ` +
797
+ `now ${out.filter((r) => r.contaminated && !r.harnessError).length} contaminated ` +
798
+ `(was ${records.filter((r) => r.contaminated && !r.harnessError).length})\n\n`
799
+ )
800
+ return out
801
+ }
802
+
803
+ /**
804
+ * Re-scores every stored solution with the current hidden tests and
805
+ * task.json, under the prompt variant its run used; the run's agent record is
806
+ * kept. Writes score.rescored.json beside each score.json (never changed).
807
+ */
808
+ async function rescore(args, records) {
809
+ let changed = 0
810
+ let errors = 0
811
+ const out = [...records]
812
+ await pool(
813
+ records.map((r, i) => [r, i]),
814
+ args.jobs,
815
+ async ([r, i]) => {
816
+ if (r.harnessError || !r._dir || !existsSync(join(r._dir, "solution")))
817
+ return
818
+ const agentFile = join(r._dir, "agent.json")
819
+ const meta = existsSync(agentFile)
820
+ ? JSON.parse(readFileSync(agentFile, "utf8"))
821
+ : {}
822
+ let score
823
+ let lastError = ""
824
+ for (let attempt = 0; attempt <= args.retries && !score; attempt += 1) {
825
+ const s = await scoreOnce(r, r._dir, r.prompt ?? "explicit")
826
+ if (s.code === 0) score = JSON.parse(s.out)
827
+ else
828
+ lastError = redact(`score.mjs exit ${s.code}: ${s.err.slice(-2000)}`)
829
+ }
830
+ if (!score) {
831
+ errors += 1
832
+ process.stderr.write(`${r._dir}: rescoring failed: ${lastError}\n`)
833
+ out[i] = { ...r, harnessError: lastError, harnessKind: "rescoring" }
834
+ return
835
+ }
836
+ delete score.details
837
+ const record = {
838
+ ...score,
839
+ ...meta,
840
+ // agent.json never carries a score; keep the run's own variant and
841
+ // a re-audit (--rescan) if one was made.
842
+ prompt: r.prompt ?? "explicit",
843
+ contaminated: r.contaminated,
844
+ ...(r.contaminatedAtRun !== undefined
845
+ ? { contaminatedAtRun: r.contaminatedAtRun, audit: r.audit }
846
+ : {}),
847
+ scoredAtRun: { safe: r.safe, requirementsMet: r.requirementsMet },
848
+ }
849
+ if (
850
+ record.safe !== r.safe ||
851
+ record.requirementsMet !== r.requirementsMet
852
+ )
853
+ changed += 1
854
+ writeFileSync(
855
+ join(r._dir, "score.rescored.json"),
856
+ redact(JSON.stringify(record, null, 2)) + "\n"
857
+ )
858
+ out[i] = { ...record, _dir: r._dir }
859
+ }
860
+ )
861
+ process.stdout.write(
862
+ `rescore: ${records.length} runs re-scored from their stored solutions with the current hidden tests; ` +
863
+ `safe or requirements-met changed in ${changed}; rescoring errors ${errors}\n\n`
864
+ )
865
+ return out
866
+ }
867
+
868
+ async function report(args, records, outDir) {
869
+ if (args.rescan) records = rescan(records)
870
+ if (args.rescore) records = await rescore(args, records)
871
+ const suffix =
872
+ (args.rescan ? ".rescanned" : "") + (args.rescore ? ".rescored" : "")
873
+ records = records.map(({ _dir, ...r }) => r)
874
+ const summary = aggregate(records)
875
+ writeFileSync(
876
+ join(outDir, `summary${suffix}.json`),
877
+ redact(JSON.stringify(summary, null, 2)) + "\n"
878
+ )
879
+ printSummary(summary)
880
+ if (args.pilot) {
881
+ const pilot = pilotReport(records, { margin: args.margin })
882
+ writeFileSync(
883
+ join(outDir, `pilot${suffix}.json`),
884
+ redact(JSON.stringify(pilot, null, 2)) + "\n"
885
+ )
886
+ process.stdout.write("\n")
887
+ printPilot(pilot)
888
+ }
889
+ }
890
+
891
+ function describeAuth(args) {
892
+ if (args.auth === "oauth") {
893
+ return (
894
+ `Claude subscription token from ${args.authSource}` +
895
+ (process.env[AUTH_VARS.api_key]
896
+ ? ` (${AUTH_VARS.api_key} is set but not passed)`
897
+ : "")
898
+ )
899
+ }
900
+ if (args.auth === "api_key") return `${AUTH_VARS.api_key} (API billing)`
901
+ return "none (custom agent command)"
902
+ }
903
+
904
+ /**
905
+ * One tiny call in an isolated run directory, environment and sandbox exactly
906
+ * like an agent run's. Succeeds when the CLI returns a successful result that
907
+ * is not an error; otherwise prints the CLI's result text and stops.
908
+ */
909
+ export async function preflight(args) {
910
+ const batchDir = makeBatchDir()
911
+ try {
912
+ const prepared = prepareBareRun({ batchDir })
913
+ const { argv } = agentCommand(
914
+ args,
915
+ { promptFile: "", runRoot: prepared.runRoot },
916
+ undefined,
917
+ args.preflightCmd
918
+ )
919
+ const logBase = join(prepared.runRoot, "preflight")
920
+ const r = await spawnAgent(argv, {
921
+ cwd: prepared.work,
922
+ env: agentEnv(prepared, AUTH),
923
+ timeoutMs: 5 * 60_000,
924
+ logBase,
925
+ })
926
+ const outcome = agentOutcome(r.out, { ...r, stderr: r.err })
927
+ if (outcome.exit !== "normal") {
928
+ throw new Error(
929
+ `preflight failed (${outcome.exit}): the CLI said: ` +
930
+ redact(outcome.resultText ?? r.err.slice(-500) ?? "(nothing)") +
931
+ (outcome.exit === "sign_in_error"
932
+ ? " — check --oauth-token-file / CLAUDE_CODE_OAUTH_TOKEN (`claude setup-token`) or ANTHROPIC_API_KEY"
933
+ : "")
934
+ )
935
+ }
936
+ process.stdout.write(
937
+ `preflight ok (${describeAuth(args)}; model ${args.model}; effort ${args.effort ?? "default"})\n`
938
+ )
939
+ } finally {
940
+ rmSync(batchDir, { recursive: true, force: true })
941
+ }
942
+ }
943
+
944
+ // ---------------------------------------------------------------- main
945
+ /**
946
+ * A new batch starts in a new or empty directory. In one that already holds
947
+ * files, plan.json would be overwritten while the run directories stayed: a
948
+ * run with an agent.json would count as run, one with a score.json as scored,
949
+ * and the summary would aggregate another batch's records with this one's.
950
+ * Only --resume continues a batch in place.
951
+ */
952
+ function refuseUsedOutDir(outDir) {
953
+ if (!existsSync(outDir)) return
954
+ if (!statSync(outDir).isDirectory()) {
955
+ throw new Error(`--out ${outDir} exists and is not a directory`)
956
+ }
957
+ if (readdirSync(outDir).length > 0) {
958
+ throw new Error(
959
+ `--out ${outDir} already holds files: a new batch needs a new or empty directory, ` +
960
+ "or it would count the runs recorded there as its own. " +
961
+ `Continue that batch with --resume ${outDir}, or pick another --out.`
962
+ )
963
+ }
964
+ }
965
+
966
+ async function main() {
967
+ const args = parseArgs(process.argv.slice(2))
968
+ if (args.preflight && !args.dryRun) {
969
+ await preflight(args)
970
+ return
971
+ }
972
+ if (args.aggregate) {
973
+ await report(
974
+ args,
975
+ loadRecords(resolve(args.aggregate)),
976
+ resolve(args.aggregate)
977
+ )
978
+ return
979
+ }
980
+ let outDir
981
+ let runs
982
+ let savedV4Source
983
+ if (args.resume) {
984
+ outDir = resolve(args.resume)
985
+ const saved = JSON.parse(readFileSync(join(outDir, "plan.json"), "utf8"))
986
+ // A batch keeps its prompt variant (batches from before --prompt existed
987
+ // were explicit); asking to resume it with another one is refused.
988
+ const savedPrompt = saved.args.prompt ?? "explicit"
989
+ if (args.promptGiven && args.prompt !== savedPrompt) {
990
+ throw new Error(
991
+ `${outDir} is a --prompt ${savedPrompt} batch; it cannot be resumed with --prompt ${args.prompt}`
992
+ )
993
+ }
994
+ Object.assign(args, {
995
+ ...saved.args,
996
+ prompt: savedPrompt,
997
+ resume: args.resume,
998
+ dryRun: args.dryRun,
999
+ pilot: args.pilot || saved.args.pilot,
1000
+ oauthTokenFile: args.oauthTokenFile ?? saved.args.oauthTokenFile,
1001
+ })
1002
+ resolveCredential(args)
1003
+ if (!args.customCmd && !AUTH) throw new Error(MISSING_AUTH_MESSAGE)
1004
+ runs = saved.runs
1005
+ savedV4Source = saved.v4Source
1006
+ } else {
1007
+ runs = plan(args)
1008
+ outDir = resolve(
1009
+ args.out ??
1010
+ join(EVALS, "runs", new Date().toISOString().replace(/[:.]/g, "-"))
1011
+ )
1012
+ refuseUsedOutDir(outDir)
1013
+ }
1014
+ const cells = args.tasks.length * args.conditions.length
1015
+ // Where the v4 packages under test came from (setup.mjs --v4-from): the
1016
+ // tarballs' integrity and the guide's size and sha256, kept in plan.json.
1017
+ const v4 = args.conditions.includes("v4") ? { v4Source: v4Source() } : {}
1018
+ if (args.conditions.includes("v4")) refuseMissingV4Source(v4.v4Source, args)
1019
+ if (args.resume && args.conditions.includes("v4"))
1020
+ refuseChangedV4Source(savedV4Source, v4.v4Source)
1021
+
1022
+ if (args.dryRun) {
1023
+ const example = agentCommand(args, { promptFile: "<run>/prompt.md" })
1024
+ process.stdout.write(
1025
+ [
1026
+ `drive.mjs --dry-run${args.pilot ? " --pilot" : ""}: nothing will be launched.`,
1027
+ `cells: ${cells} (tasks: ${args.tasks.join(", ")}; conditions: ${args.conditions.join(", ")})`,
1028
+ `runs: ${runs.length} (${args.n} per cell), round-robin in a shuffle seeded ${args.seed}; ${args.jobs} at a time; timeout ${args.timeoutMin} min; max ${args.maxTurns} turns`,
1029
+ `model: ${args.model ?? "<unset: an owner decision; required for a real run>"} (every record carries it; models are never pooled)`,
1030
+ `mode: ${args.mode} (${args.mode === "sandboxed" ? "agents may run tsc, vitest and node, inside the OS sandbox" : "type-check feedback only"})`,
1031
+ `sandbox: ${sandboxAvailable() ? `sandbox-exec; readable toolchain: ${[nodeInstallDir(), cliInstallDir("claude") ?? "<claude CLI not on PATH here>", ...args.sandboxAllow].join(", ")}` : "none available"}`,
1032
+ `run dirs: a fresh 0700 batch dir under the OS temp dir (refused if inside ${REPO}); per run work/ home/ tmp/`,
1033
+ `auth: ${args.auth === "none" ? `none found (--oauth-token-file, ${AUTH_VARS.oauth} — see \`claude setup-token\` — or ${AUTH_VARS.api_key}): a real run will refuse to start` : describeAuth(args)}; passed to the agent as exactly one variable; the value is never printed or recorded`,
1034
+ `effort: ${args.effort ?? "the CLI default"} (recorded per run; never pooled across effort levels)`,
1035
+ ...(args.conditions.includes("v4")
1036
+ ? [
1037
+ `v4 built from: ${describeV4Source(v4.v4Source)} (recorded in plan.json)`,
1038
+ ]
1039
+ : []),
1040
+ `prompt: ${args.prompt} (${args.prompt === "explicit" ? "states the safety rules the hidden tests check" : "product and public contract only; no safety rules"}; recorded per run; never pooled across prompt variants)`,
1041
+ `preflight: before any run, one tiny call ("Reply with the single word: ok", max 1 turn) in the same isolated environment and sandbox must succeed; also runnable alone with --preflight`,
1042
+ `agent environment: PATH, HOME=<run>/home, CLAUDE_CONFIG_DIR=<run>/home/.claude, TMPDIR=<run>/tmp, and exactly one of ${AUTH_VARS.oauth} / ${AUTH_VARS.api_key} (the host's ~/.claude login is not visible)`,
1043
+ "rate limits: a usage/rate-limit exit is a harness error, retried with backoff (up to --rate-limit-retries), then excluded and counted — never scored as a failed solution",
1044
+ "leak audit: stream-json transcript scanned; a successful outside read or network use marks the run contaminated (excluded from main, kept in intent-to-treat)",
1045
+ "scoring: after every agent run has ended, in score.mjs's own 0700 directory; harness errors retried, then excluded and counted",
1046
+ `results: ${outDir}/<task>/<condition>/<nnn>/{agent.stdout,agent.stderr,agent.json,solution/,score.json}, plan.json, summary.json${args.pilot ? ", pilot.json" : ""}`,
1047
+ `estimated agent time: ${runs.length} runs × ~${args.estMinutes} min = ${round((runs.length * args.estMinutes) / 60)} agent-hours` +
1048
+ ` (~${round((runs.length * args.estMinutes) / 60 / args.jobs)} h wall-clock at ${args.jobs} parallel), plus ~2 min scoring per run`,
1049
+ `agent command (cwd = <run>/work):\n ${example.argv.join(" ")}`,
1050
+ "",
1051
+ "per-cell plan:",
1052
+ ...args.tasks.flatMap((task) =>
1053
+ args.conditions.map((condition) => {
1054
+ const docs =
1055
+ conditionDocDirs(condition)
1056
+ .flatMap((d) => readdirSync(d))
1057
+ .join(", ") || "(none)"
1058
+ return ` ${task} × ${condition}: ${args.n} runs; docs/: ${docs}; ${args.prompt} prompt ${renderPrompt(task, condition, args.mode, args.prompt).length} chars`
1059
+ })
1060
+ ),
1061
+ "",
1062
+ "first runs, in order:",
1063
+ ...runs
1064
+ .slice(0, Math.min(runs.length, 10))
1065
+ .map((r) => ` ${r.task}/${r.condition}#${r.i}`),
1066
+ runs.length > 10 ? ` ... ${runs.length - 10} more` : "",
1067
+ args.pilot
1068
+ ? `\nafter the runs: pilot report (variance, minutes/turns/tokens, ceiling/floor warnings, runs per cell for margin ${args.margin})`
1069
+ : "",
1070
+ ].join("\n") + "\n"
1071
+ )
1072
+ return
1073
+ }
1074
+
1075
+ process.stdout.write(
1076
+ `auth: ${describeAuth(args)}; effort ${args.effort ?? "default"}; prompt ${args.prompt}; ${args.jobs} agents at a time\n`
1077
+ )
1078
+ mkdirSync(outDir, { recursive: true })
1079
+ if (!args.resume) {
1080
+ writeFileSync(
1081
+ join(outDir, "plan.json"),
1082
+ redact(JSON.stringify({ args, runs, ...v4 }, null, 2)) + "\n"
1083
+ )
1084
+ }
1085
+
1086
+ // Preflight: one tiny call must succeed before any agent run starts.
1087
+ if (!args.customCmd || args.preflightCmd !== PREFLIGHT_CMD)
1088
+ await preflight(args)
1089
+
1090
+ // Phase 1: agents.
1091
+ let signInFailure
1092
+ const pending = runs.filter(
1093
+ (run) => !existsSync(join(runDirOf(outDir, run), "agent.json"))
1094
+ )
1095
+ const batchDir = makeBatchDir()
1096
+ try {
1097
+ await pool(pending, args.jobs, async (run) => {
1098
+ const label = `${run.task}/${run.condition}#${run.i}`
1099
+ const fail = (kind, message) => {
1100
+ const dir = runDirOf(outDir, run)
1101
+ mkdirSync(dir, { recursive: true })
1102
+ writeFileSync(
1103
+ join(dir, "score.json"),
1104
+ redact(
1105
+ JSON.stringify(
1106
+ {
1107
+ task: run.task,
1108
+ condition: run.condition,
1109
+ run: run.i,
1110
+ model: args.model,
1111
+ effort: args.effort ?? "default",
1112
+ prompt: args.prompt,
1113
+ auth: args.auth,
1114
+ seed: args.seed,
1115
+ mode: args.mode,
1116
+ harnessError: message,
1117
+ harnessKind: kind,
1118
+ },
1119
+ null,
1120
+ 2
1121
+ )
1122
+ ) + "\n"
1123
+ )
1124
+ }
1125
+ // A pending run with a score.json is a harness error recorded by an
1126
+ // earlier attempt (`fail` above), which --resume runs again: drop that
1127
+ // record so the new attempt is scored like any other run.
1128
+ rmSync(join(runDirOf(outDir, run), "score.json"), { force: true })
1129
+ let errors = 0
1130
+ let limits = 0
1131
+ for (;;) {
1132
+ try {
1133
+ const meta = await agentRun(args, batchDir, outDir, run)
1134
+ process.stdout.write(
1135
+ `${label}: agent ${meta.agent.exit}` +
1136
+ `${meta.contaminated ? " CONTAMINATED" : ""} (${meta.agent.minutes} min)\n`
1137
+ )
1138
+ return
1139
+ } catch (error) {
1140
+ if (error instanceof SignInError) {
1141
+ if (!batchAbort.signal.aborted) {
1142
+ signInFailure = `${label}: ${error.message}`
1143
+ batchAbort.abort()
1144
+ }
1145
+ return
1146
+ }
1147
+ if (error instanceof RateLimited) {
1148
+ limits += 1
1149
+ if (limits > args.rateLimitRetries) {
1150
+ process.stderr.write(
1151
+ `${label}: still rate limited; excluded as a harness error\n`
1152
+ )
1153
+ fail("rate_limited", error.message)
1154
+ return
1155
+ }
1156
+ const backoff =
1157
+ args.rateLimitBackoffMin * 60_000 * 2 ** (limits - 1)
1158
+ const untilReset = error.until
1159
+ ? error.until - Date.now() + 60_000
1160
+ : 0
1161
+ const wait = Math.min(
1162
+ Math.max(backoff, untilReset),
1163
+ args.rateLimitMaxWaitMin * 60_000
1164
+ )
1165
+ process.stderr.write(
1166
+ `${label}: rate limited (${error.message.slice(0, 120)}); retry ${limits}/${args.rateLimitRetries} in ${round(wait / 60_000)} min\n`
1167
+ )
1168
+ await new Promise((r) => setTimeout(r, wait))
1169
+ continue
1170
+ }
1171
+ errors += 1
1172
+ const message = redact(String(error?.stack ?? error))
1173
+ process.stderr.write(
1174
+ `${label}: harness error (attempt ${errors}): ${redact(error?.message ?? error)}\n`
1175
+ )
1176
+ if (errors > args.retries) {
1177
+ fail("harness", message)
1178
+ return
1179
+ }
1180
+ }
1181
+ }
1182
+ })
1183
+ } finally {
1184
+ rmSync(batchDir, { recursive: true, force: true })
1185
+ }
1186
+
1187
+ if (signInFailure) {
1188
+ throw new Error(
1189
+ `the CLI could not sign in, so the batch was stopped at once (${signInFailure}). ` +
1190
+ "Check --oauth-token-file / CLAUDE_CODE_OAUTH_TOKEN (`claude setup-token`) or " +
1191
+ `ANTHROPIC_API_KEY, then continue with --resume ${outDir}`
1192
+ )
1193
+ }
1194
+
1195
+ // Phase 2: scoring, only now that no agent is running.
1196
+ const toScore = runs.filter(
1197
+ (run) =>
1198
+ existsSync(join(runDirOf(outDir, run), "agent.json")) &&
1199
+ !existsSync(join(runDirOf(outDir, run), "score.json"))
1200
+ )
1201
+ await pool(toScore, args.jobs, async (run) => {
1202
+ const record = await scoreRun(args, outDir, run)
1203
+ process.stdout.write(
1204
+ `${run.task}/${run.condition}#${run.i}: ` +
1205
+ (record.harnessError
1206
+ ? "SCORING HARNESS ERROR (excluded)"
1207
+ : `safe ${record.safe}, met ${record.requirementsMet}`) +
1208
+ "\n"
1209
+ )
1210
+ })
1211
+
1212
+ // Phase 3: aggregation.
1213
+ await report(args, loadRecords(outDir), outDir)
1214
+ }
1215
+
1216
+ if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
1217
+ main().catch((error) => {
1218
+ process.stderr.write(`drive.mjs: ${error?.stack ?? error}\n`)
1219
+ process.exit(2)
1220
+ })
1221
+ }