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
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
// Test runs (docs/DATA-MODEL.md section 2.3). A test run is a planned pass over a set of cases, not a dot run.
|
|
2
|
+
// A person creates a manual test run from a suite, a selection, or a plan (one test run per plan configuration), and
|
|
3
|
+
// works its run items one by one: each result is an attempt with step results, the newest attempt sets the item's
|
|
4
|
+
// state, and a retest opens the next attempt. A dot run that reports results for cases fills its own automated test
|
|
5
|
+
// run, one per Playwright project, linked by dotRunId; those are read only. Routes: src/routes/test-runs.ts.
|
|
6
|
+
import { CASE_RESULTS, CaseInputError, ensureVersion, isObj, oneOf, ownsSpec, text, caseVersion, refs } from './cases.js';
|
|
7
|
+
import { db, get, insert, list, update } from './db.js';
|
|
8
|
+
import { teamIds } from './lead.js';
|
|
9
|
+
import { needsReviewFlags } from './impact/store.js';
|
|
10
|
+
import { resultAdded, testRunStarted, testRunStatusChanged } from './true/events.js';
|
|
11
|
+
import { caseIdsOf, configLabel, configOf, getPlan, getSuite, readPlan, readSuite } from './suites.js';
|
|
12
|
+
export const TEST_RUN_STATUSES = ['open', 'in_progress', 'done', 'cancelled'];
|
|
13
|
+
export const TEST_RUN_SOURCES = ['manual', 'automated'];
|
|
14
|
+
export const RUN_ITEM_STATES = ['untested', 'passed', 'failed', 'blocked', 'retest', 'skipped'];
|
|
15
|
+
const MAX_NAME = 200;
|
|
16
|
+
const MAX_NOTES = 4000;
|
|
17
|
+
const MAX_ACTUAL = 4000;
|
|
18
|
+
const MAX_DEFECTS = 20;
|
|
19
|
+
const MAX_EVIDENCE = 50;
|
|
20
|
+
const SHA = /^[0-9a-f]{7,40}$/i;
|
|
21
|
+
const now = () => new Date().toISOString();
|
|
22
|
+
// ---------- reads ----------
|
|
23
|
+
export function getTestRun(dotId, id) {
|
|
24
|
+
const t = get('test_runs', id);
|
|
25
|
+
return t && t.dotId === dotId ? t : undefined;
|
|
26
|
+
}
|
|
27
|
+
export function getRunItem(testRun, id) {
|
|
28
|
+
const i = get('run_items', id);
|
|
29
|
+
return i && i.testRunId === testRun.id ? i : undefined;
|
|
30
|
+
}
|
|
31
|
+
const emptyProgress = () => ({ total: 0, untested: 0, passed: 0, failed: 0, blocked: 0, retest: 0, skipped: 0 });
|
|
32
|
+
function progressOf(ids) {
|
|
33
|
+
const out = new Map();
|
|
34
|
+
if (!ids.length)
|
|
35
|
+
return out;
|
|
36
|
+
const rows = db
|
|
37
|
+
.prepare(`SELECT testRunId, state, COUNT(*) AS n FROM run_items WHERE testRunId IN (${ids.map(() => '?').join(', ')}) GROUP BY testRunId, state`)
|
|
38
|
+
.all(...ids);
|
|
39
|
+
for (const r of rows) {
|
|
40
|
+
const p = out.get(r.testRunId) ?? emptyProgress();
|
|
41
|
+
const n = Number(r.n);
|
|
42
|
+
if (RUN_ITEM_STATES.includes(r.state))
|
|
43
|
+
p[r.state] += n;
|
|
44
|
+
p.total += n;
|
|
45
|
+
out.set(r.testRunId, p);
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
function viewsOf(runs) {
|
|
50
|
+
const progress = progressOf(runs.map((r) => r.id));
|
|
51
|
+
const names = new Map();
|
|
52
|
+
const nameOf = (table, id) => {
|
|
53
|
+
if (!id)
|
|
54
|
+
return undefined;
|
|
55
|
+
const k = `${table}:${id}`;
|
|
56
|
+
if (!names.has(k))
|
|
57
|
+
names.set(k, get(table, id)?.name);
|
|
58
|
+
return names.get(k);
|
|
59
|
+
};
|
|
60
|
+
return runs.map((r) => {
|
|
61
|
+
const planName = nameOf('plans', r.planId);
|
|
62
|
+
const suiteName = nameOf('suites', r.suiteId);
|
|
63
|
+
return { ...r, progress: progress.get(r.id) ?? emptyProgress(), ...(planName ? { planName } : {}), ...(suiteName ? { suiteName } : {}) };
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/** Test runs of a dot, newest first. Throws CaseInputError for an unknown filter value. */
|
|
67
|
+
export function listTestRuns(w, f = {}) {
|
|
68
|
+
const status = oneOf(f.status, TEST_RUN_STATUSES, 'Status');
|
|
69
|
+
const source = oneOf(f.source, TEST_RUN_SOURCES, 'Source');
|
|
70
|
+
const limit = Math.max(1, Math.min(500, Math.floor(f.limit ?? 100)));
|
|
71
|
+
return viewsOf(list('test_runs', { dotId: w.id, status, source }, { orderBy: 'id DESC', limit }));
|
|
72
|
+
}
|
|
73
|
+
export function testRunView(t) {
|
|
74
|
+
return viewsOf([t])[0];
|
|
75
|
+
}
|
|
76
|
+
/** The newest result of each item of a test run. */
|
|
77
|
+
function latestOfItems(testRunId) {
|
|
78
|
+
const out = new Map();
|
|
79
|
+
for (const r of list('case_results', { testRunId }, { orderBy: 'at ASC, id ASC' }))
|
|
80
|
+
if (r.runItemId)
|
|
81
|
+
out.set(r.runItemId, r);
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
function itemView(item, c, latest, flags) {
|
|
85
|
+
const v = caseVersion(item.caseId, item.caseVersion)?.snapshot;
|
|
86
|
+
const src = v ?? c;
|
|
87
|
+
return {
|
|
88
|
+
...item,
|
|
89
|
+
attempt: item.attempt ?? 1,
|
|
90
|
+
key: c?.key ?? '?',
|
|
91
|
+
title: src?.title ?? 'Deleted case',
|
|
92
|
+
kind: src?.kind ?? 'manual',
|
|
93
|
+
steps: src?.steps ?? [],
|
|
94
|
+
...(src?.specPath ? { specPath: src.specPath } : {}),
|
|
95
|
+
latest: latest ?? null,
|
|
96
|
+
// A ticket review proposed a change to this case, or its retirement, and a person has not decided (KAT-304).
|
|
97
|
+
...(flags?.get(item.caseId) ? { needsReview: flags.get(item.caseId) } : {}),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export function testRunDetail(t) {
|
|
101
|
+
const items = list('run_items', { testRunId: t.id }, { orderBy: 'position ASC, id ASC' });
|
|
102
|
+
const cases = new Map(list('test_cases', { id: [...new Set(items.map((i) => i.caseId))] }).map((c) => [c.id, c]));
|
|
103
|
+
const latest = latestOfItems(t.id);
|
|
104
|
+
const flags = needsReviewFlags(t.dotId);
|
|
105
|
+
return { ...testRunView(t), items: items.map((i) => itemView(i, cases.get(i.caseId), latest.get(i.id), flags)) };
|
|
106
|
+
}
|
|
107
|
+
export function runItemDetail(item) {
|
|
108
|
+
const c = get('test_cases', item.caseId);
|
|
109
|
+
const results = list('case_results', { runItemId: item.id }, { orderBy: 'at DESC, id DESC' });
|
|
110
|
+
return { ...itemView(item, c, results[0], needsReviewFlags(item.dotId)), results, newerVersion: !!c && (c.revision ?? 1) > item.caseVersion };
|
|
111
|
+
}
|
|
112
|
+
// ---------- create and update ----------
|
|
113
|
+
function readSha(v) {
|
|
114
|
+
const s = text(v, 'Build', 40);
|
|
115
|
+
if (!s)
|
|
116
|
+
return undefined;
|
|
117
|
+
if (!SHA.test(s))
|
|
118
|
+
throw new CaseInputError('Build must be a commit sha: 7 to 40 hex characters.');
|
|
119
|
+
return s.toLowerCase();
|
|
120
|
+
}
|
|
121
|
+
function addItems(testRun, caseIds) {
|
|
122
|
+
const at = now();
|
|
123
|
+
caseIds.forEach((id, i) => {
|
|
124
|
+
const c = get('test_cases', id);
|
|
125
|
+
if (!c)
|
|
126
|
+
return;
|
|
127
|
+
insert('run_items', {
|
|
128
|
+
testRunId: testRun.id,
|
|
129
|
+
dotId: testRun.dotId,
|
|
130
|
+
caseId: c.id,
|
|
131
|
+
caseVersion: ensureVersion(c),
|
|
132
|
+
position: i + 1,
|
|
133
|
+
state: 'untested',
|
|
134
|
+
attempt: 1,
|
|
135
|
+
updatedAt: at,
|
|
136
|
+
createdAt: at,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/** In one transaction, so a failed insert leaves no half test run. */
|
|
141
|
+
function inTx(fn) {
|
|
142
|
+
db.exec('SAVEPOINT test_runs_tx');
|
|
143
|
+
try {
|
|
144
|
+
const out = fn();
|
|
145
|
+
db.exec('RELEASE test_runs_tx');
|
|
146
|
+
return out;
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
db.exec('ROLLBACK TO test_runs_tx');
|
|
150
|
+
db.exec('RELEASE test_runs_tx');
|
|
151
|
+
throw err;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Creates manual test runs from exactly one of: `suiteId`, `caseIds` (a selection), or `planId`. A plan makes one
|
|
156
|
+
* test run per configuration. Returns the test runs it made.
|
|
157
|
+
*/
|
|
158
|
+
export function createTestRuns(w, body) {
|
|
159
|
+
return startTestRuns(w, body).runs;
|
|
160
|
+
}
|
|
161
|
+
/** As createTestRuns, plus a note for each suite or plan reference that was gone and left out. */
|
|
162
|
+
export function startTestRuns(w, body) {
|
|
163
|
+
if (!isObj(body))
|
|
164
|
+
throw new CaseInputError('Send the test run as a JSON object.');
|
|
165
|
+
const sources = ['suiteId', 'caseIds', 'planId'].filter((k) => body[k] !== undefined && body[k] !== null && body[k] !== '');
|
|
166
|
+
if (sources.length !== 1)
|
|
167
|
+
throw new CaseInputError('Start a test run from one of: a suite, a selection of cases, or a plan.');
|
|
168
|
+
const environment = text(body.environment, 'Environment', 80);
|
|
169
|
+
const assignee = text(body.assignee, 'Assignee', 80);
|
|
170
|
+
const buildSha = readSha(body.buildSha);
|
|
171
|
+
const config = configOf(body.config);
|
|
172
|
+
let givenName = text(body.name, 'Name', MAX_NAME);
|
|
173
|
+
let caseIds;
|
|
174
|
+
let configs = [config];
|
|
175
|
+
let base = {};
|
|
176
|
+
let label;
|
|
177
|
+
let notes = [];
|
|
178
|
+
if (sources[0] === 'suiteId') {
|
|
179
|
+
const s = typeof body.suiteId === 'string' ? getSuite(w.id, body.suiteId) : undefined;
|
|
180
|
+
if (!s)
|
|
181
|
+
throw new CaseInputError('That suite does not belong to this dot.');
|
|
182
|
+
const r = readSuite(w, s);
|
|
183
|
+
caseIds = r.cases.map((c) => c.id);
|
|
184
|
+
notes = r.notes;
|
|
185
|
+
base = { suiteId: s.id };
|
|
186
|
+
label = s.name;
|
|
187
|
+
}
|
|
188
|
+
else if (sources[0] === 'planId') {
|
|
189
|
+
const p = typeof body.planId === 'string' ? getPlan(w.id, body.planId) : undefined;
|
|
190
|
+
if (!p)
|
|
191
|
+
throw new CaseInputError('That plan does not belong to this dot.');
|
|
192
|
+
const r = readPlan(w, p);
|
|
193
|
+
caseIds = r.caseIds;
|
|
194
|
+
notes = r.notes;
|
|
195
|
+
if (!config && p.configs?.length)
|
|
196
|
+
configs = p.configs;
|
|
197
|
+
base = { planId: p.id, ...(p.environment && !environment ? { environment: p.environment } : {}) };
|
|
198
|
+
label = p.name;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
caseIds = caseIdsOf(w.id, body.caseIds);
|
|
202
|
+
label = `Test run ${new Date().toISOString().slice(0, 10)}`;
|
|
203
|
+
}
|
|
204
|
+
if (!caseIds.length)
|
|
205
|
+
throw new CaseInputError(`No draft or ready cases to run. Add cases first.${notes.length ? ` ${notes.join(' ')}` : ''}`);
|
|
206
|
+
givenName ??= label;
|
|
207
|
+
const runs = inTx(() => configs.map((cfg) => {
|
|
208
|
+
const at = now();
|
|
209
|
+
const suffix = configs.length > 1 && cfg ? ` (${configLabel(cfg)})` : '';
|
|
210
|
+
const t = insert('test_runs', {
|
|
211
|
+
dotId: w.id,
|
|
212
|
+
name: `${givenName}${suffix}`.slice(0, MAX_NAME),
|
|
213
|
+
source: 'manual',
|
|
214
|
+
status: 'open',
|
|
215
|
+
...base,
|
|
216
|
+
...(environment ? { environment } : {}),
|
|
217
|
+
...(cfg ? { config: cfg } : {}),
|
|
218
|
+
...(buildSha ? { buildSha } : {}),
|
|
219
|
+
...(assignee ? { assignee } : {}),
|
|
220
|
+
createdAt: at,
|
|
221
|
+
updatedAt: at,
|
|
222
|
+
});
|
|
223
|
+
addItems(t, caseIds);
|
|
224
|
+
return t;
|
|
225
|
+
}));
|
|
226
|
+
// After the transaction: True Platform hears about each manual test run once its items are stored (KAT-406).
|
|
227
|
+
for (const t of runs)
|
|
228
|
+
testRunStarted(t);
|
|
229
|
+
return { runs, notes };
|
|
230
|
+
}
|
|
231
|
+
function readOnly(t) {
|
|
232
|
+
if (t.source === 'automated')
|
|
233
|
+
throw new CaseInputError('This test run is automated. Its results come from its dot run, so it is read only.');
|
|
234
|
+
}
|
|
235
|
+
/** Edits a manual test run: status, name, environment, configuration, build, assignee. */
|
|
236
|
+
export function updateTestRun(t, body) {
|
|
237
|
+
readOnly(t);
|
|
238
|
+
if (!isObj(body))
|
|
239
|
+
throw new CaseInputError('Send the change as a JSON object.');
|
|
240
|
+
const patch = { updatedAt: now() };
|
|
241
|
+
const status = oneOf(body.status, TEST_RUN_STATUSES, 'Status');
|
|
242
|
+
if (status && status !== t.status) {
|
|
243
|
+
patch.status = status;
|
|
244
|
+
if (status === 'done' || status === 'cancelled')
|
|
245
|
+
patch.finishedAt = now();
|
|
246
|
+
else
|
|
247
|
+
patch.finishedAt = null;
|
|
248
|
+
if (status === 'in_progress' && !t.startedAt)
|
|
249
|
+
patch.startedAt = now();
|
|
250
|
+
}
|
|
251
|
+
if (body.name !== undefined) {
|
|
252
|
+
const n = text(body.name, 'Name', MAX_NAME);
|
|
253
|
+
if (!n)
|
|
254
|
+
throw new CaseInputError('A test run needs a name.');
|
|
255
|
+
patch.name = n;
|
|
256
|
+
}
|
|
257
|
+
if (body.environment !== undefined)
|
|
258
|
+
patch.environment = text(body.environment, 'Environment', 80) || null;
|
|
259
|
+
if (body.assignee !== undefined)
|
|
260
|
+
patch.assignee = text(body.assignee, 'Assignee', 80) || null;
|
|
261
|
+
if (body.buildSha !== undefined)
|
|
262
|
+
patch.buildSha = readSha(body.buildSha) ?? null;
|
|
263
|
+
if (body.config !== undefined)
|
|
264
|
+
patch.config = configOf(body.config) ?? null;
|
|
265
|
+
update('test_runs', t.id, patch);
|
|
266
|
+
const saved = get('test_runs', t.id);
|
|
267
|
+
if (status && status !== t.status)
|
|
268
|
+
testRunStatusChanged(saved, t.status, status);
|
|
269
|
+
return saved;
|
|
270
|
+
}
|
|
271
|
+
/** Sets the assignee of a run item. */
|
|
272
|
+
export function updateRunItem(t, item, body) {
|
|
273
|
+
readOnly(t);
|
|
274
|
+
if (!isObj(body))
|
|
275
|
+
throw new CaseInputError('Send the change as a JSON object.');
|
|
276
|
+
if (body.assignee === undefined)
|
|
277
|
+
throw new CaseInputError('Nothing to change. Send an assignee.');
|
|
278
|
+
update('run_items', item.id, { assignee: text(body.assignee, 'Assignee', 80) || null, updatedAt: now() });
|
|
279
|
+
return get('run_items', item.id);
|
|
280
|
+
}
|
|
281
|
+
// ---------- manual results ----------
|
|
282
|
+
function writable(t) {
|
|
283
|
+
readOnly(t);
|
|
284
|
+
if (t.status === 'done' || t.status === 'cancelled')
|
|
285
|
+
throw new CaseInputError('This test run is closed. Reopen it to add results.');
|
|
286
|
+
}
|
|
287
|
+
function stepResults(v, stepCount) {
|
|
288
|
+
if (v === undefined || v === null)
|
|
289
|
+
return [];
|
|
290
|
+
if (!Array.isArray(v))
|
|
291
|
+
throw new CaseInputError('Step results must be a list.');
|
|
292
|
+
const seen = new Set();
|
|
293
|
+
const out = [];
|
|
294
|
+
for (const raw of v) {
|
|
295
|
+
if (!isObj(raw))
|
|
296
|
+
throw new CaseInputError('Each step result needs an index and a result.');
|
|
297
|
+
const index = raw.index;
|
|
298
|
+
if (typeof index !== 'number' || !Number.isInteger(index) || index < 0 || index >= stepCount)
|
|
299
|
+
throw new CaseInputError(stepCount ? `Step index must be from 0 to ${stepCount - 1}.` : 'This case has no steps.');
|
|
300
|
+
if (seen.has(index))
|
|
301
|
+
throw new CaseInputError(`Step ${index + 1} has two results.`);
|
|
302
|
+
seen.add(index);
|
|
303
|
+
const result = oneOf(raw.result, CASE_RESULTS, `Result of step ${index + 1}`);
|
|
304
|
+
if (!result)
|
|
305
|
+
throw new CaseInputError(`Step ${index + 1} needs a result.`);
|
|
306
|
+
const actual = text(raw.actual, `Actual result of step ${index + 1}`, MAX_ACTUAL);
|
|
307
|
+
out.push({ index, result, ...(actual ? { actual } : {}) });
|
|
308
|
+
}
|
|
309
|
+
return out.sort((a, b) => a.index - b.index);
|
|
310
|
+
}
|
|
311
|
+
function defectsOf(v, stepCount) {
|
|
312
|
+
if (v === undefined || v === null)
|
|
313
|
+
return [];
|
|
314
|
+
if (!Array.isArray(v))
|
|
315
|
+
throw new CaseInputError('Defects must be a list.');
|
|
316
|
+
if (v.length > MAX_DEFECTS)
|
|
317
|
+
throw new CaseInputError(`A result links at most ${MAX_DEFECTS} defects.`);
|
|
318
|
+
return v.map((raw) => {
|
|
319
|
+
const o = typeof raw === 'string' ? { ref: raw } : isObj(raw) ? raw : {};
|
|
320
|
+
const ref = refs([o.ref])?.[0];
|
|
321
|
+
if (!ref)
|
|
322
|
+
throw new CaseInputError('Each defect needs a key such as SHOP-12, or owner/name#12.');
|
|
323
|
+
if (o.stepIndex === undefined || o.stepIndex === null)
|
|
324
|
+
return { ref };
|
|
325
|
+
const i = o.stepIndex;
|
|
326
|
+
if (typeof i !== 'number' || !Number.isInteger(i) || i < 0 || i >= stepCount)
|
|
327
|
+
throw new CaseInputError(`Defect ${ref} names a step the case does not have.`);
|
|
328
|
+
return { ref, stepIndex: i };
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
/** A person's result on a run item: the next row of the item's current attempt. */
|
|
332
|
+
export function addRunResult(t, item, body, actor) {
|
|
333
|
+
writable(t);
|
|
334
|
+
if (!isObj(body))
|
|
335
|
+
throw new CaseInputError('Send the result as a JSON object.');
|
|
336
|
+
const result = oneOf(body.result, CASE_RESULTS, 'Result');
|
|
337
|
+
if (!result)
|
|
338
|
+
throw new CaseInputError(`Result must be one of: ${CASE_RESULTS.join(', ')}.`);
|
|
339
|
+
// The case may belong to another member of the run's team (a case Ticket Reviewer designed, in a merge run of Regression Runner,
|
|
340
|
+
// KAT-405). The result is written on the case, under the dot that owns it.
|
|
341
|
+
const owner = get('test_cases', item.caseId);
|
|
342
|
+
if (owner && owner.dotId !== t.dotId && !teamIds(t.dotId).includes(owner.dotId))
|
|
343
|
+
throw new CaseInputError('That case belongs to a dot outside this team.');
|
|
344
|
+
const stepCount = itemView(item, undefined, undefined).steps.length;
|
|
345
|
+
const steps = stepResults(body.steps, stepCount);
|
|
346
|
+
const failedStep = steps.find((s) => s.result === 'failed');
|
|
347
|
+
if (result === 'passed' && failedStep)
|
|
348
|
+
throw new CaseInputError(`A result cannot pass when step ${failedStep.index + 1} failed.`);
|
|
349
|
+
const notes = text(body.notes, 'Notes', MAX_NOTES);
|
|
350
|
+
const defects = defectsOf(body.defects, stepCount);
|
|
351
|
+
let durationMs;
|
|
352
|
+
if (body.durationMs !== undefined) {
|
|
353
|
+
if (typeof body.durationMs !== 'number' || !Number.isFinite(body.durationMs) || body.durationMs < 0 || body.durationMs > 864e5)
|
|
354
|
+
throw new CaseInputError('Duration must be a number of milliseconds, at most one day.');
|
|
355
|
+
durationMs = Math.round(body.durationMs);
|
|
356
|
+
}
|
|
357
|
+
const executedBy = text(body.executedBy, 'Executed by', 80) || actor;
|
|
358
|
+
const at = now();
|
|
359
|
+
const saved = inTx(() => {
|
|
360
|
+
const row = insert('case_results', {
|
|
361
|
+
caseId: item.caseId,
|
|
362
|
+
dotId: owner?.dotId ?? t.dotId,
|
|
363
|
+
result,
|
|
364
|
+
...(notes ? { notes } : {}),
|
|
365
|
+
evidence: [],
|
|
366
|
+
source: 'manual',
|
|
367
|
+
runItemId: item.id,
|
|
368
|
+
testRunId: t.id,
|
|
369
|
+
attempt: item.attempt ?? 1,
|
|
370
|
+
engine: 'manual',
|
|
371
|
+
...(durationMs !== undefined ? { durationMs } : {}),
|
|
372
|
+
...(t.buildSha ? { sha: t.buildSha } : {}),
|
|
373
|
+
...(t.environment ? { environment: t.environment } : {}),
|
|
374
|
+
...(t.config ? { config: t.config } : {}),
|
|
375
|
+
...(executedBy ? { executedBy } : {}),
|
|
376
|
+
steps,
|
|
377
|
+
defects,
|
|
378
|
+
at,
|
|
379
|
+
createdAt: at,
|
|
380
|
+
});
|
|
381
|
+
update('run_items', item.id, { state: result, updatedAt: at });
|
|
382
|
+
if (t.status === 'open')
|
|
383
|
+
update('test_runs', t.id, { status: 'in_progress', startedAt: t.startedAt ?? at, updatedAt: at });
|
|
384
|
+
else
|
|
385
|
+
update('test_runs', t.id, { updatedAt: at });
|
|
386
|
+
return row;
|
|
387
|
+
});
|
|
388
|
+
resultAdded(get('test_runs', t.id) ?? t, item, saved);
|
|
389
|
+
return saved;
|
|
390
|
+
}
|
|
391
|
+
/** Opens the next attempt of a run item. Its earlier results stay; the item shows Retest until a new result. */
|
|
392
|
+
export function retestItem(t, item) {
|
|
393
|
+
writable(t);
|
|
394
|
+
if (item.state === 'untested' || item.state === 'retest')
|
|
395
|
+
throw new CaseInputError('This item has no result to retest yet.');
|
|
396
|
+
const at = now();
|
|
397
|
+
update('run_items', item.id, { state: 'retest', attempt: (item.attempt ?? 1) + 1, updatedAt: at });
|
|
398
|
+
if (t.status === 'open')
|
|
399
|
+
update('test_runs', t.id, { status: 'in_progress', startedAt: t.startedAt ?? at, updatedAt: at });
|
|
400
|
+
return get('run_items', item.id);
|
|
401
|
+
}
|
|
402
|
+
// ---------- automated test runs from dot runs ----------
|
|
403
|
+
const ANSI = /\u001b\[[0-9;]*m/g;
|
|
404
|
+
const plural = (n, one) => `${n} ${one}${n === 1 ? '' : 's'}`;
|
|
405
|
+
const PROJECT = /^\[([^\]]{1,80})\] /;
|
|
406
|
+
/** The Playwright project of a test, from the `[project] ` title prefix the report reader adds when there are several. */
|
|
407
|
+
export function projectOf(t) {
|
|
408
|
+
return PROJECT.exec(t.title)?.[1] ?? '';
|
|
409
|
+
}
|
|
410
|
+
function shaOf(run) {
|
|
411
|
+
const tr = run.trigger;
|
|
412
|
+
const sha = tr?.pr?.mergeSha ?? tr?.push?.after ?? tr?.pr?.headSha ?? tr?.ci?.headSha;
|
|
413
|
+
return sha && SHA.test(sha) ? sha.toLowerCase() : undefined;
|
|
414
|
+
}
|
|
415
|
+
function environmentOf(report) {
|
|
416
|
+
if (!report.baseUrl)
|
|
417
|
+
return report.mode === 'demo' ? 'Sample shop' : undefined;
|
|
418
|
+
try {
|
|
419
|
+
return new URL(report.baseUrl).host;
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
return undefined;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
function automatedName(run, project) {
|
|
426
|
+
const head = run.trigger?.title?.trim() || 'Dot run';
|
|
427
|
+
return (project ? `${head} (${project})` : head).slice(0, MAX_NAME);
|
|
428
|
+
}
|
|
429
|
+
/** The automated test run of a dot run and project, made when missing. */
|
|
430
|
+
function automatedRun(run, project, report) {
|
|
431
|
+
const found = list('test_runs', { dotRunId: run.id, configKey: project }, { limit: 1 })[0];
|
|
432
|
+
const at = now();
|
|
433
|
+
const fields = {
|
|
434
|
+
status: 'done',
|
|
435
|
+
finishedAt: at,
|
|
436
|
+
...(environmentOf(report) ? { environment: environmentOf(report) } : {}),
|
|
437
|
+
...(shaOf(run) ? { buildSha: shaOf(run) } : {}),
|
|
438
|
+
};
|
|
439
|
+
if (found) {
|
|
440
|
+
update('test_runs', found.id, { ...fields, updatedAt: at });
|
|
441
|
+
return get('test_runs', found.id);
|
|
442
|
+
}
|
|
443
|
+
return insert('test_runs', {
|
|
444
|
+
dotId: run.watchId,
|
|
445
|
+
name: automatedName(run, project),
|
|
446
|
+
source: 'automated',
|
|
447
|
+
...fields,
|
|
448
|
+
...(project ? { config: { project } } : {}),
|
|
449
|
+
dotRunId: run.id,
|
|
450
|
+
configKey: project,
|
|
451
|
+
startedAt: run.createdAt ?? report.startedAt ?? at,
|
|
452
|
+
createdAt: at,
|
|
453
|
+
updatedAt: at,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
function engineOf(c, hits = []) {
|
|
457
|
+
if (hits.length && hits.every((t) => t.file.startsWith('aivision/')))
|
|
458
|
+
return 'aivision';
|
|
459
|
+
return c.kind === 'aivision' ? 'aivision' : 'playwright';
|
|
460
|
+
}
|
|
461
|
+
/** The report file an AI-Vision run of a designed case writes (src/runner/aivision/cases.ts caseResultFile). */
|
|
462
|
+
const aivisionFileOf = (c) => `aivision/${c.id}.yaml`;
|
|
463
|
+
/** One case's result from the tests of one project that ran its spec. */
|
|
464
|
+
function summarize(hits) {
|
|
465
|
+
const failed = hits.filter((t) => t.status === 'failed' || t.status === 'timedOut');
|
|
466
|
+
const skipped = hits.filter((t) => t.status === 'skipped');
|
|
467
|
+
const flaky = hits.filter((t) => t.status === 'flaky');
|
|
468
|
+
const result = failed.length ? 'failed' : skipped.length === hits.length ? 'skipped' : 'passed';
|
|
469
|
+
const counts = [
|
|
470
|
+
hits.length - failed.length - skipped.length ? `${hits.length - failed.length - skipped.length} passed` : '',
|
|
471
|
+
failed.length ? `${failed.length} failed` : '',
|
|
472
|
+
skipped.length ? `${skipped.length} skipped` : '',
|
|
473
|
+
]
|
|
474
|
+
.filter(Boolean)
|
|
475
|
+
.join(', ');
|
|
476
|
+
let notes = `${plural(hits.length, 'test')} in ${hits[0].file}: ${counts}.`;
|
|
477
|
+
if (flaky.length)
|
|
478
|
+
notes += ` ${plural(flaky.length, 'test')} passed on a retry.`;
|
|
479
|
+
const err = failed.find((t) => t.error)?.error;
|
|
480
|
+
if (err)
|
|
481
|
+
notes += ` ${failed[0].title.replace(PROJECT, '')}: ${err.replace(ANSI, '').split('\n')[0].trim().slice(0, 300)}`;
|
|
482
|
+
const evidence = [
|
|
483
|
+
...new Set(hits.flatMap((t) => [...(t.evidence?.screenshots ?? []).map((s) => s.name), t.evidence?.video, t.evidence?.trace].filter((x) => !!x))),
|
|
484
|
+
].slice(0, MAX_EVIDENCE);
|
|
485
|
+
return { result, notes, evidence, durationMs: hits.reduce((n, t) => n + (t.durationMs || 0), 0) };
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* True when the case owns the reported file. A report path cut at Playwright's testDir ("coupon.spec.ts") matches
|
|
489
|
+
* every case whose spec ends with it; when more than one spec path matches and none is exactly the file, the owner
|
|
490
|
+
* is unknown and nobody gets the result (KAT-278).
|
|
491
|
+
*/
|
|
492
|
+
function ownsFile(c, file, all) {
|
|
493
|
+
return ownsSpec(c.specPath, file, all.map((o) => o.specPath));
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* The cases that own a reported test: the case whose AI-Vision file it is, or whose spec it is when no other spec ends with the same path.
|
|
497
|
+
* linkRunResults uses the same rule to write results; the True Platform sync names a test after its owner (KAT-406).
|
|
498
|
+
*/
|
|
499
|
+
export function casesOwning(test, cases) {
|
|
500
|
+
const live = cases.filter((c) => c.status !== 'retired');
|
|
501
|
+
const specCases = live.filter((c) => !!c.specPath);
|
|
502
|
+
return live.filter((c) => test.file === aivisionFileOf(c) || (!!c.specPath && ownsFile(c, test.file, specCases)));
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Writes the results of a dot run's report into its automated test runs: one per Playwright project, with one run
|
|
506
|
+
* item per case whose spec ran. Called each time the dot run saves its report, so a retry pass updates the rows the
|
|
507
|
+
* first save wrote instead of adding more. Retired cases get no results. Returns the number of results written.
|
|
508
|
+
*/
|
|
509
|
+
export function linkRunResults(run, report) {
|
|
510
|
+
const tests = report?.cases ?? [];
|
|
511
|
+
if (!report || !tests.length)
|
|
512
|
+
return 0;
|
|
513
|
+
// The team's cases (KAT-405): the run's own dot first, so a spec that two members hold maps to the run's own case, then the other
|
|
514
|
+
// members' in key order. A result of PR Reviewer or Regression Runner lands on the Ticket Reviewer case that owns the spec or the file.
|
|
515
|
+
const team = teamIds(run.watchId);
|
|
516
|
+
const dots = [run.watchId, ...team.filter((id) => id !== run.watchId)];
|
|
517
|
+
const cases = list('test_cases', { dotId: dots })
|
|
518
|
+
.filter((c) => c.status !== 'retired')
|
|
519
|
+
.sort((a, b) => dots.indexOf(a.dotId) - dots.indexOf(b.dotId) || Number(a.key.slice(3)) - Number(b.key.slice(3)));
|
|
520
|
+
const projects = [...new Set(tests.map(projectOf))].sort();
|
|
521
|
+
const rawStage = run.stage;
|
|
522
|
+
const stage = typeof rawStage === 'string' ? rawStage : undefined;
|
|
523
|
+
let written = 0;
|
|
524
|
+
inTx(() => {
|
|
525
|
+
for (const project of projects) {
|
|
526
|
+
const group = tests.filter((t) => projectOf(t) === project);
|
|
527
|
+
// A result belongs to a case when it ran the case's AI-Vision file, or its spec and no other case owns that file (KAT-278).
|
|
528
|
+
// A spec path two members hold counts once, for the first case (the run's own).
|
|
529
|
+
const specSeen = new Set();
|
|
530
|
+
const specCases = cases.filter((o) => !!o.specPath && !specSeen.has(o.specPath) && !!specSeen.add(o.specPath));
|
|
531
|
+
const hitsByCase = cases
|
|
532
|
+
.map((c) => [c, group.filter((t) => t.file === aivisionFileOf(c) || (!!c.specPath && specCases.includes(c) && ownsFile(c, t.file, specCases)))])
|
|
533
|
+
.filter(([, h]) => h.length);
|
|
534
|
+
if (!hitsByCase.length)
|
|
535
|
+
continue;
|
|
536
|
+
const t = automatedRun(run, project, report);
|
|
537
|
+
const items = new Map(list('run_items', { testRunId: t.id }).map((i) => [i.caseId, i]));
|
|
538
|
+
let position = items.size;
|
|
539
|
+
for (const [c, hits] of hitsByCase) {
|
|
540
|
+
const at = now();
|
|
541
|
+
const s = summarize(hits);
|
|
542
|
+
let item = items.get(c.id);
|
|
543
|
+
if (!item) {
|
|
544
|
+
item = insert('run_items', {
|
|
545
|
+
testRunId: t.id,
|
|
546
|
+
dotId: t.dotId,
|
|
547
|
+
caseId: c.id,
|
|
548
|
+
caseVersion: ensureVersion(c),
|
|
549
|
+
position: ++position,
|
|
550
|
+
state: s.result,
|
|
551
|
+
attempt: 1,
|
|
552
|
+
updatedAt: at,
|
|
553
|
+
createdAt: at,
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
else
|
|
557
|
+
update('run_items', item.id, { state: s.result, updatedAt: at });
|
|
558
|
+
const row = {
|
|
559
|
+
result: s.result,
|
|
560
|
+
notes: s.notes,
|
|
561
|
+
evidence: s.evidence,
|
|
562
|
+
durationMs: s.durationMs,
|
|
563
|
+
engine: engineOf(c, hits),
|
|
564
|
+
...(t.buildSha ? { sha: t.buildSha } : {}),
|
|
565
|
+
...(t.environment ? { environment: t.environment } : {}),
|
|
566
|
+
...(t.config ? { config: t.config } : {}),
|
|
567
|
+
...(stage ? { stage } : {}),
|
|
568
|
+
at,
|
|
569
|
+
};
|
|
570
|
+
const prev = list('case_results', { runItemId: item.id, dotRunId: run.id }, { limit: 1 })[0];
|
|
571
|
+
if (prev)
|
|
572
|
+
update('case_results', prev.id, row);
|
|
573
|
+
else
|
|
574
|
+
insert('case_results', {
|
|
575
|
+
caseId: c.id,
|
|
576
|
+
dotId: c.dotId,
|
|
577
|
+
runId: run.id,
|
|
578
|
+
dotRunId: run.id,
|
|
579
|
+
source: 'run',
|
|
580
|
+
runItemId: item.id,
|
|
581
|
+
testRunId: t.id,
|
|
582
|
+
attempt: 1,
|
|
583
|
+
steps: [],
|
|
584
|
+
defects: [],
|
|
585
|
+
...row,
|
|
586
|
+
createdAt: at,
|
|
587
|
+
});
|
|
588
|
+
written++;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
return written;
|
|
593
|
+
}
|
|
594
|
+
// ---------- backfill ----------
|
|
595
|
+
/**
|
|
596
|
+
* Gives every dot-run result written before test runs existed its automated test run: one per dot run, one run item
|
|
597
|
+
* per case (the newest result wins the item state), so the history shows in Test runs. Idempotent: it only reads
|
|
598
|
+
* results that have no test run yet. Results added by hand outside a dot run stay outside any test run.
|
|
599
|
+
*/
|
|
600
|
+
export function backfillTestRuns() {
|
|
601
|
+
const groups = db
|
|
602
|
+
.prepare(`SELECT DISTINCT dotId, runId FROM case_results WHERE testRunId IS NULL AND runId IS NOT NULL AND source = 'run' ORDER BY runId`)
|
|
603
|
+
.all();
|
|
604
|
+
let testRuns = 0;
|
|
605
|
+
let items = 0;
|
|
606
|
+
for (const g of groups) {
|
|
607
|
+
inTx(() => {
|
|
608
|
+
const rows = list('case_results', { dotId: g.dotId, runId: g.runId, source: 'run', testRunId: null }, { orderBy: 'at ASC, id ASC' });
|
|
609
|
+
if (!rows.length)
|
|
610
|
+
return;
|
|
611
|
+
const run = get('runs', g.runId);
|
|
612
|
+
const at = rows.at(-1).at ?? now();
|
|
613
|
+
let t = list('test_runs', { dotRunId: g.runId, configKey: '' }, { limit: 1 })[0];
|
|
614
|
+
if (!t) {
|
|
615
|
+
const sha = run ? shaOf(run) : undefined;
|
|
616
|
+
const env = run?.report ? environmentOf(run.report) : undefined;
|
|
617
|
+
t = insert('test_runs', {
|
|
618
|
+
dotId: g.dotId,
|
|
619
|
+
name: run ? automatedName(run, '') : 'Earlier dot run',
|
|
620
|
+
source: 'automated',
|
|
621
|
+
status: 'done',
|
|
622
|
+
dotRunId: g.runId,
|
|
623
|
+
configKey: '',
|
|
624
|
+
...(sha ? { buildSha: sha } : {}),
|
|
625
|
+
...(env ? { environment: env } : {}),
|
|
626
|
+
startedAt: run?.createdAt ?? rows[0].at,
|
|
627
|
+
finishedAt: run?.finishedAt ?? at,
|
|
628
|
+
createdAt: rows[0].createdAt ?? at,
|
|
629
|
+
updatedAt: at,
|
|
630
|
+
});
|
|
631
|
+
testRuns++;
|
|
632
|
+
}
|
|
633
|
+
const byCase = new Map();
|
|
634
|
+
for (const r of rows)
|
|
635
|
+
byCase.set(r.caseId, [...(byCase.get(r.caseId) ?? []), r]);
|
|
636
|
+
let position = list('run_items', { testRunId: t.id }).length;
|
|
637
|
+
for (const [caseId, results] of byCase) {
|
|
638
|
+
const c = get('test_cases', caseId);
|
|
639
|
+
const newest = results.at(-1);
|
|
640
|
+
let item = list('run_items', { testRunId: t.id, caseId }, { limit: 1 })[0];
|
|
641
|
+
if (!item) {
|
|
642
|
+
item = insert('run_items', {
|
|
643
|
+
testRunId: t.id,
|
|
644
|
+
dotId: g.dotId,
|
|
645
|
+
caseId,
|
|
646
|
+
caseVersion: c ? ensureVersion(c) : 1,
|
|
647
|
+
position: ++position,
|
|
648
|
+
state: newest.result,
|
|
649
|
+
attempt: 1,
|
|
650
|
+
updatedAt: newest.at,
|
|
651
|
+
createdAt: newest.at,
|
|
652
|
+
});
|
|
653
|
+
items++;
|
|
654
|
+
}
|
|
655
|
+
for (const r of results)
|
|
656
|
+
update('case_results', r.id, { testRunId: t.id, runItemId: item.id, attempt: 1, dotRunId: g.runId, ...(c ? { engine: engineOf(c) } : {}) });
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
return { testRuns, items };
|
|
661
|
+
}
|
|
662
|
+
//# sourceMappingURL=test-runs.js.map
|