@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,993 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Type-checks the TypeScript code fences that readers and AI agents copy.
4
+ *
5
+ * The root and package `llms.txt` guides, the skills, the READMEs and the
6
+ * other AI-context files are where an agent in a consumer project learns the
7
+ * API, and it pastes their snippets as they stand. `check:ai-context` keeps
8
+ * their versions and links current but never compiles a line of code, so a
9
+ * renamed export or a changed signature left a snippet that no longer
10
+ * compiles with every gate green.
11
+ *
12
+ * This extracts every ```ts, ```tsx and ```typescript fence from those files,
13
+ * writes each one to its own module in a temporary directory, and compiles them
14
+ * all as one TypeScript program with the compiler options of Vite's React
15
+ * template (`strict`, `jsx: react-jsx`, `moduleResolution: bundler`,
16
+ * `verbatimModuleSyntax`). The directory reaches the `@ic-reactor/*` packages
17
+ * through symlinks, so a snippet compiles against the declarations
18
+ * `pnpm build` wrote to `packages/<name>/dist`, through each package's
19
+ * `exports` map, as it would in an app that installed them. Build first.
20
+ *
21
+ * ## The app a snippet runs in
22
+ *
23
+ * A snippet takes an app for granted: a canister's generated
24
+ * `./declarations/backend`, a `./reactor` module holding the setup, a
25
+ * name built earlier on the page. `scripts/check-snippets/` holds that app,
26
+ * and a document whose snippets assume another one gets its own, because
27
+ * documents can disagree. On the `v4` line the app holds only what no
28
+ * library export provides (`app/globals.ts`), the modules
29
+ * `meant gen` writes (`app/generated/`, for the guide's
30
+ * `./generated/icrc1` and `./generated/backend`) and the third-party
31
+ * declarations (`ambient.d.ts`). The 3.x fixtures went with the 3.x runtime.
32
+ *
33
+ * - `scripts/check-snippets/app/` is the app of every document not listed in
34
+ * CONTEXTS below. A context directory holds only what differs for its
35
+ * documents; everything else falls through to `app/`.
36
+ * - A relative import that resolves to nothing (`./reactor`,
37
+ * `../declarations/backend`) resolves to the module of the same path in the
38
+ * snippet's context directory, then in `app/`. The longest trailing part of
39
+ * the path that names one wins, so `./declarations/backend/declarations/backend`
40
+ * finds `declarations/backend.ts`.
41
+ * - An `@/` import, the alias Next.js and Vite apps give their `src/`
42
+ * (`@/canisters/ledger/reactor`), resolves the same way with the `@` taken
43
+ * off: to `canisters/ledger/reactor.ts` in the context directory, then in
44
+ * `app/`. An alias names a path from the root, so only the whole path is
45
+ * tried, never a trailing part of it: `reactor` alone would be some other
46
+ * module. The fixture is the app's module at that path, shaped as the real
47
+ * app's is.
48
+ * - The names `globals.ts` exports stand for names a snippet uses without
49
+ * importing or declaring them, such as a `clientManager` from an earlier
50
+ * snippet. Each snippet imports those it does not declare itself, on a line
51
+ * added above its first.
52
+ * - A third-party module a snippet imports is the real package when an example
53
+ * app installs it (DEPENDENCY_SOURCES below links their dependencies), such
54
+ * as `@tanstack/react-router`, `@tanstack/react-form`, `react-hook-form` and
55
+ * `next`. `ambient.d.ts` declares each of the rest once, after the package's
56
+ * own types, and only as far as the snippets reach. Two declarations of one
57
+ * module would merge into overloads and hide a snippet's mistake, and an
58
+ * ambient declaration wins over an installed package, so a module an app
59
+ * installs is never declared there.
60
+ *
61
+ * Declare a missing app name in a fixture. Do not rewrite a snippet to suit the
62
+ * checker. A `globals.ts` never exports a library export, or a hook that one
63
+ * returns: a snippet that uses one must import it, from the library or from the
64
+ * module that binds it, or an agent pasting it cannot run it. Nor is an ambient declaration bent
65
+ * to make a snippet pass: fix the snippet, as a reader would have to.
66
+ *
67
+ * ## The consumer guides
68
+ *
69
+ * `llms.txt`, `llms-full.txt`, each package's `llms.txt` and the consumer skill
70
+ * (`skill-packages/ic-reactor/`) are what an agent in another project reads,
71
+ * and it pastes their snippets into an app that has none of the names above.
72
+ * Two rules are stricter there:
73
+ *
74
+ * - A snippet gets no globals. Every name it uses is imported or declared in
75
+ * it.
76
+ * - A relative import resolves first to a module the guide shows: a snippet
77
+ * of the same document (or of the same skill) whose first line names its
78
+ * file, such as `// src/reactor.ts` for `./reactor`. Only a module the guide
79
+ * never shows, such as the canister's declarations, comes from a fixture.
80
+ *
81
+ * The docs site's build guides (`build/` under the docs content root) follow
82
+ * the same two rules: each one takes an app from nothing to working and shows
83
+ * every file of it, so a reader can paste each file as it stands.
84
+ *
85
+ * ## Hooks
86
+ *
87
+ * The compiler cannot see the rule the guides teach first: a React hook runs
88
+ * only inside a component or a custom hook. An agent pastes a snippet as it
89
+ * stands, so a snippet that calls `useActorQuery(...)` or `query.useQuery()` at
90
+ * the top of the module teaches code that throws. A call of a `useXxx`
91
+ * function or method fails the snippet when it is outside every function, in a
92
+ * class, or in a function that is neither a component (a capitalised name) nor
93
+ * a custom hook (`useXxx`); an anonymous callback such as `renderHook(() =>
94
+ * useX())` is let through, since it can be either. Wrap it in a component, as a
95
+ * reader's code would be.
96
+ *
97
+ * ## Opting out
98
+ *
99
+ * A fence that is not code to paste, such as a type signature or an interface
100
+ * restating a library type, opts out with `nocheck` after its language,
101
+ * ```ts nocheck, or with a first line of `// @snippet-skip`. Use it sparingly:
102
+ * a skipped snippet is one nothing verifies. Give a placeholder such as `...`
103
+ * a real value instead.
104
+ *
105
+ * Usage
106
+ * node scripts/check-snippets.mjs [--docs] [--verbose] [--keep] [path...]
107
+ *
108
+ * path... check only the files whose repo-relative path contains one of
109
+ * these strings
110
+ * --docs also check the docs site's MDX pages, gated like the rest
111
+ * (`pnpm check:snippets:docs`). A page compiles against its
112
+ * section's fixtures in `scripts/check-snippets/docs/<section>/`
113
+ * (the page's directory under the docs content root, `root` for
114
+ * a top-level page), then against the default app. Their
115
+ * examples import libraries the example apps install, so it
116
+ * needs `pnpm install` to have run for the examples too.
117
+ * --verbose list every snippet with its result
118
+ * --keep leave the temporary directory in place (debugging)
119
+ */
120
+ import {
121
+ cpSync,
122
+ existsSync,
123
+ mkdirSync,
124
+ mkdtempSync,
125
+ readFileSync,
126
+ readdirSync,
127
+ realpathSync,
128
+ rmSync,
129
+ statSync,
130
+ symlinkSync,
131
+ unlinkSync,
132
+ writeFileSync,
133
+ } from "node:fs"
134
+ import { createRequire } from "node:module"
135
+ import { tmpdir } from "node:os"
136
+ import { dirname, join, relative, sep } from "node:path"
137
+ import { fileURLToPath } from "node:url"
138
+ import { AI_CONTEXT_FILES } from "./ai-context-files.js"
139
+ import { closesFence, fenceOpening } from "./lib/markdown-fences.mjs"
140
+
141
+ const rootDir = join(dirname(fileURLToPath(import.meta.url)), "..")
142
+ const fixturesDir = join(rootDir, "scripts", "check-snippets")
143
+ const ts = createRequire(import.meta.url)("typescript")
144
+
145
+ const args = process.argv.slice(2)
146
+ const includeDocs = args.includes("--docs")
147
+ const verbose = args.includes("--verbose")
148
+ const keep = args.includes("--keep")
149
+ const filters = args.filter((arg) => !arg.startsWith("--"))
150
+
151
+ /** Fence languages that are compiled, and the extension each module gets. */
152
+ const LANGUAGES = { ts: ".ts", typescript: ".ts", tsx: ".tsx" }
153
+
154
+ const SKIP_INFO = "nocheck"
155
+ const SKIP_COMMENT = /^\s*\/\/\s*@snippet-skip\b/
156
+ /** A first line that is a triple-slash directive, such as `/// <reference lib="..." />`. */
157
+ const TRIPLE_SLASH = /^\s*\/\/\/\s*</
158
+
159
+ /**
160
+ * A first line naming the file the snippet is, such as `// src/reactor.ts`
161
+ * or `// app/Supply.tsx: a React Server Component`. It captures the path
162
+ * without its extension.
163
+ */
164
+ const MODULE_HEADER = /^\s*\/\/\s*((?:[\w.-]+\/)*[\w-]+)\.tsx?\b/
165
+
166
+ /**
167
+ * The guides an agent in a consumer project reads: the docs site's
168
+ * `llms.txt` and `llms-full.txt`, each package's `llms.txt` (shipped in its
169
+ * tarball) and the consumer skill. The agent pastes their snippets into an app
170
+ * that has none of this checker's globals, so a snippet there gets no
171
+ * globals: every name it uses is imported, declared, or exported by a module
172
+ * the guide itself shows.
173
+ */
174
+ function isConsumerGuide(file) {
175
+ return (
176
+ file === "llms.txt" ||
177
+ file === "llms-full.txt" ||
178
+ /^packages\/[^/]+\/llms\.txt$/.test(file) ||
179
+ file.startsWith("skill-packages/ic-reactor/")
180
+ )
181
+ }
182
+
183
+ /**
184
+ * The documents whose snippets share the modules they define: all the files
185
+ * of one skill (its SKILL.md and references), otherwise one document.
186
+ */
187
+ function moduleGroup(file) {
188
+ const skill = /^skill-packages\/[^/]+\//.exec(file)
189
+ return skill ? skill[0] : file
190
+ }
191
+
192
+ /** The default app, `scripts/check-snippets/app/`. */
193
+ const DEFAULT_CONTEXT = "app"
194
+
195
+ const DOCS_ROOT = "docs/src/content/docs/"
196
+
197
+ /**
198
+ * The context of a docs page: `docs/<section>` when
199
+ * `scripts/check-snippets/docs/<section>/` exists, where the section is the
200
+ * page's directory under the docs content root (`reference/factories`,
201
+ * `framework`) or `root` for a page at the top. A section's directory holds
202
+ * only what its pages assume beyond the default app; without one, the page
203
+ * gets the default app.
204
+ */
205
+ /**
206
+ * A build guide of the docs site: a page under `build/` that shows every file
207
+ * of the app it builds. Its snippets are held to the consumer guides' rules.
208
+ */
209
+ function isBuildGuide(file) {
210
+ return file.startsWith(`${DOCS_ROOT}build/`)
211
+ }
212
+
213
+ function docsContext(file) {
214
+ if (!file.startsWith(DOCS_ROOT)) return undefined
215
+ const dir = dirname(file.slice(DOCS_ROOT.length))
216
+ const context = `docs/${dir === "." ? "root" : dir}`
217
+ return existsSync(join(fixturesDir, context)) ? context : undefined
218
+ }
219
+
220
+ /**
221
+ * Documents whose snippets assume an app other than the default one, by
222
+ * repo-relative path, and the directory under `scripts/check-snippets/` that
223
+ * holds what differs.
224
+ */
225
+ const CONTEXTS = {}
226
+
227
+ /**
228
+ * The compiler options of Vite's React + TypeScript template, the setup most
229
+ * consumers paste into. `verbatimModuleSyntax` is on there, so a snippet that
230
+ * imports a type without `type` fails in that app and fails here. Unlike the
231
+ * template, `noUnusedLocals` and `noUnusedParameters` are off (a snippet
232
+ * declares names to show them, not to use them), and `@types/node` joins the
233
+ * template's `vite/client`, for the `vite.config.ts` and script snippets.
234
+ * `vite/client` types `import.meta.env`, where a Vite app reads a canister id.
235
+ * `allowImportingTsExtensions` is on, as in the template, so a script that
236
+ * Node runs as TypeScript can import `./tools.ts` as Node needs it to.
237
+ */
238
+ const COMPILER_OPTIONS = {
239
+ target: "ES2022",
240
+ lib: ["ES2022", "DOM", "DOM.Iterable"],
241
+ module: "ESNext",
242
+ moduleResolution: "bundler",
243
+ moduleDetection: "force",
244
+ verbatimModuleSyntax: true,
245
+ erasableSyntaxOnly: true,
246
+ allowImportingTsExtensions: true,
247
+ jsx: "react-jsx",
248
+ strict: true,
249
+ noEmit: true,
250
+ skipLibCheck: true,
251
+ noFallthroughCasesInSwitch: true,
252
+ types: ["node", "vite/client"],
253
+ }
254
+
255
+ /**
256
+ * Where third-party packages are linked from, in order of preference. A
257
+ * snippet can import anything a workspace package installs, and the first
258
+ * directory listed here that has it wins, so `react` and `@tanstack/*`
259
+ * resolve to the copies `@ic-reactor/react` itself compiles against.
260
+ *
261
+ * A docs page whose examples import a library no package installs (a router,
262
+ * a form library, `next`) needs an example app that installs it listed after
263
+ * the runtime packages, so that `react`, `@tanstack/react-query` and the rest
264
+ * keep the versions the packages themselves compile against.
265
+ * `examples/next-ssr` provides `next` for the SSR guide's App Router
266
+ * snippets (`next/server`, `next/headers`). A library only a build guide's app
267
+ * uses, and no example, is a devDependency of `docs`, listed last:
268
+ * `@modelcontextprotocol/server`, `@modelcontextprotocol/client` and `zod` for
269
+ * the agent tools guide.
270
+ */
271
+ const DEPENDENCY_SOURCES = [
272
+ "packages/react",
273
+ "packages/core",
274
+ "packages/vite-plugin",
275
+ ".",
276
+ "examples/next-ssr",
277
+ "docs",
278
+ ]
279
+
280
+ // ── Source files ─────────────────────────────────────────────────────────────
281
+
282
+ function walk(dir, predicate, out = []) {
283
+ // A tree that does not exist, such as skill-packages/ before a skill lands,
284
+ // holds no files.
285
+ if (!existsSync(dir)) return out
286
+ for (const entry of readdirSync(dir).sort()) {
287
+ const path = join(dir, entry)
288
+ if (statSync(path).isDirectory()) {
289
+ if (entry === "node_modules" || entry === "dist") continue
290
+ walk(path, predicate, out)
291
+ } else if (predicate(path)) {
292
+ out.push(path)
293
+ }
294
+ }
295
+ return out
296
+ }
297
+
298
+ const toPosix = (path) => path.split(sep).join("/")
299
+
300
+ const packageDirs = readdirSync(join(rootDir, "packages"))
301
+ .filter((dir) => existsSync(join(rootDir, "packages", dir, "package.json")))
302
+ .sort()
303
+
304
+ /**
305
+ * The files agents and npm readers are pointed at: the READMEs and guides, the
306
+ * skills, and every file of `scripts/ai-context-files.js`. The last is what
307
+ * ties this gate to `check:ai-context`: a file that script checks for stale
308
+ * versions and removed names, this one compiles the snippets of, so a guide
309
+ * (the DX3 `packages/core/llms.txt`, a skill, a pointer) is gated from the
310
+ * commit that adds it, with no second list to forget.
311
+ */
312
+ function gatedFiles() {
313
+ return [
314
+ ...new Set([
315
+ "llms.txt",
316
+ "llms-full.txt",
317
+ "README.md",
318
+ ...packageDirs.flatMap((dir) => [
319
+ `packages/${dir}/llms.txt`,
320
+ `packages/${dir}/README.md`,
321
+ ]),
322
+ ...walk(join(rootDir, "skill-packages"), (path) =>
323
+ path.endsWith(".md")
324
+ ).map((path) => toPosix(relative(rootDir, path))),
325
+ ...AI_CONTEXT_FILES,
326
+ ]),
327
+ ].filter((file) => existsSync(join(rootDir, file)))
328
+ }
329
+
330
+ /** The docs site's hand-written pages; `libs/` is TypeDoc output. */
331
+ function docsFiles() {
332
+ const docsDir = join(rootDir, "docs", "src", "content", "docs")
333
+ return walk(docsDir, (path) => path.endsWith(".mdx"))
334
+ .filter((path) => !path.startsWith(join(docsDir, "libs") + sep))
335
+ .map((path) => toPosix(relative(rootDir, path)))
336
+ }
337
+
338
+ // ── Fence extraction ─────────────────────────────────────────────────────────
339
+
340
+ /**
341
+ * The fenced code blocks of a Markdown (or MDX) file, by the rule in
342
+ * `lib/markdown-fences.mjs`. A fence that is never closed runs to the end of
343
+ * the file, as CommonMark has it, so its code is checked rather than dropped
344
+ * (#980). The opening fence's indentation is removed from each line (fences
345
+ * nested in lists and MDX components are indented).
346
+ *
347
+ * @returns {{ lang: string, info: string[], line: number, code: string }[]}
348
+ * `line` is the 1-based line of the fence's first line of code.
349
+ */
350
+ function extractFences(text) {
351
+ const lines = text.split("\n")
352
+ const fences = []
353
+ let open = null
354
+ for (let i = 0; i < lines.length; i++) {
355
+ const line = lines[i]
356
+ if (open === null) {
357
+ const opening = fenceOpening(line)
358
+ if (opening) open = { ...opening, line: i + 2, body: [] }
359
+ continue
360
+ }
361
+ if (closesFence(line, open.marker)) {
362
+ const { lang, info, line: start, body } = open
363
+ fences.push({ lang, info, line: start, code: body.join("\n") })
364
+ open = null
365
+ continue
366
+ }
367
+ const indent = /^\s*/.exec(line)[0].length
368
+ open.body.push(line.slice(Math.min(indent, open.indent)))
369
+ }
370
+ if (open !== null) {
371
+ const { lang, info, line: start, body } = open
372
+ fences.push({ lang, info, line: start, code: body.join("\n") })
373
+ }
374
+ return fences
375
+ }
376
+
377
+ function collectSnippets(files, docs) {
378
+ const snippets = []
379
+ for (const file of files) {
380
+ const text = readFileSync(join(rootDir, file), "utf8")
381
+ for (const fence of extractFences(text)) {
382
+ if (!(fence.lang in LANGUAGES)) continue
383
+ const firstLine = fence.code.split("\n").find((l) => l.trim() !== "")
384
+ const skipped =
385
+ fence.info.includes(SKIP_INFO) ||
386
+ (firstLine !== undefined && SKIP_COMMENT.test(firstLine))
387
+ const defines =
388
+ firstLine === undefined ? undefined : MODULE_HEADER.exec(firstLine)
389
+ snippets.push({
390
+ file,
391
+ line: fence.line,
392
+ lang: fence.lang,
393
+ code: fence.code,
394
+ context: CONTEXTS[file] ?? docsContext(file) ?? DEFAULT_CONTEXT,
395
+ group: moduleGroup(file),
396
+ defines: defines ? defines[1].split("/") : undefined,
397
+ selfContained: isConsumerGuide(file) || isBuildGuide(file),
398
+ skipped,
399
+ docs,
400
+ })
401
+ }
402
+ }
403
+ return snippets
404
+ }
405
+
406
+ // ── The app a snippet assumes ────────────────────────────────────────────────
407
+
408
+ /** Whether a statement carries the `export` modifier. */
409
+ const isExported = (node) =>
410
+ ts.getModifiers?.(node)?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)
411
+
412
+ /** The names a binding (`a`, `{ a, b: c }`, `[d, ...e]`) declares. */
413
+ function bindingNames(name, out = []) {
414
+ if (ts.isIdentifier(name)) out.push(name.text)
415
+ else
416
+ for (const element of name.elements) {
417
+ if (!ts.isOmittedExpression(element)) bindingNames(element.name, out)
418
+ }
419
+ return out
420
+ }
421
+
422
+ function parse(fileName, text) {
423
+ return ts.createSourceFile(fileName, text, ts.ScriptTarget.Latest, true)
424
+ }
425
+
426
+ /**
427
+ * The names a context's `globals.ts` exports, each marked as a type or a
428
+ * value, following its `export * from "..."` statements.
429
+ *
430
+ * @returns {Map<string, "type" | "value">}
431
+ */
432
+ function globalNames(file, seen = new Set()) {
433
+ const names = new Map()
434
+ if (seen.has(file)) return names
435
+ seen.add(file)
436
+ for (const statement of parse(file, readFileSync(file, "utf8")).statements) {
437
+ if (
438
+ ts.isExportDeclaration(statement) &&
439
+ !statement.exportClause &&
440
+ statement.moduleSpecifier
441
+ ) {
442
+ const target = join(dirname(file), statement.moduleSpecifier.text)
443
+ for (const [name, kind] of globalNames(`${target}.ts`, seen)) {
444
+ if (!names.has(name)) names.set(name, kind)
445
+ }
446
+ } else if (ts.isExportDeclaration(statement) && statement.exportClause) {
447
+ for (const element of statement.exportClause.elements) {
448
+ const isType = statement.isTypeOnly || element.isTypeOnly
449
+ names.set(element.name.text, isType ? "type" : "value")
450
+ }
451
+ } else if (!isExported(statement)) {
452
+ continue
453
+ } else if (ts.isVariableStatement(statement)) {
454
+ for (const declaration of statement.declarationList.declarations) {
455
+ for (const name of bindingNames(declaration.name)) {
456
+ names.set(name, "value")
457
+ }
458
+ }
459
+ } else if (
460
+ ts.isInterfaceDeclaration(statement) ||
461
+ ts.isTypeAliasDeclaration(statement)
462
+ ) {
463
+ names.set(statement.name.text, "type")
464
+ } else if (statement.name && ts.isIdentifier(statement.name)) {
465
+ names.set(statement.name.text, "value")
466
+ }
467
+ }
468
+ return names
469
+ }
470
+
471
+ /** The names a snippet declares or imports at its top level. */
472
+ function declaredNames(sourceFile) {
473
+ const names = new Set()
474
+ for (const statement of sourceFile.statements) {
475
+ if (ts.isImportDeclaration(statement)) {
476
+ const clause = statement.importClause
477
+ if (!clause) continue
478
+ if (clause.name) names.add(clause.name.text)
479
+ const bindings = clause.namedBindings
480
+ if (bindings && ts.isNamespaceImport(bindings)) {
481
+ names.add(bindings.name.text)
482
+ } else if (bindings) {
483
+ for (const element of bindings.elements) names.add(element.name.text)
484
+ }
485
+ } else if (ts.isVariableStatement(statement)) {
486
+ for (const declaration of statement.declarationList.declarations) {
487
+ for (const name of bindingNames(declaration.name)) names.add(name)
488
+ }
489
+ } else if (statement.name && ts.isIdentifier(statement.name)) {
490
+ names.add(statement.name.text)
491
+ }
492
+ }
493
+ return names
494
+ }
495
+
496
+ /**
497
+ * The `@/` alias of Next.js and Vite apps: `@/canisters/ledger/reactor` is
498
+ * `src/canisters/ledger/reactor`, whichever module imports it.
499
+ */
500
+ const isAppAlias = (specifier) => specifier.startsWith("@/")
501
+
502
+ /**
503
+ * The path segments of an import that name the module: a relative import's
504
+ * without its `.` and `..`, an `@/` import's without the alias, and either
505
+ * without a `.ts` or `.tsx` extension, which a script Node runs as
506
+ * TypeScript writes (`./generated/icrc1.ts`).
507
+ */
508
+ function moduleSegments(specifier) {
509
+ return (isAppAlias(specifier) ? specifier.slice(1) : specifier)
510
+ .replace(/\.tsx?$/, "")
511
+ .split("/")
512
+ .filter((segment) => segment !== "" && segment !== "." && segment !== "..")
513
+ }
514
+
515
+ /**
516
+ * The module a relative or `@/` import names in `context`: the longest
517
+ * trailing part of its path that is a file in the context directory, then in
518
+ * `app/`. An `@/` import is anchored at the alias's root (`src/`), so only its
519
+ * whole path is tried: a trailing part of `@/canisters/ledger/reactor` such as
520
+ * `reactor` would name some other module.
521
+ */
522
+ function findFixture(project, context, specifier) {
523
+ const segments = moduleSegments(specifier)
524
+ const contexts = [...new Set([context, DEFAULT_CONTEXT])]
525
+ const last = isAppAlias(specifier) ? 1 : segments.length
526
+ for (let start = 0; start < last; start++) {
527
+ const path = segments.slice(start).join("/")
528
+ for (const name of contexts) {
529
+ for (const candidate of [
530
+ `${path}.ts`,
531
+ `${path}.tsx`,
532
+ `${path}/index.ts`,
533
+ ]) {
534
+ const file = join(project, "fixtures", name, candidate)
535
+ if (existsSync(file)) return file
536
+ }
537
+ }
538
+ }
539
+ return undefined
540
+ }
541
+
542
+ /**
543
+ * The snippet module a relative import of a consumer guide or a build guide
544
+ * names when the guide shows that module itself: a snippet of the same
545
+ * document, or of the same skill, whose first line names a path ending in the
546
+ * import's
547
+ * (`// src/reactor.ts` for `./reactor`). The nearest one above the importing
548
+ * snippet wins, then the first below it, then the first in another file of
549
+ * the skill. The import is then checked against the module the reader was
550
+ * shown, and a fixture cannot hide a name that module does not export.
551
+ *
552
+ * The READMEs keep their fixtures: they show a module such as `src/reactor.ts`
553
+ * several times, once per alternative setup, and later sections mean the
554
+ * first.
555
+ */
556
+ function findPageModule(byModule, snippet, specifier) {
557
+ if (!snippet.selfContained) return undefined
558
+ const segments = moduleSegments(specifier)
559
+ const matches = (other) =>
560
+ other !== snippet &&
561
+ other.group === snippet.group &&
562
+ other.defines !== undefined &&
563
+ other.defines.length >= segments.length &&
564
+ other.defines.slice(-segments.length).join("/") === segments.join("/")
565
+ const candidates = [...byModule].filter(([, other]) => matches(other))
566
+ const rank = ([, other]) =>
567
+ other.file !== snippet.file
568
+ ? Number.MAX_SAFE_INTEGER
569
+ : other.line < snippet.line
570
+ ? snippet.line - other.line
571
+ : Number.MAX_SAFE_INTEGER / 2 + other.line
572
+ candidates.sort((a, b) => rank(a) - rank(b))
573
+ return candidates[0]?.[0]
574
+ }
575
+
576
+ // ── The compilation ──────────────────────────────────────────────────────────
577
+
578
+ function readJson(path) {
579
+ return JSON.parse(readFileSync(path, "utf8"))
580
+ }
581
+
582
+ /** The installed packages under `nodeModules`, scoped ones as `@scope/name`. */
583
+ function installedPackages(nodeModules) {
584
+ if (!existsSync(nodeModules)) return []
585
+ return readdirSync(nodeModules)
586
+ .filter((entry) => !entry.startsWith("."))
587
+ .flatMap((entry) =>
588
+ entry.startsWith("@")
589
+ ? readdirSync(join(nodeModules, entry)).map((n) => `${entry}/${n}`)
590
+ : [entry]
591
+ )
592
+ }
593
+
594
+ /**
595
+ * Links every workspace package, and every dependency installed for one, into
596
+ * `project/node_modules`. Returns the links, so they can be removed before the
597
+ * directory is: they point into the workspace.
598
+ */
599
+ function linkPackages(project) {
600
+ // The docs pages import libraries only an example app installs. Without
601
+ // them their imports fail one by one as missing modules, which hides what
602
+ // is wrong. CI installs the workspace without the examples, and checks only
603
+ // the guides, skills and READMEs, which need none of them.
604
+ for (const source of DEPENDENCY_SOURCES) {
605
+ if (
606
+ includeDocs &&
607
+ source.startsWith("examples/") &&
608
+ !existsSync(join(rootDir, source, "node_modules"))
609
+ ) {
610
+ throw new Error(
611
+ `${source} is not installed, and the docs pages import libraries it provides. Run \`pnpm install\` without \`--filter '!./examples/**'\`.`
612
+ )
613
+ }
614
+ }
615
+ const links = []
616
+ const linked = new Set()
617
+ const link = (target, name) => {
618
+ if (linked.has(name)) return
619
+ linked.add(name)
620
+ const path = join(project, "node_modules", name)
621
+ mkdirSync(dirname(path), { recursive: true })
622
+ symlinkSync(target, path, "dir")
623
+ links.push(path)
624
+ }
625
+ for (const dir of packageDirs) {
626
+ const packageDir = join(rootDir, "packages", dir)
627
+ const manifest = readJson(join(packageDir, "package.json"))
628
+ if (manifest.private !== true && !existsSync(join(packageDir, "dist"))) {
629
+ throw new Error(
630
+ `${manifest.name} is not built (no dist/). Run \`pnpm build\` first.`
631
+ )
632
+ }
633
+ link(packageDir, manifest.name)
634
+ }
635
+ for (const source of DEPENDENCY_SOURCES) {
636
+ const sourceModules = join(rootDir, source, "node_modules")
637
+ for (const name of installedPackages(sourceModules)) {
638
+ link(join(sourceModules, name), name)
639
+ }
640
+ }
641
+ return links
642
+ }
643
+
644
+ /**
645
+ * Writes each snippet to `project/snippets/`, preceded by an import of the
646
+ * globals it does not declare, and returns them by absolute module path.
647
+ */
648
+ function writeSnippets(project, snippets) {
649
+ const globals = new Map()
650
+ const byModule = new Map()
651
+ mkdirSync(join(project, "snippets"), { recursive: true })
652
+ for (const snippet of snippets) {
653
+ const slug = snippet.file.replace(/[^A-Za-z0-9]+/g, "_")
654
+ const modulePath = toPosix(
655
+ join(
656
+ project,
657
+ "snippets",
658
+ `${slug}_L${snippet.line}${LANGUAGES[snippet.lang]}`
659
+ )
660
+ )
661
+
662
+ const contextDir = join(project, "fixtures", snippet.context)
663
+ const globalsFile = existsSync(join(contextDir, "globals.ts"))
664
+ ? join(contextDir, "globals.ts")
665
+ : join(project, "fixtures", DEFAULT_CONTEXT, "globals.ts")
666
+ if (!globals.has(globalsFile)) {
667
+ globals.set(globalsFile, globalNames(globalsFile))
668
+ }
669
+ const declared = declaredNames(parse(modulePath, snippet.code))
670
+ const imported = snippet.selfContained
671
+ ? []
672
+ : [...globals.get(globalsFile)]
673
+ .filter(([name]) => !declared.has(name))
674
+ .map(([name, kind]) => (kind === "type" ? `type ${name}` : name))
675
+ const specifier = toPosix(
676
+ relative(dirname(modulePath), globalsFile)
677
+ ).replace(/\.ts$/, "")
678
+ const prelude =
679
+ imported.length > 0
680
+ ? `import { ${imported.join(", ")} } from "${specifier}"\n`
681
+ : ""
682
+
683
+ // A triple-slash directive (`/// <reference lib="es2023.intl" />`) counts
684
+ // only above the first statement, so a snippet that opens with one gets
685
+ // the import after its code instead: an import is hoisted wherever it is.
686
+ const directive = TRIPLE_SLASH.test(snippet.code)
687
+ writeFileSync(
688
+ modulePath,
689
+ directive ? snippet.code + "\n" + prelude : prelude + snippet.code + "\n"
690
+ )
691
+ snippet.offset = prelude === "" || directive ? 0 : 1
692
+ byModule.set(modulePath, snippet)
693
+ }
694
+ return byModule
695
+ }
696
+
697
+ /**
698
+ * Compiles the snippets in one program and returns its diagnostics, each
699
+ * mapped back to the Markdown line it came from.
700
+ *
701
+ * This drives the compiler API rather than `tsc`: `tsc` reports no type errors
702
+ * at all while any file has a syntax error, so one malformed snippet would
703
+ * hide every other failure. Here a snippet with a syntax error reports only
704
+ * those, and every other snippet is still checked.
705
+ */
706
+ function compile(project, byModule) {
707
+ const { options, errors } = ts.convertCompilerOptionsFromJson(
708
+ COMPILER_OPTIONS,
709
+ project
710
+ )
711
+ if (errors.length > 0) {
712
+ throw new Error(
713
+ ts.flattenDiagnosticMessageText(errors[0].messageText, "\n")
714
+ )
715
+ }
716
+ const host = ts.createCompilerHost(options)
717
+ // `types` and the other lookups a program without a tsconfig makes start
718
+ // from the current directory; make that the project, wherever this runs.
719
+ host.getCurrentDirectory = () => project
720
+ const cache = ts.createModuleResolutionCache(project, (name) => name, options)
721
+ const snippetModule = (fileName) => ({
722
+ resolvedModule: {
723
+ resolvedFileName: fileName,
724
+ extension: fileName.endsWith(".tsx") ? ts.Extension.Tsx : ts.Extension.Ts,
725
+ isExternalLibraryImport: false,
726
+ },
727
+ })
728
+ host.resolveModuleNameLiterals = (
729
+ literals,
730
+ containingFile,
731
+ redirectedReference,
732
+ compilerOptions,
733
+ containingSourceFile
734
+ ) =>
735
+ literals.map((literal) => {
736
+ const snippet = byModule.get(containingFile)
737
+ const resolved = ts.resolveModuleName(
738
+ literal.text,
739
+ containingFile,
740
+ compilerOptions,
741
+ host,
742
+ cache,
743
+ redirectedReference,
744
+ ts.getModeForUsageLocation(
745
+ containingSourceFile,
746
+ literal,
747
+ compilerOptions
748
+ )
749
+ )
750
+ if (
751
+ resolved.resolvedModule ||
752
+ !snippet ||
753
+ !(literal.text.startsWith(".") || isAppAlias(literal.text))
754
+ ) {
755
+ return resolved
756
+ }
757
+ const shown = findPageModule(byModule, snippet, literal.text)
758
+ if (shown) return snippetModule(shown)
759
+ const fixture = findFixture(project, snippet.context, literal.text)
760
+ return fixture ? snippetModule(fixture) : resolved
761
+ })
762
+
763
+ const program = ts.createProgram({
764
+ rootNames: [join(project, "fixtures", "ambient.d.ts"), ...byModule.keys()],
765
+ options,
766
+ host,
767
+ })
768
+
769
+ const found = [
770
+ ...program.getOptionsDiagnostics(),
771
+ ...program.getGlobalDiagnostics(),
772
+ ]
773
+ for (const sourceFile of program.getSourceFiles()) {
774
+ if (!sourceFile.fileName.startsWith(toPosix(project) + "/")) continue
775
+ if (sourceFile.fileName.includes("/node_modules/")) continue
776
+ const syntactic = program.getSyntacticDiagnostics(sourceFile)
777
+ found.push(
778
+ ...(syntactic.length > 0
779
+ ? syntactic
780
+ : program.getSemanticDiagnostics(sourceFile))
781
+ )
782
+ }
783
+
784
+ return found.map((diagnostic) => {
785
+ const message = ts.flattenDiagnosticMessageText(
786
+ diagnostic.messageText,
787
+ "\n "
788
+ )
789
+ const code = `TS${diagnostic.code}`
790
+ if (!diagnostic.file || diagnostic.start === undefined) {
791
+ return { snippet: undefined, where: "", code, message }
792
+ }
793
+ const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(
794
+ diagnostic.start
795
+ )
796
+ const snippet = byModule.get(diagnostic.file.fileName)
797
+ if (!snippet) {
798
+ const file = toPosix(relative(project, diagnostic.file.fileName))
799
+ return {
800
+ snippet: undefined,
801
+ where: `${file.replace(/^fixtures\//, "scripts/check-snippets/")}:${line + 1}:${character + 1}`,
802
+ code,
803
+ message,
804
+ }
805
+ }
806
+ // An error on the added import line names a global the snippet shadows
807
+ // or misuses; report it on the snippet's first line.
808
+ const row = Math.max(line - snippet.offset, 0)
809
+ return {
810
+ snippet,
811
+ where: `${snippet.file}:${snippet.line + row}:${character + 1}`,
812
+ code,
813
+ message,
814
+ }
815
+ })
816
+ }
817
+
818
+ // ── Hooks outside a component ────────────────────────────────────────────────
819
+
820
+ /** The name a function is declared or assigned under, if it has one. */
821
+ function functionName(node) {
822
+ if (node.name && ts.isIdentifier(node.name)) return node.name.text
823
+ const parent = node.parent
824
+ if (
825
+ parent &&
826
+ ts.isVariableDeclaration(parent) &&
827
+ ts.isIdentifier(parent.name)
828
+ )
829
+ return parent.name.text
830
+ if (parent && ts.isPropertyAssignment(parent) && ts.isIdentifier(parent.name))
831
+ return parent.name.text
832
+ return undefined
833
+ }
834
+
835
+ /**
836
+ * What surrounds a hook call: `"ok"` inside a component (a function named with
837
+ * a capital) or a custom hook (`useXxx`), or inside an anonymous callback of
838
+ * some call (`renderHook(() => useX())`, `memo(() => ...)`), which can be
839
+ * either; `"outside"` with no function at all; `"helper"` in a class or in a
840
+ * function named otherwise (`handleClick`, `load`), where React throws.
841
+ */
842
+ function hookContext(call) {
843
+ let anonymousCallback = false
844
+ for (let node = call.parent; node; node = node.parent) {
845
+ if (ts.isClassLike(node)) return "helper"
846
+ if (!ts.isFunctionLike(node)) continue
847
+ const name = functionName(node)
848
+ if (name !== undefined) {
849
+ return /^[A-Z]/.test(name) || /^use[A-Z]/.test(name) ? "ok" : "helper"
850
+ }
851
+ if (node.parent && ts.isCallExpression(node.parent))
852
+ anonymousCallback = true
853
+ }
854
+ return anonymousCallback ? "ok" : "outside"
855
+ }
856
+
857
+ /**
858
+ * A call of a hook (`useXxx(...)` or `something.useXxx(...)`) outside a
859
+ * component or a custom hook, reported as a diagnostic of its snippet.
860
+ * TypeScript accepts one, and React throws when it runs.
861
+ */
862
+ function hookDiagnostics(byModule) {
863
+ const found = []
864
+ for (const snippet of byModule.values()) {
865
+ const extension = LANGUAGES[snippet.lang]
866
+ const source = ts.createSourceFile(
867
+ `snippet${extension}`,
868
+ snippet.code,
869
+ ts.ScriptTarget.Latest,
870
+ true,
871
+ extension === ".tsx" ? ts.ScriptKind.TSX : ts.ScriptKind.TS
872
+ )
873
+ const visit = (node) => {
874
+ if (ts.isCallExpression(node)) {
875
+ const callee = node.expression
876
+ const name = ts.isIdentifier(callee)
877
+ ? callee.text
878
+ : ts.isPropertyAccessExpression(callee)
879
+ ? callee.name.text
880
+ : ""
881
+ if (/^use[A-Z]/.test(name)) {
882
+ const context = hookContext(node)
883
+ if (context !== "ok") {
884
+ const { line, character } = source.getLineAndCharacterOfPosition(
885
+ node.getStart(source)
886
+ )
887
+ found.push({
888
+ snippet,
889
+ where: `${snippet.file}:${snippet.line + line}:${character + 1}`,
890
+ code: "hooks",
891
+ message: `\`${name}\` is a React hook, called ${context === "outside" ? "outside any function" : "in a helper or a class, which is neither a component (capitalised) nor a custom hook (useXxx)"}. Call it from a component or a custom hook.`,
892
+ })
893
+ }
894
+ }
895
+ }
896
+ ts.forEachChild(node, visit)
897
+ }
898
+ visit(source)
899
+ }
900
+ return found
901
+ }
902
+
903
+ // ── Main ─────────────────────────────────────────────────────────────────────
904
+
905
+ const matches = (file) =>
906
+ filters.length === 0 || filters.some((filter) => file.includes(filter))
907
+ const snippets = [
908
+ ...collectSnippets(gatedFiles().filter(matches), false),
909
+ ...(includeDocs ? collectSnippets(docsFiles().filter(matches), true) : []),
910
+ ]
911
+
912
+ // Its real path: TypeScript names the files it reads by theirs, and a
913
+ // temporary directory can sit behind a symlink (/var -> /private/var on macOS).
914
+ const project = realpathSync(
915
+ mkdtempSync(join(tmpdir(), "ic-reactor-snippets-"))
916
+ )
917
+ let links = []
918
+ let exitCode = 1
919
+ try {
920
+ links = linkPackages(project)
921
+ cpSync(fixturesDir, join(project, "fixtures"), { recursive: true })
922
+ const byModule = writeSnippets(
923
+ project,
924
+ snippets.filter((snippet) => !snippet.skipped)
925
+ )
926
+ const diagnostics = [
927
+ ...compile(project, byModule),
928
+ ...hookDiagnostics(byModule),
929
+ ]
930
+
931
+ const failed = new Set(diagnostics.map((d) => d.snippet).filter(Boolean))
932
+ const fixtureErrors = diagnostics.filter((d) => !d.snippet)
933
+
934
+ if (verbose) {
935
+ for (const snippet of snippets) {
936
+ const state = snippet.skipped
937
+ ? "skip"
938
+ : failed.has(snippet)
939
+ ? "FAIL"
940
+ : "ok "
941
+ // The line of the opening fence
942
+ console.log(`${state} ${snippet.file}:${snippet.line - 1}`)
943
+ }
944
+ console.log("")
945
+ }
946
+ for (const { snippet, where, code, message } of diagnostics) {
947
+ console.log(`${where ? `${where} ` : ""}${code}: ${message}`)
948
+ }
949
+ if (diagnostics.length > 0) console.log("")
950
+
951
+ const report = (label, list) => {
952
+ const failures = list.filter((s) => failed.has(s)).length
953
+ const skipped = list.filter((s) => s.skipped).length
954
+ console.log(
955
+ `${label}: ${list.length - skipped} checked (${list.length - skipped - failures} passed, ${failures} failed), ${skipped} skipped`
956
+ )
957
+ return failures
958
+ }
959
+ let gatedFailures = report(
960
+ "Guides, skills and READMEs",
961
+ snippets.filter((s) => !s.docs)
962
+ )
963
+ if (includeDocs) {
964
+ gatedFailures += report(
965
+ "Docs pages",
966
+ snippets.filter((s) => s.docs)
967
+ )
968
+ }
969
+
970
+ if (fixtureErrors.length > 0) {
971
+ console.error(
972
+ "✖ The snippets' app in scripts/check-snippets/ does not compile."
973
+ )
974
+ } else if (gatedFailures > 0) {
975
+ console.error(
976
+ "✖ Fix each failing snippet in its file. Only a name the snippet's app would define belongs in scripts/check-snippets/ (a docs page's in scripts/check-snippets/docs/<section>/); a deliberate fragment is marked ```ts nocheck."
977
+ )
978
+ } else {
979
+ exitCode = 0
980
+ console.log("✔ Every checked snippet compiles")
981
+ }
982
+ } catch (error) {
983
+ console.error(`✖ ${error.stack ?? error.message}`)
984
+ } finally {
985
+ if (keep) {
986
+ console.log(` project kept at ${project}`)
987
+ } else {
988
+ for (const link of links) unlinkSync(link)
989
+ rmSync(project, { recursive: true, force: true })
990
+ }
991
+ }
992
+ // Not process.exit(): it can cut off output still being written to a pipe.
993
+ process.exitCode = exitCode