tinybeeai 0.0.0-stage → 0.16.1
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/.railway/railway.ts +83 -0
- package/.railway/tsconfig.json +13 -0
- package/AGENTS.md +102 -0
- package/Dockerfile +108 -0
- package/LICENSE +21 -0
- package/README.md +275 -2
- package/bin/localdost.js +29 -0
- package/bin/tinybeeai.js +28 -0
- package/compose.yml +63 -0
- package/demo/payloads/ci_failure.json +46 -0
- package/demo/payloads/outage.json +18 -0
- package/demo/payloads/pr_comment_edited.json +50 -0
- package/demo/payloads/pr_merged.json +80 -0
- package/demo/payloads/pr_opened.json +69 -0
- package/demo/payloads/pr_synchronize.json +69 -0
- package/demo/payloads/ticket_created.json +138 -0
- package/demo/sample-app/playwright.config.ts +20 -0
- package/demo/sample-app/server.ts +163 -0
- package/demo/sample-app/tests/checkout.spec.ts +13 -0
- package/demo/sample-app/tests/smoke.spec.ts +8 -0
- package/dist/agent/approval-retries.js +59 -0
- package/dist/agent/approval-retries.js.map +1 -0
- package/dist/agent/approvals.js +390 -0
- package/dist/agent/approvals.js.map +1 -0
- package/dist/agent/chat-bridge.js +154 -0
- package/dist/agent/chat-bridge.js.map +1 -0
- package/dist/agent/chat-lead.js +475 -0
- package/dist/agent/chat-lead.js.map +1 -0
- package/dist/agent/chat-loop.js +106 -0
- package/dist/agent/chat-loop.js.map +1 -0
- package/dist/agent/chat-mcp.js +49 -0
- package/dist/agent/chat-mcp.js.map +1 -0
- package/dist/agent/chat-tool-blocks.js +453 -0
- package/dist/agent/chat-tool-blocks.js.map +1 -0
- package/dist/agent/chat-view.js +94 -0
- package/dist/agent/chat-view.js.map +1 -0
- package/dist/agent/chat-views.js +781 -0
- package/dist/agent/chat-views.js.map +1 -0
- package/dist/agent/chat.js +1703 -0
- package/dist/agent/chat.js.map +1 -0
- package/dist/agent/destinations.js +150 -0
- package/dist/agent/destinations.js.map +1 -0
- package/dist/agent/llm-cli.js +451 -0
- package/dist/agent/llm-cli.js.map +1 -0
- package/dist/agent/llm-codex.js +493 -0
- package/dist/agent/llm-codex.js.map +1 -0
- package/dist/agent/llm-openai.js +211 -0
- package/dist/agent/llm-openai.js.map +1 -0
- package/dist/agent/llm.js +1464 -0
- package/dist/agent/llm.js.map +1 -0
- package/dist/agent/memory.js +33 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/mock-views.js +93 -0
- package/dist/agent/mock-views.js.map +1 -0
- package/dist/agent/model-availability.js +207 -0
- package/dist/agent/model-availability.js.map +1 -0
- package/dist/agent/model-errors.js +188 -0
- package/dist/agent/model-errors.js.map +1 -0
- package/dist/agent/model-guard.js +311 -0
- package/dist/agent/model-guard.js.map +1 -0
- package/dist/agent/prompts.js +374 -0
- package/dist/agent/prompts.js.map +1 -0
- package/dist/agent/qa-lenses/qa-auth.md +32 -0
- package/dist/agent/qa-lenses/qa-check-then-act.md +33 -0
- package/dist/agent/qa-lenses/qa-control-has-no-effect.md +32 -0
- package/dist/agent/qa-lenses/qa-dates.md +31 -0
- package/dist/agent/qa-lenses/qa-double-submit.md +34 -0
- package/dist/agent/qa-lenses/qa-feature-flag.md +29 -0
- package/dist/agent/qa-lenses/qa-migration.md +35 -0
- package/dist/agent/qa-lenses/qa-money.md +38 -0
- package/dist/agent/qa-lenses/qa-response-shape-break.md +33 -0
- package/dist/agent/qa-lenses/qa-validation.md +29 -0
- package/dist/agent/qa-prompts.js +660 -0
- package/dist/agent/qa-prompts.js.map +1 -0
- package/dist/agent/reasoning.js +55 -0
- package/dist/agent/reasoning.js.map +1 -0
- package/dist/agent/redact.js +48 -0
- package/dist/agent/redact.js.map +1 -0
- package/dist/agent/rules.js +927 -0
- package/dist/agent/rules.js.map +1 -0
- package/dist/agent/runs.js +440 -0
- package/dist/agent/runs.js.map +1 -0
- package/dist/agent/send-retry.js +62 -0
- package/dist/agent/send-retry.js.map +1 -0
- package/dist/agent/team-notes.js +288 -0
- package/dist/agent/team-notes.js.map +1 -0
- package/dist/agent/token-meter.js +31 -0
- package/dist/agent/token-meter.js.map +1 -0
- package/dist/agent/triage.js +506 -0
- package/dist/agent/triage.js.map +1 -0
- package/dist/api.js +1047 -0
- package/dist/api.js.map +1 -0
- package/dist/approval-targets.js +107 -0
- package/dist/approval-targets.js.map +1 -0
- package/dist/bee/cloudflared.js +108 -0
- package/dist/bee/cloudflared.js.map +1 -0
- package/dist/bee/health.js +99 -0
- package/dist/bee/health.js.map +1 -0
- package/dist/bee/hive-client.js +75 -0
- package/dist/bee/hive-client.js.map +1 -0
- package/dist/bee/identity.js +39 -0
- package/dist/bee/identity.js.map +1 -0
- package/dist/bee/models.js +510 -0
- package/dist/bee/models.js.map +1 -0
- package/dist/bee/pairing.js +351 -0
- package/dist/bee/pairing.js.map +1 -0
- package/dist/bee/relay-client.js +50 -0
- package/dist/bee/relay-client.js.map +1 -0
- package/dist/bee/routes.js +214 -0
- package/dist/bee/routes.js.map +1 -0
- package/dist/bee/setup-page.js +223 -0
- package/dist/bee/setup-page.js.map +1 -0
- package/dist/bee/state.js +41 -0
- package/dist/bee/state.js.map +1 -0
- package/dist/bee/status.js +117 -0
- package/dist/bee/status.js.map +1 -0
- package/dist/bee/tunnel-manager.js +245 -0
- package/dist/bee/tunnel-manager.js.map +1 -0
- package/dist/bee/updater.js +268 -0
- package/dist/bee/updater.js.map +1 -0
- package/dist/boot.js +41 -0
- package/dist/boot.js.map +1 -0
- package/dist/call/index.js +145 -0
- package/dist/call/index.js.map +1 -0
- package/dist/case-folders.js +294 -0
- package/dist/case-folders.js.map +1 -0
- package/dist/cases.js +554 -0
- package/dist/cases.js.map +1 -0
- package/dist/chat-blocks.js +709 -0
- package/dist/chat-blocks.js.map +1 -0
- package/dist/chat-parse-util.js +38 -0
- package/dist/chat-parse-util.js.map +1 -0
- package/dist/chat-results.js +96 -0
- package/dist/chat-results.js.map +1 -0
- package/dist/chat-stats.js +193 -0
- package/dist/chat-stats.js.map +1 -0
- package/dist/chat-view-specs.js +186 -0
- package/dist/chat-view-specs.js.map +1 -0
- package/dist/cli/doctor-ops.js +361 -0
- package/dist/cli/doctor-ops.js.map +1 -0
- package/dist/cli/doctor.js +289 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/dogfood.js +70 -0
- package/dist/cli/dogfood.js.map +1 -0
- package/dist/cli/env-file.js +34 -0
- package/dist/cli/env-file.js.map +1 -0
- package/dist/cli/eval-chat-cases.js +359 -0
- package/dist/cli/eval-chat-cases.js.map +1 -0
- package/dist/cli/eval-chat-results.js +85 -0
- package/dist/cli/eval-chat-results.js.map +1 -0
- package/dist/cli/eval-chat.js +508 -0
- package/dist/cli/eval-chat.js.map +1 -0
- package/dist/cli/eval-designer.js +67 -0
- package/dist/cli/eval-designer.js.map +1 -0
- package/dist/cli/eval-qa-review.js +284 -0
- package/dist/cli/eval-qa-review.js.map +1 -0
- package/dist/cli/golden-export.js +35 -0
- package/dist/cli/golden-export.js.map +1 -0
- package/dist/cli/index.js +90 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.js +746 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/scan-repo.js +199 -0
- package/dist/cli/scan-repo.js.map +1 -0
- package/dist/cli/seed.js +108 -0
- package/dist/cli/seed.js.map +1 -0
- package/dist/cli/tinybee.js +247 -0
- package/dist/cli/tinybee.js.map +1 -0
- package/dist/config.js +138 -0
- package/dist/config.js.map +1 -0
- package/dist/connect/aivision-local.js +833 -0
- package/dist/connect/aivision-local.js.map +1 -0
- package/dist/connect/aivision-token.js +84 -0
- package/dist/connect/aivision-token.js.map +1 -0
- package/dist/connect/crypto.js +65 -0
- package/dist/connect/crypto.js.map +1 -0
- package/dist/connect/deps.js +110 -0
- package/dist/connect/deps.js.map +1 -0
- package/dist/connect/engines.js +144 -0
- package/dist/connect/engines.js.map +1 -0
- package/dist/connect/github-access.js +74 -0
- package/dist/connect/github-access.js.map +1 -0
- package/dist/connect/github-app.js +129 -0
- package/dist/connect/github-app.js.map +1 -0
- package/dist/connect/index.js +9 -0
- package/dist/connect/index.js.map +1 -0
- package/dist/connect/model-choices.js +201 -0
- package/dist/connect/model-choices.js.map +1 -0
- package/dist/connect/providers.js +900 -0
- package/dist/connect/providers.js.map +1 -0
- package/dist/connect/readiness.js +232 -0
- package/dist/connect/readiness.js.map +1 -0
- package/dist/connect/redact.js +16 -0
- package/dist/connect/redact.js.map +1 -0
- package/dist/connect/registry.js +406 -0
- package/dist/connect/registry.js.map +1 -0
- package/dist/connect/store.js +283 -0
- package/dist/connect/store.js.map +1 -0
- package/dist/connect/tunnel.js +134 -0
- package/dist/connect/tunnel.js.map +1 -0
- package/dist/connect/types.js +8 -0
- package/dist/connect/types.js.map +1 -0
- package/dist/connections/index.js +5 -0
- package/dist/connections/index.js.map +1 -0
- package/dist/connections/manager.js +223 -0
- package/dist/connections/manager.js.map +1 -0
- package/dist/connections/presets.js +264 -0
- package/dist/connections/presets.js.map +1 -0
- package/dist/connections/store.js +132 -0
- package/dist/connections/store.js.map +1 -0
- package/dist/connections/tools.js +206 -0
- package/dist/connections/tools.js.map +1 -0
- package/dist/db-schema.js +355 -0
- package/dist/db-schema.js.map +1 -0
- package/dist/db.js +379 -0
- package/dist/db.js.map +1 -0
- package/dist/delivery.js +49 -0
- package/dist/delivery.js.map +1 -0
- package/dist/deploy-wait.js +701 -0
- package/dist/deploy-wait.js.map +1 -0
- package/dist/disk.js +243 -0
- package/dist/disk.js.map +1 -0
- package/dist/dot-health.js +966 -0
- package/dist/dot-health.js.map +1 -0
- package/dist/dot-remove.js +246 -0
- package/dist/dot-remove.js.map +1 -0
- package/dist/events.js +38 -0
- package/dist/events.js.map +1 -0
- package/dist/evidence-pack.js +423 -0
- package/dist/evidence-pack.js.map +1 -0
- package/dist/flows/answers.js +289 -0
- package/dist/flows/answers.js.map +1 -0
- package/dist/flows/change.js +811 -0
- package/dist/flows/change.js.map +1 -0
- package/dist/flows/checkStatus.js +524 -0
- package/dist/flows/checkStatus.js.map +1 -0
- package/dist/flows/ci.js +236 -0
- package/dist/flows/ci.js.map +1 -0
- package/dist/flows/ciFailure.js +76 -0
- package/dist/flows/ciFailure.js.map +1 -0
- package/dist/flows/common.js +522 -0
- package/dist/flows/common.js.map +1 -0
- package/dist/flows/default-branch.js +29 -0
- package/dist/flows/default-branch.js.map +1 -0
- package/dist/flows/defectDraft.js +447 -0
- package/dist/flows/defectDraft.js.map +1 -0
- package/dist/flows/defects.js +623 -0
- package/dist/flows/defects.js.map +1 -0
- package/dist/flows/digest.js +295 -0
- package/dist/flows/digest.js.map +1 -0
- package/dist/flows/impact.js +82 -0
- package/dist/flows/impact.js.map +1 -0
- package/dist/flows/index.js +23 -0
- package/dist/flows/index.js.map +1 -0
- package/dist/flows/intent-sources.js +72 -0
- package/dist/flows/intent-sources.js.map +1 -0
- package/dist/flows/mergeCases.js +169 -0
- package/dist/flows/mergeCases.js.map +1 -0
- package/dist/flows/nightlyRun.js +82 -0
- package/dist/flows/nightlyRun.js.map +1 -0
- package/dist/flows/outage.js +64 -0
- package/dist/flows/outage.js.map +1 -0
- package/dist/flows/postMerge.js +5 -0
- package/dist/flows/postMerge.js.map +1 -0
- package/dist/flows/prCheck.js +5 -0
- package/dist/flows/prCheck.js.map +1 -0
- package/dist/flows/prTarget.js +66 -0
- package/dist/flows/prTarget.js.map +1 -0
- package/dist/flows/qa.js +363 -0
- package/dist/flows/qa.js.map +1 -0
- package/dist/flows/questions.js +160 -0
- package/dist/flows/questions.js.map +1 -0
- package/dist/flows/recovery.js +64 -0
- package/dist/flows/recovery.js.map +1 -0
- package/dist/flows/rerun.js +50 -0
- package/dist/flows/rerun.js.map +1 -0
- package/dist/flows/testDesign.js +294 -0
- package/dist/flows/testDesign.js.map +1 -0
- package/dist/flows/testDesignJob.js +46 -0
- package/dist/flows/testDesignJob.js.map +1 -0
- package/dist/flows/testRepo.js +228 -0
- package/dist/flows/testRepo.js.map +1 -0
- package/dist/flows/testSavings.js +381 -0
- package/dist/flows/testSavings.js.map +1 -0
- package/dist/flows/testStatus.js +343 -0
- package/dist/flows/testStatus.js.map +1 -0
- package/dist/flows/ticketContext.js +425 -0
- package/dist/flows/ticketContext.js.map +1 -0
- package/dist/flows/ticketReview.js +249 -0
- package/dist/flows/ticketReview.js.map +1 -0
- package/dist/flows/ticks.js +73 -0
- package/dist/flows/ticks.js.map +1 -0
- package/dist/hive/admin.js +122 -0
- package/dist/hive/admin.js.map +1 -0
- package/dist/hive/auth.js +130 -0
- package/dist/hive/auth.js.map +1 -0
- package/dist/hive/billing.js +278 -0
- package/dist/hive/billing.js.map +1 -0
- package/dist/hive/config.js +63 -0
- package/dist/hive/config.js.map +1 -0
- package/dist/hive/db.js +186 -0
- package/dist/hive/db.js.map +1 -0
- package/dist/hive/embed.js +76 -0
- package/dist/hive/embed.js.map +1 -0
- package/dist/hive/errors.js +17 -0
- package/dist/hive/errors.js.map +1 -0
- package/dist/hive/google.js +75 -0
- package/dist/hive/google.js.map +1 -0
- package/dist/hive/index.js +25 -0
- package/dist/hive/index.js.map +1 -0
- package/dist/hive/jwt.js +57 -0
- package/dist/hive/jwt.js.map +1 -0
- package/dist/hive/keys.js +61 -0
- package/dist/hive/keys.js.map +1 -0
- package/dist/hive/mail.js +27 -0
- package/dist/hive/mail.js.map +1 -0
- package/dist/hive/native-push.js +255 -0
- package/dist/hive/native-push.js.map +1 -0
- package/dist/hive/pairing.js +342 -0
- package/dist/hive/pairing.js.map +1 -0
- package/dist/hive/presence.js +121 -0
- package/dist/hive/presence.js.map +1 -0
- package/dist/hive/push.js +185 -0
- package/dist/hive/push.js.map +1 -0
- package/dist/hive/relay.js +205 -0
- package/dist/hive/relay.js.map +1 -0
- package/dist/hive/routes.js +228 -0
- package/dist/hive/routes.js.map +1 -0
- package/dist/hive/server.js +12 -0
- package/dist/hive/server.js.map +1 -0
- package/dist/hive/session.js +28 -0
- package/dist/hive/session.js.map +1 -0
- package/dist/hive/tenants.js +287 -0
- package/dist/hive/tenants.js.map +1 -0
- package/dist/hive/tunnel/cloudflare.js +160 -0
- package/dist/hive/tunnel/cloudflare.js.map +1 -0
- package/dist/hive/tunnel/mock.js +52 -0
- package/dist/hive/tunnel/mock.js.map +1 -0
- package/dist/hive/tunnel/provider.js +19 -0
- package/dist/hive/tunnel/provider.js.map +1 -0
- package/dist/hive/updates.js +61 -0
- package/dist/hive/updates.js.map +1 -0
- package/dist/http-error.js +11 -0
- package/dist/http-error.js.map +1 -0
- package/dist/impact/classify.js +226 -0
- package/dist/impact/classify.js.map +1 -0
- package/dist/impact/find.js +259 -0
- package/dist/impact/find.js.map +1 -0
- package/dist/impact/pr.js +54 -0
- package/dist/impact/pr.js.map +1 -0
- package/dist/impact/store.js +365 -0
- package/dist/impact/store.js.map +1 -0
- package/dist/impact/text.js +158 -0
- package/dist/impact/text.js.map +1 -0
- package/dist/index.js +288 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/adf.js +397 -0
- package/dist/integrations/adf.js.map +1 -0
- package/dist/integrations/bot-marker.js +103 -0
- package/dist/integrations/bot-marker.js.map +1 -0
- package/dist/integrations/github-issues.js +705 -0
- package/dist/integrations/github-issues.js.map +1 -0
- package/dist/integrations/github.js +1284 -0
- package/dist/integrations/github.js.map +1 -0
- package/dist/integrations/issue-create.js +60 -0
- package/dist/integrations/issue-create.js.map +1 -0
- package/dist/integrations/jira.js +279 -0
- package/dist/integrations/jira.js.map +1 -0
- package/dist/integrations/linear.js +273 -0
- package/dist/integrations/linear.js.map +1 -0
- package/dist/integrations/own-identity-warm.js +47 -0
- package/dist/integrations/own-identity-warm.js.map +1 -0
- package/dist/integrations/own-identity.js +39 -0
- package/dist/integrations/own-identity.js.map +1 -0
- package/dist/integrations/status-change.js +42 -0
- package/dist/integrations/status-change.js.map +1 -0
- package/dist/lead-defects.js +202 -0
- package/dist/lead-defects.js.map +1 -0
- package/dist/lead-digest.js +333 -0
- package/dist/lead-digest.js.map +1 -0
- package/dist/lead-release.js +286 -0
- package/dist/lead-release.js.map +1 -0
- package/dist/lead.js +328 -0
- package/dist/lead.js.map +1 -0
- package/dist/legacy-names.js +51 -0
- package/dist/legacy-names.js.map +1 -0
- package/dist/limits.js +44 -0
- package/dist/limits.js.map +1 -0
- package/dist/link-trust.js +224 -0
- package/dist/link-trust.js.map +1 -0
- package/dist/links.js +219 -0
- package/dist/links.js.map +1 -0
- package/dist/loopback.js +35 -0
- package/dist/loopback.js.map +1 -0
- package/dist/model-cap.js +60 -0
- package/dist/model-cap.js.map +1 -0
- package/dist/model-usage.js +173 -0
- package/dist/model-usage.js.map +1 -0
- package/dist/monitor/backfill.js +39 -0
- package/dist/monitor/backfill.js.map +1 -0
- package/dist/monitor/browser-probe.js +198 -0
- package/dist/monitor/browser-probe.js.map +1 -0
- package/dist/monitor/catch-up.js +31 -0
- package/dist/monitor/catch-up.js.map +1 -0
- package/dist/monitor/pollers.js +1606 -0
- package/dist/monitor/pollers.js.map +1 -0
- package/dist/monitor/probes.js +178 -0
- package/dist/monitor/probes.js.map +1 -0
- package/dist/monitor/self-health.js +228 -0
- package/dist/monitor/self-health.js.map +1 -0
- package/dist/monitor/statuspage.js +105 -0
- package/dist/monitor/statuspage.js.map +1 -0
- package/dist/nightly-scheduler.js +127 -0
- package/dist/nightly-scheduler.js.map +1 -0
- package/dist/nightly.js +141 -0
- package/dist/nightly.js.map +1 -0
- package/dist/notify/headline.js +114 -0
- package/dist/notify/headline.js.map +1 -0
- package/dist/notify/push.js +174 -0
- package/dist/notify/push.js.map +1 -0
- package/dist/object-cards.js +585 -0
- package/dist/object-cards.js.map +1 -0
- package/dist/object-links.js +47 -0
- package/dist/object-links.js.map +1 -0
- package/dist/onboarding-checks.js +141 -0
- package/dist/onboarding-checks.js.map +1 -0
- package/dist/onboarding.js +401 -0
- package/dist/onboarding.js.map +1 -0
- package/dist/path-filters.js +62 -0
- package/dist/path-filters.js.map +1 -0
- package/dist/phone/alerts.js +67 -0
- package/dist/phone/alerts.js.map +1 -0
- package/dist/phone/auth.js +240 -0
- package/dist/phone/auth.js.map +1 -0
- package/dist/phone/pairing.js +442 -0
- package/dist/phone/pairing.js.map +1 -0
- package/dist/phone/prefs.js +27 -0
- package/dist/phone/prefs.js.map +1 -0
- package/dist/phone/tailscale.js +161 -0
- package/dist/phone/tailscale.js.map +1 -0
- package/dist/pr-scope.js +441 -0
- package/dist/pr-scope.js.map +1 -0
- package/dist/proc.js +156 -0
- package/dist/proc.js.map +1 -0
- package/dist/profile/cache.js +108 -0
- package/dist/profile/cache.js.map +1 -0
- package/dist/profile/ci.js +216 -0
- package/dist/profile/ci.js.map +1 -0
- package/dist/profile/index.js +8 -0
- package/dist/profile/index.js.map +1 -0
- package/dist/profile/job.js +135 -0
- package/dist/profile/job.js.map +1 -0
- package/dist/profile/queries/go-tags.scm +47 -0
- package/dist/profile/queries/java-tags.scm +25 -0
- package/dist/profile/queries/javascript-tags.scm +104 -0
- package/dist/profile/queries/python-tags.scm +19 -0
- package/dist/profile/queries/typescript-tags.scm +28 -0
- package/dist/profile/scan-thread.js +42 -0
- package/dist/profile/scan-thread.js.map +1 -0
- package/dist/profile/scan-worker.js +16 -0
- package/dist/profile/scan-worker.js.map +1 -0
- package/dist/profile/scan.js +351 -0
- package/dist/profile/scan.js.map +1 -0
- package/dist/profile/stack.js +528 -0
- package/dist/profile/stack.js.map +1 -0
- package/dist/profile/store.js +35 -0
- package/dist/profile/store.js.map +1 -0
- package/dist/profile/tests.js +399 -0
- package/dist/profile/tests.js.map +1 -0
- package/dist/queue.js +350 -0
- package/dist/queue.js.map +1 -0
- package/dist/refs.js +756 -0
- package/dist/refs.js.map +1 -0
- package/dist/release-notes.js +272 -0
- package/dist/release-notes.js.map +1 -0
- package/dist/reports/build.js +243 -0
- package/dist/reports/build.js.map +1 -0
- package/dist/reports/index.js +211 -0
- package/dist/reports/index.js.map +1 -0
- package/dist/reports/store.js +150 -0
- package/dist/reports/store.js.map +1 -0
- package/dist/reports/ticket-titles.js +124 -0
- package/dist/reports/ticket-titles.js.map +1 -0
- package/dist/reports/trace-map.js +1278 -0
- package/dist/reports/trace-map.js.map +1 -0
- package/dist/reports/traceability.js +422 -0
- package/dist/reports/traceability.js.map +1 -0
- package/dist/repos/mirror.js +356 -0
- package/dist/repos/mirror.js.map +1 -0
- package/dist/repos-github.js +108 -0
- package/dist/repos-github.js.map +1 -0
- package/dist/repos.js +891 -0
- package/dist/repos.js.map +1 -0
- package/dist/review/backend-anthropic.js +90 -0
- package/dist/review/backend-anthropic.js.map +1 -0
- package/dist/review/backend-cli.js +248 -0
- package/dist/review/backend-cli.js.map +1 -0
- package/dist/review/backend-codex.js +81 -0
- package/dist/review/backend-codex.js.map +1 -0
- package/dist/review/backend-mock.js +686 -0
- package/dist/review/backend-mock.js.map +1 -0
- package/dist/review/backend-only.js +168 -0
- package/dist/review/backend-only.js.map +1 -0
- package/dist/review/backend.js +105 -0
- package/dist/review/backend.js.map +1 -0
- package/dist/review/baseline/render-v1.js +483 -0
- package/dist/review/baseline/render-v1.js.map +1 -0
- package/dist/review/change-summary.js +197 -0
- package/dist/review/change-summary.js.map +1 -0
- package/dist/review/changelog.js +40 -0
- package/dist/review/changelog.js.map +1 -0
- package/dist/review/check.js +494 -0
- package/dist/review/check.js.map +1 -0
- package/dist/review/checkout.js +185 -0
- package/dist/review/checkout.js.map +1 -0
- package/dist/review/classify.js +178 -0
- package/dist/review/classify.js.map +1 -0
- package/dist/review/coverage.js +347 -0
- package/dist/review/coverage.js.map +1 -0
- package/dist/review/decision-eval.js +121 -0
- package/dist/review/decision-eval.js.map +1 -0
- package/dist/review/deliver.js +104 -0
- package/dist/review/deliver.js.map +1 -0
- package/dist/review/designer-eval.js +280 -0
- package/dist/review/designer-eval.js.map +1 -0
- package/dist/review/dogfood-digest.js +136 -0
- package/dist/review/dogfood-digest.js.map +1 -0
- package/dist/review/dogfood-eval.js +486 -0
- package/dist/review/dogfood-eval.js.map +1 -0
- package/dist/review/environment.js +109 -0
- package/dist/review/environment.js.map +1 -0
- package/dist/review/eval.js +405 -0
- package/dist/review/eval.js.map +1 -0
- package/dist/review/glob.js +110 -0
- package/dist/review/glob.js.map +1 -0
- package/dist/review/golden-export.js +219 -0
- package/dist/review/golden-export.js.map +1 -0
- package/dist/review/impact.js +406 -0
- package/dist/review/impact.js.map +1 -0
- package/dist/review/imports.js +542 -0
- package/dist/review/imports.js.map +1 -0
- package/dist/review/index.js +512 -0
- package/dist/review/index.js.map +1 -0
- package/dist/review/intent.js +128 -0
- package/dist/review/intent.js.map +1 -0
- package/dist/review/lenses.js +167 -0
- package/dist/review/lenses.js.map +1 -0
- package/dist/review/linked-tickets.js +293 -0
- package/dist/review/linked-tickets.js.map +1 -0
- package/dist/review/merge.js +370 -0
- package/dist/review/merge.js.map +1 -0
- package/dist/review/on-demand.js +218 -0
- package/dist/review/on-demand.js.map +1 -0
- package/dist/review/prompt-eval.js +299 -0
- package/dist/review/prompt-eval.js.map +1 -0
- package/dist/review/prompt-variants.js +37 -0
- package/dist/review/prompt-variants.js.map +1 -0
- package/dist/review/readability-eval.js +217 -0
- package/dist/review/readability-eval.js.map +1 -0
- package/dist/review/readability.js +295 -0
- package/dist/review/readability.js.map +1 -0
- package/dist/review/render.js +2409 -0
- package/dist/review/render.js.map +1 -0
- package/dist/review/repo.js +194 -0
- package/dist/review/repo.js.map +1 -0
- package/dist/review/report-plan.js +90 -0
- package/dist/review/report-plan.js.map +1 -0
- package/dist/review/routes.js +195 -0
- package/dist/review/routes.js.map +1 -0
- package/dist/review/run-summary.js +34 -0
- package/dist/review/run-summary.js.map +1 -0
- package/dist/review/run.js +245 -0
- package/dist/review/run.js.map +1 -0
- package/dist/review/scope.js +454 -0
- package/dist/review/scope.js.map +1 -0
- package/dist/review/security.js +432 -0
- package/dist/review/security.js.map +1 -0
- package/dist/review/signals.js +550 -0
- package/dist/review/signals.js.map +1 -0
- package/dist/review/specs.js +150 -0
- package/dist/review/specs.js.map +1 -0
- package/dist/review/ste.js +133 -0
- package/dist/review/ste.js.map +1 -0
- package/dist/review/test-repo-file.js +18 -0
- package/dist/review/test-repo-file.js.map +1 -0
- package/dist/review/test-repo-lines.js +53 -0
- package/dist/review/test-repo-lines.js.map +1 -0
- package/dist/review/ticket-on-demand.js +232 -0
- package/dist/review/ticket-on-demand.js.map +1 -0
- package/dist/review/yaml.js +298 -0
- package/dist/review/yaml.js.map +1 -0
- package/dist/room.js +361 -0
- package/dist/room.js.map +1 -0
- package/dist/routes/activity.js +219 -0
- package/dist/routes/activity.js.map +1 -0
- package/dist/routes/call.js +29 -0
- package/dist/routes/call.js.map +1 -0
- package/dist/routes/cards.js +40 -0
- package/dist/routes/cards.js.map +1 -0
- package/dist/routes/cases.js +133 -0
- package/dist/routes/cases.js.map +1 -0
- package/dist/routes/connect.js +268 -0
- package/dist/routes/connect.js.map +1 -0
- package/dist/routes/connection-presets.js +32 -0
- package/dist/routes/connection-presets.js.map +1 -0
- package/dist/routes/connections.js +177 -0
- package/dist/routes/connections.js.map +1 -0
- package/dist/routes/disk.js +19 -0
- package/dist/routes/disk.js.map +1 -0
- package/dist/routes/docs.js +71 -0
- package/dist/routes/docs.js.map +1 -0
- package/dist/routes/dot-suggest.js +1002 -0
- package/dist/routes/dot-suggest.js.map +1 -0
- package/dist/routes/evidence-pack.js +16 -0
- package/dist/routes/evidence-pack.js.map +1 -0
- package/dist/routes/health.js +121 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/impact.js +48 -0
- package/dist/routes/impact.js.map +1 -0
- package/dist/routes/lead.js +50 -0
- package/dist/routes/lead.js.map +1 -0
- package/dist/routes/links.js +13 -0
- package/dist/routes/links.js.map +1 -0
- package/dist/routes/markdown.js +62 -0
- package/dist/routes/markdown.js.map +1 -0
- package/dist/routes/onboarding.js +47 -0
- package/dist/routes/onboarding.js.map +1 -0
- package/dist/routes/phone.js +231 -0
- package/dist/routes/phone.js.map +1 -0
- package/dist/routes/release-notes.js +30 -0
- package/dist/routes/release-notes.js.map +1 -0
- package/dist/routes/reports.js +102 -0
- package/dist/routes/reports.js.map +1 -0
- package/dist/routes/repos.js +91 -0
- package/dist/routes/repos.js.map +1 -0
- package/dist/routes/review.js +283 -0
- package/dist/routes/review.js.map +1 -0
- package/dist/routes/roles.js +114 -0
- package/dist/routes/roles.js.map +1 -0
- package/dist/routes/room.js +21 -0
- package/dist/routes/room.js.map +1 -0
- package/dist/routes/runner.js +156 -0
- package/dist/routes/runner.js.map +1 -0
- package/dist/routes/runs.js +84 -0
- package/dist/routes/runs.js.map +1 -0
- package/dist/routes/setup.js +18 -0
- package/dist/routes/setup.js.map +1 -0
- package/dist/routes/test-runs.js +220 -0
- package/dist/routes/test-runs.js.map +1 -0
- package/dist/routes/ticket-status.js +17 -0
- package/dist/routes/ticket-status.js.map +1 -0
- package/dist/routes/traceability.js +143 -0
- package/dist/routes/traceability.js.map +1 -0
- package/dist/routes/true.js +142 -0
- package/dist/routes/true.js.map +1 -0
- package/dist/routes/updates.js +70 -0
- package/dist/routes/updates.js.map +1 -0
- package/dist/runner/adapters/index.js +12 -0
- package/dist/runner/adapters/index.js.map +1 -0
- package/dist/runner/adapters/playwright.js +68 -0
- package/dist/runner/adapters/playwright.js.map +1 -0
- package/dist/runner/aivision/cases.js +172 -0
- package/dist/runner/aivision/cases.js.map +1 -0
- package/dist/runner/aivision/cli.js +201 -0
- package/dist/runner/aivision/cli.js.map +1 -0
- package/dist/runner/aivision/index.js +281 -0
- package/dist/runner/aivision/index.js.map +1 -0
- package/dist/runner/aivision/server.js +394 -0
- package/dist/runner/aivision/server.js.map +1 -0
- package/dist/runner/aivision/shared.js +140 -0
- package/dist/runner/aivision/shared.js.map +1 -0
- package/dist/runner/artifact-cap.js +189 -0
- package/dist/runner/artifact-cap.js.map +1 -0
- package/dist/runner/artifacts.js +433 -0
- package/dist/runner/artifacts.js.map +1 -0
- package/dist/runner/command.js +564 -0
- package/dist/runner/command.js.map +1 -0
- package/dist/runner/copyfiles.js +221 -0
- package/dist/runner/copyfiles.js.map +1 -0
- package/dist/runner/engines.js +32 -0
- package/dist/runner/engines.js.map +1 -0
- package/dist/runner/evidence.js +114 -0
- package/dist/runner/evidence.js.map +1 -0
- package/dist/runner/host-env.js +160 -0
- package/dist/runner/host-env.js.map +1 -0
- package/dist/runner/index.js +1221 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/runner/observe.js +603 -0
- package/dist/runner/observe.js.map +1 -0
- package/dist/runner/playwright-json.js +108 -0
- package/dist/runner/playwright-json.js.map +1 -0
- package/dist/runner/pwgen/exec.js +192 -0
- package/dist/runner/pwgen/exec.js.map +1 -0
- package/dist/runner/pwgen/explore.js +111 -0
- package/dist/runner/pwgen/explore.js.map +1 -0
- package/dist/runner/pwgen/index.js +423 -0
- package/dist/runner/pwgen/index.js.map +1 -0
- package/dist/runner/pwgen/propose.js +69 -0
- package/dist/runner/pwgen/propose.js.map +1 -0
- package/dist/runner/pwgen/source.js +632 -0
- package/dist/runner/pwgen/source.js.map +1 -0
- package/dist/runner/setup.js +222 -0
- package/dist/runner/setup.js.map +1 -0
- package/dist/runner/step-reporter.js +107 -0
- package/dist/runner/step-reporter.js.map +1 -0
- package/dist/runner/test-repo.js +326 -0
- package/dist/runner/test-repo.js.map +1 -0
- package/dist/runner/typed-value.js +46 -0
- package/dist/runner/typed-value.js.map +1 -0
- package/dist/runner/verify.js +133 -0
- package/dist/runner/verify.js.map +1 -0
- package/dist/runner/worktree.js +349 -0
- package/dist/runner/worktree.js.map +1 -0
- package/dist/sandbox.js +61 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/server.js +262 -0
- package/dist/server.js.map +1 -0
- package/dist/shadow-week.js +126 -0
- package/dist/shadow-week.js.map +1 -0
- package/dist/shutdown.js +92 -0
- package/dist/shutdown.js.map +1 -0
- package/dist/slack/index.js +645 -0
- package/dist/slack/index.js.map +1 -0
- package/dist/stages/config.js +147 -0
- package/dist/stages/config.js.map +1 -0
- package/dist/stages/index.js +41 -0
- package/dist/stages/index.js.map +1 -0
- package/dist/suites.js +293 -0
- package/dist/suites.js.map +1 -0
- package/dist/target-url.js +116 -0
- package/dist/target-url.js.map +1 -0
- package/dist/test-runs.js +662 -0
- package/dist/test-runs.js.map +1 -0
- package/dist/ticket-keys.js +97 -0
- package/dist/ticket-keys.js.map +1 -0
- package/dist/ticket-supersede.js +105 -0
- package/dist/ticket-supersede.js.map +1 -0
- package/dist/tinybee/ed25519.js +99 -0
- package/dist/tinybee/ed25519.js.map +1 -0
- package/dist/tinybee/models-routes.js +19 -0
- package/dist/tinybee/models-routes.js.map +1 -0
- package/dist/tinybee/pair-payload.js +41 -0
- package/dist/tinybee/pair-payload.js.map +1 -0
- package/dist/tinybee/update-manifest.js +77 -0
- package/dist/tinybee/update-manifest.js.map +1 -0
- package/dist/tinybee/well-known.js +64 -0
- package/dist/tinybee/well-known.js.map +1 -0
- package/dist/tinybee/workflows/activity.js +23 -0
- package/dist/tinybee/workflows/activity.js.map +1 -0
- package/dist/tinybee/workflows/cron.js +210 -0
- package/dist/tinybee/workflows/cron.js.map +1 -0
- package/dist/tinybee/workflows/engine.js +371 -0
- package/dist/tinybee/workflows/engine.js.map +1 -0
- package/dist/tinybee/workflows/from-text.js +203 -0
- package/dist/tinybee/workflows/from-text.js.map +1 -0
- package/dist/tinybee/workflows/routes.js +189 -0
- package/dist/tinybee/workflows/routes.js.map +1 -0
- package/dist/tinybee/workflows/scheduler.js +100 -0
- package/dist/tinybee/workflows/scheduler.js.map +1 -0
- package/dist/tinybee/workflows/skills.js +227 -0
- package/dist/tinybee/workflows/skills.js.map +1 -0
- package/dist/tinybee/workflows/store.js +205 -0
- package/dist/tinybee/workflows/store.js.map +1 -0
- package/dist/tinybee/workflows/types.js +180 -0
- package/dist/tinybee/workflows/types.js.map +1 -0
- package/dist/tinybee/workflows/yaml.js +323 -0
- package/dist/tinybee/workflows/yaml.js.map +1 -0
- package/dist/true/api.js +495 -0
- package/dist/true/api.js.map +1 -0
- package/dist/true/client.js +292 -0
- package/dist/true/client.js.map +1 -0
- package/dist/true/clock.js +36 -0
- package/dist/true/clock.js.map +1 -0
- package/dist/true/events.js +125 -0
- package/dist/true/events.js.map +1 -0
- package/dist/true/hosts.js +98 -0
- package/dist/true/hosts.js.map +1 -0
- package/dist/true/index.js +29 -0
- package/dist/true/index.js.map +1 -0
- package/dist/true/key.js +54 -0
- package/dist/true/key.js.map +1 -0
- package/dist/true/line.js +69 -0
- package/dist/true/line.js.map +1 -0
- package/dist/true/mask.js +31 -0
- package/dist/true/mask.js.map +1 -0
- package/dist/true/names.js +114 -0
- package/dist/true/names.js.map +1 -0
- package/dist/true/outbox.js +233 -0
- package/dist/true/outbox.js.map +1 -0
- package/dist/true/replay.js +164 -0
- package/dist/true/replay.js.map +1 -0
- package/dist/true/settings.js +123 -0
- package/dist/true/settings.js.map +1 -0
- package/dist/true/status.js +189 -0
- package/dist/true/status.js.map +1 -0
- package/dist/true/sync-cases.js +222 -0
- package/dist/true/sync-cases.js.map +1 -0
- package/dist/true/sync-manual.js +295 -0
- package/dist/true/sync-manual.js.map +1 -0
- package/dist/true/sync-runs.js +109 -0
- package/dist/true/sync-runs.js.map +1 -0
- package/dist/true/worker.js +414 -0
- package/dist/true/worker.js.map +1 -0
- package/dist/types.js +32 -0
- package/dist/types.js.map +1 -0
- package/dist/updates/asks.js +38 -0
- package/dist/updates/asks.js.map +1 -0
- package/dist/updates/index.js +835 -0
- package/dist/updates/index.js.map +1 -0
- package/dist/updates/owner.js +24 -0
- package/dist/updates/owner.js.map +1 -0
- package/dist/updates/prefs.js +118 -0
- package/dist/updates/prefs.js.map +1 -0
- package/dist/updates/route.js +78 -0
- package/dist/updates/route.js.map +1 -0
- package/dist/updates/sources.js +345 -0
- package/dist/updates/sources.js.map +1 -0
- package/dist/updates/words.js +452 -0
- package/dist/updates/words.js.map +1 -0
- package/dist/version.js +53 -0
- package/dist/version.js.map +1 -0
- package/dist/view-compute.js +382 -0
- package/dist/view-compute.js.map +1 -0
- package/dist/view-spec.js +894 -0
- package/dist/view-spec.js.map +1 -0
- package/dist/web/apple-touch-icon.png +0 -0
- package/dist/web/assets/ApprovalCard-Br_z5z7G.css +1 -0
- package/dist/web/assets/ApprovalCard-CfGhGFo_.js +3 -0
- package/dist/web/assets/CardFromRef-BaTGmZ9c.js +2 -0
- package/dist/web/assets/CardFromRef-DO7i2uDd.css +1 -0
- package/dist/web/assets/Cases-8l_6UcLh.js +2 -0
- package/dist/web/assets/Cases-CpfED0uB.css +1 -0
- package/dist/web/assets/Chat-BKDiR0qt.js +3 -0
- package/dist/web/assets/Chat-DxjdyYUu.css +1 -0
- package/dist/web/assets/ConfirmDialog-CIMveD-b.js +2 -0
- package/dist/web/assets/ConnectSheet-Cm5vbZdR.js +4 -0
- package/dist/web/assets/Docs-HKGuY0WE.js +2 -0
- package/dist/web/assets/Docs-fodKx8S7.css +1 -0
- package/dist/web/assets/DotDetail-DskS3NWe.js +2 -0
- package/dist/web/assets/DotDetail-OWRSD_1x.css +1 -0
- package/dist/web/assets/DotStage-BZDclfzV.css +1 -0
- package/dist/web/assets/DotStage-CtMNzCN3.js +2 -0
- package/dist/web/assets/Dots-BqCsS34m.js +2 -0
- package/dist/web/assets/EvidencePack-DQ3kCJX4.js +2 -0
- package/dist/web/assets/EvidencePack-DV_9ETsA.css +1 -0
- package/dist/web/assets/FailedDeliveries-1F2kFcs9.js +2 -0
- package/dist/web/assets/FailedDeliveries-DXa2_VvI.css +1 -0
- package/dist/web/assets/Feed-5wiHRTFK.js +2 -0
- package/dist/web/assets/GfmView-C-NYaduC.js +4 -0
- package/dist/web/assets/ImpactList-C-RNuDB0.js +2 -0
- package/dist/web/assets/ImpactList-C612dFdw.css +1 -0
- package/dist/web/assets/Inbox-kc1bKVL_.js +2 -0
- package/dist/web/assets/JoinScreen-C3L4wmP3.js +2 -0
- package/dist/web/assets/JoinScreen-COeAUv5v.css +1 -0
- package/dist/web/assets/LeadDialog-N3Zul9Rw.js +8 -0
- package/dist/web/assets/LeadDialog-xyWjAuAS.css +1 -0
- package/dist/web/assets/ListeningLine-BRFNaczY.js +2 -0
- package/dist/web/assets/ListeningLine-pN8CgyiK.css +1 -0
- package/dist/web/assets/Mascots-pIyGpxtD.js +2 -0
- package/dist/web/assets/ModelChoices-BxO1zyyr.js +2 -0
- package/dist/web/assets/ModelChoices-DQJnVxfs.css +1 -0
- package/dist/web/assets/NewDotDialog-CDPUWmgN.js +2 -0
- package/dist/web/assets/NewDotDialog-DrPPqkSZ.css +1 -0
- package/dist/web/assets/NewTestRunDialog-BQBthVHE.js +2 -0
- package/dist/web/assets/NoBreakNames-Csxdqdt6.js +2 -0
- package/dist/web/assets/Pair-omex_K7H.js +2 -0
- package/dist/web/assets/PushSection-CmqHlE_2.js +2 -0
- package/dist/web/assets/ReleaseNotes-B6VqFewP.js +2 -0
- package/dist/web/assets/ReleaseNotes-DBJUL7Vm.css +1 -0
- package/dist/web/assets/ReportPage-BHS1xWEt.js +162 -0
- package/dist/web/assets/Reports-BEHnDIb1.js +2 -0
- package/dist/web/assets/ReviewChangeDialog-BVSt-cw-.js +2 -0
- package/dist/web/assets/ReviewChangeDialog-BbIlHRx0.css +1 -0
- package/dist/web/assets/Room-BoG_uge4.js +2 -0
- package/dist/web/assets/Room-evAfiW_e.css +1 -0
- package/dist/web/assets/RunActions-ZY7yf1AF.js +2 -0
- package/dist/web/assets/RunDetail-C8St20GQ.css +1 -0
- package/dist/web/assets/RunDetail-qADXjBvd.js +9 -0
- package/dist/web/assets/RunRow-BKEJv8ib.js +2 -0
- package/dist/web/assets/RunnerTry-Dgpp67-s.js +6 -0
- package/dist/web/assets/RunnerTry-DsweWOfO.css +1 -0
- package/dist/web/assets/Settings-fs-QJwNM.js +2 -0
- package/dist/web/assets/Setup-DI6hBEP-.js +2 -0
- package/dist/web/assets/TestRows-wh03T5Li.js +4 -0
- package/dist/web/assets/TestRun-DTOyF-Pv.js +2 -0
- package/dist/web/assets/TestRuns-ggDjm1Q8.js +2 -0
- package/dist/web/assets/TinyBeeAddLaptop-bc3pmh3T.js +2 -0
- package/dist/web/assets/TinyBeeAi-CkyOzhm5.js +2 -0
- package/dist/web/assets/TinyBeeConnections-B2K_P38u.js +2 -0
- package/dist/web/assets/TinyBeeHome-DSpxX5KS.js +3 -0
- package/dist/web/assets/TinyBeePlan-BamiLziu.js +2 -0
- package/dist/web/assets/TinyBeeSignup-vHcz0Wen.js +2 -0
- package/dist/web/assets/TinyBeeSkills-By9RLUse.js +2 -0
- package/dist/web/assets/TinyBeeWorkflow-DeNO7Jsh.js +2 -0
- package/dist/web/assets/TinyBeeWorkflowEditor-B6OGC2OT.js +2 -0
- package/dist/web/assets/TinyBeeWorkflows-BN4-h6lt.js +2 -0
- package/dist/web/assets/Trace-BBCI1aIB.css +1 -0
- package/dist/web/assets/Trace-aF92UWaH.js +2 -0
- package/dist/web/assets/UpdatesSection-CCWEbkue.js +2 -0
- package/dist/web/assets/Welcome-CCcy558Q.js +2 -0
- package/dist/web/assets/activity-C3qilrDm.css +1 -0
- package/dist/web/assets/activity-CBfTSxqw.js +2 -0
- package/dist/web/assets/authedMedia-BTYt_tyu.js +2 -0
- package/dist/web/assets/beeApi-BHW8Tx1s.js +2 -0
- package/dist/web/assets/data-CmXvx3Mj.js +2 -0
- package/dist/web/assets/engines-CfdJODFj.css +1 -0
- package/dist/web/assets/format-BBZ8vFyT.js +2 -0
- package/dist/web/assets/forms-Coc7p2UF.css +1 -0
- package/dist/web/assets/hivePush-DZJDokj7.js +2 -0
- package/dist/web/assets/impactModel-MY1OFuiP.js +2 -0
- package/dist/web/assets/index-B6qKm1NW.js +13 -0
- package/dist/web/assets/index-BvKyT1X7.css +1 -0
- package/dist/web/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/web/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/web/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/web/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/web/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/web/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/web/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/web/assets/lead-BL_P_kri.css +1 -0
- package/dist/web/assets/model-BIQy5IVG.js +2 -0
- package/dist/web/assets/modelsApi-PUSySRQw.js +2 -0
- package/dist/web/assets/newDotModel-BaLLyw57.js +2 -0
- package/dist/web/assets/onboarding-bfKqnM4Z.css +1 -0
- package/dist/web/assets/phone-Rs7FoyG0.css +1 -0
- package/dist/web/assets/phoneApi-BG_1-M-D.js +3 -0
- package/dist/web/assets/releaseModel-EynYMVOC.js +2 -0
- package/dist/web/assets/releaseNotesModel-A1Rtv3cV.js +2 -0
- package/dist/web/assets/reports-BWaA1HhM.js +37 -0
- package/dist/web/assets/reports-DXwdWQsB.css +1 -0
- package/dist/web/assets/router-W6nZsQ33.js +2 -0
- package/dist/web/assets/runs-BY0Owv93.css +1 -0
- package/dist/web/assets/shadowWeekModel-BUUiww09.js +2 -0
- package/dist/web/assets/storage-yvL36AWt.js +2 -0
- package/dist/web/assets/store-IqrqHuFR.js +2 -0
- package/dist/web/assets/testruns-BzIZ0cR0.css +1 -0
- package/dist/web/assets/testruns-DyaqX4ji.js +2 -0
- package/dist/web/assets/true-9Q68cs5b.js +2 -0
- package/dist/web/assets/true-DPGBpoir.css +1 -0
- package/dist/web/assets/ui-DcmhYyYp.js +13 -0
- package/dist/web/assets/ui-DxEDgbIx.css +1 -0
- package/dist/web/assets/usePauseDot-BV60ZVy1.js +2 -0
- package/dist/web/assets/usePauseDot-NrSzMI1C.css +1 -0
- package/dist/web/assets/usePush-Dsm-TjlG.js +2 -0
- package/dist/web/assets/useRefChips-CbafNx59.js +68 -0
- package/dist/web/assets/useRestoreDot-D0B6W82H.js +2 -0
- package/dist/web/assets/view-worker-pyeVAhUT.js +2 -0
- package/dist/web/assets/workflowUi-QYsd3n9J.js +2 -0
- package/dist/web/favicon.png +0 -0
- package/dist/web/icon-192.png +0 -0
- package/dist/web/icon-512.png +0 -0
- package/dist/web/icon-maskable-512.png +0 -0
- package/dist/web/index.html +45 -0
- package/dist/web/manifest.webmanifest +23 -0
- package/dist/web/mascots/argus-attention.svg +7 -0
- package/dist/web/mascots/argus-ok.svg +7 -0
- package/dist/web/mascots/argus-outage.svg +7 -0
- package/dist/web/mascots/argus-running.svg +7 -0
- package/dist/web/mascots/bolt-attention.svg +7 -0
- package/dist/web/mascots/bolt-ok.svg +7 -0
- package/dist/web/mascots/bolt-outage.svg +7 -0
- package/dist/web/mascots/bolt-running.svg +7 -0
- package/dist/web/mascots/echo-attention.svg +7 -0
- package/dist/web/mascots/echo-ok.svg +7 -0
- package/dist/web/mascots/echo-outage.svg +7 -0
- package/dist/web/mascots/echo-running.svg +7 -0
- package/dist/web/mascots/lens-attention.svg +7 -0
- package/dist/web/mascots/lens-ok.svg +7 -0
- package/dist/web/mascots/lens-outage.svg +7 -0
- package/dist/web/mascots/lens-running.svg +7 -0
- package/dist/web/mascots/moss-attention.svg +7 -0
- package/dist/web/mascots/moss-ok.svg +7 -0
- package/dist/web/mascots/moss-outage.svg +7 -0
- package/dist/web/mascots/moss-running.svg +7 -0
- package/dist/web/mascots/nit-attention.svg +7 -0
- package/dist/web/mascots/nit-ok.svg +7 -0
- package/dist/web/mascots/nit-outage.svg +7 -0
- package/dist/web/mascots/nit-running.svg +7 -0
- package/dist/web/mascots/nova-attention.svg +7 -0
- package/dist/web/mascots/nova-ok.svg +7 -0
- package/dist/web/mascots/nova-outage.svg +7 -0
- package/dist/web/mascots/nova-running.svg +7 -0
- package/dist/web/mascots/penn-attention.svg +7 -0
- package/dist/web/mascots/penn-ok.svg +7 -0
- package/dist/web/mascots/penn-outage.svg +7 -0
- package/dist/web/mascots/penn-running.svg +7 -0
- package/dist/web/mascots/pip-attention.svg +7 -0
- package/dist/web/mascots/pip-ok.svg +7 -0
- package/dist/web/mascots/pip-outage.svg +7 -0
- package/dist/web/mascots/pip-running.svg +7 -0
- package/dist/web/mascots/ward-attention.svg +7 -0
- package/dist/web/mascots/ward-ok.svg +7 -0
- package/dist/web/mascots/ward-outage.svg +7 -0
- package/dist/web/mascots/ward-running.svg +7 -0
- package/dist/web/sw.js +98 -0
- package/dist/webhook-seen.js +53 -0
- package/dist/webhook-seen.js.map +1 -0
- package/dist/webhooks.js +625 -0
- package/dist/webhooks.js.map +1 -0
- package/dist/zip.js +63 -0
- package/dist/zip.js.map +1 -0
- package/docs/API-V2.md +532 -0
- package/docs/CHAT-EVAL.md +130 -0
- package/docs/CHAT-UI.md +416 -0
- package/docs/CONNECTIONS.md +89 -0
- package/docs/DATA-MODEL.md +518 -0
- package/docs/DEPLOY.md +577 -0
- package/docs/DOGFOOD-LEDGER.md +81 -0
- package/docs/GITHUB.md +148 -0
- package/docs/INTEGRATION-MODEL.md +200 -0
- package/docs/LEAD-DOT.md +553 -0
- package/docs/LIST-PATTERNS.md +52 -0
- package/docs/MULTI-REPO.md +766 -0
- package/docs/PARITY.md +276 -0
- package/docs/PR-REVIEW-QA.md +1266 -0
- package/docs/PR-REVIEW.md +357 -0
- package/docs/SANDBOX.md +320 -0
- package/docs/SETUP.md +776 -0
- package/docs/SLACK.md +80 -0
- package/docs/STAGES.md +619 -0
- package/docs/TRACE-MAP.md +89 -0
- package/docs/TRACKERS.md +225 -0
- package/docs/VOICE.md +36 -0
- package/docs/tinybee/00-README.md +45 -0
- package/docs/tinybee/01-PRD.md +216 -0
- package/docs/tinybee/02-architecture-pairing.md +199 -0
- package/docs/tinybee/03-local-agent.md +222 -0
- package/docs/tinybee/04-local-setup-ui.md +128 -0
- package/docs/tinybee/05-mobile-app-ux.md +199 -0
- package/docs/tinybee/06-environments-and-delivery.md +148 -0
- package/docs/tinybee/07-coding-agent-handoff.md +116 -0
- package/docs/tinybee/OPEN-QUESTIONS.md +26 -0
- package/docs/tinybee/PROGRESS.md +134 -0
- package/package.json +111 -4
package/docs/SANDBOX.md
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# Test runners
|
|
2
|
+
|
|
3
|
+
A dot runs your Playwright tests after a merge, on a PR, and when you ask it in chat. The dot's `runner` field says where the tests run:
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
{
|
|
7
|
+
"mode": "local",
|
|
8
|
+
"setup": "npm ci --no-audit --no-fund\nnpx playwright install chromium\nnpm run build",
|
|
9
|
+
"command": "npx playwright test --grep @smoke",
|
|
10
|
+
"smokeGrep": "@smoke"
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
| Field | Default | Purpose |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `mode` | | `local`, `docker`, or `demo` |
|
|
17
|
+
| `setup` | unset | Install and build steps that run through the shell before the tests, see [Setup steps](#setup-steps) |
|
|
18
|
+
| `command` | `npx playwright test` | Test command. It runs without a shell, see [Test command](#test-command) |
|
|
19
|
+
| `workdir` | unset | A checkout on the localdost host. Unset: localdost clones the commit under test into a temp folder |
|
|
20
|
+
| `workingDirectory` | unset | A folder inside the checkout, such as `apps/web`, where setup and the test command run. Set from a CI workflow's `working-directory`. No absolute path and no `..` |
|
|
21
|
+
| `copyFiles` | unset | Files of the `workdir`, relative paths such as `.env`, copied into the temporary worktree of a run before the setup steps, see [Copy files](#copy-files) |
|
|
22
|
+
| `passEnv` | unset | Host variables, each starting with `LOCALDOST_TEST_`, that carry the sign-in of the app under test. The tests see them as `TEST_<name>`, see [Test login](#test-login) |
|
|
23
|
+
| `image` | `mcr.microsoft.com/playwright:v<version>-noble` | Docker image, with `<version>` from the checkout's `@playwright/test` |
|
|
24
|
+
| `smokeGrep` | `@smoke` | Text that marks a spec as a smoke spec |
|
|
25
|
+
| `trustForks` | `false` | Runs tests for fork PRs too, see [Fork safety](#fork-safety) |
|
|
26
|
+
|
|
27
|
+
`testBranches` is a field of the dot itself, not of `runner`: a list of branches besides the default branch that run post-merge tests, see [Test branches](#test-branches). The dot dialog has it under **Test branches** in the Test runner section.
|
|
28
|
+
|
|
29
|
+
localdost appends `--reporter=json`, the spec files, and `--output=<temp folder>` to the command, and passes `BASE_URL` from the dot's `baseUrl` or the PR's preview URL. Your Playwright config should read `process.env.BASE_URL`. A run times out after 10 minutes.
|
|
30
|
+
|
|
31
|
+
## Setup steps
|
|
32
|
+
|
|
33
|
+
`setup` holds the steps that prepare the checkout: install dependencies, install browsers, build the app. Write one step per line, or join them with `&&`. Each step runs through `sh -c` in the workdir, in order, and the first step that fails stops the run before the tests start. Pipes, redirects, and `||` work inside a step.
|
|
34
|
+
|
|
35
|
+
The output of every step streams to the run's live terminal, and its tail is kept in the report next to the test output. Setup has its own time budget of 15 minutes (`LOCALDOST_SETUP_TIMEOUT_MS`), on top of the 10 minutes for the tests.
|
|
36
|
+
|
|
37
|
+
An install step that only reads the lockfile (`npm ci`, `npm install` or `npm i` with flags only, `pnpm install`, `yarn`, `yarn install`, `bun install`) is cached. After a successful install, localdost copies `node_modules` to `<LOCALDOST_DATA_DIR>/runner-cache/<key>/`, where the key hashes the lockfile, the step text, the platform, and the Node major version. A later run with the same key copies `node_modules` back and skips the install, and a workdir whose `node_modules` already carry the key skips the copy too. On macOS and Linux the copy uses copy-on-write where the file system has it. The four most recently used entries are kept. Every other step, such as a build, runs on every attempt. A step that adds a package (`npm install left-pad`) or holds a redirect is never cached.
|
|
38
|
+
|
|
39
|
+
Setup runs with the same filtered environment as the tests (see [Local](#local)), so a private registry token in `NPM_TOKEN` does not reach `npm ci`. Use a registry config the host user already has, outside the repo.
|
|
40
|
+
|
|
41
|
+
## Test command
|
|
42
|
+
|
|
43
|
+
`command` runs without a shell. localdost splits it into words with shell quoting rules: single quotes, double quotes, and backslash escapes work, and leading `NAME=value` words set environment variables. It then appends `--reporter=json`, the spec files, and `--output=<temp folder>`.
|
|
44
|
+
|
|
45
|
+
A shell operator in the command (`&&`, `||`, `|`, `;`, `&`, `<`, `>`, a backtick, or `$(`) is an error. The dot dialog and `PATCH /api/dots/:id` refuse it with a message that points to Setup steps, and a dot saved before this check gets the same message as a "tests did not run" result. Move install and build steps into `setup` and keep only the test command here.
|
|
46
|
+
|
|
47
|
+
## Tests that did not run
|
|
48
|
+
|
|
49
|
+
When setup fails, the command is not valid, or the command ends without a Playwright JSON report, the tests did not run. The report carries `notRun` with the stage (`setup`, `command`, or `report`), one sentence on why, the exit code, and the command output. It counts no failed test and is not retried.
|
|
50
|
+
|
|
51
|
+
The verdict is `environment_failure`. Its headline reads "Tests did not run: a setup step failed" (or the command or report reason), and the summary says that the result says nothing about whether the change works, then gives the reason, the fix, and the redacted tail of the output. The model does not write this verdict, so a PR comment never reads a missing report as a product or test failure. The GitHub check concludes neutral, and the QA review section reads "tests: did not run".
|
|
52
|
+
|
|
53
|
+
## Run tests per repo
|
|
54
|
+
|
|
55
|
+
A repo of a dot has a **Run tests** switch, on by default for an app repo (`runTests: false` on the repo entry turns it off, KAT-361). Turn it off for a repo that has no Playwright suite, such as a Python or Java back end that shares a dot with a front end. A PR or a merge of that repo still gets the review, the report, and the check, and no test command starts: no setup step, no AI-Vision case, no generated spec. The run step reads "Tests skipped: Run tests is off for acme/api", the report has `notRun.stage` `skipped`, and the verdict is a pass with no test counts, the same as a docs-only change. It is never "Tests did not run": the run page shows "Tests skipped" with the reason in the summary card and in the Tests section, with no warning and no runner advice. The review still reads the results of the PR's own CI jobs for that repo. An Issues only repo is not watched at all, and a Tests repo is the tests, so neither has the switch. The switch decides about the app repo's own suite only: a Tests repo of the dot still runs for a PR or a merge of that repo, see [Tests repo](#tests-repo).
|
|
56
|
+
|
|
57
|
+
The switch is on the repo form of the dot dialog (Sources, under the PR scope) and on each App card of the Repos step. A dot with several app repos has one switch for each in the dot dialog, named by its repo, and the dialog saves them through `repos`; the note at the top of the Test runner section says its settings are idle only when no app repo is tested. A dot with several app repos picks the repo from the event, so a front end with the switch on is tested and a back end with it off is not. Try it and a rerun asked for by a person ignore the switch: they run what you ask for. `PATCH /api/dots/:id` takes `repo.runTests` or `repos[].runTests`, answers 400 for a value that is not a boolean or for a test or docs repo, and stores only `false`.
|
|
58
|
+
|
|
59
|
+
## Tests repo
|
|
60
|
+
|
|
61
|
+
A team often keeps its end-to-end suite in a repo of its own, and its app repos have no Playwright suite. A repo of a dot with the role **Tests** holds that suite. When a PR of an app repo is checked, or an app repo is tested after a merge, the dot runs the suite of the Tests repo after the app repo's own tests, against the same app, and puts the result in the same report. The app repo's Run tests switch does not hold it back: an app repo with Run tests off still gets the Tests repo run (KAT-86). The setup side of this is in [SETUP.md](SETUP.md#tests-repo); this section is what a run does on the localdost host.
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"repo": "acme/shop-e2e",
|
|
66
|
+
"role": "test",
|
|
67
|
+
"test": { "framework": "playwright", "dir": "e2e", "setup": "npm ci", "label": "Shop", "passEnv": ["LOCALDOST_TEST_USER"] }
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
| `test` field | Default | Purpose |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| `framework` | | `playwright` runs. `cypress`, `webdriverio`, `pytest`, `junit` and `katalon` are accepted and not run yet: the report says "which localdost cannot run yet" |
|
|
74
|
+
| `command` | `npx playwright test` | Test command, without a shell, like the dot's own. localdost appends the reporter, the spec files, the title filter and `--output` |
|
|
75
|
+
| `dir` | the repo root | The folder with the Playwright project, such as `e2e`. No absolute path and no `..` |
|
|
76
|
+
| `setup` | the default install | Install and build steps for the Tests repo, run through `sh -c` in `dir` before the tests. The app repo's `runner.setup` never runs for a Tests repo. Without `setup`, a checkout with a `package.json` gets the default install and the install cache, as a clone does |
|
|
77
|
+
| `ref` | `default` | Which version of the Tests repo runs: `default`, `match_branch`, or `{ "fixed": "<branch or tag>" }`, see [Which version of the tests](SETUP.md#tests-repo) |
|
|
78
|
+
| `baseUrlEnv` | `["BASE_URL"]` | Variables that carry the URL of the app under test. At most 5 names in capital letters that end in `_URL` or are `BASE_URL` or `BASEURL`; `PATH`, `NODE_OPTIONS` and names that look like a credential are refused. An admin setting |
|
|
79
|
+
| `passEnv` | the dot's `runner.passEnv` | Host variables that carry the test login, `LOCALDOST_TEST_` names only, passed as `TEST_<name>`, see [Test login](#test-login). With none listed, the dot's own list is used |
|
|
80
|
+
| `label` | unset | The product the tests cover, up to 40 characters, for the report line "Ran 24 True Platform tests from true-dogfood-tests" |
|
|
81
|
+
| `areas` | unset | Which tests cover which area of a change, see [SETUP.md](SETUP.md#tests-repo) |
|
|
82
|
+
| `smokeGrep` | `@smoke` | The text of the quick tests that run with a narrowed selection |
|
|
83
|
+
| `on` | `["pr_check", "post_merge"]` | The jobs that run the Tests repo |
|
|
84
|
+
|
|
85
|
+
**The run.** localdost asks GitHub for the commit of the chosen ref (the event never names a commit), fetches that commit into a cache folder, `<data folder>/test-repos/<owner>__<name>`, and adds a git worktree of it at `<data folder>/worktrees/<run id>-a<attempt>-tests`, the folder the app repo's worktrees use. A worktree is a clean checkout: none of the files of another folder are copied in, and `copyFiles` of the dot does not apply. The runner then checks that the worktree is on the commit GitHub named, and a count is shown only then. The app repo is never cloned for this run: only its URL crosses over, the PR's preview or the dot's base URL. The worktree is removed when the run ends, after a failure, a cancel or a timeout, and the server removes leftovers of a crash at start with the other worktrees. A fetch that cannot reach GitHub fails the job, which runs again after a short wait, like a clone of the app repo. Runs of one Tests repo share its cache folder, and git allows one shallow fetch into a folder at a time, so localdost lets them take turns: a second run waits for the first fetch and checkout instead of failing.
|
|
86
|
+
|
|
87
|
+
The run uses the dot's mode (local or Docker), image and video setting, and the 10 minute test timeout and 15 minute setup timeout. The report of one run holds the cases of the app repo's own tests and of each Tests repo. Each case of a Tests repo names its file `owner/name:path`, with the repo in lower case and the path in the repo (Playwright reports a spec by its path under its `testDir`; localdost rewrites it to the path in the repo, so the link in a defect and the file a retry filters on are the real ones). The same spec file of two repos is two cases, with their own results, flaky memory and bug signatures. A failing spec is retried twice, in the Tests repo, as an app spec is. Screenshots, video and trace of each test are artifacts of the run like any other.
|
|
88
|
+
|
|
89
|
+
**The login and the environment.** The suite gets the environment of a local run (the host environment minus every credential of the server, see [Local](#local)) or of a Docker run (nothing but the test login and `BASE_URL`), plus the test login from `passEnv`, renamed to `TEST_<name>`. A `test.passEnv` name must start with `LOCALDOST_TEST_`, as `runner.passEnv` names must, and a name that does not is refused at save and dropped at every run. `GITHUB_TOKEN` and a model key cannot reach the suite this way.
|
|
90
|
+
|
|
91
|
+
**When the Tests repo cannot be read.** A read of the Tests repo that fails does not stop the app repo's review: the batch shows as not run, with one sentence. A 401 says GitHub refused the credentials. A 403 says GitHub denied access and asks for read access for the App or token. A 403 that GitHub sends for a spent rate limit (a `Retry-After` header, or the words rate limit or secondary limit) and a 429 say that GitHub is throttling requests and that localdost retries on the next run: no permission is missing. A 5xx or a network error says GitHub did not answer.
|
|
92
|
+
|
|
93
|
+
**Fork safety.** A Tests repo run for a fork PR never gets the environment of this machine. A fork PR does not run the Tests repo in local mode: the batch is skipped with the step "Tests repo skipped" and a sentence in the report, and nothing is fetched. In Docker mode it runs only when no test login would go with it: when the Tests repo's login list (or, without one, the dot's) names a variable, the batch is skipped as well, with a sentence that says so, because the page under test is the fork's preview and its author controls it. A Docker run for a fork that has no login list gets nothing from this machine: the container holds only the report paths and `BASE_URL`. The description of a fork PR and the name of its branch never pick the ref of the Tests repo; only the fixed ref or the default branch of the settings apply. A PR of the repo itself is not a fork.
|
|
94
|
+
|
|
95
|
+
**Runs of the Tests repo itself.** A PR or a merge of the Tests repo does not start this run yet: such an event gets CI failure triage only. See [MULTI-REPO.md](MULTI-REPO.md#5-build-tasks) task T5.
|
|
96
|
+
|
|
97
|
+
## Try it
|
|
98
|
+
|
|
99
|
+
The Test runner section of the dot dialog has a **Try it** button. It runs the setup steps and the test command once with the settings in the form, saved or not, and shows the outcome: tests passed, tests failed, or tests did not run and why, plus whether the install came from the cache and the command output. A try is not a run: it posts nothing, keeps no artifacts, and makes no verdict.
|
|
100
|
+
|
|
101
|
+
The API is `POST /api/runner/try` with `{ dotId?, runner, repo?, baseUrl? }`, which answers `202 { id }`, then `GET /api/runner/try/:id` for the state, the output lines so far, and the result. One try runs at a time; a second request gets `409`. A try without a workdir clones the repo's default branch.
|
|
102
|
+
|
|
103
|
+
## Which specs run
|
|
104
|
+
|
|
105
|
+
For a merge or a PR, the dot picks specs from three sources: specs whose file name contains a changed area (`src/checkout/...` picks `checkout.spec.ts`), specs the diff itself touched, and every spec that contains the smoke text. When the PR review names an existing test in its What to test list, that spec runs too. When nothing matches, the full suite runs.
|
|
106
|
+
|
|
107
|
+
Failing specs are retried up to two times. A spec that passes on a retry counts as flaky, and the dot saves it to memory, so a later verdict can tell a flaky test from a real break.
|
|
108
|
+
|
|
109
|
+
## Modes
|
|
110
|
+
|
|
111
|
+
### Local
|
|
112
|
+
|
|
113
|
+
The setup steps and the command run as child processes on the localdost host. With `workdir` set, it runs in that folder: the dot tests what is checked out there. A run for a commit (a PR head or a merge) counts only if that folder is on the commit; see Tests for the PR head below. Without `workdir`, localdost clones the repo at the commit under test into a temp folder and deletes it after the run. A local run in a clone needs dependencies and browsers. Without `setup`, a clone that has a `package.json` first runs the default install, `npm ci --no-audit --no-fund || npm install --no-audit --no-fund`, with browser downloads off and dev dependencies on, and the install cache makes the second run fast. The localdost `runner` image already has the browsers. On a host without them, put `npx playwright install chromium` in `setup`; setting `setup` replaces the default install, so list `npm ci` there too. A `workdir` is your own checkout and gets no default install.
|
|
114
|
+
|
|
115
|
+
The child process, and every setup step, gets the host environment minus every variable that holds a credential of the server (KAT-361): names that contain `TOKEN`, `SECRET`, `PASSWORD`, `PRIVATE`, `API_KEY`, or `COOKIE`, names that end in `_KEY` or `_HEADERS`, and names that start with `AWS_`, `GITHUB_`, `JIRA_`, `LINEAR_`, `ANTHROPIC_`, `NTFY_`, `OPENAI_`, `SLACK_`, `ELEVENLABS_`, or `LOCALDOST_`. The header variable of each connection goes too, whatever it is called: the one a preset names (`KATALON_MCP_HEADERS` for Connect True Platform) and the `headersSecretRef` of every saved connection. The AI-Vision sign-in variables go too, under the default names (`AIVISION_INTERNAL_TOKEN`, `VEESAN_SESSION_COOKIE`, `VEESAN_USER`, `VEESAN_PASSWORD`) and under the names any dot gives in `runner.aivision` (`tokenEnv`, `cookieEnv`, `userEnv`, `passwordEnv`), archived dots included, because those names can be anything under `AIVISION_` or `VEESAN_`. `src/runner/host-env.ts` lists the names the server reads, and `test/runner-env.test.ts` starts a child process and checks it sees none of them. The AI-Vision CLI gets the same list. Only variables are filtered. The test process still has `HOME` and `PATH`, so PR code can use a login that lives in a file of the host user: the GitHub CLI login (`gh auth token`), or the Claude or Codex CLI login that bills a personal account. Test code runs with the host user's file access, so use local mode only for repos you trust, and see [Test login](#test-login) for the one set of variables a dot may pass on.
|
|
116
|
+
|
|
117
|
+
`PORT` and `HOST` of the localdost server are not passed on, because a test project that reads `PORT` would start its app on the port of localdost. When the dot's base URL is on this machine and names a port (`http://localhost:3000`), the run sets `PORT=3000` and `HOST=localhost`, so a project that starts its own app finds it where the base URL points. A `PORT=` or `HOST=` word at the start of the command wins.
|
|
118
|
+
|
|
119
|
+
When the command is `npm run <script>`, localdost adds the `--` npm needs to pass its options on only if the script ends in `playwright test`. Any other script runs with the arguments you wrote.
|
|
120
|
+
|
|
121
|
+
### Docker
|
|
122
|
+
|
|
123
|
+
The test runs in a container from the Playwright image, through the host's Docker daemon:
|
|
124
|
+
|
|
125
|
+
- The checkout is mounted read-only at `/src` and copied into the container without `node_modules`, `.git`, and credential files (`.env*`, `.npmrc`, `.netrc`, `.aws`, `.ssh`, `*.pem`, `*.key`, `credentials.json`, and more).
|
|
126
|
+
- The container runs the `setup` steps, each through `bash -c`, then the test command. Without `setup`, it runs `npm ci`, falling back to `npm install`. Docker runs do not use the install cache.
|
|
127
|
+
- Only `CI`, `BASE_URL`, the report paths, and the [test login](#test-login) cross into the container. No other host variable and no localdost credential.
|
|
128
|
+
- Limits: 4 GB of memory and 2 CPUs.
|
|
129
|
+
- `host.docker.internal` points to the host, so tests can reach an app that runs there.
|
|
130
|
+
- Docker covers your own specs and the test command. A test the model writes for a new scenario (the Playwright e2e engine, see [Generated Playwright specs](#generated-playwright-specs)) runs on the localdost host in every mode, not in the container. The dot form says so when Docker is picked.
|
|
131
|
+
|
|
132
|
+
The container has network access, because `npm ci` needs the registry and tests need the app. A private registry must come from the image, since `.npmrc` stays behind.
|
|
133
|
+
|
|
134
|
+
localdost needs to reach a Docker daemon. The Docker runner row on the Setup page detects it: when it shows Docker as not reachable, start Docker Desktop or the daemon and press **Check again**. On your machine that is Docker Desktop or the local socket. In Docker Compose, mount `/var/run/docker.sock` into the app container, as the comment in `compose.yml` shows. The socket gives the container root-equivalent control of the host, so mount it only on a machine dedicated to localdost. Railway has no Docker daemon.
|
|
135
|
+
|
|
136
|
+
### Demo
|
|
137
|
+
|
|
138
|
+
The run uses the bundled sample shop in `demo/sample-app` and its Playwright specs. A simulated merge turns on a seeded bug first, so one spec fails. The demo dot uses this mode.
|
|
139
|
+
|
|
140
|
+
## Test login
|
|
141
|
+
|
|
142
|
+
Tests for an app behind a sign-in need a user. Put the user's variables in the environment of the localdost server, and name them in `runner.passEnv`:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{ "mode": "local", "passEnv": ["LOCALDOST_TEST_USER", "LOCALDOST_TEST_PASSWORD"] }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Each name must start with `LOCALDOST_TEST_` and use capital letters, digits, and underscores, so a dot cannot forward `GITHUB_TOKEN`, a model key, or a connection header (KAT-361). The server checks it when you save and again on every run. A local run and its setup steps, and a Docker container, get each name that is set on the host with `LOCALDOST_TEST_` replaced by `TEST_`: `LOCALDOST_TEST_USER` reaches the test as `TEST_USER`. A name that is not set is not passed, and a `NAME=value` word at the start of the test command wins. At most 20 names.
|
|
149
|
+
|
|
150
|
+
The dot dialog has **Test login variables** in the Test runner section. It lists each name with what the test sees it as and whether the server has it set (`GET /api/runner/pass-env?names=A,B`). The answer holds names and a flag, never a value. After you set a variable on the host, restart the server: a process does not see a later change of its environment.
|
|
151
|
+
|
|
152
|
+
The values are masked as `[redacted]` in the report, the live output, and the error text, because Playwright's call log of a failed `fill()` prints the text it typed. A value shorter than 4 characters is not masked. A variable named for a user or an email (`TEST_USER`, `TEST_ADMIN_EMAIL`) is not masked either, so a user called `admin` does not blank out every `/admin/users` in an error line; a name that also says `PASS`, `SECRET`, `TOKEN`, or `KEY` is masked, and so is any name this rule does not know. Traces and videos of a failed test can still show what the page showed, so make the test user a low-privilege account made for this. Generated Playwright specs get no host variables at all. An AI-Vision case gets no test login either: `userEnv` and `passwordEnv` sign localdost in to the AI-Vision server, never to the app under test, so a case opens the app signed out unless the AI-Vision profile it runs under already holds a session.
|
|
153
|
+
|
|
154
|
+
## Live view
|
|
155
|
+
|
|
156
|
+
While a local or demo run is in progress, the run page shows each test step as it happens. localdost adds a step reporter and writes a wrapper config `.localdost-run-<run id>-<attempt>.config.ts` next to your Playwright config. The wrapper imports your config and turns on screenshots, traces, and video. Your config file stays as it is. Video is kept for tests that did not pass; to keep the video of every test, set **Keep video of** to Every test in the dot's Test runner settings (`runner.video: "on"`). A video mode your own config asks for stays. Docker runs keep no video. It is deleted when the run ends. Add `.localdost-run-*` to your repo's `.gitignore` in case the server stops mid-run.
|
|
157
|
+
|
|
158
|
+
With browser frames on, the wrapper also opens a DevTools port on Chromium projects and runs one worker, and the run page shows the page as the test drives it, about two frames per second. Frames are on by default for demo runs. Set `LOCALDOST_LIVE_FRAMES=1` for local runs. Docker runs show their log when the run ends and stream no frames.
|
|
159
|
+
|
|
160
|
+
## Artifacts
|
|
161
|
+
|
|
162
|
+
After each attempt, localdost copies screenshots, traces, videos, and the JSON report into `<LOCALDOST_DATA_DIR>/artifacts/<run id>/`. The runner records a trace of every test (`--trace=on`) and reads the pages each test visited from it into `observations.jsonl`, with one screenshot per page per test, for the Traceability map ([TRACE-MAP.md](TRACE-MAP.md#capture)). It then deletes the traces of tests that passed, so the run keeps traces only of tests that did not pass. The run page lists them, and `GET /api/runs/:id/artifacts` returns the list. Files are served from `/artifacts/<run id>/<file>` behind the same bearer token as the API, with a content security policy that blocks scripts. Open a trace in `npx playwright show-trace` or at trace.playwright.dev.
|
|
163
|
+
|
|
164
|
+
### Evidence per test
|
|
165
|
+
|
|
166
|
+
The report names the files of each test in `cases[].evidence`: `screenshots` (`{ name, step }`, in the order taken), `video`, and `trace`, all artifact names. On the run page, each test is a row under Steps. Open it to see its video in a player, its screenshots, and its trace. The Browser tab is a timeline of the frames of all tests; pick a frame to see it, and choose **Show test in Steps** to jump to the row of its test. Artifact files support byte ranges (`Range`), so the video player can seek.
|
|
167
|
+
|
|
168
|
+
localdost does not delete artifacts on its own. Remove old run folders when the disk fills.
|
|
169
|
+
|
|
170
|
+
## Cancel and rerun
|
|
171
|
+
|
|
172
|
+
`POST /api/runs/:id/cancel` stops a running test process. `POST /api/runs/:id/rerun` queues the run again. A run whose server stopped mid-run ends as interrupted, and a rerun picks it up (the app shows Retry).
|
|
173
|
+
|
|
174
|
+
On SIGTERM or SIGINT the server stops claiming jobs, marks every running run interrupted, and kills the process group of every git clone, setup step, test command, AI-Vision CLI, and model CLI it started, then exits. The process is gone within 10 seconds whatever is still running, and a second signal exits at once. Runs a crashed process left running are marked interrupted at the next boot. Queued jobs wait until the connections, the GitHub client, the model, and the HTTP server have loaded, so a run that starts during a restart does not fail its setup. A setup step that fails in under a second with no output at all is retried once; the failure report carries the exit code, signal, or spawn error and the last lines the step printed.
|
|
175
|
+
|
|
176
|
+
## Tests for the PR head
|
|
177
|
+
|
|
178
|
+
A dot with a `workdir` that is a git checkout of the PR's repository (one of its remotes names the repo) runs a PR check of that repository in a temporary git worktree at the PR head commit, so the test count belongs to the PR and not to whatever the folder has checked out (KAT-284). localdost fetches the commit, or `refs/pull/<n>/head`, when the folder does not have it. The worktree is a clean checkout: it gets the same install as a fresh clone (your `setup` steps, else the default install, with the install cache) and none of the untracked or ignored files of your folder, such as `.env` or a build output, so put what the tests need in `setup`, and list the config files that git does not carry in `copyFiles` ([Copy files](#copy-files)). A `workdir` inside the repo maps to the same sub folder of the worktree.
|
|
179
|
+
|
|
180
|
+
A merge run (a push to the base branch, or a merged PR) works the same way: the merge commit is on the base branch of the repo itself, so it is trusted, and its tests run in a worktree at that commit. localdost fetches the commit, or the base branch, when the folder does not have it. A range a person asked for on demand can name any commit, so it keeps the rule below: the folder itself must be on the commit.
|
|
181
|
+
|
|
182
|
+
The worktree lives in `<data folder>/worktrees/<run id>-a<attempt>`, never in your repo folder, and is removed when the run ends, also after a failure, a cancel, or a timeout. The checkout, branch, index, and files of your folder do not change; git only adds and removes a worktree entry under its `.git/worktrees`. The artifact cap, the disk watch, and the install cache never delete a worktree a run holds, and the server removes leftovers of a crash at start.
|
|
183
|
+
|
|
184
|
+
After the worktree is made, the runner checks that it is on the head commit, and a count is reported only then. When the folder is not a checkout of the repo, the run needs the folder itself to be on the commit. When the commit cannot be fetched, no tests run for it and the report says so.
|
|
185
|
+
|
|
186
|
+
A PR from a fork gets no own run (next section): the report says that no tests have run for the commit, and the results come from the CI of the PR.
|
|
187
|
+
|
|
188
|
+
## Copy files
|
|
189
|
+
|
|
190
|
+
A worktree has only what git tracks, so an untracked `.env` of your working folder is not there, and tests that read it fail. List such files in the dot's `runner.copyFiles` (**Copy files** in the Test runner section of the dot dialog, comma separated):
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{ "mode": "local", "workdir": "/home/me/shop-web", "copyFiles": [".env", "config/.env.ci"] }
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Before the first setup step, localdost copies each listed file from the `workdir` to the same place in the worktree. The paths are relative to the `workdir`; for a `workdir` inside the repo, the worktree has the same sub folder. Nothing else of your folder is copied, and your folder is not changed. The rules, which the API and the dialog check on save (a bad value is a 400) and the runner checks again on every run:
|
|
197
|
+
|
|
198
|
+
- Only relative paths of files. An absolute path, a drive letter, `~`, `..`, a backslash, a path inside `.git` (in any letter case, as `.GIT` is the same folder on a default macOS volume), and a folder are refused. At most 20 files, and a file larger than 1 MB is skipped.
|
|
199
|
+
- The real path of the file, after symlinks, must be inside the `workdir`. A symlink that leads out of the folder is not followed and the file is skipped; a symlink that stays inside the folder is copied as the file it points to.
|
|
200
|
+
- The copy never writes through a symlink of the worktree. If the commit has a symlink where a listed file or one of its folders should go, that file is skipped. This includes the folders from the worktree root down to the `workdir` (`apps/web`): a symlink on that path skips every file, and the real path of the destination must stay inside the worktree.
|
|
201
|
+
- A file that does not exist is skipped, and the run goes on. Each copied or skipped file has one line in the setup output of the run ("copyFiles: copied .env into the worktree.", "copyFiles: .env.test is not in the working folder, skipped."), never its contents.
|
|
202
|
+
- An existing file of the worktree with the same path is replaced by the file of your folder.
|
|
203
|
+
|
|
204
|
+
Only runs in a worktree copy files: PR checks and merge runs of a `workdir` that is a checkout of the repo. A run in a fresh clone has no working folder to copy from. Docker mode copies the worktree into the container without credential files (`.env*` and more, see [Docker](#docker)), so a `.env` still does not reach the container; pass what the tests need in `setup` or the image.
|
|
205
|
+
|
|
206
|
+
When a run in a worktree did not pass (a test failed, or the tests did not run) and the `workdir` has untracked dotfiles that are not in `copyFiles` (`.env`, `.env.local`, ignored files included), the report carries a `hint` that says untracked files were not copied and points to `runner.copyFiles`. The `hint` holds no file name, so the "tests did not run" comment and the PR comment can repeat it on a public repo. The names (`hintFiles`) are shown on the run page under Tests only. A passing run has no hint, and neither has a folder without such dotfiles.
|
|
207
|
+
|
|
208
|
+
## Test branches
|
|
209
|
+
|
|
210
|
+
A merge or push runs post-merge tests only on the default branch of the repository, as GitHub reports it. To test release branches too, list them in the dot's `testBranches` (`["release/1.0", "release/2.0"]`, or comma separated in the dot dialog). Empty or unset means the default branch only. A name is a plain branch name: no `refs/heads/` prefix and no wildcards, at most 20 names, and names are case sensitive. `POST /api/dots` and `PATCH /api/dots/:id` answer 400 for anything else.
|
|
211
|
+
|
|
212
|
+
A merge or push to a listed branch is picked up like one to the default branch (a webhook, or the poller, which then also reads the new commits of each listed branch). The run is checked before anything is checked out:
|
|
213
|
+
|
|
214
|
+
- The branch the event names counts only when it is listed (or is the default branch). The event is not trusted for anything else, so a forged event cannot name a branch of its own.
|
|
215
|
+
- The commit must be an ancestor of that branch as fetched from the repository. With a `workdir`, localdost fetches the branch into a private ref and asks git; without one, it asks GitHub to compare the commit with the branch. A commit of another branch, an unpushed commit, or a branch that cannot be fetched is not run and no count is shown.
|
|
216
|
+
- A branch that is not listed keeps the refusal. The commit is still checked against the default branch only, and the "tests did not run" reason names the branch and the setting, for example "It was sent for branch release/1, which is not the default branch (main) and is not listed in the dot's Test branches setting (testBranches), so only the default branch is tested."
|
|
217
|
+
|
|
218
|
+
Everything else follows the default branch run: the worktree, the setup steps, the install cache, and the report. Generated specs that the dot proposes as a pull request after a merge target the listed branch the merge went to.
|
|
219
|
+
|
|
220
|
+
## Fork safety
|
|
221
|
+
|
|
222
|
+
A PR from a fork carries code from someone outside your repo. When a dot would clone and run that code, it skips the test run and records "Tests did not run: fork pull request" on the run. The PR comment and the check say "Tests did not run: this PR comes from a fork. Ask a maintainer to check it again." The rule for the Tests repo run of a fork PR is in [Tests repo](#tests-repo). This applies in local and docker modes without a `workdir`. With a `workdir`, the runner refuses a fork PR as well: the tests would run in your folder, and a count for other code is never reported. The report has the same line. Set `runner.trustForks: true` on the dot to run fork PRs anyway, for example when only your team can open PRs.
|
|
223
|
+
|
|
224
|
+
The PR review still runs for fork PRs, because it only reads files and runs nothing (KAT-384). The report is not a pass: it says the tests did not run, and the results of the CI of the PR show in it once that CI has run.
|
|
225
|
+
|
|
226
|
+
## AI-Vision cases
|
|
227
|
+
|
|
228
|
+
A dot can also run natural-language browser cases next to Playwright, on an AI-Vision server (Veesan) or the open-source Midscene CLI. The cases come from the PR review: each What to test item of type e2e or exploratory that has no existing test becomes one case, and test ideas from a ticket review of a ticket the PR names (in its title, branch, or body) fill the rest. Each case is one YAML file with a start URL and `ai`, `aiAssert`, and `aiQuery` steps that describe what the user does and sees. The start URL is the PR preview URL or the dot's `baseUrl`, joined with the first route of the item's impact area. The cases run in `pr_check` and `post_merge` jobs, and their results merge into the same report and verdict as the Playwright results, as `aivision/<item id>.yaml`.
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{ "mode": "local", "workdir": "/home/me/shop-web", "aivision": { "backend": "server", "serverUrl": "http://localhost:5880", "profile": "smoke" } }
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
| Field | Default | Purpose |
|
|
235
|
+
|---|---|---|
|
|
236
|
+
| `backend` | | `server`, `cli`, or `midscene` |
|
|
237
|
+
| `enabled` | `true` | Turns the cases off without removing the settings |
|
|
238
|
+
| `on` | `["pr_check", "post_merge"]` | Jobs that run the cases |
|
|
239
|
+
| `maxCases` | `5` | Upper bound on cases per run |
|
|
240
|
+
| `timeoutMs` | 15 minutes | Per run |
|
|
241
|
+
| `serverUrl` | the AI-Vision server on the Setup page (`AIVISION_SERVER_URL`) | `server`: base URL of the AI-Vision server |
|
|
242
|
+
| `profile` | unset | `server`: run profile to bind |
|
|
243
|
+
| `tokenEnv`, `cookieEnv` | `AIVISION_INTERNAL_TOKEN`, `VEESAN_SESSION_COOKIE` | `server`: names of the env vars that hold an internal token or a signed-in session cookie |
|
|
244
|
+
| `userEnv`, `passwordEnv` | `VEESAN_USER`, `VEESAN_PASSWORD` | `server`: names of the env vars for localdost' own sign-in to the AI-Vision server on a 401. They never sign in to the app under test |
|
|
245
|
+
| `checkout` | unset | `cli`: AI-Vision checkout; the CLI is `packages/cli/bin/veesan` in it. `VEESAN_CLI` wins |
|
|
246
|
+
| `midsceneVersion` | `1.14.0` | `midscene`: exact `@midscene/cli` version for `npx` |
|
|
247
|
+
| `casesDir` | temp folder | `cli` and `midscene`: where the YAML is written |
|
|
248
|
+
| `passEnv` | `[]` | `cli` and `midscene`: extra env var names passed to the CLI |
|
|
249
|
+
|
|
250
|
+
The dot stores only env var names, never a token, cookie, or password. The four `server` env refs must name a variable that starts with `AIVISION_` or `VEESAN_`; any other name fails the run, so a dot config cannot send `GITHUB_TOKEN` or a model key to the server URL it names. When an AI-Vision server is connected on the Setup page, the default refs go only to that server; a dot that points at another server must name its own refs to send credentials there.
|
|
251
|
+
|
|
252
|
+
### Server backend
|
|
253
|
+
|
|
254
|
+
localdost writes each case into the server's tests repo under the `localdost/` category, with a file name that stays the same for the same dot and content, so a rerun overwrites it. Then it starts one run over all cases, polls it every 3 seconds, and streams each finished step and its screenshot to the run page. A failed case carries the failed step, its error, and a link to the server's report. Each HTTP request times out after 60 seconds, and screenshots over 10 MB, or past 200 MB for one run, are skipped. When the server stops a run to ask a question, localdost stops the run and reports the cases as skipped, since nobody is there to answer. Cancel on the run page stops the server run.
|
|
255
|
+
|
|
256
|
+
### CLI and Midscene backends
|
|
257
|
+
|
|
258
|
+
localdost writes the YAML into a temp folder, or `casesDir`, and runs the CLI once: `<cli> --summary <file> --continue-on-error --files <yaml...>`. It reads the summary JSON for the verdicts and keeps each case's HTML report as a run artifact. The CLI output streams to the run log.
|
|
259
|
+
|
|
260
|
+
- `cli` runs the AI-Vision CLI from `VEESAN_CLI` or `<checkout>/packages/cli/bin/veesan` with the Node that runs localdost.
|
|
261
|
+
- `midscene` runs `npx --yes @midscene/cli@<version>`. Set the model with the Midscene variables on the localdost host, for example `MIDSCENE_MODEL_NAME`, `MIDSCENE_MODEL_BASE_URL`, and `MIDSCENE_MODEL_API_KEY`. Puppeteer needs a Chrome; set `PUPPETEER_EXECUTABLE_PATH` to use an installed one.
|
|
262
|
+
|
|
263
|
+
The CLI gets the host environment minus credentials, by the same rule and the same list as a local Playwright run (see [Local](#local)). Variables that start with `MIDSCENE_` or `VEESAN_MODEL_`, `PUPPETEER_EXECUTABLE_PATH`, and the names in `passEnv` are passed on purpose, model keys included.
|
|
264
|
+
|
|
265
|
+
### Prompt safety
|
|
266
|
+
|
|
267
|
+
Review items come from a model that read the PR, so PR text can reach a prompt. The YAML engines expand `${NAME}` to an environment variable, evaluate `{{expression}}` as JavaScript, and resolve `<<KEY>>` to a vault secret. localdost turns every brace in a prompt into a parenthesis and splits doubled angle brackets, so none of the three can form, and it percent-encodes the same characters in the start URL. Every value is written as a quoted YAML string. Only http and https start URLs without credentials are used; a case without one is reported as skipped.
|
|
268
|
+
|
|
269
|
+
## Generated Playwright specs
|
|
270
|
+
|
|
271
|
+
In the app this engine is called **Playwright e2e**. A dot can write real Playwright specs for What to test items that no existing spec covers, run them, and report them next to the repo specs and AI-Vision cases. Each item then shows the engine that covered it: an existing spec, a generated Playwright spec, or an AI-Vision case.
|
|
272
|
+
|
|
273
|
+
The engine is a per-dot setting, `runner.engine`, also in the dot dialog, under the Change reviewer stage, as **Engine for new scenarios**. Existing Playwright specs in the repo always run through the test command; the engine covers new scenarios only. When a dot sets none, it uses the workspace default from the Setup page, see [Test engines](SETUP.md#test-engines):
|
|
274
|
+
|
|
275
|
+
| Value | Label in the app | What runs items without an existing spec |
|
|
276
|
+
|---|---|---|
|
|
277
|
+
| unset | Uses the workspace default | The workspace default (`LOCALDOST_TEST_ENGINE`, saved on Setup). While none is chosen it is `aivision`, so a dot behaves as before |
|
|
278
|
+
| `auto` | Playwright e2e, then AI-Vision | A generated Playwright spec first; AI-Vision runs the items no kept spec covered |
|
|
279
|
+
| `playwright` | Playwright e2e only | Generated Playwright specs only |
|
|
280
|
+
| `aivision` | AI-Vision only | AI-Vision cases only, when `runner.aivision` is set |
|
|
281
|
+
| `both` | Both on every item | Both engines on every item. The worse result stands |
|
|
282
|
+
|
|
283
|
+
```json
|
|
284
|
+
{ "mode": "local", "workdir": "/home/me/shop-web", "engine": "auto", "pwgen": { "maxSpecs": 3 } }
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
| `runner.pwgen` field | Default | Purpose |
|
|
288
|
+
|---|---|---|
|
|
289
|
+
| `on` | `["pr_check", "post_merge"]` | Jobs that generate specs |
|
|
290
|
+
| `maxSpecs` | `3` | Upper bound on generated specs per run, at most 10 |
|
|
291
|
+
| `timeoutMs` | 15 minutes | The whole generation stage per run. Exploration, model calls, and spec runs stop at it |
|
|
292
|
+
| `proposePr` | `true` | Propose kept passing specs as a pull request through the `open_pr` rule |
|
|
293
|
+
|
|
294
|
+
The loop follows the Playwright test agents (planner, generator, healer; `npx playwright init-agents`), run inside localdost with its own model backend and no agent tools. One difference is on purpose: the Playwright healer may change expected values until a test passes, and the localdost healer may not, so a product bug cannot be healed away.
|
|
295
|
+
|
|
296
|
+
1. Plan. The PR review is the plan: the item's scenario, steps, expected result, and test data. Items of type e2e or exploratory without an existing spec qualify, must before should before could.
|
|
297
|
+
2. Explore. Headless Chromium opens the preview URL, or the dot's `baseUrl`, at `/`, the item's area routes, paths written in its steps (for example `/member?tier=gold`), and links from the first page, up to six pages. It records each page's ARIA snapshot, its `data-testid` elements, and its links. Links that read like log out, delete, or reset are never followed.
|
|
298
|
+
3. Generate. The model writes one `.spec.ts` with one `test()` from the item and the page snapshots, into `data/artifacts/<run id>/pwgen/<item id>/`.
|
|
299
|
+
4. Run. Playwright Test (the copy localdost ships) runs it once against the target URL with `BASE_URL` set, Chromium, no retries, and a trace and screenshot on failure.
|
|
300
|
+
5. Heal. When the spec fails for its own reason (a locator that matched nothing or several elements, a timeout, a syntax error), the model repairs it once from the error and the page snapshot Playwright wrote on failure. A repair that changes an expected value (in a matcher, or a value such as `'$6.40'` in the located element), drops an assertion, or turns one into a check for absence is rejected.
|
|
301
|
+
6. Keep or discard. A spec is kept when it passes, or when a value assertion found its element and read another value (a product failure). A value failure goes to the healer once as a check: when it leaves the spec as it is, or its repair fails the same way, the product failure stands; when its repair passes, the item gets no generated result, since the repair may read another element that shows the expected value. A spec that still fails for its own reason on a preview runs once on the base URL: when it passes there, the flow broke in the change, and the spec is kept as failed. Any other spec is discarded, and its item shows why.
|
|
302
|
+
|
|
303
|
+
Results land in the run report as `pwgen/<item id>.spec.ts`, and the final source of each spec is a run artifact (`pwgen-<item id>.spec.ts`), with screenshots and traces next to it. The sticky comment marks each item, for example `passed (checked by a Playwright e2e test)`.
|
|
304
|
+
|
|
305
|
+
Generation needs a model that writes text: the Claude CLI, the Codex CLI, or an Anthropic key. With the mock backend, every item is discarded with that reason, and `auto` sends all of them to AI-Vision.
|
|
306
|
+
|
|
307
|
+
### Proposing specs
|
|
308
|
+
|
|
309
|
+
When kept specs passed, the run drafts a pull request that adds them under `<spec folder>/localdost/`, where the spec folder is the top folder most existing e2e specs live in (else `tests`). On a pull request the proposal targets the PR branch, so the specs land with the change they test; after a merge it targets the default branch. The PR opens as a draft. Approving again after a failed send moves the same branch and reuses an open PR for it. The draft goes through the `open_pr` rule: with the default `act_when_asked` it is recorded on the run and skipped, with `ask` it waits in the Inbox for approval, and with `act` it opens after the auto-review. Fork pull requests get no proposal.
|
|
310
|
+
|
|
311
|
+
### Spec safety
|
|
312
|
+
|
|
313
|
+
A model wrote the spec from text a PR author can shape, and it runs on the localdost host, so a spec must pass these checks before it runs. A spec that fails them is sent back once with the problems listed, then discarded:
|
|
314
|
+
|
|
315
|
+
- One import, from `@playwright/test`. No `require`, dynamic import, or `import.meta`.
|
|
316
|
+
- Names come from an allowlist: the spec's own `const` and `let` names and arrow parameters, `test`, `expect`, `page`, and a few plain helpers (`Math`, `Number`, `String`). Properties come from an allowlist too: Playwright page, locator, keyboard, and assertion calls, `test.step`, and string, number, and array helpers. So `evaluate`, `route`, `context`, `request`, `constructor`, `test.fail`, and `test.skip` all fail the check, and host names such as `process`, `globalThis`, `Object`, and `eval` are refused by name. Words inside strings, regexes, and comments do not count.
|
|
317
|
+
- No bracket property access other than a number index, and no absolute URLs. `page.goto()` takes one quoted path that starts with a single `/`.
|
|
318
|
+
- Exactly one `test()` and at least one `expect()`.
|
|
319
|
+
|
|
320
|
+
The spec process gets only `PATH`, `TMPDIR`, `LANG`, `TZ`, `BASE_URL`, `CI`, and `PLAYWRIGHT_BROWSERS_PATH`, never a token or key, and its `HOME` is the scratch folder. These checks narrow what a spec can do; they are not a sandbox, and generated specs run on the host in every runner mode. Keep the engine unset for repos where people you do not trust write PR text, or run localdost as a user whose files hold no credentials.
|