@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.
- package/.github/ISSUE_TEMPLATE/bug_report.yml +108 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +77 -0
- package/.github/actions/setup-rust-wasm/action.yml +25 -0
- package/.github/dependabot.yml +107 -0
- package/.github/workflows/auth-latest.yml +67 -0
- package/.github/workflows/b3pay-site.yml +49 -0
- package/.github/workflows/ci.yml +430 -0
- package/.github/workflows/codeql.yml +41 -0
- package/.github/workflows/dependency-review.yml +68 -0
- package/.github/workflows/docs-check.yml +98 -0
- package/.github/workflows/docs.yml +265 -0
- package/.github/workflows/e2e.yml +90 -0
- package/.github/workflows/examples-published.yml +97 -0
- package/.github/workflows/release.yml +326 -0
- package/.husky/pre-commit +12 -0
- package/.prettierignore +109 -0
- package/.prettierrc +6 -0
- package/AGENTS.md +103 -0
- package/CHANGELOG.md +3268 -0
- package/CLAUDE.md +93 -0
- package/CNAME +1 -0
- package/CODE_OF_CONDUCT.md +7 -0
- package/CONTRIBUTING.md +433 -0
- package/LICENSE +21 -0
- package/README.md +2 -2
- package/SECURITY.md +74 -0
- package/b3pay-module.json +194 -0
- package/docs/.remarkrc.json +10 -0
- package/docs/README.md +64 -0
- package/docs/astro.config.mjs +205 -0
- package/docs/favicon.svg +15 -0
- package/docs/package.json +39 -0
- package/docs/public/favicon.svg +15 -0
- package/docs/public/ic-reactor-social-card.png +0 -0
- package/docs/scripts/b3pay-static.mjs +22 -0
- package/docs/scripts/check-example-docs.mjs +214 -0
- package/docs/scripts/check-links.mjs +212 -0
- package/docs/scripts/fix-dist-links.js +125 -0
- package/docs/scripts/fix-frontmatter.js +71 -0
- package/docs/scripts/remove-redundant-h1.cjs +48 -0
- package/docs/scripts/rewrite-typedoc-links.js +110 -0
- package/docs/scripts/split-index.js +69 -0
- package/docs/src/assets/ic-reactor-hero-dark.svg +23 -0
- package/docs/src/assets/ic-reactor-hero-light.svg +23 -0
- package/docs/src/assets/ic-reactor-lockup-dark.svg +15 -0
- package/docs/src/assets/ic-reactor-lockup-light.svg +15 -0
- package/docs/src/assets/ic-reactor-mark-dark.svg +14 -0
- package/docs/src/assets/ic-reactor-mark-light.svg +14 -0
- package/docs/src/assets/layers/candid-core-layer-icon-dark.svg +4 -0
- package/docs/src/assets/layers/candid-core-layer-icon-light.svg +4 -0
- package/docs/src/assets/layers/candid-profile-layer-icon-dark.svg +4 -0
- package/docs/src/assets/layers/candid-profile-layer-icon-light.svg +4 -0
- package/docs/src/assets/layers/ic-reactor-layer-icon-dark.svg +4 -0
- package/docs/src/assets/layers/ic-reactor-layer-icon-light.svg +4 -0
- package/docs/src/components/LibraryCards.astro +172 -0
- package/docs/src/components/LibraryIcon.astro +28 -0
- package/docs/src/components/SiteTitle.astro +241 -0
- package/docs/src/content/docs/404.mdx +19 -0
- package/docs/src/content/docs/build/agent-tools.mdx +593 -0
- package/docs/src/content/docs/build/icrc1-wallet.mdx +619 -0
- package/docs/src/content/docs/build/ssr-per-user.mdx +552 -0
- package/docs/src/content/docs/examples/canister-studio.mdx +95 -0
- package/docs/src/content/docs/examples/icrc-ledger.mdx +45 -0
- package/docs/src/content/docs/examples/index.mdx +38 -0
- package/docs/src/content/docs/examples/next-ssr.mdx +73 -0
- package/docs/src/content/docs/examples/node-agent-tool.mdx +80 -0
- package/docs/src/content/docs/examples/vite-wallet.mdx +71 -0
- package/docs/src/content/docs/guides/auth.mdx +1181 -0
- package/docs/src/content/docs/guides/client.mdx +551 -0
- package/docs/src/content/docs/guides/deploy.mdx +180 -0
- package/docs/src/content/docs/guides/errors.mdx +475 -0
- package/docs/src/content/docs/guides/getting-started.mdx +620 -0
- package/docs/src/content/docs/guides/reads.mdx +586 -0
- package/docs/src/content/docs/guides/ssr.mdx +529 -0
- package/docs/src/content/docs/guides/testing.mdx +401 -0
- package/docs/src/content/docs/guides/values.mdx +261 -0
- package/docs/src/content/docs/guides/vite-plugin.mdx +690 -0
- package/docs/src/content/docs/guides/writes.mdx +572 -0
- package/docs/src/content/docs/ic-reactor/index.mdx +167 -0
- package/docs/src/content/docs/index.mdx +65 -0
- package/docs/src/content/docs/migrating-from-3.mdx +535 -0
- package/docs/src/content/docs/packages/core.mdx +186 -0
- package/docs/src/content/docs/packages/mcp.mdx +163 -0
- package/docs/src/content/docs/packages/react.mdx +207 -0
- package/docs/src/content/docs/packages/vite-plugin.mdx +73 -0
- package/docs/src/content/docs/versioning.mdx +104 -0
- package/docs/src/content.config.ts +7 -0
- package/docs/src/styles/custom.css +189 -0
- package/docs/tsconfig.typedoc.json +26 -0
- package/docs/typedoc-entry.ts +17 -0
- package/docs/typedoc.json +37 -0
- package/e2e/Cargo.lock +646 -0
- package/e2e/Cargo.toml +3 -0
- package/e2e/README.md +101 -0
- package/e2e/frontends/build.mjs +94 -0
- package/e2e/frontends/index.html +10 -0
- package/e2e/global-setup.ts +65 -0
- package/e2e/icp.yaml +38 -0
- package/e2e/package.json +40 -0
- package/e2e/setup.ts +6 -0
- package/e2e/src/actor/Cargo.toml +14 -0
- package/e2e/src/actor/hello_actor.did +10 -0
- package/e2e/src/actor/src/lib.rs +73 -0
- package/e2e/src/calls.test.ts +132 -0
- package/e2e/src/declarations/hello_actor.envelope.json +175 -0
- package/e2e/src/declarations/hello_actor.ts +15 -0
- package/e2e/src/errors.test.ts +107 -0
- package/e2e/src/frontend-headers.test.ts +253 -0
- package/e2e/src/identity.test.ts +61 -0
- package/e2e/src/react.test.tsx +59 -0
- package/e2e/src/replica.ts +70 -0
- package/e2e/src/vite-env.test.ts +108 -0
- package/e2e/test.sh +47 -0
- package/e2e/tsconfig.json +20 -0
- package/e2e/tsconfig.typecheck.json +9 -0
- package/e2e/vitest.config.ts +22 -0
- package/eslint.config.mjs +100 -0
- package/evals/PREREGISTRATION.md +1346 -0
- package/evals/README.md +756 -0
- package/evals/conditions/thin/condition.json +8 -0
- package/evals/conditions/thin/docs/candid-core-cli.README.md +90 -0
- package/evals/conditions/thin/docs/candid-core-schema.README.md +339 -0
- package/evals/conditions/thin/package.json +25 -0
- package/evals/conditions/thin/starter/src/generated/icrc1.ts +57 -0
- package/evals/conditions/thin-guide/condition.json +10 -0
- package/evals/conditions/thin-guide/docs/llms.txt +292 -0
- package/evals/conditions/v3/condition.json +9 -0
- package/evals/conditions/v3/docs/ic-reactor-core.llms.txt +232 -0
- package/evals/conditions/v3/docs/ic-reactor-react.llms.txt +280 -0
- package/evals/conditions/v3/docs/llms-full.txt +1053 -0
- package/evals/conditions/v3/package.json +26 -0
- package/evals/conditions/v3/starter/src/declarations/icrc1.did.d.ts +95 -0
- package/evals/conditions/v3/starter/src/declarations/icrc1.did.js +140 -0
- package/evals/conditions/v4/PORTING.md +384 -0
- package/evals/conditions/v4/README.md +106 -0
- package/evals/conditions/v4/condition.json +5 -0
- package/evals/conditions/v4/docs/llms.txt +323 -0
- package/evals/conditions/v4/package.json +27 -0
- package/evals/conditions/v4/starter/src/generated/icrc1.ts +78 -0
- package/evals/conditions/v4-proto/condition.json +6 -0
- package/evals/conditions/v4-proto/docs/llms.txt +291 -0
- package/evals/conditions/v4-proto/lib/SHIM-NOTES.md +20 -0
- package/evals/conditions/v4-proto/lib/package.json +27 -0
- package/evals/conditions/v4-proto/lib/src/client.ts +471 -0
- package/evals/conditions/v4-proto/lib/src/errors.ts +214 -0
- package/evals/conditions/v4-proto/lib/src/index.ts +36 -0
- package/evals/conditions/v4-proto/lib/src/principal.ts +175 -0
- package/evals/conditions/v4-proto/lib/src/service.ts +69 -0
- package/evals/conditions/v4-proto/lib/src/types.ts +174 -0
- package/evals/conditions/v4-proto/lib/test/runtime.test.ts +170 -0
- package/evals/conditions/v4-proto/lib/test/tsconfig.json +10 -0
- package/evals/conditions/v4-proto/lib/test/types.test-d.ts +145 -0
- package/evals/conditions/v4-proto/lib/test/vitest.config.mjs +8 -0
- package/evals/conditions/v4-proto/lib/tsconfig.json +17 -0
- package/evals/conditions/v4-proto/package.json +26 -0
- package/evals/conditions/v4-proto/starter/src/generated/icrc1.service.ts +19 -0
- package/evals/conditions/v4-proto/starter/src/generated/icrc1.ts +57 -0
- package/evals/drive.mjs +1221 -0
- package/evals/gate.mjs +161 -0
- package/evals/harness/aggregate.mjs +534 -0
- package/evals/harness/aggregate.test.mjs +344 -0
- package/evals/harness/assemble.mjs +216 -0
- package/evals/harness/assemble.test.mjs +143 -0
- package/evals/harness/auth.mjs +91 -0
- package/evals/harness/check-docs.mjs +157 -0
- package/evals/harness/declarations/icrc1.did.d.ts +95 -0
- package/evals/harness/declarations/icrc1.did.js +140 -0
- package/evals/harness/drive-auth.test.mjs +584 -0
- package/evals/harness/drive.test.mjs +509 -0
- package/evals/harness/fake-auth.ts +67 -0
- package/evals/harness/fake-ledger.ts +178 -0
- package/evals/harness/gate-plan.mjs +104 -0
- package/evals/harness/gate-plan.test.mjs +243 -0
- package/evals/harness/icrc1.did +88 -0
- package/evals/harness/judge.mjs +63 -0
- package/evals/harness/judge.test.mjs +81 -0
- package/evals/harness/leak-scan.mjs +1373 -0
- package/evals/harness/leak-scan.test.mjs +1300 -0
- package/evals/harness/probes/amounts.ts +14 -0
- package/evals/harness/probes/node-tool.probe.ts +48 -0
- package/evals/harness/probes/probe.mjs +149 -0
- package/evals/harness/probes/react-wallet.probe.ts +96 -0
- package/evals/harness/public/support/auth.ts +38 -0
- package/evals/harness/public/support/fake-replica.d.ts +28 -0
- package/evals/harness/public/support/fake-replica.js +434 -0
- package/evals/harness/public/support/ledger.idl.d.ts +95 -0
- package/evals/harness/public/support/ledger.idl.js +140 -0
- package/evals/harness/public/support/world.ts +179 -0
- package/evals/harness/runs.mjs +139 -0
- package/evals/harness/sandbox.mjs +88 -0
- package/evals/harness/sandbox.test.mjs +134 -0
- package/evals/harness/ship.mjs +264 -0
- package/evals/harness/ship.test.mjs +552 -0
- package/evals/harness/world.ts +291 -0
- package/evals/package.json +26 -0
- package/evals/pnpm-lock.yaml +1537 -0
- package/evals/pnpm-workspace.yaml +12 -0
- package/evals/results/2026-09-30T14-22-05-924Z/pilot.json +384 -0
- package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.json +404 -0
- package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.rescored.json +404 -0
- package/evals/results/2026-09-30T14-22-05-924Z/plan.json +240 -0
- package/evals/results/2026-09-30T14-22-05-924Z/summary.json +1800 -0
- package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.json +1843 -0
- package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.rescored.json +2100 -0
- package/evals/results/2026-09-30T15-48-23-343Z/pilot.json +404 -0
- package/evals/results/2026-09-30T15-48-23-343Z/pilot.rescored.json +404 -0
- package/evals/results/2026-09-30T15-48-23-343Z/plan.json +242 -0
- package/evals/results/2026-09-30T15-48-23-343Z/summary.json +1843 -0
- package/evals/results/2026-09-30T15-48-23-343Z/summary.rescored.json +2195 -0
- package/evals/results/2026-10-03-beta1-gate/pilot.json +162 -0
- package/evals/results/2026-10-03-beta1-gate/plan.json +141 -0
- package/evals/results/2026-10-03-beta1-gate/summary.json +983 -0
- package/evals/results/2026-10-05-ga-gate/contaminated-run.json +55 -0
- package/evals/results/2026-10-05-ga-gate/pilot.json +162 -0
- package/evals/results/2026-10-05-ga-gate/plan.json +457 -0
- package/evals/results/2026-10-05-ga-gate/summary.json +1037 -0
- package/evals/results/2026-10-05-ga-gate/summary.rescanned.json +1037 -0
- package/evals/results/README.md +31 -0
- package/evals/runs-pilot.log +150 -0
- package/evals/runs-pilot2.log +150 -0
- package/evals/score.mjs +256 -0
- package/evals/setup.mjs +547 -0
- package/evals/tasks/node-tool/faulty/thin-accepts-exponent/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-accepts-exponent/src/index.ts +121 -0
- package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/src/index.ts +116 -0
- package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/thin-ignores-root-key/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-ignores-root-key/src/index.ts +117 -0
- package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/src/index.ts +119 -0
- package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/thin-number-amount/meta.json +10 -0
- package/evals/tasks/node-tool/faulty/thin-number-amount/src/index.ts +117 -0
- package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/src/index.ts +120 -0
- package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/v3-retry-call-errors/meta.json +11 -0
- package/evals/tasks/node-tool/faulty/v3-retry-call-errors/src/index.ts +149 -0
- package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/src/index.ts +71 -0
- package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/src/index.ts +84 -0
- package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/src/index.ts +72 -0
- package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/src/index.ts +72 -0
- package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/src/index.ts +84 -0
- package/evals/tasks/node-tool/hidden/node-tool.test.ts +312 -0
- package/evals/tasks/node-tool/prompt.md +55 -0
- package/evals/tasks/node-tool/prompt.minimal.md +30 -0
- package/evals/tasks/node-tool/solutions/thin/reference/src/index.ts +118 -0
- package/evals/tasks/node-tool/solutions/thin/reference-module-scope/src/index.ts +145 -0
- package/evals/tasks/node-tool/solutions/thin-guide/reference/src/index.ts +118 -0
- package/evals/tasks/node-tool/solutions/thin-guide/reference-module-scope/src/index.ts +145 -0
- package/evals/tasks/node-tool/solutions/v3/reference/src/index.ts +140 -0
- package/evals/tasks/node-tool/solutions/v3/reference-module-scope/src/index.ts +153 -0
- package/evals/tasks/node-tool/solutions/v4/reference/src/index.ts +84 -0
- package/evals/tasks/node-tool/solutions/v4/reference-module-scope/src/index.ts +105 -0
- package/evals/tasks/node-tool/solutions/v4-proto/reference/src/index.ts +72 -0
- package/evals/tasks/node-tool/solutions/v4-proto/reference-module-scope/src/index.ts +87 -0
- package/evals/tasks/node-tool/starter/src/contract.ts +31 -0
- package/evals/tasks/node-tool/starter/src/index.ts +7 -0
- package/evals/tasks/node-tool/starter/test/smoke.test.ts +22 -0
- package/evals/tasks/node-tool/starter/tsconfig.json +17 -0
- package/evals/tasks/node-tool/task.json +63 -0
- package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/src/Wallet.tsx +216 -0
- package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/src/Wallet.tsx +212 -0
- package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/src/Wallet.tsx +210 -0
- package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/meta.json +8 -0
- package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/meta.json +9 -0
- package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/faulty/thin-number-balance/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-number-balance/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/src/Wallet.tsx +254 -0
- package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/src/Wallet.tsx +215 -0
- package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/src/Wallet.tsx +214 -0
- package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/src/Wallet.tsx +224 -0
- package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/meta.json +12 -0
- package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/src/Wallet.tsx +225 -0
- package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/meta.json +11 -0
- package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/src/Wallet.tsx +182 -0
- package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/src/Wallet.tsx +160 -0
- package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/src/Wallet.tsx +166 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/src/Wallet.tsx +161 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/src/Wallet.tsx +163 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/meta.json +12 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/src/Wallet.tsx +162 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/src/Wallet.tsx +163 -0
- package/evals/tasks/react-wallet/faulty/v4-retry-spread/meta.json +12 -0
- package/evals/tasks/react-wallet/faulty/v4-retry-spread/src/Wallet.tsx +163 -0
- package/evals/tasks/react-wallet/faulty/v4-status-not-idle/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-status-not-idle/src/Wallet.tsx +162 -0
- package/evals/tasks/react-wallet/hidden/react-wallet.test.ts +536 -0
- package/evals/tasks/react-wallet/prompt.md +88 -0
- package/evals/tasks/react-wallet/prompt.minimal.md +51 -0
- package/evals/tasks/react-wallet/solutions/thin/reference/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/solutions/thin/reference-module-scope/src/Wallet.tsx +227 -0
- package/evals/tasks/react-wallet/solutions/thin-guide/reference/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/solutions/thin-guide/reference-module-scope/src/Wallet.tsx +227 -0
- package/evals/tasks/react-wallet/solutions/v3/reference/src/Wallet.tsx +224 -0
- package/evals/tasks/react-wallet/solutions/v3/reference-module-scope/src/Wallet.tsx +230 -0
- package/evals/tasks/react-wallet/solutions/v4/reference/src/Wallet.tsx +160 -0
- package/evals/tasks/react-wallet/solutions/v4/reference-module-scope/src/Wallet.tsx +178 -0
- package/evals/tasks/react-wallet/solutions/v4-proto/reference/src/Wallet.tsx +161 -0
- package/evals/tasks/react-wallet/solutions/v4-proto/reference-module-scope/src/Wallet.tsx +161 -0
- package/evals/tasks/react-wallet/starter/src/Wallet.tsx +12 -0
- package/evals/tasks/react-wallet/starter/src/auth.ts +16 -0
- package/evals/tasks/react-wallet/starter/src/config.ts +14 -0
- package/evals/tasks/react-wallet/starter/src/ii-auth.ts +43 -0
- package/evals/tasks/react-wallet/starter/src/main.tsx +15 -0
- package/evals/tasks/react-wallet/starter/test/smoke.test.ts +34 -0
- package/evals/tasks/react-wallet/starter/tsconfig.json +18 -0
- package/evals/tasks/react-wallet/task.json +84 -0
- package/examples/canister-studio/.stackblitzrc +4 -0
- package/examples/canister-studio/README.md +183 -0
- package/examples/canister-studio/did/ckbtc_minter.did +806 -0
- package/examples/canister-studio/did/icp_ledger.did +586 -0
- package/examples/canister-studio/did/icrc1.did +88 -0
- package/examples/canister-studio/package.json +45 -0
- package/examples/canister-studio/scripts/smoke.ts +188 -0
- package/examples/canister-studio/src/calls/CacheKeyPanel.tsx +104 -0
- package/examples/canister-studio/src/calls/ConfirmWrite.tsx +265 -0
- package/examples/canister-studio/src/calls/ErrorPanel.test.tsx +113 -0
- package/examples/canister-studio/src/calls/ErrorPanel.tsx +214 -0
- package/examples/canister-studio/src/calls/MethodRunner.test.tsx +354 -0
- package/examples/canister-studio/src/calls/MethodRunner.tsx +57 -0
- package/examples/canister-studio/src/calls/ReadRunner.tsx +244 -0
- package/examples/canister-studio/src/calls/ResendPanel.tsx +165 -0
- package/examples/canister-studio/src/calls/ShareLink.tsx +59 -0
- package/examples/canister-studio/src/calls/WriteRunner.test.tsx +678 -0
- package/examples/canister-studio/src/calls/WriteRunner.tsx +670 -0
- package/examples/canister-studio/src/calls/dedupe.ts +189 -0
- package/examples/canister-studio/src/calls/error-info.ts +168 -0
- package/examples/canister-studio/src/calls/history.test.ts +284 -0
- package/examples/canister-studio/src/calls/history.ts +287 -0
- package/examples/canister-studio/src/calls/kinds.ts +68 -0
- package/examples/canister-studio/src/calls/prepare.ts +32 -0
- package/examples/canister-studio/src/calls/query-options.ts +30 -0
- package/examples/canister-studio/src/calls/read.ts +47 -0
- package/examples/canister-studio/src/calls/readback.ts +100 -0
- package/examples/canister-studio/src/calls/record.ts +123 -0
- package/examples/canister-studio/src/calls/safe-calls.test.ts +299 -0
- package/examples/canister-studio/src/calls/share.ts +46 -0
- package/examples/canister-studio/src/calls/testing/doubles.tsx +108 -0
- package/examples/canister-studio/src/calls/testing/fixtures.ts +185 -0
- package/examples/canister-studio/src/calls/useCanisterHandle.ts +35 -0
- package/examples/canister-studio/src/canisters/ckbtc_minter.envelope.json +4228 -0
- package/examples/canister-studio/src/canisters/ckbtc_minter.ts +868 -0
- package/examples/canister-studio/src/canisters/icp_ledger.envelope.json +3454 -0
- package/examples/canister-studio/src/canisters/icp_ledger.ts +584 -0
- package/examples/canister-studio/src/canisters/icrc1.envelope.json +840 -0
- package/examples/canister-studio/src/canisters/icrc1.ts +78 -0
- package/examples/canister-studio/src/components/ActionButton.tsx +32 -0
- package/examples/canister-studio/src/components/AppHeader.tsx +83 -0
- package/examples/canister-studio/src/components/AppShell.tsx +29 -0
- package/examples/canister-studio/src/components/AuthButton.tsx +79 -0
- package/examples/canister-studio/src/components/Badge.tsx +79 -0
- package/examples/canister-studio/src/components/CanisterHeader.tsx +200 -0
- package/examples/canister-studio/src/components/CanisterJump.tsx +130 -0
- package/examples/canister-studio/src/components/Card.tsx +64 -0
- package/examples/canister-studio/src/components/Code.tsx +101 -0
- package/examples/canister-studio/src/components/CopyButton.tsx +126 -0
- package/examples/canister-studio/src/components/Disclosure.tsx +34 -0
- package/examples/canister-studio/src/components/EmptyState.tsx +34 -0
- package/examples/canister-studio/src/components/MethodList.test.tsx +137 -0
- package/examples/canister-studio/src/components/MethodList.tsx +244 -0
- package/examples/canister-studio/src/components/Notice.tsx +36 -0
- package/examples/canister-studio/src/components/ProvenanceBadge.tsx +44 -0
- package/examples/canister-studio/src/components/RouteError.tsx +42 -0
- package/examples/canister-studio/src/components/SectionBoundary.tsx +76 -0
- package/examples/canister-studio/src/components/Spinner.tsx +33 -0
- package/examples/canister-studio/src/components/Tabs.tsx +96 -0
- package/examples/canister-studio/src/components/canister/CanisterLoadFailure.test.tsx +56 -0
- package/examples/canister-studio/src/components/canister/CanisterLoadFailure.tsx +165 -0
- package/examples/canister-studio/src/components/canister/CanisterNotFound.tsx +59 -0
- package/examples/canister-studio/src/components/canister/CanisterPending.tsx +33 -0
- package/examples/canister-studio/src/components/canister/MethodOverview.tsx +93 -0
- package/examples/canister-studio/src/components/canister/MethodWorkspace.test.tsx +201 -0
- package/examples/canister-studio/src/components/canister/MethodWorkspace.tsx +187 -0
- package/examples/canister-studio/src/components/canister/shared-call.test.ts +186 -0
- package/examples/canister-studio/src/components/canister/shared-call.ts +133 -0
- package/examples/canister-studio/src/components/canister/shared-link-loader.test.ts +116 -0
- package/examples/canister-studio/src/components/canister/use-canister-page.ts +44 -0
- package/examples/canister-studio/src/components/canister/workspace-key.test.ts +27 -0
- package/examples/canister-studio/src/components/canister/workspace-key.ts +36 -0
- package/examples/canister-studio/src/components/canister-id-input.ts +69 -0
- package/examples/canister-studio/src/components/canister-names.ts +11 -0
- package/examples/canister-studio/src/components/download.ts +34 -0
- package/examples/canister-studio/src/components/fallbacks.tsx +33 -0
- package/examples/canister-studio/src/components/helpers.test.ts +107 -0
- package/examples/canister-studio/src/components/history/HistoryList.tsx +284 -0
- package/examples/canister-studio/src/components/home/FeaturedLedger.tsx +149 -0
- package/examples/canister-studio/src/components/home/OpenCanister.tsx +99 -0
- package/examples/canister-studio/src/components/home/featured.test.tsx +92 -0
- package/examples/canister-studio/src/components/home/featured.ts +64 -0
- package/examples/canister-studio/src/components/interface/CandidTab.tsx +38 -0
- package/examples/canister-studio/src/components/interface/CompatReport.tsx +92 -0
- package/examples/canister-studio/src/components/interface/CompatibilityTab.tsx +190 -0
- package/examples/canister-studio/src/components/interface/ProjectTab.tsx +196 -0
- package/examples/canister-studio/src/components/interface/TypeScriptTab.tsx +114 -0
- package/examples/canister-studio/src/components/interface/tools.test.tsx +169 -0
- package/examples/canister-studio/src/components/modes.ts +31 -0
- package/examples/canister-studio/src/components/playground/MethodPicker.tsx +67 -0
- package/examples/canister-studio/src/components/playground/PlaygroundForms.tsx +112 -0
- package/examples/canister-studio/src/components/playground/PlaygroundTools.tsx +219 -0
- package/examples/canister-studio/src/components/playground/sample.ts +43 -0
- package/examples/canister-studio/src/components/playground/target.test.tsx +86 -0
- package/examples/canister-studio/src/components/primitives.test.tsx +121 -0
- package/examples/canister-studio/src/components/provenance.ts +38 -0
- package/examples/canister-studio/src/components/route-render.test.tsx +71 -0
- package/examples/canister-studio/src/components/use-task.ts +56 -0
- package/examples/canister-studio/src/components/wallet/BalancePanel.tsx +110 -0
- package/examples/canister-studio/src/components/wallet/LedgerSummary.tsx +63 -0
- package/examples/canister-studio/src/components/wallet/MinterPanel.tsx +255 -0
- package/examples/canister-studio/src/components/wallet/SendPanel.test.tsx +297 -0
- package/examples/canister-studio/src/components/wallet/SendPanel.tsx +446 -0
- package/examples/canister-studio/src/components/wallet/ledgers.test.ts +36 -0
- package/examples/canister-studio/src/components/wallet/ledgers.ts +111 -0
- package/examples/canister-studio/src/forms/JsonPanel.tsx +157 -0
- package/examples/canister-studio/src/forms/MethodForm.test.tsx +369 -0
- package/examples/canister-studio/src/forms/MethodForm.tsx +368 -0
- package/examples/canister-studio/src/forms/TypedForm.tsx +55 -0
- package/examples/canister-studio/src/forms/context.ts +62 -0
- package/examples/canister-studio/src/forms/convert.ts +131 -0
- package/examples/canister-studio/src/forms/edge.test.ts +252 -0
- package/examples/canister-studio/src/forms/engine.test.ts +358 -0
- package/examples/canister-studio/src/forms/engine.ts +1492 -0
- package/examples/canister-studio/src/forms/fields/BytesField.tsx +210 -0
- package/examples/canister-studio/src/forms/fields/Field.tsx +106 -0
- package/examples/canister-studio/src/forms/fields/FieldShell.tsx +101 -0
- package/examples/canister-studio/src/forms/fields/Group.tsx +74 -0
- package/examples/canister-studio/src/forms/fields/ListField.tsx +256 -0
- package/examples/canister-studio/src/forms/fields/Segmented.tsx +78 -0
- package/examples/canister-studio/src/forms/fields/TimestampField.tsx +108 -0
- package/examples/canister-studio/src/forms/fields/UnitsField.tsx +119 -0
- package/examples/canister-studio/src/forms/fields/composites.tsx +389 -0
- package/examples/canister-studio/src/forms/fields/leaves.tsx +350 -0
- package/examples/canister-studio/src/forms/fields.test.tsx +396 -0
- package/examples/canister-studio/src/forms/helpers.test.ts +225 -0
- package/examples/canister-studio/src/forms/hints.ts +128 -0
- package/examples/canister-studio/src/forms/json.ts +119 -0
- package/examples/canister-studio/src/forms/parsing.test.ts +217 -0
- package/examples/canister-studio/src/forms/useMethodForm.ts +251 -0
- package/examples/canister-studio/src/interface/browser.test.ts +23 -0
- package/examples/canister-studio/src/interface/browser.ts +153 -0
- package/examples/canister-studio/src/interface/cache.ts +68 -0
- package/examples/canister-studio/src/interface/cli-cache.test.ts +155 -0
- package/examples/canister-studio/src/interface/cli-cache.ts +125 -0
- package/examples/canister-studio/src/interface/compile.server.test.ts +198 -0
- package/examples/canister-studio/src/interface/compile.server.ts +262 -0
- package/examples/canister-studio/src/interface/compile.test.ts +108 -0
- package/examples/canister-studio/src/interface/compile.ts +305 -0
- package/examples/canister-studio/src/interface/docs.test.ts +75 -0
- package/examples/canister-studio/src/interface/docs.ts +100 -0
- package/examples/canister-studio/src/interface/functions.test.ts +42 -0
- package/examples/canister-studio/src/interface/functions.ts +200 -0
- package/examples/canister-studio/src/interface/live-candid.server.ts +91 -0
- package/examples/canister-studio/src/interface/live-loader.test.ts +515 -0
- package/examples/canister-studio/src/interface/live-loader.ts +364 -0
- package/examples/canister-studio/src/interface/load.test.ts +328 -0
- package/examples/canister-studio/src/interface/load.ts +249 -0
- package/examples/canister-studio/src/interface/read-candid.test.ts +185 -0
- package/examples/canister-studio/src/interface/read-candid.ts +233 -0
- package/examples/canister-studio/src/interface/server-result.ts +42 -0
- package/examples/canister-studio/src/interface/typed.ts +68 -0
- package/examples/canister-studio/src/interface/types.ts +121 -0
- package/examples/canister-studio/src/lib/format.test.ts +107 -0
- package/examples/canister-studio/src/lib/format.ts +139 -0
- package/examples/canister-studio/src/lib/hex.test.ts +43 -0
- package/examples/canister-studio/src/lib/hex.ts +33 -0
- package/examples/canister-studio/src/lib/ids.test.ts +70 -0
- package/examples/canister-studio/src/lib/ids.ts +93 -0
- package/examples/canister-studio/src/lib/reactor.test.ts +55 -0
- package/examples/canister-studio/src/lib/reactor.ts +55 -0
- package/examples/canister-studio/src/lib/registry.test.ts +74 -0
- package/examples/canister-studio/src/lib/registry.ts +238 -0
- package/examples/canister-studio/src/lib/schema.ts +148 -0
- package/examples/canister-studio/src/routeTree.gen.ts +227 -0
- package/examples/canister-studio/src/router.test.ts +290 -0
- package/examples/canister-studio/src/router.tsx +127 -0
- package/examples/canister-studio/src/routes/__root.tsx +58 -0
- package/examples/canister-studio/src/routes/canister.$canisterId.index.tsx +172 -0
- package/examples/canister-studio/src/routes/canister.$canisterId.interface.tsx +98 -0
- package/examples/canister-studio/src/routes/canister.$canisterId.tsx +91 -0
- package/examples/canister-studio/src/routes/history.tsx +55 -0
- package/examples/canister-studio/src/routes/index.tsx +169 -0
- package/examples/canister-studio/src/routes/playground.tsx +286 -0
- package/examples/canister-studio/src/routes/safety.tsx +57 -0
- package/examples/canister-studio/src/routes/wallet.tsx +213 -0
- package/examples/canister-studio/src/safety/LabTransferForm.tsx +84 -0
- package/examples/canister-studio/src/safety/RequestLog.tsx +79 -0
- package/examples/canister-studio/src/safety/SafetyLab.test.tsx +89 -0
- package/examples/canister-studio/src/safety/SafetyLab.tsx +140 -0
- package/examples/canister-studio/src/safety/ScenarioCard.tsx +262 -0
- package/examples/canister-studio/src/safety/lab-run.ts +283 -0
- package/examples/canister-studio/src/safety/mock-ledger.test.ts +99 -0
- package/examples/canister-studio/src/safety/mock-ledger.ts +263 -0
- package/examples/canister-studio/src/safety/scenarios.test.ts +157 -0
- package/examples/canister-studio/src/safety/scenarios.ts +924 -0
- package/examples/canister-studio/src/styles.css +3453 -0
- package/examples/canister-studio/src/styles.test.ts +46 -0
- package/examples/canister-studio/src/values/CallPreview.test.tsx +86 -0
- package/examples/canister-studio/src/values/CallPreview.tsx +148 -0
- package/examples/canister-studio/src/values/ErrValueView.tsx +66 -0
- package/examples/canister-studio/src/values/Inspector.tsx +133 -0
- package/examples/canister-studio/src/values/ReplyView.test.tsx +341 -0
- package/examples/canister-studio/src/values/ReplyView.tsx +164 -0
- package/examples/canister-studio/src/values/candid-text.test.ts +516 -0
- package/examples/canister-studio/src/values/candid-text.ts +479 -0
- package/examples/canister-studio/src/values/hints.ts +58 -0
- package/examples/canister-studio/src/values/json.test.ts +66 -0
- package/examples/canister-studio/src/values/json.ts +31 -0
- package/examples/canister-studio/src/values/leaves.tsx +309 -0
- package/examples/canister-studio/src/values/schema.test.ts +123 -0
- package/examples/canister-studio/src/values/schema.ts +78 -0
- package/examples/canister-studio/src/values/test-router.tsx +21 -0
- package/examples/canister-studio/src/values/tree.tsx +670 -0
- package/examples/canister-studio/src/values/use-sha256.ts +29 -0
- package/examples/canister-studio/tsconfig.json +20 -0
- package/examples/canister-studio/vite.config.ts +50 -0
- package/examples/canister-studio/vitest.config.ts +20 -0
- package/examples/icrc-ledger/.stackblitzrc +4 -0
- package/examples/icrc-ledger/README.md +100 -0
- package/examples/icrc-ledger/ckbtc_minter.did +12 -0
- package/examples/icrc-ledger/icp_ledger.did +147 -0
- package/examples/icrc-ledger/icrc1.did +88 -0
- package/examples/icrc-ledger/index.html +13 -0
- package/examples/icrc-ledger/package.json +40 -0
- package/examples/icrc-ledger/scripts/smoke.ts +151 -0
- package/examples/icrc-ledger/src/App.tsx +71 -0
- package/examples/icrc-ledger/src/ErrorPanel.tsx +105 -0
- package/examples/icrc-ledger/src/MainnetTab.tsx +450 -0
- package/examples/icrc-ledger/src/SandboxTab.test.tsx +379 -0
- package/examples/icrc-ledger/src/SandboxTab.tsx +761 -0
- package/examples/icrc-ledger/src/blocks.test.ts +247 -0
- package/examples/icrc-ledger/src/blocks.ts +140 -0
- package/examples/icrc-ledger/src/canisters/ckbtc_minter.envelope.json +96 -0
- package/examples/icrc-ledger/src/canisters/ckbtc_minter.ts +16 -0
- package/examples/icrc-ledger/src/canisters/icp_ledger.envelope.json +690 -0
- package/examples/icrc-ledger/src/canisters/icp_ledger.ts +223 -0
- package/examples/icrc-ledger/src/canisters/icrc1.envelope.json +840 -0
- package/examples/icrc-ledger/src/canisters/icrc1.ts +78 -0
- package/examples/icrc-ledger/src/format.test.ts +41 -0
- package/examples/icrc-ledger/src/format.ts +68 -0
- package/examples/icrc-ledger/src/ledger.ts +15 -0
- package/examples/icrc-ledger/src/main.tsx +10 -0
- package/examples/icrc-ledger/src/minter.ts +16 -0
- package/examples/icrc-ledger/src/sandbox.test.ts +464 -0
- package/examples/icrc-ledger/src/sandbox.ts +281 -0
- package/examples/icrc-ledger/src/styles.css +391 -0
- package/examples/icrc-ledger/src/transfer-form.test.ts +62 -0
- package/examples/icrc-ledger/src/transfer-form.ts +97 -0
- package/examples/icrc-ledger/tsconfig.json +19 -0
- package/examples/icrc-ledger/vite.config.ts +44 -0
- package/examples/icrc-ledger/vitest.config.ts +12 -0
- package/examples/next-ssr/.stackblitzrc +4 -0
- package/examples/next-ssr/README.md +112 -0
- package/examples/next-ssr/icrc1.did +88 -0
- package/examples/next-ssr/next.config.ts +10 -0
- package/examples/next-ssr/package.json +41 -0
- package/examples/next-ssr/scripts/smoke.ts +169 -0
- package/examples/next-ssr/src/app/account/CertifiedBalances.tsx +58 -0
- package/examples/next-ssr/src/app/account/account.test.tsx +165 -0
- package/examples/next-ssr/src/app/account/page.tsx +82 -0
- package/examples/next-ssr/src/app/api/balance/[ledger]/[principal]/route.ts +10 -0
- package/examples/next-ssr/src/app/globals.css +278 -0
- package/examples/next-ssr/src/app/layout.tsx +34 -0
- package/examples/next-ssr/src/app/page.tsx +46 -0
- package/examples/next-ssr/src/app/providers.browser.test.tsx +127 -0
- package/examples/next-ssr/src/app/providers.test.tsx +73 -0
- package/examples/next-ssr/src/app/providers.tsx +60 -0
- package/examples/next-ssr/src/canisters/icrc1.envelope.json +840 -0
- package/examples/next-ssr/src/canisters/icrc1.ts +78 -0
- package/examples/next-ssr/src/components/BalanceTable.tsx +43 -0
- package/examples/next-ssr/src/components/LedgerCard.test.tsx +96 -0
- package/examples/next-ssr/src/components/LedgerCard.tsx +230 -0
- package/examples/next-ssr/src/components/LedgerError.tsx +32 -0
- package/examples/next-ssr/src/components/LedgerSections.tsx +22 -0
- package/examples/next-ssr/src/components/MyBalances.test.tsx +253 -0
- package/examples/next-ssr/src/components/MyBalances.tsx +129 -0
- package/examples/next-ssr/src/components/SessionBadge.tsx +18 -0
- package/examples/next-ssr/src/components/hydration.test.tsx +259 -0
- package/examples/next-ssr/src/components/server-data.ts +10 -0
- package/examples/next-ssr/src/format.ts +46 -0
- package/examples/next-ssr/src/ledgers.ts +38 -0
- package/examples/next-ssr/src/server/balance-route.test.ts +151 -0
- package/examples/next-ssr/src/server/balance-route.ts +157 -0
- package/examples/next-ssr/src/server/error-summary.test.ts +34 -0
- package/examples/next-ssr/src/server/error-summary.ts +37 -0
- package/examples/next-ssr/src/server/parse-owner.test.ts +39 -0
- package/examples/next-ssr/src/server/parse-owner.ts +34 -0
- package/examples/next-ssr/src/server/prefetch-ledgers.test.ts +137 -0
- package/examples/next-ssr/src/server/prefetch-ledgers.ts +70 -0
- package/examples/next-ssr/src/server/read-balances.test.ts +103 -0
- package/examples/next-ssr/src/server/read-balances.ts +78 -0
- package/examples/next-ssr/src/server/request-client.rsc.test.tsx +110 -0
- package/examples/next-ssr/src/server/request-client.ts +24 -0
- package/examples/next-ssr/src/testing/mock-ledgers.ts +115 -0
- package/examples/next-ssr/src/testing/react-server-dom-turbopack.d.ts +15 -0
- package/examples/next-ssr/src/testing/setup.ts +10 -0
- package/examples/next-ssr/tsconfig.json +31 -0
- package/examples/next-ssr/vitest.config.ts +59 -0
- package/examples/node-agent-tool/.stackblitzrc +4 -0
- package/examples/node-agent-tool/README.md +165 -0
- package/examples/node-agent-tool/icp.yaml +11 -0
- package/examples/node-agent-tool/icrc1.did +88 -0
- package/examples/node-agent-tool/package.json +32 -0
- package/examples/node-agent-tool/src/canisters/icrc1.envelope.json +840 -0
- package/examples/node-agent-tool/src/canisters/icrc1.ts +78 -0
- package/examples/node-agent-tool/src/cli.test.ts +64 -0
- package/examples/node-agent-tool/src/cli.ts +23 -0
- package/examples/node-agent-tool/src/command-line.ts +159 -0
- package/examples/node-agent-tool/src/commands/balance.ts +73 -0
- package/examples/node-agent-tool/src/commands/demo.test.ts +51 -0
- package/examples/node-agent-tool/src/commands/demo.ts +359 -0
- package/examples/node-agent-tool/src/commands/info.ts +69 -0
- package/examples/node-agent-tool/src/commands/reads.test.ts +133 -0
- package/examples/node-agent-tool/src/commands/resend.test.ts +363 -0
- package/examples/node-agent-tool/src/commands/transfer.test.ts +313 -0
- package/examples/node-agent-tool/src/commands/transfer.ts +415 -0
- package/examples/node-agent-tool/src/commands/watch.test.ts +159 -0
- package/examples/node-agent-tool/src/commands/watch.ts +135 -0
- package/examples/node-agent-tool/src/commands/whoami.ts +36 -0
- package/examples/node-agent-tool/src/context.ts +20 -0
- package/examples/node-agent-tool/src/dispatch.ts +70 -0
- package/examples/node-agent-tool/src/failure.test.ts +59 -0
- package/examples/node-agent-tool/src/failure.ts +176 -0
- package/examples/node-agent-tool/src/identity.test.ts +242 -0
- package/examples/node-agent-tool/src/identity.ts +228 -0
- package/examples/node-agent-tool/src/input.ts +110 -0
- package/examples/node-agent-tool/src/ledgers.test.ts +74 -0
- package/examples/node-agent-tool/src/ledgers.ts +62 -0
- package/examples/node-agent-tool/src/mock-ledger.ts +211 -0
- package/examples/node-agent-tool/src/network.test.ts +128 -0
- package/examples/node-agent-tool/src/network.ts +101 -0
- package/examples/node-agent-tool/src/output.test.ts +208 -0
- package/examples/node-agent-tool/src/output.ts +163 -0
- package/examples/node-agent-tool/src/run.ts +73 -0
- package/examples/node-agent-tool/src/test-kit.ts +167 -0
- package/examples/node-agent-tool/tsconfig.json +18 -0
- package/examples/node-agent-tool/vitest.config.ts +8 -0
- package/examples/vite-wallet/.stackblitzrc +4 -0
- package/examples/vite-wallet/Cargo.lock +646 -0
- package/examples/vite-wallet/Cargo.toml +5 -0
- package/examples/vite-wallet/README.md +107 -0
- package/examples/vite-wallet/backend/Cargo.toml +12 -0
- package/examples/vite-wallet/backend/backend.did +37 -0
- package/examples/vite-wallet/backend/src/lib.rs +133 -0
- package/examples/vite-wallet/icp.yaml +44 -0
- package/examples/vite-wallet/index.html +13 -0
- package/examples/vite-wallet/ledger.did +54 -0
- package/examples/vite-wallet/package.json +46 -0
- package/examples/vite-wallet/public/.ic-assets.json5 +26 -0
- package/examples/vite-wallet/scripts/faucet-args.test.ts +30 -0
- package/examples/vite-wallet/scripts/faucet-args.ts +41 -0
- package/examples/vite-wallet/scripts/faucet.ts +41 -0
- package/examples/vite-wallet/src/AddressBook.test.tsx +191 -0
- package/examples/vite-wallet/src/AddressBook.tsx +147 -0
- package/examples/vite-wallet/src/App.tsx +53 -0
- package/examples/vite-wallet/src/Balance.test.tsx +57 -0
- package/examples/vite-wallet/src/Balance.tsx +58 -0
- package/examples/vite-wallet/src/EnvironmentPanel.test.tsx +83 -0
- package/examples/vite-wallet/src/EnvironmentPanel.tsx +103 -0
- package/examples/vite-wallet/src/ErrorNote.tsx +70 -0
- package/examples/vite-wallet/src/Profile.test.tsx +145 -0
- package/examples/vite-wallet/src/Profile.tsx +92 -0
- package/examples/vite-wallet/src/SendIcp.test.tsx +231 -0
- package/examples/vite-wallet/src/SendIcp.tsx +244 -0
- package/examples/vite-wallet/src/SendToContact.test.tsx +113 -0
- package/examples/vite-wallet/src/SendToContact.tsx +102 -0
- package/examples/vite-wallet/src/SignIn.test.tsx +106 -0
- package/examples/vite-wallet/src/SignIn.tsx +120 -0
- package/examples/vite-wallet/src/Wallet.test.tsx +89 -0
- package/examples/vite-wallet/src/account-switch.test.tsx +108 -0
- package/examples/vite-wallet/src/auth/dev-accounts.test.ts +113 -0
- package/examples/vite-wallet/src/auth/dev-accounts.ts +216 -0
- package/examples/vite-wallet/src/auth/local-page.test.ts +28 -0
- package/examples/vite-wallet/src/auth/local-page.ts +20 -0
- package/examples/vite-wallet/src/auth/wallet-auth.test.ts +159 -0
- package/examples/vite-wallet/src/auth/wallet-auth.ts +131 -0
- package/examples/vite-wallet/src/canisters/backend.envelope.json +275 -0
- package/examples/vite-wallet/src/canisters/backend.ts +58 -0
- package/examples/vite-wallet/src/canisters/ledger.envelope.json +451 -0
- package/examples/vite-wallet/src/canisters/ledger.ts +56 -0
- package/examples/vite-wallet/src/client.ts +45 -0
- package/examples/vite-wallet/src/main.tsx +18 -0
- package/examples/vite-wallet/src/optimistic-contacts.ts +113 -0
- package/examples/vite-wallet/src/refusal.ts +17 -0
- package/examples/vite-wallet/src/styles.css +282 -0
- package/examples/vite-wallet/src/test/test-wallet.tsx +322 -0
- package/examples/vite-wallet/src/token.ts +50 -0
- package/examples/vite-wallet/src/transfer.test.ts +178 -0
- package/examples/vite-wallet/src/transfer.ts +110 -0
- package/examples/vite-wallet/src/use-canisters.ts +49 -0
- package/examples/vite-wallet/tsconfig.json +19 -0
- package/examples/vite-wallet/vite.config.ts +47 -0
- package/examples/vite-wallet/vitest.config.ts +17 -0
- package/package.json +9 -4
- package/packages/core/.size-limit.js +47 -0
- package/packages/core/LICENSE +21 -0
- package/packages/core/README.md +84 -0
- package/packages/core/llms.txt +610 -0
- package/packages/core/package.json +89 -0
- package/packages/core/src/call.ts +961 -0
- package/packages/core/src/canister.ts +259 -0
- package/packages/core/src/client.ts +2061 -0
- package/packages/core/src/errors.ts +1079 -0
- package/packages/core/src/hydration.ts +239 -0
- package/packages/core/src/index.ts +23 -0
- package/packages/core/src/keys.ts +108 -0
- package/packages/core/src/management.ts +138 -0
- package/packages/core/src/network.ts +1020 -0
- package/packages/core/src/options.ts +1000 -0
- package/packages/core/src/runtime.ts +50 -0
- package/packages/core/src/testing/fake-replica.ts +1166 -0
- package/packages/core/src/testing/index.ts +16 -0
- package/packages/core/src/testing/test-auth.ts +340 -0
- package/packages/core/src/testing/test-client.ts +559 -0
- package/packages/core/src/types.ts +541 -0
- package/packages/core/src/units.ts +299 -0
- package/packages/core/src/version.ts +4 -0
- package/packages/core/tests/canister-helpers.ts +187 -0
- package/packages/core/tests/canister-id.test.ts +158 -0
- package/packages/core/tests/canister-unwrap.test.ts +94 -0
- package/packages/core/tests/canister.test-d.ts +406 -0
- package/packages/core/tests/canister.test.ts +1921 -0
- package/packages/core/tests/client-account-change.test.ts +131 -0
- package/packages/core/tests/client-agents.test.ts +402 -0
- package/packages/core/tests/client-auth-network.test.ts +719 -0
- package/packages/core/tests/client-disposed.test.ts +403 -0
- package/packages/core/tests/client-helpers.ts +136 -0
- package/packages/core/tests/client-hydration.test.ts +166 -0
- package/packages/core/tests/client-pinned.test.ts +626 -0
- package/packages/core/tests/client-session.test.ts +348 -0
- package/packages/core/tests/client.test-d.ts +181 -0
- package/packages/core/tests/client.test.ts +1162 -0
- package/packages/core/tests/encode.test.ts +171 -0
- package/packages/core/tests/env-canister-id.test.ts +666 -0
- package/packages/core/tests/env-cookie-copies.test.ts +182 -0
- package/packages/core/tests/error-guard.test.ts +222 -0
- package/packages/core/tests/errors.test-d.ts +280 -0
- package/packages/core/tests/errors.test.ts +1359 -0
- package/packages/core/tests/fixtures/README.md +28 -0
- package/packages/core/tests/fixtures/accounts.did +21 -0
- package/packages/core/tests/fixtures/accounts.envelope.json +367 -0
- package/packages/core/tests/fixtures/accounts.ts +26 -0
- package/packages/core/tests/fixtures/archive.did +31 -0
- package/packages/core/tests/fixtures/archive.envelope.json +259 -0
- package/packages/core/tests/fixtures/archive.ts +55 -0
- package/packages/core/tests/fixtures/icrc1.did +88 -0
- package/packages/core/tests/fixtures/icrc1.envelope.json +840 -0
- package/packages/core/tests/fixtures/icrc1.ts +78 -0
- package/packages/core/tests/fixtures/management.did +724 -0
- package/packages/core/tests/fixtures/management.envelope.json +4455 -0
- package/packages/core/tests/fixtures/management.ts +486 -0
- package/packages/core/tests/fixtures/shapes.did +33 -0
- package/packages/core/tests/fixtures/shapes.envelope.json +440 -0
- package/packages/core/tests/fixtures/shapes.ts +56 -0
- package/packages/core/tests/fixtures/skippable.did +15 -0
- package/packages/core/tests/fixtures/skippable.envelope.json +182 -0
- package/packages/core/tests/fixtures/skippable.ts +33 -0
- package/packages/core/tests/func.test.ts +154 -0
- package/packages/core/tests/identity-attributes.test.ts +214 -0
- package/packages/core/tests/keys.test.ts +289 -0
- package/packages/core/tests/management.test.ts +206 -0
- package/packages/core/tests/network-helpers.ts +121 -0
- package/packages/core/tests/network.test-d.ts +78 -0
- package/packages/core/tests/network.test.ts +1051 -0
- package/packages/core/tests/options.test.ts +1594 -0
- package/packages/core/tests/redirect-sign-in.test.ts +393 -0
- package/packages/core/tests/resend.test-d.ts +81 -0
- package/packages/core/tests/resend.test.ts +723 -0
- package/packages/core/tests/skip.test-d.ts +125 -0
- package/packages/core/tests/testing-entry.test.ts +73 -0
- package/packages/core/tests/testing-fake-replica.test.ts +1242 -0
- package/packages/core/tests/testing-test-auth.test-d.ts +84 -0
- package/packages/core/tests/testing-test-auth.test.ts +483 -0
- package/packages/core/tests/testing-test-client.test-d.ts +184 -0
- package/packages/core/tests/testing-test-client.test.ts +1272 -0
- package/packages/core/tests/time-realm.test.ts +63 -0
- package/packages/core/tests/time.test.ts +238 -0
- package/packages/core/tests/traps/README.md +39 -0
- package/packages/core/tests/traps/anonymous-write.test.ts +145 -0
- package/packages/core/tests/traps/classification-table.test.ts +256 -0
- package/packages/core/tests/traps/err-arm.test.ts +144 -0
- package/packages/core/tests/traps/fetch-spy.ts +39 -0
- package/packages/core/tests/traps/invalidation-after-write.test.ts +178 -0
- package/packages/core/tests/traps/ledger.ts +248 -0
- package/packages/core/tests/traps/root-key-off-local.test.ts +130 -0
- package/packages/core/tests/traps/stale-data-across-users.test.ts +173 -0
- package/packages/core/tests/traps/unresolved-name.test.ts +155 -0
- package/packages/core/tests/traps/update-as-query.test.ts +244 -0
- package/packages/core/tests/traps/update-not-resent.test.ts +126 -0
- package/packages/core/tests/traps/update-resent-when-never-delivered.test.ts +159 -0
- package/packages/core/tests/traps.test-d.ts +476 -0
- package/packages/core/tests/units.test-d.ts +118 -0
- package/packages/core/tests/units.test.ts +634 -0
- package/packages/core/tsconfig.json +19 -0
- package/packages/core/tsconfig.typecheck.json +16 -0
- package/packages/core/vitest.config.ts +13 -0
- package/packages/mcp/LICENSE +21 -0
- package/packages/mcp/README.md +189 -0
- package/packages/mcp/package.json +62 -0
- package/packages/mcp/src/candid/candid-text.test.ts +455 -0
- package/packages/mcp/src/candid/candid-text.ts +501 -0
- package/packages/mcp/src/candid/contract.test.ts +398 -0
- package/packages/mcp/src/candid/formats.ts +155 -0
- package/packages/mcp/src/candid/hex.ts +29 -0
- package/packages/mcp/src/candid/json-schema.test.ts +758 -0
- package/packages/mcp/src/candid/json-schema.ts +454 -0
- package/packages/mcp/src/candid/json.test.ts +1207 -0
- package/packages/mcp/src/candid/json.ts +1053 -0
- package/packages/mcp/src/candid/schema-walk.ts +189 -0
- package/packages/mcp/src/candid/type-text.test.ts +179 -0
- package/packages/mcp/src/candid/type-text.ts +238 -0
- package/packages/mcp/src/cli.ts +134 -0
- package/packages/mcp/src/identity.ts +188 -0
- package/packages/mcp/src/interface/cache.test.ts +48 -0
- package/packages/mcp/src/interface/cache.ts +68 -0
- package/packages/mcp/src/interface/cli-cache.test.ts +150 -0
- package/packages/mcp/src/interface/cli-cache.ts +122 -0
- package/packages/mcp/src/interface/compile-worker.test.ts +246 -0
- package/packages/mcp/src/interface/compile-worker.ts +290 -0
- package/packages/mcp/src/interface/compile.test.ts +155 -0
- package/packages/mcp/src/interface/compile.ts +281 -0
- package/packages/mcp/src/interface/docs.test.ts +105 -0
- package/packages/mcp/src/interface/docs.ts +86 -0
- package/packages/mcp/src/interface/fixtures/icrc1.did +88 -0
- package/packages/mcp/src/interface/hex.ts +8 -0
- package/packages/mcp/src/interface/ids.test.ts +71 -0
- package/packages/mcp/src/interface/ids.ts +87 -0
- package/packages/mcp/src/interface/loader.test.ts +804 -0
- package/packages/mcp/src/interface/loader.ts +519 -0
- package/packages/mcp/src/interface/read-candid.test.ts +300 -0
- package/packages/mcp/src/interface/read-candid.ts +259 -0
- package/packages/mcp/src/interface/types.ts +113 -0
- package/packages/mcp/src/network.ts +122 -0
- package/packages/mcp/src/options.ts +149 -0
- package/packages/mcp/src/server/approval.ts +159 -0
- package/packages/mcp/src/server/naming.ts +43 -0
- package/packages/mcp/src/server/results.ts +102 -0
- package/packages/mcp/src/server/server.ts +797 -0
- package/packages/mcp/src/server/tools.ts +116 -0
- package/packages/mcp/src/usage.ts +40 -0
- package/packages/mcp/tests/approval.test.ts +60 -0
- package/packages/mcp/tests/identity.test.ts +234 -0
- package/packages/mcp/tests/naming.test.ts +62 -0
- package/packages/mcp/tests/options.test.ts +140 -0
- package/packages/mcp/tests/server.test.ts +997 -0
- package/packages/mcp/tsconfig.json +19 -0
- package/packages/mcp/tsconfig.typecheck.json +10 -0
- package/packages/mcp/vitest.config.ts +10 -0
- package/packages/react/LICENSE +21 -0
- package/packages/react/README.md +328 -0
- package/packages/react/llms.txt +95 -0
- package/packages/react/package.json +95 -0
- package/packages/react/src/index.tsx +678 -0
- package/packages/react/tests/abandoned-render.test.tsx +816 -0
- package/packages/react/tests/auth.test.tsx +315 -0
- package/packages/react/tests/caller-keys.test.tsx +2334 -0
- package/packages/react/tests/client-time.test.ts +40 -0
- package/packages/react/tests/entry.test.ts +52 -0
- package/packages/react/tests/helpers.tsx +291 -0
- package/packages/react/tests/hydration.test.tsx +262 -0
- package/packages/react/tests/ownership.test.tsx +260 -0
- package/packages/react/tests/provider.server.test.tsx +169 -0
- package/packages/react/tests/query-client.test.tsx +107 -0
- package/packages/react/tests/strict-mode.test.tsx +288 -0
- package/packages/react/tests/suspense.test-d.tsx +357 -0
- package/packages/react/tests/two-query-cores.test.tsx +135 -0
- package/packages/react/tests/types.test-d.tsx +63 -0
- package/packages/react/tsconfig.json +23 -0
- package/packages/react/tsconfig.test.json +8 -0
- package/packages/react/tsconfig.typecheck.json +16 -0
- package/packages/react/vitest.config.ts +39 -0
- package/packages/vite-plugin/LICENSE +21 -0
- package/packages/vite-plugin/README.md +532 -0
- package/packages/vite-plugin/package.json +76 -0
- package/packages/vite-plugin/src/describe-value.test.ts +43 -0
- package/packages/vite-plugin/src/describe-value.ts +167 -0
- package/packages/vite-plugin/src/dev-environment.test.ts +747 -0
- package/packages/vite-plugin/src/dev-environment.ts +510 -0
- package/packages/vite-plugin/src/env.ts +431 -0
- package/packages/vite-plugin/src/fetch.ts +348 -0
- package/packages/vite-plugin/src/file-identity.ts +106 -0
- package/packages/vite-plugin/src/generate.ts +691 -0
- package/packages/vite-plugin/src/index.test.ts +1243 -0
- package/packages/vite-plugin/src/index.ts +2565 -0
- package/packages/vite-plugin/src/interface.ts +339 -0
- package/packages/vite-plugin/src/local-host.ts +34 -0
- package/packages/vite-plugin/src/options.ts +641 -0
- package/packages/vite-plugin/src/principal-text.test.ts +87 -0
- package/packages/vite-plugin/src/principal-text.ts +98 -0
- package/packages/vite-plugin/tests/close.test.ts +141 -0
- package/packages/vite-plugin/tests/environment-mode.test.ts +136 -0
- package/packages/vite-plugin/tests/fake-ic.ts +214 -0
- package/packages/vite-plugin/tests/fetch-sdk.test.ts +27 -0
- package/packages/vite-plugin/tests/fetch.test.ts +1196 -0
- package/packages/vite-plugin/tests/fixtures/fake-cli/bin.js +90 -0
- package/packages/vite-plugin/tests/fixtures/fake-cli/package.json +8 -0
- package/packages/vite-plugin/tests/fixtures/icrc1.did +88 -0
- package/packages/vite-plugin/tests/generation.test.ts +1036 -0
- package/packages/vite-plugin/tests/icp-command.test.ts +194 -0
- package/packages/vite-plugin/tests/icp-timeout.test.ts +83 -0
- package/packages/vite-plugin/tests/no-process-exit.test.ts +83 -0
- package/packages/vite-plugin/tests/on-generated.test.ts +323 -0
- package/packages/vite-plugin/tests/output-collision.test.ts +329 -0
- package/packages/vite-plugin/tests/package.test.ts +62 -0
- package/packages/vite-plugin/tests/project.test.ts +2993 -0
- package/packages/vite-plugin/tests/support.ts +339 -0
- package/packages/vite-plugin/tests/timeout.test.ts +107 -0
- package/packages/vite-plugin/tsconfig.json +23 -0
- package/packages/vite-plugin/tsconfig.typecheck.json +16 -0
- package/packages/vite-plugin/vitest.config.ts +9 -0
- package/pnpm-workspace.yaml +23 -0
- package/scripts/ai-context-files.js +72 -0
- package/scripts/assemble-docs-site.mjs +485 -0
- package/scripts/assemble-docs-site.test.mjs +568 -0
- package/scripts/build-examples.js +58 -0
- package/scripts/check-ai-context.js +963 -0
- package/scripts/check-ai-context.test.mjs +811 -0
- package/scripts/check-exports.mjs +767 -0
- package/scripts/check-exports.test.mjs +1136 -0
- package/scripts/check-snippets/ambient.d.ts +428 -0
- package/scripts/check-snippets/app/generated/backend.did +7 -0
- package/scripts/check-snippets/app/generated/backend.ts +15 -0
- package/scripts/check-snippets/app/generated/icrc1.did +88 -0
- package/scripts/check-snippets/app/generated/icrc1.ts +78 -0
- package/scripts/check-snippets/app/globals.ts +26 -0
- package/scripts/check-snippets/docs/guides/App.tsx +21 -0
- package/scripts/check-snippets/docs/guides/app/providers.tsx +23 -0
- package/scripts/check-snippets/docs/guides/auth-client.ts +47 -0
- package/scripts/check-snippets/docs/guides/canisters/backend.ts +3 -0
- package/scripts/check-snippets/docs/guides/canisters/icrc1.ts +3 -0
- package/scripts/check-snippets/docs/guides/components/LedgerCard.tsx +26 -0
- package/scripts/check-snippets/docs/guides/components/shell.tsx +11 -0
- package/scripts/check-snippets/docs/guides/components/sign-in-page.tsx +29 -0
- package/scripts/check-snippets/docs/guides/components/slow-section.tsx +5 -0
- package/scripts/check-snippets/docs/guides/generated/accounts.ts +95 -0
- package/scripts/check-snippets/docs/guides/generated/ckbtc_minter.ts +40 -0
- package/scripts/check-snippets/docs/guides/generated/icp_ledger.ts +267 -0
- package/scripts/check-snippets/docs/guides/ledger.ts +10 -0
- package/scripts/check-snippets/docs/guides/server/request-client.ts +8 -0
- package/scripts/check-snippets.mjs +993 -0
- package/scripts/check-snippets.test.mjs +338 -0
- package/scripts/check-stack.mjs +501 -0
- package/scripts/check-stack.test.mjs +800 -0
- package/scripts/clean-node-modules.js +67 -0
- package/scripts/example-projects.js +58 -0
- package/scripts/export-budget.mjs +145 -0
- package/scripts/faults.json +6749 -0
- package/scripts/lib/fault-workspace.mjs +210 -0
- package/scripts/lib/io.mjs +29 -0
- package/scripts/lib/io.test.mjs +38 -0
- package/scripts/lib/markdown-fences.mjs +56 -0
- package/scripts/lib/markdown-fences.test.mjs +84 -0
- package/scripts/lib/package-exports.mjs +54 -0
- package/scripts/lib/package-exports.test.mjs +66 -0
- package/scripts/lib/release-pr-steps.mjs +47 -0
- package/scripts/release-tag.mjs +95 -0
- package/scripts/release-tag.test.mjs +278 -0
- package/scripts/release-workflow.test.mjs +98 -0
- package/scripts/release.js +167 -0
- package/scripts/release.test.mjs +347 -0
- package/scripts/removed-v3-names.js +125 -0
- package/scripts/size-app/.size-limit.js +90 -0
- package/scripts/size-app/core.js +3 -0
- package/scripts/size-app/package.json +24 -0
- package/scripts/size-app/react.js +4 -0
- package/scripts/size-app.test.mjs +73 -0
- package/scripts/sync-ai-context-versions.js +102 -0
- package/scripts/sync-example-versions.js +151 -0
- package/scripts/test-examples-published.mjs +1585 -0
- package/scripts/test-examples-published.test.mjs +1586 -0
- package/scripts/traps/any-method-vars-not-a-list.json +5 -0
- package/scripts/traps/canister-method-unknown.json +5 -0
- package/scripts/traps/client-says-who-calls-once.json +5 -0
- package/scripts/traps/client-says-who-calls.json +5 -0
- package/scripts/traps/err-only-on-canister-err.json +14 -0
- package/scripts/traps/format-units-refuses-missing-value.json +5 -0
- package/scripts/traps/format-units-refuses-number.json +5 -0
- package/scripts/traps/format-units-unknown-option.json +5 -0
- package/scripts/traps/guard-err-is-the-methods.json +5 -0
- package/scripts/traps/guard-false-keeps-every-kind.json +5 -0
- package/scripts/traps/internals-not-exported.json +9 -0
- package/scripts/traps/network-refuses-unknown-name.json +5 -0
- package/scripts/traps/never-err-has-no-type.json +5 -0
- package/scripts/traps/options-method-unknown.json +5 -0
- package/scripts/traps/options-vars-wrong-type.json +5 -0
- package/scripts/traps/parse-units-refuses-number.json +5 -0
- package/scripts/traps/parse-units-unknown-option.json +5 -0
- package/scripts/traps/principal-is-not-plain-text.json +14 -0
- package/scripts/traps/query-options-refuses-oneway.json +5 -0
- package/scripts/traps/query-options-refuses-update.json +5 -0
- package/scripts/traps/refuse-next-unknown-option.json +5 -0
- package/scripts/traps/resend-key-reads-the-methods-arg.json +5 -0
- package/scripts/traps/resend-states-its-dedupe-key.json +5 -0
- package/scripts/traps/suspense-refuses-argument-skip.json +5 -0
- package/scripts/traps/suspense-refuses-skippable-read.json +5 -0
- package/scripts/traps/suspense-refuses-vars-skip-fits.json +5 -0
- package/scripts/traps/test-handler-method-unknown.json +5 -0
- package/scripts/traps/test-handler-nat-is-bigint.json +5 -0
- package/scripts/traps/test-handler-takes-the-domain-value.json +5 -0
- package/scripts/traps/vars-of-two-arguments-are-the-tuple.json +5 -0
- package/scripts/typecheck-examples.js +122 -0
- package/scripts/verify-faults.mjs +375 -0
- package/scripts/verify-faults.test.mjs +402 -0
- package/scripts/verify-package-artifacts.mjs +590 -0
- package/scripts/verify-peer-floors.js +399 -0
- package/scripts/verify-peer-floors.test.mjs +422 -0
- package/scripts/verify-test-fails-rules.mjs +104 -0
- package/scripts/verify-test-fails-rules.test.mjs +215 -0
- package/scripts/verify-test-fails.js +371 -0
- package/scripts/verify-traps.mjs +505 -0
- package/scripts/verify-traps.test.mjs +521 -0
- package/scripts/verify-typescript-floor.js +239 -0
- package/skill-packages/ic-reactor/SKILL.md +103 -0
- package/stack.json +8 -0
- package/tsconfig.base.json +23 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks the example docs pages against the examples/ tree they document.
|
|
3
|
+
*
|
|
4
|
+
* Every page in docs/src/content/docs/examples/ other than index.mdx must
|
|
5
|
+
* embed a StackBlitz or CodeSandbox link, and every such link must resolve
|
|
6
|
+
* inside this repo. Its sandbox root has to exist and hold a package.json,
|
|
7
|
+
* because StackBlitz has nothing to install or boot without one. The file
|
|
8
|
+
* named by its `file=` parameter has to exist under that root. Every directory
|
|
9
|
+
* in examples/ with a package.json at its root or one level down must be
|
|
10
|
+
* linked from at least one of those pages.
|
|
11
|
+
*
|
|
12
|
+
* index.mdx is exempt from the sandbox rules. It is a card grid with no
|
|
13
|
+
* sandbox link of its own, and a sandbox link added there must not count as
|
|
14
|
+
* documenting an example that has no page. It must instead carry exactly one
|
|
15
|
+
* LinkCard per example page. Nothing checked the index before, and the
|
|
16
|
+
* ckbtc-wallet and icp-reactor cards fell off it while both pages stayed
|
|
17
|
+
* published.
|
|
18
|
+
*
|
|
19
|
+
* This reads the MDX sources and needs no build. check-links.mjs cannot catch
|
|
20
|
+
* any of this. It skips external links, and fetching a StackBlitz URL would not
|
|
21
|
+
* help, since a `file=` parameter and a sandbox root's package.json only mean
|
|
22
|
+
* something against this repo's own tree. A missing card or an undocumented
|
|
23
|
+
* example is not a broken link at all.
|
|
24
|
+
*/
|
|
25
|
+
import fs from "node:fs"
|
|
26
|
+
import path from "node:path"
|
|
27
|
+
|
|
28
|
+
// Resolved from this file, not the working directory. `path.resolve("..")` only
|
|
29
|
+
// found the repo when run from docs/. From the repo root it scanned a directory
|
|
30
|
+
// outside the checkout and died with ENOENT.
|
|
31
|
+
const repoRoot = path.resolve(import.meta.dirname, "../..")
|
|
32
|
+
const docsExamplesDir = path.join(repoRoot, "docs/src/content/docs/examples")
|
|
33
|
+
const examplesDir = path.join(repoRoot, "examples")
|
|
34
|
+
// A sandbox opens a branch of the repository. Only `main` is the 4.x line: a
|
|
35
|
+
// link to a version branch (`v3`, or `v4`, which is retired after the 4.0 GA
|
|
36
|
+
// flip) is matched so that it can be refused below.
|
|
37
|
+
const SANDBOX_BRANCH = "main"
|
|
38
|
+
const providerPattern =
|
|
39
|
+
/https:\/\/(?:stackblitz\.com\/github|codesandbox\.io\/p\/github)\/b3pay\/ic-reactor\/(?:tree\/)?(main|v\d+)(?:\/examples)?\/([^?"\s)]+)[^"\s)]*/g
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* `target` resolved under `root`, or `undefined` when it leaves `root` or names
|
|
43
|
+
* `root` itself. Sandbox paths and `file=` parameters are free text in the
|
|
44
|
+
* pages, and a `../` in either would check a file outside the example the link
|
|
45
|
+
* actually opens.
|
|
46
|
+
*/
|
|
47
|
+
function resolveInside(root, target) {
|
|
48
|
+
const resolved = path.resolve(root, target)
|
|
49
|
+
const relative = path.relative(root, resolved)
|
|
50
|
+
const escapes =
|
|
51
|
+
relative === "" ||
|
|
52
|
+
relative === ".." ||
|
|
53
|
+
relative.startsWith(`..${path.sep}`) ||
|
|
54
|
+
path.isAbsolute(relative)
|
|
55
|
+
return escapes ? undefined : resolved
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function hasPackageJson(dir) {
|
|
59
|
+
return fs.existsSync(path.join(dir, "package.json"))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function findPackageRoot(exampleDir) {
|
|
63
|
+
const root = path.join(examplesDir, exampleDir)
|
|
64
|
+
if (hasPackageJson(root)) return root
|
|
65
|
+
|
|
66
|
+
for (const child of fs.readdirSync(root, { withFileTypes: true })) {
|
|
67
|
+
if (child.isDirectory() && hasPackageJson(path.join(root, child.name))) {
|
|
68
|
+
return path.join(root, child.name)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return null
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function getExampleDirs() {
|
|
76
|
+
return fs
|
|
77
|
+
.readdirSync(examplesDir, { withFileTypes: true })
|
|
78
|
+
.filter((entry) => entry.isDirectory())
|
|
79
|
+
.map((entry) => entry.name)
|
|
80
|
+
.filter((name) => findPackageRoot(name))
|
|
81
|
+
.sort()
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function getMdxFiles() {
|
|
85
|
+
return fs
|
|
86
|
+
.readdirSync(docsExamplesDir)
|
|
87
|
+
.filter((name) => name.endsWith(".mdx"))
|
|
88
|
+
.sort()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!fs.existsSync(examplesDir)) {
|
|
92
|
+
console.error(`- examples/ does not exist`)
|
|
93
|
+
process.exit(1)
|
|
94
|
+
}
|
|
95
|
+
if (!fs.existsSync(docsExamplesDir)) {
|
|
96
|
+
console.error(
|
|
97
|
+
`- examples/ exists, but no docs page in ${docsExamplesDir} documents it`
|
|
98
|
+
)
|
|
99
|
+
process.exit(1)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const pages = getMdxFiles().filter((file) => file !== "index.mdx")
|
|
103
|
+
const documentedExamples = new Set()
|
|
104
|
+
// A Set, because each page points at the same sandbox twice, once in the
|
|
105
|
+
// "Open in StackBlitz" LinkCard href and again in the iframe src. With an
|
|
106
|
+
// array, one broken link produced two identical findings.
|
|
107
|
+
const errors = new Set()
|
|
108
|
+
|
|
109
|
+
for (const file of pages) {
|
|
110
|
+
const fullPath = path.join(docsExamplesDir, file)
|
|
111
|
+
const content = fs.readFileSync(fullPath, "utf8")
|
|
112
|
+
const matches = [...content.matchAll(providerPattern)]
|
|
113
|
+
|
|
114
|
+
if (matches.length === 0) {
|
|
115
|
+
errors.add(`${file} has no StackBlitz or CodeSandbox example link`)
|
|
116
|
+
continue
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
for (const match of matches) {
|
|
120
|
+
const url = match[0]
|
|
121
|
+
if (match[1] !== SANDBOX_BRANCH) {
|
|
122
|
+
errors.add(
|
|
123
|
+
`${file} opens the ${match[1]} branch (${url}); sandbox links open ${SANDBOX_BRANCH}`
|
|
124
|
+
)
|
|
125
|
+
continue
|
|
126
|
+
}
|
|
127
|
+
let examplePath
|
|
128
|
+
try {
|
|
129
|
+
examplePath = decodeURIComponent(match[2]).replace(/\/+$/, "")
|
|
130
|
+
} catch {
|
|
131
|
+
errors.add(`${file} has a sandbox path that is not valid: ${match[2]}`)
|
|
132
|
+
continue
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// The documented example is read from the normalized path, so a link to
|
|
136
|
+
// `new-example/../existing-example` cannot mark new-example as covered.
|
|
137
|
+
const sandboxRoot = resolveInside(examplesDir, examplePath)
|
|
138
|
+
const normalized =
|
|
139
|
+
sandboxRoot && path.relative(examplesDir, sandboxRoot).split(path.sep)
|
|
140
|
+
if (!normalized || normalized.join("/") !== examplePath) {
|
|
141
|
+
errors.add(
|
|
142
|
+
`${file} sandbox root is not a plain path inside examples/: ${examplePath}`
|
|
143
|
+
)
|
|
144
|
+
continue
|
|
145
|
+
}
|
|
146
|
+
documentedExamples.add(normalized[0])
|
|
147
|
+
|
|
148
|
+
if (!fs.existsSync(sandboxRoot)) {
|
|
149
|
+
errors.add(
|
|
150
|
+
`${file} links to missing sandbox root: examples/${examplePath}`
|
|
151
|
+
)
|
|
152
|
+
continue
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (!hasPackageJson(sandboxRoot)) {
|
|
156
|
+
errors.add(
|
|
157
|
+
`${file} sandbox root has no package.json: examples/${examplePath}`
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const parsedUrl = new URL(url)
|
|
162
|
+
const focusedFile = parsedUrl.searchParams.get("file")
|
|
163
|
+
if (focusedFile) {
|
|
164
|
+
const target = resolveInside(sandboxRoot, focusedFile)
|
|
165
|
+
if (!target) {
|
|
166
|
+
errors.add(
|
|
167
|
+
`${file} focuses a file outside its sandbox root: examples/${examplePath} file=${focusedFile}`
|
|
168
|
+
)
|
|
169
|
+
} else if (!fs.existsSync(target) || !fs.statSync(target).isFile()) {
|
|
170
|
+
errors.add(
|
|
171
|
+
`${file} focuses missing file: examples/${examplePath}/${focusedFile}`
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
for (const exampleDir of getExampleDirs()) {
|
|
179
|
+
if (!documentedExamples.has(exampleDir)) {
|
|
180
|
+
errors.add(`examples/${exampleDir} is not linked from an example docs page`)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Cards are matched to pages by the last segment of an `/examples/<slug>` href,
|
|
185
|
+
// so the check does not depend on the site's base path. A card whose href is
|
|
186
|
+
// not shaped like that is skipped, and its page then reports a missing card.
|
|
187
|
+
const cardCounts = new Map(pages.map((page) => [page, 0]))
|
|
188
|
+
const index = fs.readFileSync(path.join(docsExamplesDir, "index.mdx"), "utf8")
|
|
189
|
+
for (const [, attributes] of index.matchAll(/<LinkCard\b([\s\S]*?)\/>/g)) {
|
|
190
|
+
const href = attributes.match(/\bhref="([^"]*)"/)?.[1]
|
|
191
|
+
const slug = href?.match(/\/examples\/([^/?#]+)\/?$/)?.[1]
|
|
192
|
+
if (!slug) continue
|
|
193
|
+
|
|
194
|
+
const page = `${slug}.mdx`
|
|
195
|
+
if (cardCounts.has(page)) {
|
|
196
|
+
cardCounts.set(page, cardCounts.get(page) + 1)
|
|
197
|
+
} else {
|
|
198
|
+
errors.add(`index.mdx has a LinkCard for a missing page: ${href}`)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
for (const [page, count] of cardCounts) {
|
|
203
|
+
if (count === 0) errors.add(`index.mdx has no LinkCard for ${page}`)
|
|
204
|
+
if (count > 1) errors.add(`index.mdx has ${count} LinkCards for ${page}`)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (errors.size > 0) {
|
|
208
|
+
console.error([...errors].map((error) => `- ${error}`).join("\n"))
|
|
209
|
+
process.exit(1)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
console.log(
|
|
213
|
+
`Checked ${documentedExamples.size} documented examples with sandbox links and ${pages.length} index cards.`
|
|
214
|
+
)
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crawls the BUILT docs for broken links.
|
|
3
|
+
*
|
|
4
|
+
* Runs against `docs/dist` rather than the Markdown sources because the site's
|
|
5
|
+
* hand-written hrefs are absolute and base-prefixed (`](/v3/...)`) -- they only
|
|
6
|
+
* resolve once Astro has rendered routes under the configured base. Checking the
|
|
7
|
+
* sources would miss exactly the links a page rename breaks.
|
|
8
|
+
*
|
|
9
|
+
* Astro writes the site to `dist/` root while emitting `/v3/`-prefixed hrefs, so
|
|
10
|
+
* the crawl needs `dist` mounted AT the base rather than served as the web root.
|
|
11
|
+
* A staging directory with a symlink gives that without copying 24 MB.
|
|
12
|
+
*
|
|
13
|
+
* The base is read from astro.config.mjs rather than hardcoded, so the two
|
|
14
|
+
* cannot drift.
|
|
15
|
+
*
|
|
16
|
+
* The pages also link Candid Core's site, which the deploy serves at
|
|
17
|
+
* `/candid-core/` from a build of its own repository
|
|
18
|
+
* (scripts/assemble-docs-site.mjs). `CANDID_CORE_SITE` names that build
|
|
19
|
+
* (`website/dist` of a B3Pay/Meant checkout, after
|
|
20
|
+
* `node website/build.mjs`; a relative path is read from docs/, where it runs),
|
|
21
|
+
* and it is mounted there too: each such link and its `#fragment` are checked
|
|
22
|
+
* against the real pages, and those pages are crawled as well, as they will be
|
|
23
|
+
* published. Without it those links are skipped and counted, and in CI (`CI`
|
|
24
|
+
* set) the check fails instead.
|
|
25
|
+
*/
|
|
26
|
+
import { mkdtemp, readFile, readdir, rm, symlink } from "node:fs/promises"
|
|
27
|
+
import { tmpdir } from "node:os"
|
|
28
|
+
import { existsSync } from "node:fs"
|
|
29
|
+
import { join, posix, resolve } from "node:path"
|
|
30
|
+
import { LinkChecker } from "linkinator"
|
|
31
|
+
|
|
32
|
+
const docsRoot = resolve(import.meta.dirname, "..")
|
|
33
|
+
|
|
34
|
+
const config = await readFile(join(docsRoot, "astro.config.mjs"), "utf8")
|
|
35
|
+
const baseMatch = config.match(/^\s*base:\s*["'](.+?)["']/m)
|
|
36
|
+
if (!baseMatch) {
|
|
37
|
+
console.error("Could not read `base` from astro.config.mjs")
|
|
38
|
+
process.exit(1)
|
|
39
|
+
}
|
|
40
|
+
const base = baseMatch[1].replace(/^\/|\/$/g, "")
|
|
41
|
+
|
|
42
|
+
// Where the deploy serves Candid Core's site (CANDID_CORE_DIR in
|
|
43
|
+
// scripts/assemble-docs-site.mjs).
|
|
44
|
+
const candidCoreDir = "candid-core"
|
|
45
|
+
const candidCoreSite = process.env.CANDID_CORE_SITE
|
|
46
|
+
? resolve(process.env.CANDID_CORE_SITE)
|
|
47
|
+
: undefined
|
|
48
|
+
if (candidCoreSite && !existsSync(join(candidCoreSite, "index.html"))) {
|
|
49
|
+
console.error(
|
|
50
|
+
`CANDID_CORE_SITE=${candidCoreSite} holds no built Candid Core site (no index.html)`
|
|
51
|
+
)
|
|
52
|
+
process.exit(1)
|
|
53
|
+
}
|
|
54
|
+
if (!candidCoreSite && process.env.CI) {
|
|
55
|
+
console.error(
|
|
56
|
+
`CANDID_CORE_SITE is not set: in CI the links under /${candidCoreDir}/ are checked against a build of B3Pay/Meant's site`
|
|
57
|
+
)
|
|
58
|
+
process.exit(1)
|
|
59
|
+
}
|
|
60
|
+
// linkinator matches a skip pattern against the absolute URL, and reports a
|
|
61
|
+
// link of its own server by its path from the server root.
|
|
62
|
+
const candidCoreUrl = new RegExp(
|
|
63
|
+
`^(https?://(localhost|127\\.0\\.0\\.1)(:\\d+)?/|/)?${candidCoreDir}(/|$)`
|
|
64
|
+
)
|
|
65
|
+
const candidCoreRoot = new RegExp(
|
|
66
|
+
`^(https?://(localhost|127\\.0\\.0\\.1)(:\\d+)?/|/)?${candidCoreDir}/?$`
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
const staging = await mkdtemp(join(tmpdir(), "ic-reactor-links-"))
|
|
70
|
+
try {
|
|
71
|
+
await symlink(join(docsRoot, "dist"), join(staging, base), "dir")
|
|
72
|
+
if (candidCoreSite) {
|
|
73
|
+
await symlink(candidCoreSite, join(staging, candidCoreDir), "dir")
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const options = {
|
|
77
|
+
// The crawl root must be the DIRECTORY, not index.html. linkinator sets
|
|
78
|
+
// `rootPath` to the full starting URL and only recurses into links whose
|
|
79
|
+
// href string-prefixes it (build/src/index.js:271 and :892). With
|
|
80
|
+
// `${base}/index.html` nothing on the site starts with that string, so the
|
|
81
|
+
// crawl never leaves the home page: it reported "Checked 191 internal
|
|
82
|
+
// links" for a 180-page site while visiting exactly one page.
|
|
83
|
+
path: `${base}/`,
|
|
84
|
+
serverRoot: staging,
|
|
85
|
+
recurse: true,
|
|
86
|
+
// A `#fragment` must name an id on its page, so a reworded heading that
|
|
87
|
+
// breaks a link like `/v4/guides/ssr/#a-read-...` fails here.
|
|
88
|
+
checkFragments: true,
|
|
89
|
+
// linkinator's default concurrency (100) overwhelms its own static server
|
|
90
|
+
// once the crawl is a few hundred links: requests come back with status 0
|
|
91
|
+
// (connection dropped, not a 404) and the gate fails intermittently on
|
|
92
|
+
// whichever page lost the race. Capping concurrency and retrying transport
|
|
93
|
+
// errors makes it deterministic -- a flaky gate gets ignored, which is the
|
|
94
|
+
// failure mode this whole gate exists to avoid.
|
|
95
|
+
concurrency: 25,
|
|
96
|
+
retryErrors: true,
|
|
97
|
+
retryErrorsCount: 3,
|
|
98
|
+
linksToSkip: [
|
|
99
|
+
// External links are someone else's uptime, not this repo's correctness.
|
|
100
|
+
// linkinator resolves every internal link against its own server, which
|
|
101
|
+
// binds 127.0.0.1 -- so this must exempt the local host explicitly or it
|
|
102
|
+
// skips the entire site and the gate silently checks nothing.
|
|
103
|
+
"^https?://(?!(localhost|127\\.0\\.0\\.1)[:/])",
|
|
104
|
+
// Without a build of Candid Core's site, its links cannot be checked.
|
|
105
|
+
...(candidCoreSite ? [] : [candidCoreUrl.source]),
|
|
106
|
+
],
|
|
107
|
+
}
|
|
108
|
+
const result = await new LinkChecker().check(options)
|
|
109
|
+
// Candid Core's own pages, as they will be published: the crawl above only
|
|
110
|
+
// follows links under the base, so it stops at their entry links.
|
|
111
|
+
const candidCoreResult = candidCoreSite
|
|
112
|
+
? await new LinkChecker().check({ ...options, path: `${candidCoreDir}/` })
|
|
113
|
+
: { links: [] }
|
|
114
|
+
|
|
115
|
+
// Case-sensitivity pass. linkinator serves the built site from the local
|
|
116
|
+
// filesystem, so on macOS every href resolves case-insensitively and a link
|
|
117
|
+
// that is a hard 404 on the Linux host comes back 200. That is not a
|
|
118
|
+
// hypothetical: `starlight-page-actions` writes each page's `.md` companion
|
|
119
|
+
// at the SOURCE-cased path while building the href from the lowercased route,
|
|
120
|
+
// and the mismatch is invisible here without this check. Compare exact
|
|
121
|
+
// strings against the real file set rather than asking the filesystem.
|
|
122
|
+
const realFiles = new Set()
|
|
123
|
+
const walk = async (dir, rel = "") => {
|
|
124
|
+
for (const e of await readdir(dir, { withFileTypes: true })) {
|
|
125
|
+
const r = rel ? `${rel}/${e.name}` : e.name
|
|
126
|
+
if (e.isDirectory()) await walk(join(dir, e.name), r)
|
|
127
|
+
else realFiles.add(r)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
await walk(join(docsRoot, "dist"))
|
|
131
|
+
|
|
132
|
+
const caseBroken = []
|
|
133
|
+
for (const page of [...realFiles].filter((f) => f.endsWith(".html"))) {
|
|
134
|
+
const html = await readFile(join(docsRoot, "dist", page), "utf8")
|
|
135
|
+
const route = `/${base}/${page.replace(/index\.html$/, "")}`
|
|
136
|
+
for (const [, href] of html.matchAll(/href="([^"]+)"/g)) {
|
|
137
|
+
if (/^(https?:|mailto:|#|\/\/)/.test(href)) continue
|
|
138
|
+
const clean = href.split("#")[0].split("?")[0]
|
|
139
|
+
if (!clean) continue
|
|
140
|
+
const abs = clean.startsWith("/")
|
|
141
|
+
? clean
|
|
142
|
+
: posix.normalize(posix.join(route, clean))
|
|
143
|
+
if (!abs.startsWith(`/${base}/`)) continue
|
|
144
|
+
let f = abs.slice(base.length + 2)
|
|
145
|
+
if (f === "") f = "index.html"
|
|
146
|
+
else if (f.endsWith("/")) f += "index.html"
|
|
147
|
+
else if (!/\.[a-z0-9]+$/i.test(f)) f += "/index.html"
|
|
148
|
+
if (!realFiles.has(f)) caseBroken.push(`${href}\n <- ${route}`)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (caseBroken.length > 0) {
|
|
152
|
+
console.error(
|
|
153
|
+
`\n${caseBroken.length} link(s) resolve only on a case-insensitive filesystem ` +
|
|
154
|
+
`- these are 404s on the Linux host that serves the site:\n`
|
|
155
|
+
)
|
|
156
|
+
for (const b of caseBroken.slice(0, 20)) console.error(` ${b}`)
|
|
157
|
+
if (caseBroken.length > 20)
|
|
158
|
+
console.error(` ... and ${caseBroken.length - 20} more`)
|
|
159
|
+
process.exit(1)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const broken = [...result.links, ...candidCoreResult.links].filter(
|
|
163
|
+
(l) => l.state === "BROKEN"
|
|
164
|
+
)
|
|
165
|
+
const checked = result.links.filter((l) => l.state !== "SKIPPED")
|
|
166
|
+
// What the crawl of Candid Core's pages reached past the home page it
|
|
167
|
+
// started from, which it reports twice (`candid-core`, then `candid-core/`).
|
|
168
|
+
const candidCoreReached = new Set(
|
|
169
|
+
candidCoreResult.links
|
|
170
|
+
.filter((l) => l.state !== "SKIPPED" && !candidCoreRoot.test(l.url))
|
|
171
|
+
.map((l) => l.url)
|
|
172
|
+
)
|
|
173
|
+
// linkinator reports a skipped URL once per page that links it.
|
|
174
|
+
const candidCoreSkipped = new Set(
|
|
175
|
+
result.links
|
|
176
|
+
.filter((l) => l.state === "SKIPPED" && candidCoreUrl.test(l.url))
|
|
177
|
+
.map((l) => l.url)
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
if (broken.length > 0) {
|
|
181
|
+
console.error(`\n${broken.length} broken link(s):\n`)
|
|
182
|
+
for (const link of broken) {
|
|
183
|
+
console.error(` [${link.status}] ${link.url}\n <- ${link.parent}`)
|
|
184
|
+
}
|
|
185
|
+
process.exit(1)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// A mounted site whose crawl reached nothing past its home page was not
|
|
189
|
+
// checked.
|
|
190
|
+
if (candidCoreSite && candidCoreReached.size === 0) {
|
|
191
|
+
console.error(
|
|
192
|
+
`The crawl of /${candidCoreDir}/ reached nothing past its home page: is ${candidCoreSite} the site's website/dist?`
|
|
193
|
+
)
|
|
194
|
+
process.exit(1)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
console.log(
|
|
198
|
+
`Checked ${checked.length} internal links under /${base}/ - no broken links.`
|
|
199
|
+
)
|
|
200
|
+
if (candidCoreSite) {
|
|
201
|
+
const entries = checked.filter((l) => candidCoreUrl.test(l.url)).length
|
|
202
|
+
console.log(
|
|
203
|
+
`${entries} of them reach Candid Core's site under /${candidCoreDir}/, and the crawl of its pages reached ${candidCoreReached.size} more, none broken (built at ${candidCoreSite}).`
|
|
204
|
+
)
|
|
205
|
+
} else {
|
|
206
|
+
console.log(
|
|
207
|
+
`${candidCoreSkipped.size} links under /${candidCoreDir}/ were not checked: set CANDID_CORE_SITE to a build of B3Pay/Meant's site (website/dist).`
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
} finally {
|
|
211
|
+
await rm(staging, { recursive: true, force: true })
|
|
212
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Post-`astro build` repairs to the built site, for two things neither Astro
|
|
4
|
+
* nor the plugins get right on their own.
|
|
5
|
+
*
|
|
6
|
+
* 1. PAGE-ACTION MARKDOWN LINKS. `starlight-page-actions` writes each page's
|
|
7
|
+
* `.md` companion at the SOURCE-cased path but builds the href from the
|
|
8
|
+
* RENDERED ROUTE, which Starlight lowercases. TypeDoc filenames are
|
|
9
|
+
* PascalCase, so every such link on a mixed-case page 404s:
|
|
10
|
+
*
|
|
11
|
+
* href /v3/libs/classes/authenticationmanager.md
|
|
12
|
+
* file dist/libs/classes/AuthenticationManager.md
|
|
13
|
+
*
|
|
14
|
+
* This is invisible on macOS, whose filesystem is case-insensitive, and a
|
|
15
|
+
* hard 404 on the Linux host. The home page has a second variant of the same
|
|
16
|
+
* bug: its href is `${base}.md`, but the file is served at `${base}/index.md`.
|
|
17
|
+
*
|
|
18
|
+
* We repoint the hrefs at the files that exist rather than emitting
|
|
19
|
+
* lowercase duplicates, so the already-deployed source-cased URLs keep
|
|
20
|
+
* working and nothing is published twice.
|
|
21
|
+
*
|
|
22
|
+
* 2. llms.txt. The plugin builds it from the site origin and drops the base
|
|
23
|
+
* path, so every entry points one level above the real page. Setting
|
|
24
|
+
* `baseUrl` in astro.config.mjs does not help: the plugin reduces the URL to
|
|
25
|
+
* `urlObj.origin`.
|
|
26
|
+
*/
|
|
27
|
+
import {
|
|
28
|
+
readFileSync,
|
|
29
|
+
writeFileSync,
|
|
30
|
+
readdirSync,
|
|
31
|
+
statSync,
|
|
32
|
+
existsSync,
|
|
33
|
+
} from "node:fs"
|
|
34
|
+
import { join, resolve } from "node:path"
|
|
35
|
+
|
|
36
|
+
const docsRoot = resolve(import.meta.dirname, "..")
|
|
37
|
+
const DIST = join(docsRoot, "dist")
|
|
38
|
+
|
|
39
|
+
const astroConfig = readFileSync(join(docsRoot, "astro.config.mjs"), "utf8")
|
|
40
|
+
const base =
|
|
41
|
+
"/" +
|
|
42
|
+
(astroConfig.match(/^\s*base:\s*["'](.+?)["']/m)?.[1] ?? "").replace(
|
|
43
|
+
/^\/|\/$/g,
|
|
44
|
+
""
|
|
45
|
+
)
|
|
46
|
+
const site = astroConfig
|
|
47
|
+
.match(/^\s*site:\s*["'](.+?)["']/m)?.[1]
|
|
48
|
+
?.replace(/\/$/, "")
|
|
49
|
+
if (base === "/" || !site) {
|
|
50
|
+
console.error(
|
|
51
|
+
"fix-dist-links: could not read `base`/`site` from astro.config.mjs"
|
|
52
|
+
)
|
|
53
|
+
process.exit(1)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function* files(dir, rel = "") {
|
|
57
|
+
for (const name of readdirSync(dir)) {
|
|
58
|
+
const full = join(dir, name)
|
|
59
|
+
const r = rel ? `${rel}/${name}` : name
|
|
60
|
+
if (statSync(full).isDirectory()) yield* files(full, r)
|
|
61
|
+
else yield [full, r]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Two exact sets. `real` is compared by STRING, never with existsSync: macOS
|
|
66
|
+
// resolves paths case-insensitively, so existsSync reports every lowercase
|
|
67
|
+
// page-action href as already valid and this script silently fixes nothing --
|
|
68
|
+
// while the same href is a hard 404 on the Linux host that serves the site.
|
|
69
|
+
const real = new Set()
|
|
70
|
+
const byLower = new Map()
|
|
71
|
+
for (const [, rel] of files(DIST)) {
|
|
72
|
+
if (!rel.endsWith(".md")) continue
|
|
73
|
+
real.add(rel)
|
|
74
|
+
byLower.set(rel.toLowerCase(), rel)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let hrefsFixed = 0
|
|
78
|
+
let pagesTouched = 0
|
|
79
|
+
for (const [full, rel] of files(DIST)) {
|
|
80
|
+
if (!rel.endsWith(".html")) continue
|
|
81
|
+
const src = readFileSync(full, "utf8")
|
|
82
|
+
const out = src.replace(/href="([^"]+\.md)"/g, (whole, href) => {
|
|
83
|
+
// `${base}.md` on the home page -> the real `${base}/index.md`
|
|
84
|
+
if (href === `${base}.md`) {
|
|
85
|
+
if (!real.has("index.md")) return whole
|
|
86
|
+
hrefsFixed++
|
|
87
|
+
return `href="${base}/index.md"`
|
|
88
|
+
}
|
|
89
|
+
if (!href.startsWith(`${base}/`)) return whole
|
|
90
|
+
const wanted = href.slice(base.length + 1)
|
|
91
|
+
if (real.has(wanted)) return whole // exact match; already correct
|
|
92
|
+
const actual = byLower.get(wanted.toLowerCase())
|
|
93
|
+
if (!actual) return whole // genuinely missing; leave it for the link gate
|
|
94
|
+
hrefsFixed++
|
|
95
|
+
return `href="${base}/${actual}"`
|
|
96
|
+
})
|
|
97
|
+
if (out !== src) {
|
|
98
|
+
writeFileSync(full, out)
|
|
99
|
+
pagesTouched++
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// llms.txt: `https://host/foo/` -> `https://host/v3/foo/`
|
|
104
|
+
let llmsFixed = 0
|
|
105
|
+
for (const name of ["llms.txt", "llms-full.txt"]) {
|
|
106
|
+
const p = join(DIST, name)
|
|
107
|
+
if (!existsSync(p)) continue
|
|
108
|
+
const src = readFileSync(p, "utf8")
|
|
109
|
+
const out = src.replace(
|
|
110
|
+
new RegExp(
|
|
111
|
+
`${site.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?!${base}/)/`,
|
|
112
|
+
"g"
|
|
113
|
+
),
|
|
114
|
+
() => {
|
|
115
|
+
llmsFixed++
|
|
116
|
+
return `${site}${base}/`
|
|
117
|
+
}
|
|
118
|
+
)
|
|
119
|
+
if (out !== src) writeFileSync(p, out)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
console.log(
|
|
123
|
+
`fix-dist-links: repointed ${hrefsFixed} .md hrefs across ${pagesTouched} pages; ` +
|
|
124
|
+
`prefixed ${llmsFixed} llms.txt URLs with ${base}`
|
|
125
|
+
)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, writeFileSync, statSync } from "fs"
|
|
2
|
+
import { join, extname } from "path"
|
|
3
|
+
|
|
4
|
+
const DOCS_DIR = "src/content/docs"
|
|
5
|
+
|
|
6
|
+
function processFile(filePath) {
|
|
7
|
+
if (extname(filePath) !== ".md" && extname(filePath) !== ".mdx") return
|
|
8
|
+
|
|
9
|
+
const content = readFileSync(filePath, "utf-8")
|
|
10
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/)
|
|
11
|
+
|
|
12
|
+
if (frontmatterMatch) {
|
|
13
|
+
const frontmatter = frontmatterMatch[1]
|
|
14
|
+
if (frontmatter.includes("title:")) return // Already has title
|
|
15
|
+
|
|
16
|
+
// Try to find H1
|
|
17
|
+
const h1Match = content.match(/^# (.*)/m)
|
|
18
|
+
if (h1Match) {
|
|
19
|
+
const title = h1Match[1].trim()
|
|
20
|
+
const newFrontmatter = `title: ${title}\n${frontmatter}`
|
|
21
|
+
const newContent = content.replace(
|
|
22
|
+
frontmatterMatch[0],
|
|
23
|
+
`---\n${newFrontmatter}\n---`
|
|
24
|
+
)
|
|
25
|
+
writeFileSync(filePath, newContent)
|
|
26
|
+
console.log(`Added title to ${filePath}: ${title}`)
|
|
27
|
+
} else {
|
|
28
|
+
// Use filename as fallback
|
|
29
|
+
const filename = filePath
|
|
30
|
+
.split("/")
|
|
31
|
+
.pop()
|
|
32
|
+
.replace(/\.(md|mdx)$/, "")
|
|
33
|
+
const title = filename.charAt(0).toUpperCase() + filename.slice(1)
|
|
34
|
+
const newFrontmatter = `title: ${title}\n${frontmatter}`
|
|
35
|
+
const newContent = content.replace(
|
|
36
|
+
frontmatterMatch[0],
|
|
37
|
+
`---\n${newFrontmatter}\n---`
|
|
38
|
+
)
|
|
39
|
+
writeFileSync(filePath, newContent)
|
|
40
|
+
console.log(`Added title (fallback) to ${filePath}: ${title}`)
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
// No frontmatter at all
|
|
44
|
+
const h1Match = content.match(/^# (.*)/m)
|
|
45
|
+
const title = h1Match
|
|
46
|
+
? h1Match[1].trim()
|
|
47
|
+
: filePath
|
|
48
|
+
.split("/")
|
|
49
|
+
.pop()
|
|
50
|
+
.replace(/\.(md|mdx)$/, "")
|
|
51
|
+
const newContent = `---\ntitle: ${title}\n---\n\n${content}`
|
|
52
|
+
writeFileSync(filePath, newContent)
|
|
53
|
+
console.log(`Created frontmatter for ${filePath}: ${title}`)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function walk(dir) {
|
|
58
|
+
const files = readdirSync(dir)
|
|
59
|
+
for (const file of files) {
|
|
60
|
+
const filePath = join(dir, file)
|
|
61
|
+
if (statSync(filePath).isDirectory()) {
|
|
62
|
+
if (file !== "node_modules" && file !== ".astro") {
|
|
63
|
+
walk(filePath)
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
processFile(filePath)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
walk(DOCS_DIR)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const fs = require("fs")
|
|
2
|
+
const path = require("path")
|
|
3
|
+
|
|
4
|
+
const docsDir = path.join(__dirname, "../src/content/docs")
|
|
5
|
+
|
|
6
|
+
function getFiles(dir) {
|
|
7
|
+
let results = []
|
|
8
|
+
const list = fs.readdirSync(dir)
|
|
9
|
+
list.forEach((file) => {
|
|
10
|
+
const fullPath = path.join(dir, file)
|
|
11
|
+
const stat = fs.statSync(fullPath)
|
|
12
|
+
if (stat && stat.isDirectory()) {
|
|
13
|
+
results = results.concat(getFiles(fullPath))
|
|
14
|
+
} else if (fullPath.endsWith(".mdx") || fullPath.endsWith(".md")) {
|
|
15
|
+
results.push(fullPath)
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
return results
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const files = getFiles(docsDir)
|
|
22
|
+
|
|
23
|
+
files.forEach((file) => {
|
|
24
|
+
let content = fs.readFileSync(file, "utf8")
|
|
25
|
+
const lines = content.split("\n")
|
|
26
|
+
let hasFrontmatterTitle = content.match(/^title:\s*/m)
|
|
27
|
+
|
|
28
|
+
if (hasFrontmatterTitle) {
|
|
29
|
+
// Find the FIRST H1 in the file that is NOT inside a code block
|
|
30
|
+
let insideCodeBlock = false
|
|
31
|
+
for (let i = 0; i < lines.length; i++) {
|
|
32
|
+
const trimmedLine = lines[i].trim()
|
|
33
|
+
if (trimmedLine.startsWith("```")) {
|
|
34
|
+
insideCodeBlock = !insideCodeBlock
|
|
35
|
+
}
|
|
36
|
+
if (!insideCodeBlock && trimmedLine.startsWith("# ")) {
|
|
37
|
+
console.log(`Removing redundant H1 from ${file}: ${lines[i]}`)
|
|
38
|
+
lines.splice(i, 1)
|
|
39
|
+
// Remove trailing empty line if it exists
|
|
40
|
+
if (lines[i] && lines[i].trim() === "") {
|
|
41
|
+
lines.splice(i, 1)
|
|
42
|
+
}
|
|
43
|
+
break
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
fs.writeFileSync(file, lines.join("\n"))
|
|
47
|
+
}
|
|
48
|
+
})
|