@alumbwe/anvil 1.0.20 → 1.0.22
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/package.json +74 -70
- package/src/agents/bundled-agents.generated.ts +4 -4
- package/src/chat.tsx +1703 -1698
- package/src/cli-args.ts +134 -134
- package/src/components/status-bar.tsx +331 -313
- package/src/hooks/helpers/send-message.ts +663 -654
- package/src/hooks/use-send-message.ts +806 -773
- package/src/index.tsx +473 -473
- package/src/state/chat-store.ts +553 -544
- package/src/utils/create-run-config.ts +121 -121
- package/src/utils/format-compact-number.ts +37 -0
- package/vendor/@anvil/common/package.json +27 -0
- package/vendor/@anvil/common/src/__tests__/agent-validation.test.ts +846 -0
- package/vendor/@anvil/common/src/__tests__/anvil-model-availability.test.ts +101 -0
- package/vendor/@anvil/common/src/__tests__/anvil-models.test.ts +1408 -0
- package/vendor/@anvil/common/src/__tests__/anvil-public-data-use-copy.test.ts +258 -0
- package/vendor/@anvil/common/src/__tests__/anvil-referral-tiers.test.ts +48 -0
- package/vendor/@anvil/common/src/__tests__/anvil-spend-ceilings.test.ts +282 -0
- package/vendor/@anvil/common/src/__tests__/anvil-trust.test.ts +526 -0
- package/vendor/@anvil/common/src/__tests__/deepseek-direct.test.ts +68 -0
- package/vendor/@anvil/common/src/__tests__/disposable-email.test.ts +132 -0
- package/vendor/@anvil/common/src/__tests__/dynamic-agent-template-schema.test.ts +422 -0
- package/vendor/@anvil/common/src/__tests__/env-ci.test.ts +167 -0
- package/vendor/@anvil/common/src/__tests__/env-process.test.ts +145 -0
- package/vendor/@anvil/common/src/__tests__/foreign-client-shipped-agents.test.ts +234 -0
- package/vendor/@anvil/common/src/__tests__/foreign-client-signals.test.ts +379 -0
- package/vendor/@anvil/common/src/__tests__/free-agents.test.ts +807 -0
- package/vendor/@anvil/common/src/__tests__/gravity-capi.test.ts +154 -0
- package/vendor/@anvil/common/src/__tests__/handlesteps-parsing.test.ts +246 -0
- package/vendor/@anvil/common/src/__tests__/kimi-k3-god-only.test.ts +77 -0
- package/vendor/@anvil/common/src/__tests__/model-config.test.ts +89 -0
- package/vendor/@anvil/common/src/__tests__/project-file-tree.test.ts +298 -0
- package/vendor/@anvil/common/src/__tests__/provisioned-model-tiers.test.ts +116 -0
- package/vendor/@anvil/common/src/__tests__/reasoning-effort.test.ts +167 -0
- package/vendor/@anvil/common/src/__tests__/reddit-capi.test.ts +132 -0
- package/vendor/@anvil/common/src/__tests__/response-ad-positions.test.ts +72 -0
- package/vendor/@anvil/common/src/__tests__/user-state.test.ts +30 -0
- package/vendor/@anvil/common/src/actions.ts +215 -0
- package/vendor/@anvil/common/src/analytics-core.ts +69 -0
- package/vendor/@anvil/common/src/analytics.ts +93 -0
- package/vendor/@anvil/common/src/api-keys/constants.ts +26 -0
- package/vendor/@anvil/common/src/browser-actions.ts +413 -0
- package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding-gate.test.ts +63 -0
- package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding.test.ts +246 -0
- package/vendor/@anvil/common/src/constants/__tests__/cf-worker-signals.test.ts +106 -0
- package/vendor/@anvil/common/src/constants/agents.ts +99 -0
- package/vendor/@anvil/common/src/constants/analytics-events.ts +435 -0
- package/vendor/@anvil/common/src/constants/anthropic.ts +73 -0
- package/vendor/@anvil/common/src/constants/anvil-data-use.ts +81 -0
- package/vendor/@anvil/common/src/constants/anvil-errors.ts +7 -0
- package/vendor/@anvil/common/src/constants/anvil-gemini-thinker.ts +21 -0
- package/vendor/@anvil/common/src/constants/anvil-model-ids.ts +11 -0
- package/vendor/@anvil/common/src/constants/anvil-models.ts +2130 -0
- package/vendor/@anvil/common/src/constants/anvil-onboarding-gate.ts +55 -0
- package/vendor/@anvil/common/src/constants/anvil-onboarding.ts +307 -0
- package/vendor/@anvil/common/src/constants/anvil-referral-tiers.ts +87 -0
- package/vendor/@anvil/common/src/constants/anvil-signup-block.ts +68 -0
- package/vendor/@anvil/common/src/constants/anvil-spend-ceilings.ts +450 -0
- package/vendor/@anvil/common/src/constants/anvil-trust.ts +976 -0
- package/vendor/@anvil/common/src/constants/auth.ts +18 -0
- package/vendor/@anvil/common/src/constants/byok.ts +2 -0
- package/vendor/@anvil/common/src/constants/cf-worker-signals.ts +132 -0
- package/vendor/@anvil/common/src/constants/composio.ts +34 -0
- package/vendor/@anvil/common/src/constants/deepseek-direct.ts +55 -0
- package/vendor/@anvil/common/src/constants/feedback.ts +13 -0
- package/vendor/@anvil/common/src/constants/foreign-client-signals.ts +272 -0
- package/vendor/@anvil/common/src/constants/free-agents.ts +777 -0
- package/vendor/@anvil/common/src/constants/gemini.ts +15 -0
- package/vendor/@anvil/common/src/constants/grant-priorities.ts +13 -0
- package/vendor/@anvil/common/src/constants/hosts.ts +6 -0
- package/vendor/@anvil/common/src/constants/images.ts +51 -0
- package/vendor/@anvil/common/src/constants/index.ts +7 -0
- package/vendor/@anvil/common/src/constants/knowledge.ts +35 -0
- package/vendor/@anvil/common/src/constants/limits.ts +23 -0
- package/vendor/@anvil/common/src/constants/model-config.ts +277 -0
- package/vendor/@anvil/common/src/constants/openrouter-attribution.ts +8 -0
- package/vendor/@anvil/common/src/constants/paths.ts +69 -0
- package/vendor/@anvil/common/src/constants/provider-routes.ts +317 -0
- package/vendor/@anvil/common/src/constants/reasoning-effort.ts +79 -0
- package/vendor/@anvil/common/src/constants/skills.ts +60 -0
- package/vendor/@anvil/common/src/constants/subscription-plans.ts +49 -0
- package/vendor/@anvil/common/src/constants/ui.ts +25 -0
- package/vendor/@anvil/common/src/env-ci.ts +36 -0
- package/vendor/@anvil/common/src/env-process.ts +95 -0
- package/vendor/@anvil/common/src/env-schema.ts +95 -0
- package/vendor/@anvil/common/src/env.ts +24 -0
- package/vendor/@anvil/common/src/gravity-capi.ts +207 -0
- package/vendor/@anvil/common/src/mcp/client.ts +233 -0
- package/vendor/@anvil/common/src/old-constants.ts +10 -0
- package/vendor/@anvil/common/src/project-file-tree.ts +355 -0
- package/vendor/@anvil/common/src/reddit-capi.ts +254 -0
- package/vendor/@anvil/common/src/schemas/feedback.ts +52 -0
- package/vendor/@anvil/common/src/schemas/logs.ts +66 -0
- package/vendor/@anvil/common/src/templates/agent-validation.ts +392 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/LICENSE +202 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/README.md +294 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/examples/01-basic-diff-reviewer.ts +17 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/examples/02-intermediate-git-committer.ts +78 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/examples/03-advanced-file-explorer.ts +73 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/my-custom-agent.ts +40 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/package.json +6 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/skills/README.md +65 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/skills/example-skill/SKILL.md +29 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/types/agent-definition.ts +497 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/types/tools.ts +444 -0
- package/vendor/@anvil/common/src/templates/initial-agents-dir/types/util-types.ts +178 -0
- package/vendor/@anvil/common/src/testing/TESTING_PATTERNS.md +351 -0
- package/vendor/@anvil/common/src/testing/anvil-offer-invariants.ts +169 -0
- package/vendor/@anvil/common/src/testing/errors.ts +33 -0
- package/vendor/@anvil/common/src/testing/fixtures/agent-runtime.ts +334 -0
- package/vendor/@anvil/common/src/testing/impl/agent-runtime.ts +6 -0
- package/vendor/@anvil/common/src/testing/index.ts +84 -0
- package/vendor/@anvil/common/src/testing/mock-modules.ts +53 -0
- package/vendor/@anvil/common/src/testing/mock-types.ts +123 -0
- package/vendor/@anvil/common/src/testing/mocks/analytics.ts +261 -0
- package/vendor/@anvil/common/src/testing/mocks/child-process.ts +93 -0
- package/vendor/@anvil/common/src/testing/mocks/crypto.ts +218 -0
- package/vendor/@anvil/common/src/testing/mocks/database.ts +337 -0
- package/vendor/@anvil/common/src/testing/mocks/fetch.ts +219 -0
- package/vendor/@anvil/common/src/testing/mocks/filesystem.ts +166 -0
- package/vendor/@anvil/common/src/testing/mocks/index.ts +101 -0
- package/vendor/@anvil/common/src/testing/mocks/logger.ts +135 -0
- package/vendor/@anvil/common/src/testing/mocks/stream.ts +313 -0
- package/vendor/@anvil/common/src/testing/mocks/timers.ts +132 -0
- package/vendor/@anvil/common/src/testing/mocks/tree-sitter.ts +127 -0
- package/vendor/@anvil/common/src/testing/setup.ts +282 -0
- package/vendor/@anvil/common/src/testing-env-ci.ts +15 -0
- package/vendor/@anvil/common/src/testing-env-process.ts +78 -0
- package/vendor/@anvil/common/src/tools/__tests__/compile-tool-definitions.test.ts +34 -0
- package/vendor/@anvil/common/src/tools/compile-tool-definitions.ts +157 -0
- package/vendor/@anvil/common/src/tools/constants.ts +117 -0
- package/vendor/@anvil/common/src/tools/list.ts +190 -0
- package/vendor/@anvil/common/src/tools/params/__tests__/coerce-to-array.test.ts +213 -0
- package/vendor/@anvil/common/src/tools/params/__tests__/read-docs.test.ts +47 -0
- package/vendor/@anvil/common/src/tools/params/__tests__/render-ui.test.ts +65 -0
- package/vendor/@anvil/common/src/tools/params/tool/__tests__/run-terminal-command-timeout.test.ts +49 -0
- package/vendor/@anvil/common/src/tools/params/tool/add-message.ts +39 -0
- package/vendor/@anvil/common/src/tools/params/tool/add-subgoal.ts +57 -0
- package/vendor/@anvil/common/src/tools/params/tool/apply-patch.ts +110 -0
- package/vendor/@anvil/common/src/tools/params/tool/ask-user.ts +181 -0
- package/vendor/@anvil/common/src/tools/params/tool/browser-logs.ts +85 -0
- package/vendor/@anvil/common/src/tools/params/tool/cloud-plan-ready.ts +94 -0
- package/vendor/@anvil/common/src/tools/params/tool/code-search.ts +159 -0
- package/vendor/@anvil/common/src/tools/params/tool/composio.ts +131 -0
- package/vendor/@anvil/common/src/tools/params/tool/create-plan.ts +80 -0
- package/vendor/@anvil/common/src/tools/params/tool/end-turn.ts +57 -0
- package/vendor/@anvil/common/src/tools/params/tool/find-files.ts +60 -0
- package/vendor/@anvil/common/src/tools/params/tool/glob.ts +80 -0
- package/vendor/@anvil/common/src/tools/params/tool/gravity-index.ts +93 -0
- package/vendor/@anvil/common/src/tools/params/tool/list-directory.ts +58 -0
- package/vendor/@anvil/common/src/tools/params/tool/lookup-agent-info.ts +37 -0
- package/vendor/@anvil/common/src/tools/params/tool/propose-str-replace.ts +103 -0
- package/vendor/@anvil/common/src/tools/params/tool/propose-write-file.ts +71 -0
- package/vendor/@anvil/common/src/tools/params/tool/read-docs.ts +90 -0
- package/vendor/@anvil/common/src/tools/params/tool/read-files.ts +109 -0
- package/vendor/@anvil/common/src/tools/params/tool/read-subtree.ts +79 -0
- package/vendor/@anvil/common/src/tools/params/tool/read-url.ts +81 -0
- package/vendor/@anvil/common/src/tools/params/tool/render-ui.ts +168 -0
- package/vendor/@anvil/common/src/tools/params/tool/run-file-change-hooks.ts +57 -0
- package/vendor/@anvil/common/src/tools/params/tool/run-terminal-command.ts +211 -0
- package/vendor/@anvil/common/src/tools/params/tool/screenshot.ts +97 -0
- package/vendor/@anvil/common/src/tools/params/tool/set-messages.ts +44 -0
- package/vendor/@anvil/common/src/tools/params/tool/set-output.ts +61 -0
- package/vendor/@anvil/common/src/tools/params/tool/skill.ts +59 -0
- package/vendor/@anvil/common/src/tools/params/tool/spawn-agent-inline.ts +56 -0
- package/vendor/@anvil/common/src/tools/params/tool/spawn-agents.ts +154 -0
- package/vendor/@anvil/common/src/tools/params/tool/str-replace.ts +107 -0
- package/vendor/@anvil/common/src/tools/params/tool/suggest-followups.ts +97 -0
- package/vendor/@anvil/common/src/tools/params/tool/task-completed.ts +61 -0
- package/vendor/@anvil/common/src/tools/params/tool/think-deeply.ts +56 -0
- package/vendor/@anvil/common/src/tools/params/tool/update-subgoal.ts +89 -0
- package/vendor/@anvil/common/src/tools/params/tool/vision-analyze.ts +82 -0
- package/vendor/@anvil/common/src/tools/params/tool/web-search.ts +73 -0
- package/vendor/@anvil/common/src/tools/params/tool/write-file.ts +71 -0
- package/vendor/@anvil/common/src/tools/params/tool/write-todos.ts +67 -0
- package/vendor/@anvil/common/src/tools/params/utils.ts +150 -0
- package/vendor/@anvil/common/src/tools/utils.ts +24 -0
- package/vendor/@anvil/common/src/types/__tests__/dynamic-agent-template.test.ts +20 -0
- package/vendor/@anvil/common/src/types/agent-template.ts +215 -0
- package/vendor/@anvil/common/src/types/anvil-session.ts +535 -0
- package/vendor/@anvil/common/src/types/anvil-streak.ts +6 -0
- package/vendor/@anvil/common/src/types/anvil-usage.ts +64 -0
- package/vendor/@anvil/common/src/types/api/agents/publish.ts +61 -0
- package/vendor/@anvil/common/src/types/bun-test.d.ts +5 -0
- package/vendor/@anvil/common/src/types/contracts/agent-runtime.ts +75 -0
- package/vendor/@anvil/common/src/types/contracts/analytics.ts +9 -0
- package/vendor/@anvil/common/src/types/contracts/bigquery.ts +55 -0
- package/vendor/@anvil/common/src/types/contracts/billing.ts +46 -0
- package/vendor/@anvil/common/src/types/contracts/client.ts +53 -0
- package/vendor/@anvil/common/src/types/contracts/database.ts +112 -0
- package/vendor/@anvil/common/src/types/contracts/env.ts +203 -0
- package/vendor/@anvil/common/src/types/contracts/llm.ts +191 -0
- package/vendor/@anvil/common/src/types/contracts/logger.ts +14 -0
- package/vendor/@anvil/common/src/types/contracts/logs.ts +34 -0
- package/vendor/@anvil/common/src/types/contracts/trace.ts +21 -0
- package/vendor/@anvil/common/src/types/dynamic-agent-template.ts +328 -0
- package/vendor/@anvil/common/src/types/filesystem.ts +10 -0
- package/vendor/@anvil/common/src/types/function-params.ts +33 -0
- package/vendor/@anvil/common/src/types/grant.ts +20 -0
- package/vendor/@anvil/common/src/types/gravity-index.ts +170 -0
- package/vendor/@anvil/common/src/types/json.ts +29 -0
- package/vendor/@anvil/common/src/types/mcp.ts +24 -0
- package/vendor/@anvil/common/src/types/messages/anvil-message.ts +58 -0
- package/vendor/@anvil/common/src/types/messages/content-part.ts +59 -0
- package/vendor/@anvil/common/src/types/messages/data-content.ts +14 -0
- package/vendor/@anvil/common/src/types/messages/provider-metadata.ts +13 -0
- package/vendor/@anvil/common/src/types/organization.ts +118 -0
- package/vendor/@anvil/common/src/types/print-mode.ts +121 -0
- package/vendor/@anvil/common/src/types/publisher.ts +67 -0
- package/vendor/@anvil/common/src/types/session-state.ts +149 -0
- package/vendor/@anvil/common/src/types/skill.ts +86 -0
- package/vendor/@anvil/common/src/types/source.ts +11 -0
- package/vendor/@anvil/common/src/types/spawn.ts +13 -0
- package/vendor/@anvil/common/src/types/subscription.ts +67 -0
- package/vendor/@anvil/common/src/types/usage.ts +16 -0
- package/vendor/@anvil/common/src/types/util.ts +3 -0
- package/vendor/@anvil/common/src/util/__tests__/ad-user-agent.test.ts +26 -0
- package/vendor/@anvil/common/src/util/__tests__/analytics-dispatcher.test.ts +122 -0
- package/vendor/@anvil/common/src/util/__tests__/analytics-log.test.ts +102 -0
- package/vendor/@anvil/common/src/util/__tests__/analytics-sampling.test.ts +143 -0
- package/vendor/@anvil/common/src/util/__tests__/anvil-streak.test.ts +202 -0
- package/vendor/@anvil/common/src/util/__tests__/anvil-usage-summary.test.ts +193 -0
- package/vendor/@anvil/common/src/util/__tests__/axiom-only-log.test.ts +140 -0
- package/vendor/@anvil/common/src/util/__tests__/client-user-agent.test.ts +148 -0
- package/vendor/@anvil/common/src/util/__tests__/engagement-tracker.test.ts +115 -0
- package/vendor/@anvil/common/src/util/__tests__/env-file-path.test.ts +57 -0
- package/vendor/@anvil/common/src/util/__tests__/error-abort.test.ts +774 -0
- package/vendor/@anvil/common/src/util/__tests__/error-api-details.test.ts +206 -0
- package/vendor/@anvil/common/src/util/__tests__/file-read-limits.test.ts +173 -0
- package/vendor/@anvil/common/src/util/__tests__/format-code-search.test.ts +60 -0
- package/vendor/@anvil/common/src/util/__tests__/log-mirror.test.ts +31 -0
- package/vendor/@anvil/common/src/util/__tests__/messages.test.ts +1252 -0
- package/vendor/@anvil/common/src/util/__tests__/partial-json-delta.test.ts +505 -0
- package/vendor/@anvil/common/src/util/__tests__/path.test.ts +22 -0
- package/vendor/@anvil/common/src/util/__tests__/project-ignore.test.ts +90 -0
- package/vendor/@anvil/common/src/util/__tests__/promise.test.ts +325 -0
- package/vendor/@anvil/common/src/util/__tests__/rate-limit.test.ts +28 -0
- package/vendor/@anvil/common/src/util/__tests__/reddit-anvil-retention.test.ts +130 -0
- package/vendor/@anvil/common/src/util/__tests__/saxy.test.ts +1008 -0
- package/vendor/@anvil/common/src/util/__tests__/split-data.test.ts +289 -0
- package/vendor/@anvil/common/src/util/__tests__/string.test.ts +239 -0
- package/vendor/@anvil/common/src/util/__tests__/thread-title.test.ts +70 -0
- package/vendor/@anvil/common/src/util/__tests__/tool-result-media-order.test.ts +108 -0
- package/vendor/@anvil/common/src/util/__tests__/ttft-histogram.test.ts +180 -0
- package/vendor/@anvil/common/src/util/__tests__/with-timeout.test.ts +24 -0
- package/vendor/@anvil/common/src/util/__tests__/zoned-time.test.ts +88 -0
- package/vendor/@anvil/common/src/util/ad-user-agent.ts +25 -0
- package/vendor/@anvil/common/src/util/agent-file-utils.ts +110 -0
- package/vendor/@anvil/common/src/util/agent-id-parsing.ts +136 -0
- package/vendor/@anvil/common/src/util/agent-name-normalization.ts +38 -0
- package/vendor/@anvil/common/src/util/agent-name-resolver.ts +86 -0
- package/vendor/@anvil/common/src/util/analytics-dispatcher.ts +82 -0
- package/vendor/@anvil/common/src/util/analytics-log.ts +78 -0
- package/vendor/@anvil/common/src/util/analytics-sampling.ts +255 -0
- package/vendor/@anvil/common/src/util/anvil-model-availability.ts +102 -0
- package/vendor/@anvil/common/src/util/anvil-privacy.ts +82 -0
- package/vendor/@anvil/common/src/util/anvil-streak-line.ts +103 -0
- package/vendor/@anvil/common/src/util/anvil-streak.ts +156 -0
- package/vendor/@anvil/common/src/util/anvil-usage-summary.ts +125 -0
- package/vendor/@anvil/common/src/util/array.ts +31 -0
- package/vendor/@anvil/common/src/util/axiom-only-log.ts +124 -0
- package/vendor/@anvil/common/src/util/cache-debug.ts +171 -0
- package/vendor/@anvil/common/src/util/client-user-agent.ts +114 -0
- package/vendor/@anvil/common/src/util/credentials.ts +26 -0
- package/vendor/@anvil/common/src/util/currency.ts +25 -0
- package/vendor/@anvil/common/src/util/dates.ts +81 -0
- package/vendor/@anvil/common/src/util/disposable-email.ts +277 -0
- package/vendor/@anvil/common/src/util/engagement-tracker.ts +129 -0
- package/vendor/@anvil/common/src/util/env-file-path.ts +40 -0
- package/vendor/@anvil/common/src/util/error.ts +562 -0
- package/vendor/@anvil/common/src/util/file-read-limits.ts +236 -0
- package/vendor/@anvil/common/src/util/file.ts +339 -0
- package/vendor/@anvil/common/src/util/format-code-search.ts +115 -0
- package/vendor/@anvil/common/src/util/lazy-response-ads.ts +92 -0
- package/vendor/@anvil/common/src/util/log-data.ts +57 -0
- package/vendor/@anvil/common/src/util/log-ingest.ts +58 -0
- package/vendor/@anvil/common/src/util/log-mirror.ts +34 -0
- package/vendor/@anvil/common/src/util/lru-cache.ts +67 -0
- package/vendor/@anvil/common/src/util/messages.ts +685 -0
- package/vendor/@anvil/common/src/util/min-heap.ts +87 -0
- package/vendor/@anvil/common/src/util/model-utils.ts +4 -0
- package/vendor/@anvil/common/src/util/object.ts +128 -0
- package/vendor/@anvil/common/src/util/partial-json-delta.ts +89 -0
- package/vendor/@anvil/common/src/util/path.ts +15 -0
- package/vendor/@anvil/common/src/util/project-ignore.ts +119 -0
- package/vendor/@anvil/common/src/util/promise.ts +73 -0
- package/vendor/@anvil/common/src/util/random.ts +15 -0
- package/vendor/@anvil/common/src/util/rate-limit.ts +56 -0
- package/vendor/@anvil/common/src/util/reddit-anvil-retention.ts +60 -0
- package/vendor/@anvil/common/src/util/reddit-capi-events.ts +36 -0
- package/vendor/@anvil/common/src/util/response-ad-positions.ts +54 -0
- package/vendor/@anvil/common/src/util/saxy.ts +741 -0
- package/vendor/@anvil/common/src/util/skills.test.ts +44 -0
- package/vendor/@anvil/common/src/util/skills.ts +36 -0
- package/vendor/@anvil/common/src/util/split-data.ts +259 -0
- package/vendor/@anvil/common/src/util/stop-sequence.ts +61 -0
- package/vendor/@anvil/common/src/util/string.ts +426 -0
- package/vendor/@anvil/common/src/util/system-info.ts +53 -0
- package/vendor/@anvil/common/src/util/thread-title.ts +46 -0
- package/vendor/@anvil/common/src/util/ttft-histogram.ts +73 -0
- package/vendor/@anvil/common/src/util/xml-parser.ts +27 -0
- package/vendor/@anvil/common/src/util/xml.ts +17 -0
- package/vendor/@anvil/common/src/util/zod-schema.ts +25 -0
- package/vendor/@anvil/common/src/util/zoned-time.ts +136 -0
- package/vendor/@anvil/common/src/utils/ask-user-bridge.ts +44 -0
- package/vendor/@anvil/sdk/dist/index.cjs +52297 -0
- package/vendor/@anvil/sdk/dist/index.cjs.map +440 -0
- package/vendor/@anvil/sdk/dist/index.d.ts +4277 -0
- package/vendor/@anvil/sdk/dist/index.mjs +52290 -0
- package/vendor/@anvil/sdk/dist/index.mjs.map +440 -0
- package/vendor/@anvil/sdk/dist/vendor/ai.cjs +30886 -0
- package/vendor/@anvil/sdk/dist/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/vendor/@anvil/sdk/dist/vendor/ripgrep/arm64-linux/rg +0 -0
- package/vendor/@anvil/sdk/dist/vendor/ripgrep/x64-darwin/rg +0 -0
- package/vendor/@anvil/sdk/dist/vendor/ripgrep/x64-linux/rg +0 -0
- package/vendor/@anvil/sdk/dist/vendor/ripgrep/x64-win32/rg.exe +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter-c-sharp.wasm +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter-cpp.wasm +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter-go.wasm +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter-java.wasm +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter-javascript.wasm +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter-python.wasm +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter-ruby.wasm +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter-rust.wasm +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter-tsx.wasm +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter-typescript.wasm +0 -0
- package/vendor/@anvil/sdk/dist/wasm/tree-sitter.wasm +0 -0
- package/vendor/@anvil/sdk/package.json +21 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import { z } from 'zod/v4'
|
|
2
|
+
|
|
3
|
+
// Default values for browser actions
|
|
4
|
+
export const BROWSER_DEFAULTS = {
|
|
5
|
+
// Common defaults
|
|
6
|
+
headless: true,
|
|
7
|
+
debug: false,
|
|
8
|
+
timeout: 15000, // 15 seconds
|
|
9
|
+
userDataDir: '_browser_profile', // Will be relative to project data dir
|
|
10
|
+
retryOptions: {
|
|
11
|
+
maxRetries: 3,
|
|
12
|
+
retryDelay: 1000, // 1 second
|
|
13
|
+
retryOnErrors: ['TimeoutError', 'TargetClosedError', 'DetachedFrameError'],
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
// Viewport defaults
|
|
17
|
+
viewportWidth: 1280,
|
|
18
|
+
viewportHeight: 720,
|
|
19
|
+
|
|
20
|
+
// Navigation defaults
|
|
21
|
+
waitUntil: 'networkidle0' as const,
|
|
22
|
+
|
|
23
|
+
// Click defaults
|
|
24
|
+
waitForNavigation: false,
|
|
25
|
+
button: 'left' as const,
|
|
26
|
+
|
|
27
|
+
// Type defaults
|
|
28
|
+
delay: 100, // 100ms between keystrokes
|
|
29
|
+
|
|
30
|
+
// Screenshot defaults
|
|
31
|
+
fullPage: false,
|
|
32
|
+
screenshotCompression: 'jpeg' as const,
|
|
33
|
+
screenshotCompressionQuality: 25,
|
|
34
|
+
compressScreenshotData: true,
|
|
35
|
+
|
|
36
|
+
// Advanced configuration defaults
|
|
37
|
+
maxConsecutiveErrors: 3,
|
|
38
|
+
totalErrorThreshold: 10,
|
|
39
|
+
} as const
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Response schema for browser action results
|
|
43
|
+
*/
|
|
44
|
+
export const LogSchema = z.object({
|
|
45
|
+
type: z.enum(['error', 'warning', 'info', 'debug', 'verbose']),
|
|
46
|
+
message: z.string(),
|
|
47
|
+
timestamp: z.number(),
|
|
48
|
+
location: z.string().optional(),
|
|
49
|
+
stack: z.string().optional(),
|
|
50
|
+
category: z.string().optional(),
|
|
51
|
+
level: z.number().optional(),
|
|
52
|
+
source: z.enum(['browser', 'tool']).default('tool'),
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
export type Log = z.infer<typeof LogSchema>
|
|
56
|
+
|
|
57
|
+
export const MetricsSchema = z.object({
|
|
58
|
+
loadTime: z.number(),
|
|
59
|
+
memoryUsage: z.number(),
|
|
60
|
+
jsErrors: z.number(),
|
|
61
|
+
networkErrors: z.number(),
|
|
62
|
+
ttfb: z.number().optional(),
|
|
63
|
+
lcp: z.number().optional(),
|
|
64
|
+
fcp: z.number().optional(),
|
|
65
|
+
domContentLoaded: z.number().optional(),
|
|
66
|
+
sessionDuration: z.number().optional(),
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
export const NetworkEventSchema = z.object({
|
|
70
|
+
url: z.string(),
|
|
71
|
+
method: z.string(),
|
|
72
|
+
status: z.number().optional(),
|
|
73
|
+
errorText: z.string().optional(),
|
|
74
|
+
timestamp: z.number(),
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
export const LogFilterSchema = z.object({
|
|
78
|
+
types: z
|
|
79
|
+
.array(z.enum(['error', 'warning', 'info', 'debug', 'verbose']))
|
|
80
|
+
.optional(),
|
|
81
|
+
minLevel: z.number().optional(),
|
|
82
|
+
categories: z.array(z.string()).optional(),
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
// Required options for each action type
|
|
86
|
+
export const RequiredRetryOptionsSchema = z.object({
|
|
87
|
+
maxRetries: z.number(),
|
|
88
|
+
retryDelay: z.number(),
|
|
89
|
+
retryOnErrors: z.array(z.string()),
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
// Optional configurations that can be added to any action
|
|
93
|
+
export const OptionalBrowserConfigSchema = z.object({
|
|
94
|
+
timeout: z.number().optional(),
|
|
95
|
+
retryOptions: z
|
|
96
|
+
.object({
|
|
97
|
+
maxRetries: z.number().optional(),
|
|
98
|
+
retryDelay: z.number().optional(),
|
|
99
|
+
retryOnErrors: z.array(z.string()).optional(),
|
|
100
|
+
})
|
|
101
|
+
.optional(),
|
|
102
|
+
logFilter: LogFilterSchema.optional(),
|
|
103
|
+
debug: z.boolean().optional(),
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
// Advanced optional configurations specific to start action
|
|
107
|
+
export const OptionalStartConfigSchema = z.object({
|
|
108
|
+
maxConsecutiveErrors: z.number().optional(),
|
|
109
|
+
totalErrorThreshold: z.number().optional(),
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
export type BrowserConfig = z.infer<typeof OptionalBrowserConfigSchema> &
|
|
113
|
+
z.infer<typeof OptionalStartConfigSchema>
|
|
114
|
+
|
|
115
|
+
// Optional configurations specific to each action type
|
|
116
|
+
export const OptionalNavigateConfigSchema = z.object({
|
|
117
|
+
waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle0']).optional(),
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
export const OptionalClickConfigSchema = z.object({
|
|
121
|
+
waitForNavigation: z.boolean().optional(),
|
|
122
|
+
button: z.enum(['left', 'right', 'middle']).optional(),
|
|
123
|
+
// New optional fields for visual verification
|
|
124
|
+
visualVerify: z.boolean().optional(),
|
|
125
|
+
visualThreshold: z.number().min(0).max(1).optional(), // fraction from 0..1
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
export const OptionalTypeConfigSchema = z.object({
|
|
129
|
+
delay: z.number().optional(),
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
export const OptionalScreenshotConfigSchema = z.object({
|
|
133
|
+
fullPage: z.boolean().optional(),
|
|
134
|
+
screenshotCompression: z.enum(['jpeg', 'png']).optional(),
|
|
135
|
+
screenshotCompressionQuality: z.number().optional(),
|
|
136
|
+
compressScreenshotData: z.boolean().optional(),
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
// Maximum size for a single WebSocket message (10MB)
|
|
140
|
+
export const MAX_MESSAGE_SIZE = 10 * 1024 * 1024
|
|
141
|
+
|
|
142
|
+
export const BrowserResponseChunkSchema = z.object({
|
|
143
|
+
id: z.string(),
|
|
144
|
+
total: z.number(),
|
|
145
|
+
index: z.number(),
|
|
146
|
+
data: z.string(), // Base64 encoded chunk
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
export const ImageContentSchema = z.object({
|
|
150
|
+
type: z.literal('image'),
|
|
151
|
+
source: z.object({
|
|
152
|
+
type: z.literal('base64'),
|
|
153
|
+
media_type: z.literal('image/jpeg'),
|
|
154
|
+
data: z.string(),
|
|
155
|
+
}),
|
|
156
|
+
})
|
|
157
|
+
export type ImageContent = z.infer<typeof ImageContentSchema>
|
|
158
|
+
|
|
159
|
+
export const BrowserResponseSchema = z.object({
|
|
160
|
+
success: z.boolean(),
|
|
161
|
+
error: z.string().optional(),
|
|
162
|
+
logs: z.array(LogSchema),
|
|
163
|
+
logFilter: LogFilterSchema.optional(),
|
|
164
|
+
networkEvents: z.array(NetworkEventSchema).optional(),
|
|
165
|
+
metrics: MetricsSchema.optional(),
|
|
166
|
+
screenshots: z
|
|
167
|
+
.object({
|
|
168
|
+
pre: ImageContentSchema.optional(),
|
|
169
|
+
post: ImageContentSchema,
|
|
170
|
+
})
|
|
171
|
+
.optional(),
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
// Update action schemas to include retry options
|
|
175
|
+
// Required base schemas
|
|
176
|
+
export const RequiredBrowserStartActionSchema = z.object({
|
|
177
|
+
type: z.literal('start'),
|
|
178
|
+
url: z.string().url(),
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
// Combined schema
|
|
182
|
+
export const BrowserStartActionSchema = RequiredBrowserStartActionSchema.merge(
|
|
183
|
+
OptionalBrowserConfigSchema,
|
|
184
|
+
).merge(OptionalStartConfigSchema)
|
|
185
|
+
|
|
186
|
+
export const RequiredBrowserNavigateActionSchema = z.object({
|
|
187
|
+
type: z.literal('navigate'),
|
|
188
|
+
url: z.string().url(),
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
export const BrowserNavigateActionSchema =
|
|
192
|
+
RequiredBrowserNavigateActionSchema.merge(OptionalBrowserConfigSchema).merge(
|
|
193
|
+
OptionalNavigateConfigSchema,
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
const _RangeSchema = z.object({
|
|
197
|
+
min: z.number(),
|
|
198
|
+
max: z.number(),
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
export const RequiredBrowserClickActionSchema = z.object({
|
|
202
|
+
type: z.literal('click'),
|
|
203
|
+
// xRange: RangeSchema,
|
|
204
|
+
// yRange: RangeSchema,
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
export const BrowserClickActionSchema = RequiredBrowserClickActionSchema.merge(
|
|
208
|
+
OptionalBrowserConfigSchema,
|
|
209
|
+
).merge(OptionalClickConfigSchema)
|
|
210
|
+
|
|
211
|
+
export const RequiredBrowserTypeActionSchema = z.object({
|
|
212
|
+
type: z.literal('type'),
|
|
213
|
+
selector: z.string(),
|
|
214
|
+
text: z.string(),
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
export const BrowserTypeActionSchema = RequiredBrowserTypeActionSchema.merge(
|
|
218
|
+
OptionalBrowserConfigSchema,
|
|
219
|
+
).merge(OptionalTypeConfigSchema)
|
|
220
|
+
|
|
221
|
+
export const RequiredBrowserScrollActionSchema = z.object({
|
|
222
|
+
type: z.literal('scroll'),
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
export const OptionalScrollConfigSchema = z.object({
|
|
226
|
+
direction: z.enum(['up', 'down']).optional(),
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
export const BrowserScrollActionSchema =
|
|
230
|
+
RequiredBrowserScrollActionSchema.merge(OptionalBrowserConfigSchema).merge(
|
|
231
|
+
OptionalScrollConfigSchema,
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
export const RequiredBrowserScreenshotActionSchema = z.object({
|
|
235
|
+
type: z.literal('screenshot'),
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
export const BrowserScreenshotActionSchema =
|
|
239
|
+
RequiredBrowserScreenshotActionSchema.merge(
|
|
240
|
+
OptionalBrowserConfigSchema,
|
|
241
|
+
).merge(OptionalScreenshotConfigSchema)
|
|
242
|
+
|
|
243
|
+
export const RequiredBrowserStopActionSchema = z.object({
|
|
244
|
+
type: z.literal('stop'),
|
|
245
|
+
})
|
|
246
|
+
export const BrowserStopActionSchema = RequiredBrowserStopActionSchema.merge(
|
|
247
|
+
OptionalBrowserConfigSchema,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
// First define the base action schemas without the diagnostic step
|
|
251
|
+
const BaseBrowserActionSchema = z.discriminatedUnion('type', [
|
|
252
|
+
BrowserStartActionSchema,
|
|
253
|
+
BrowserNavigateActionSchema,
|
|
254
|
+
BrowserClickActionSchema,
|
|
255
|
+
BrowserTypeActionSchema,
|
|
256
|
+
BrowserScrollActionSchema,
|
|
257
|
+
BrowserScreenshotActionSchema,
|
|
258
|
+
BrowserStopActionSchema,
|
|
259
|
+
])
|
|
260
|
+
|
|
261
|
+
// Now we can define the diagnostic step schema that references the base actions
|
|
262
|
+
export const DiagnosticStepSchema = z.object({
|
|
263
|
+
label: z.string().optional(),
|
|
264
|
+
// The actual browser action to run
|
|
265
|
+
action: BaseBrowserActionSchema,
|
|
266
|
+
// Success conditions to verify after step
|
|
267
|
+
expectedLogs: z.array(z.string()).optional(),
|
|
268
|
+
noJsErrors: z.boolean().optional(),
|
|
269
|
+
noNetworkErrors: z.boolean().optional(),
|
|
270
|
+
customCondition: z.string().optional(),
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
// The 'diagnose' action for multi-step debugging
|
|
274
|
+
export const BrowserDiagnoseActionSchema = z.object({
|
|
275
|
+
type: z.literal('diagnose'),
|
|
276
|
+
// Array of steps to run
|
|
277
|
+
steps: z.array(DiagnosticStepSchema),
|
|
278
|
+
// Toggle whether to run all steps automatically or step-by-step
|
|
279
|
+
automated: z.boolean().optional(),
|
|
280
|
+
// Optional maximum steps/time to run
|
|
281
|
+
maxSteps: z.number().optional(),
|
|
282
|
+
sessionTimeoutMs: z.number().optional(),
|
|
283
|
+
// Include optional browser config
|
|
284
|
+
...OptionalBrowserConfigSchema.shape,
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
// Finally, export the complete schema that includes diagnostic actions
|
|
288
|
+
export const BrowserActionSchema = z.discriminatedUnion('type', [
|
|
289
|
+
BrowserStartActionSchema,
|
|
290
|
+
BrowserNavigateActionSchema,
|
|
291
|
+
BrowserClickActionSchema,
|
|
292
|
+
BrowserTypeActionSchema,
|
|
293
|
+
BrowserScrollActionSchema,
|
|
294
|
+
BrowserScreenshotActionSchema,
|
|
295
|
+
BrowserStopActionSchema,
|
|
296
|
+
BrowserDiagnoseActionSchema,
|
|
297
|
+
])
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Creates an XML string from a BrowserAction object
|
|
301
|
+
*/
|
|
302
|
+
export function createBrowserActionXML(action: BrowserAction): string {
|
|
303
|
+
const { type, ...attributes } = action
|
|
304
|
+
const attrsString = Object.entries(attributes)
|
|
305
|
+
.filter(([_, v]) => v !== undefined && v !== null)
|
|
306
|
+
.map(([k, v]) => {
|
|
307
|
+
// Handle different value types
|
|
308
|
+
const val = typeof v === 'object' ? JSON.stringify(v) : String(v)
|
|
309
|
+
// Escape special characters in XML attributes
|
|
310
|
+
const escaped = val.replace(/[<>&'"]/g, (char) => {
|
|
311
|
+
switch (char) {
|
|
312
|
+
case '<':
|
|
313
|
+
return '<'
|
|
314
|
+
case '>':
|
|
315
|
+
return '>'
|
|
316
|
+
case '&':
|
|
317
|
+
return '&'
|
|
318
|
+
case '"':
|
|
319
|
+
return '"'
|
|
320
|
+
case "'":
|
|
321
|
+
return '''
|
|
322
|
+
default:
|
|
323
|
+
return char
|
|
324
|
+
}
|
|
325
|
+
})
|
|
326
|
+
return `${k}="${escaped}"`
|
|
327
|
+
})
|
|
328
|
+
.join(' ')
|
|
329
|
+
return `<browser_logs action="${type}" ${attrsString} />`
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Parses XML attributes into a BrowserAction object
|
|
334
|
+
*/
|
|
335
|
+
export function parseBrowserActionXML(xmlString: string): BrowserAction {
|
|
336
|
+
// Basic XML validation
|
|
337
|
+
if (!xmlString.includes('<browser_logs') || !xmlString.includes('/>')) {
|
|
338
|
+
throw new Error('Invalid browser action XML: missing browser_logs tag')
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Extract attributes using regex
|
|
342
|
+
const attrs: Record<string, string> = {}
|
|
343
|
+
const attrPattern = /(\w+)="([^"]*)"/g
|
|
344
|
+
let match
|
|
345
|
+
|
|
346
|
+
while ((match = attrPattern.exec(xmlString)) !== null) {
|
|
347
|
+
const [_, key, value] = match
|
|
348
|
+
attrs[key] = value
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (!attrs.action) {
|
|
352
|
+
throw new Error('Invalid browser action XML: missing action attribute')
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Convert action attribute to type
|
|
356
|
+
const type = attrs.action
|
|
357
|
+
delete attrs.action
|
|
358
|
+
|
|
359
|
+
// Parse special values (booleans, numbers, objects)
|
|
360
|
+
const parsedAttrs = Object.entries(attrs).reduce(
|
|
361
|
+
(acc, [key, value]) => {
|
|
362
|
+
try {
|
|
363
|
+
// Try to parse as JSON for objects
|
|
364
|
+
if (value.startsWith('{') || value.startsWith('[')) {
|
|
365
|
+
acc[key] = JSON.parse(value)
|
|
366
|
+
}
|
|
367
|
+
// Parse booleans
|
|
368
|
+
else if (value === 'true' || value === 'false') {
|
|
369
|
+
acc[key] = value === 'true'
|
|
370
|
+
}
|
|
371
|
+
// Parse numbers
|
|
372
|
+
else if (!isNaN(Number(value))) {
|
|
373
|
+
acc[key] = Number(value)
|
|
374
|
+
}
|
|
375
|
+
// Keep as string
|
|
376
|
+
else {
|
|
377
|
+
acc[key] = value
|
|
378
|
+
}
|
|
379
|
+
} catch {
|
|
380
|
+
// If parsing fails, keep as string
|
|
381
|
+
acc[key] = value
|
|
382
|
+
}
|
|
383
|
+
return acc
|
|
384
|
+
},
|
|
385
|
+
{} as Record<string, any>,
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
// Construct and validate the BrowserAction
|
|
389
|
+
const action = { type, ...parsedAttrs } as BrowserAction
|
|
390
|
+
return BrowserActionSchema.parse(action)
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export type BrowserResponse = z.infer<typeof BrowserResponseSchema>
|
|
394
|
+
export type BrowserAction = z.infer<typeof BrowserActionSchema>
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Parse browser action XML attributes into a typed BrowserAction object
|
|
398
|
+
*/
|
|
399
|
+
export function parseBrowserActionAttributes(
|
|
400
|
+
attributes: Record<string, string>,
|
|
401
|
+
): BrowserAction {
|
|
402
|
+
const { action, ...rest } = attributes
|
|
403
|
+
return {
|
|
404
|
+
type: action,
|
|
405
|
+
...Object.entries(rest).reduce((acc, [key, value]) => {
|
|
406
|
+
// Convert string values to appropriate types
|
|
407
|
+
if (value === 'true') return { ...acc, [key]: true }
|
|
408
|
+
if (value === 'false') return { ...acc, [key]: false }
|
|
409
|
+
if (!isNaN(Number(value))) return { ...acc, [key]: Number(value) }
|
|
410
|
+
return { ...acc, [key]: value }
|
|
411
|
+
}, {}),
|
|
412
|
+
} as BrowserAction
|
|
413
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
evaluateOnboardingRequirement,
|
|
5
|
+
parseOnboardingEnabled,
|
|
6
|
+
} from '../anvil-onboarding-gate'
|
|
7
|
+
|
|
8
|
+
describe('evaluateOnboardingRequirement', () => {
|
|
9
|
+
it('asks nobody while the switch is off', () => {
|
|
10
|
+
// The load-bearing polarity: absence of config disables the feature. The
|
|
11
|
+
// opposite convention would show a form nobody decided to launch to every
|
|
12
|
+
// user at once.
|
|
13
|
+
const result = evaluateOnboardingRequirement({
|
|
14
|
+
enabled: false,
|
|
15
|
+
complete: false,
|
|
16
|
+
})
|
|
17
|
+
expect(result.required).toBe(false)
|
|
18
|
+
if (result.required) throw new Error('unreachable')
|
|
19
|
+
expect(result.reason).toBe('gate_disabled')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('asks anyone who has not answered, regardless of account age', () => {
|
|
23
|
+
// Deliberately no cutover: a long-standing account that never answered is
|
|
24
|
+
// exactly who we have the least data about. Skip and the seen-cookie are
|
|
25
|
+
// what keep this from being a burden.
|
|
26
|
+
expect(
|
|
27
|
+
evaluateOnboardingRequirement({ enabled: true, complete: false }).required,
|
|
28
|
+
).toBe(true)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('stops asking once the answers are in', () => {
|
|
32
|
+
const result = evaluateOnboardingRequirement({
|
|
33
|
+
enabled: true,
|
|
34
|
+
complete: true,
|
|
35
|
+
})
|
|
36
|
+
expect(result.required).toBe(false)
|
|
37
|
+
if (result.required) throw new Error('unreachable')
|
|
38
|
+
expect(result.reason).toBe('already_complete')
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
describe('parseOnboardingEnabled', () => {
|
|
43
|
+
it('accepts the affirmative spellings', () => {
|
|
44
|
+
for (const raw of ['on', 'ON', ' true ', '1']) {
|
|
45
|
+
expect(parseOnboardingEnabled(raw)).toBe(true)
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('treats anything else as off', () => {
|
|
50
|
+
// Unset, empty and misspelt all fail the same safe way — nothing about a
|
|
51
|
+
// broken value should be able to switch a user-facing screen on.
|
|
52
|
+
for (const raw of [undefined, null, '', ' ', 'off', 'yes', 'enabled']) {
|
|
53
|
+
expect(parseOnboardingEnabled(raw)).toBe(false)
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
describe('seen cookie', () => {
|
|
59
|
+
it('is a stable name with a months-long life', () => {
|
|
60
|
+
// The name is read by the `/web` layout and written by the welcome page;
|
|
61
|
+
// changing it re-asks everyone, so it is pinned here on purpose.
|
|
62
|
+
})
|
|
63
|
+
})
|