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,83 @@
|
|
|
1
|
+
// Railway Infrastructure as Code for localdost. Preview with `railway config plan`, then run
|
|
2
|
+
// `railway config apply --yes`. docs/DEPLOY.md has the full recipe. The project is `localdost`
|
|
3
|
+
// (workspace "Huy Dao's Projects", next to `superapp`); both services below live in it.
|
|
4
|
+
//
|
|
5
|
+
// There is no build target here. Railway builds the root Dockerfile, and its last stage is the
|
|
6
|
+
// `runner` target (Playwright image with browsers), so hosted test runs work.
|
|
7
|
+
// No `source` either: `railway up` or a GitHub link supplies the code.
|
|
8
|
+
import { defineRailway, preserve, project, service, volume } from 'railway/iac';
|
|
9
|
+
|
|
10
|
+
export default defineRailway(() => {
|
|
11
|
+
// SQLite, VAPID keys, saved credentials, and run artifacts live here.
|
|
12
|
+
const data = volume('qadots-data', { sizeMB: 5120 });
|
|
13
|
+
|
|
14
|
+
const qadots = service('qadots', {
|
|
15
|
+
start: 'node dist/index.js',
|
|
16
|
+
healthcheck: '/',
|
|
17
|
+
healthcheckTimeout: 60,
|
|
18
|
+
// SQLite needs exactly one replica.
|
|
19
|
+
replicas: 1,
|
|
20
|
+
deploy: {
|
|
21
|
+
// Refuse to start without the volume, so a missing mount cannot silently write to the container disk.
|
|
22
|
+
requiredMountPath: '/data',
|
|
23
|
+
// Restart a crashed server a few times, then stop and show the failure instead of looping.
|
|
24
|
+
restartPolicyType: 'ON_FAILURE',
|
|
25
|
+
restartPolicyMaxRetries: 5,
|
|
26
|
+
// Seconds the old instance gets to finish SQLite writes after SIGTERM.
|
|
27
|
+
drainingSeconds: 10,
|
|
28
|
+
},
|
|
29
|
+
env: {
|
|
30
|
+
HOST: '0.0.0.0',
|
|
31
|
+
PORT: '4319',
|
|
32
|
+
QADOTS_DATA_DIR: '/data',
|
|
33
|
+
QADOTS_POLL: '1',
|
|
34
|
+
QADOTS_LLM: 'anthropic',
|
|
35
|
+
// Railway mounts volumes as root. The container starts as root, and its entrypoint gives /data
|
|
36
|
+
// to the qadots user and drops to it before the server starts (KAT-209).
|
|
37
|
+
RAILWAY_RUN_UID: '0',
|
|
38
|
+
// Secrets are set with `railway variable set NAME --stdin`; apply keeps the stored value.
|
|
39
|
+
QADOTS_TOKEN: preserve(),
|
|
40
|
+
GITHUB_TOKEN: preserve(),
|
|
41
|
+
ANTHROPIC_API_KEY: preserve(),
|
|
42
|
+
LINEAR_API_KEY: preserve(),
|
|
43
|
+
// TinyBee: this service is the staging Bee (`bee-dev`). The Hive URL is the private address of the hive service.
|
|
44
|
+
TINYBEE_ENV: 'staging',
|
|
45
|
+
TINYBEE_HIVE_URL: 'http://hive.railway.internal:4330',
|
|
46
|
+
},
|
|
47
|
+
volumeMounts: { '/data': data },
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// TinyBee (docs/tinybee/06-environments-and-delivery.md section 1.1). The `qadots` service above doubles as
|
|
51
|
+
// `bee-dev`, the cloud-hosted Bee of tenant `dev`; the Hive control plane is a service of its own. The PWA
|
|
52
|
+
// reaches Hive through the Bee's /api/hive proxy (TINYBEE_HIVE_URL), so one origin serves both.
|
|
53
|
+
const hiveData = volume('hive-data', { sizeMB: 1024 });
|
|
54
|
+
const hive = service('hive', {
|
|
55
|
+
start: 'node dist/hive/index.js',
|
|
56
|
+
healthcheck: '/api/hive/health',
|
|
57
|
+
healthcheckTimeout: 60,
|
|
58
|
+
replicas: 1,
|
|
59
|
+
deploy: {
|
|
60
|
+
requiredMountPath: '/data',
|
|
61
|
+
restartPolicyType: 'ON_FAILURE',
|
|
62
|
+
restartPolicyMaxRetries: 5,
|
|
63
|
+
drainingSeconds: 10,
|
|
64
|
+
},
|
|
65
|
+
env: {
|
|
66
|
+
HOST: '0.0.0.0',
|
|
67
|
+
PORT: '4330',
|
|
68
|
+
TINYBEE_ENV: 'staging',
|
|
69
|
+
TINYBEE_TENANT_HOST: 'dots-{slug}.testllms.com',
|
|
70
|
+
HIVE_DATA_DIR: '/data',
|
|
71
|
+
RAILWAY_RUN_UID: '0',
|
|
72
|
+
// Set with `railway variable set NAME --stdin --service hive`. Unset CF_* keeps the mock tunnel provider.
|
|
73
|
+
HIVE_JWT_PRIVATE_KEY: preserve(),
|
|
74
|
+
HIVE_JWT_KID: preserve(),
|
|
75
|
+
CF_ACCOUNT_ID: preserve(),
|
|
76
|
+
CF_ZONE_ID: preserve(),
|
|
77
|
+
CF_API_TOKEN: preserve(),
|
|
78
|
+
},
|
|
79
|
+
volumeMounts: { '/data': hiveData },
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return project('localdost', { resources: [data, qadots, hiveData, hive] });
|
|
83
|
+
});
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Set up localdost for a repo
|
|
2
|
+
|
|
3
|
+
These are the steps a coding agent follows when a person asks it to set up localdost for their repo, and to host it when they ask for that. Run each step, read its output, and fix what it reports before the next step. The person's repo is the "target repo" below. localdost itself lives in a separate checkout.
|
|
4
|
+
|
|
5
|
+
## Safety rules
|
|
6
|
+
|
|
7
|
+
- Never ask the person to paste a token, key, or password into the chat. When a step needs a secret, ask them to export it in their own shell, or to run the login command themselves.
|
|
8
|
+
- Never print a secret. Do not run `printenv` or `env` without a variable name, `railway variable list --kv`, or `gh auth token` on its own. Pipe a secret straight into the command that needs it (`gh auth token | railway variable set GITHUB_TOKEN --stdin --service localdost`).
|
|
9
|
+
- Never write a secret into a file. `.env.localdost` holds only references: `${env:NAME}` reads the person's shell, `${cmd:gh auth token}` runs a command at start. Keep it that way.
|
|
10
|
+
- Never commit `.env.localdost` or `.localdost/data/`. `localdost init` adds both to `.gitignore`. `.localdost/config.json` holds no secrets and is safe to commit.
|
|
11
|
+
- Set `LOCALDOST_TOKEN` before the server is reachable from the internet (a tunnel, a cloud host). Without it the API has no auth.
|
|
12
|
+
- Leave the dot's rules at their defaults. Ticket comments ask first. Change a rule to `act` only when the person asks for it.
|
|
13
|
+
- Logins open a browser: `gh auth login`, `claude auth login`, `railway login`. Ask the person to run them, then continue.
|
|
14
|
+
|
|
15
|
+
## Steps
|
|
16
|
+
|
|
17
|
+
### 1. Install localdost
|
|
18
|
+
|
|
19
|
+
localdost needs Node 24. If `~/localdost` does not exist, clone and build it once, then put the `localdost` command on the PATH:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
git clone https://github.com/duonghaijoe/localdost ~/localdost
|
|
23
|
+
cd ~/localdost
|
|
24
|
+
npm ci
|
|
25
|
+
npm run build
|
|
26
|
+
npm link
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
When `npm link` is not allowed, use `node ~/localdost/bin/localdost.js` wherever this file says `localdost`.
|
|
30
|
+
|
|
31
|
+
### 2. Init in the target repo
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cd <target repo>
|
|
35
|
+
localdost init --yes
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`init` reads the GitHub repo and default branch from `git remote get-url origin`, the test command and Playwright config from `package.json`, checks `gh auth token`, checks the Claude CLI login with a `claude -p` round trip (else uses `ANTHROPIC_API_KEY` from the shell), and picks Linear or Jira when `LINEAR_API_KEY` or `JIRA_*` is exported. It writes `.env.localdost` and `.localdost/config.json`, and creates the first dot in `.localdost/data/`. Running it again updates the same dot.
|
|
39
|
+
|
|
40
|
+
Pass flags for what it cannot detect:
|
|
41
|
+
|
|
42
|
+
| Need | Flag |
|
|
43
|
+
|---|---|
|
|
44
|
+
| Linear team | `--tracker linear --linear-team ENG` |
|
|
45
|
+
| Jira project | `--tracker jira --jira-url https://acme.atlassian.net --jira-project SHOP` |
|
|
46
|
+
| GitHub Issues | `--tracker github`, with `--tracker-repos owner/name` for the repo whose issues the dot reviews and where it files defects, `--require-labels pod:agentic` to review only issues with that label, and `--milestone 2026.11` |
|
|
47
|
+
| No tracker | `--tracker none` |
|
|
48
|
+
| A test command other than `npx playwright test` | `--command "npx playwright test --project=chromium"` |
|
|
49
|
+
| The app URL the tests run against | `--base-url http://localhost:3000` |
|
|
50
|
+
| A fixed port | `--port 4319` (default: 4319, or the next free port) |
|
|
51
|
+
|
|
52
|
+
The test command runs without a shell, so `&&` and pipes do not work in it. Put install and build steps in the dot's Setup steps (`runner.setup`), for example `npm ci && npx playwright install chromium && npm run build`, and use **Try it** in the dot dialog to check both.
|
|
53
|
+
|
|
54
|
+
### 3. Doctor
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
localdost doctor
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
It prints one line per service. `FAIL` lines carry a `fix:` command. Run each fix, or ask the person to run it when it is a login or needs a key, then run `localdost doctor` again. Repeat until it exits 0. `warn` lines are optional services (Slack, voice, Docker, a public URL) and do not block. `localdost doctor --json` gives the same checks as JSON.
|
|
61
|
+
|
|
62
|
+
### 4. Start
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
localdost start
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Run it in the background. It loads `.env.localdost`, resolves the references, and serves the app on `http://localhost:<PORT>`. Check that `curl -s http://localhost:<PORT>/api/dots` lists the dot. GitHub and the tracker are polled every 60 seconds, so no webhook is needed. The first poll of a new dot takes its 5 most recently updated open PRs, and their PR comment and check wait for approval unless the repo's PR scope names authors, a team or issue labels; after that, only new work.
|
|
69
|
+
|
|
70
|
+
### 5. Deploy, only when the person asks to host it
|
|
71
|
+
|
|
72
|
+
Skip this step unless the person asked to host or deploy localdost (for example "and host it on Railway"). Do not create cloud projects, services, or volumes on your own. When they did ask, follow the Railway section of `~/localdost/docs/DEPLOY.md`. It needs Railway CLI 5.42.1 or newer (`railway --version`). Run from `~/localdost`:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
cd ~/localdost
|
|
76
|
+
railway login # the person runs this one, it opens a browser
|
|
77
|
+
railway init --name localdost
|
|
78
|
+
railway config plan # preview what .railway/railway.ts creates
|
|
79
|
+
railway config apply --yes # service, 5 GB volume at /data, non-secret variables
|
|
80
|
+
|
|
81
|
+
# Secrets from stdin, never printed. Set only the ones the person has.
|
|
82
|
+
openssl rand -hex 24 | railway variable set LOCALDOST_TOKEN --stdin --skip-deploys --service localdost
|
|
83
|
+
gh auth token | railway variable set GITHUB_TOKEN --stdin --skip-deploys --service localdost
|
|
84
|
+
printenv ANTHROPIC_API_KEY | railway variable set ANTHROPIC_API_KEY --stdin --skip-deploys --service localdost
|
|
85
|
+
printenv LINEAR_API_KEY | railway variable set LINEAR_API_KEY --stdin --skip-deploys --service localdost
|
|
86
|
+
|
|
87
|
+
railway up --detach --service localdost
|
|
88
|
+
railway domain --port 4319 --service localdost
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Then create the dot on the hosted server with the domain `railway domain` printed:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
railway run --service localdost node bin/localdost.js init --yes --dir <target repo> --server https://<railway domain>
|
|
95
|
+
railway run --service localdost node bin/localdost.js doctor --dir <target repo>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Test runs work on Railway: the default image is the `runner` target with browsers, and the first run of each cloned repo installs its dependencies. The real limits are memory and disk. Chromium needs at least 2 GB of RAM, and the volume is 5 GB. Tell the person both.
|
|
99
|
+
|
|
100
|
+
## Done
|
|
101
|
+
|
|
102
|
+
Tell the person, in a few lines: the URL, the dot name, the doctor result, and any `warn` line they may want to fix. Do not include any secret value.
|
package/Dockerfile
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
#
|
|
3
|
+
# localdost image. Two targets:
|
|
4
|
+
# app Node 24 slim. Serves the API and the PWA. No browsers, so demo and local
|
|
5
|
+
# Playwright runs need either the runner target or docker runner mode.
|
|
6
|
+
# runner The same app on the pinned Playwright image, so local and demo runs have
|
|
7
|
+
# Chromium, Firefox, and WebKit installed. It is the last stage, so a plain
|
|
8
|
+
# `docker build` and Railway (which builds the last stage) produce it.
|
|
9
|
+
#
|
|
10
|
+
# docker build --target app -t qadots:app .
|
|
11
|
+
# docker build --target runner -t qadots:runner .
|
|
12
|
+
#
|
|
13
|
+
# Keep runner last. Reordering the stages changes what Railway deploys (test/runner-default-install.test.ts).
|
|
14
|
+
#
|
|
15
|
+
# PLAYWRIGHT_VERSION must match node_modules/@playwright/test. A mismatch fails at run
|
|
16
|
+
# time with "Executable doesn't exist". Renovate bumps both together (renovate.json).
|
|
17
|
+
|
|
18
|
+
ARG NODE_VERSION=24
|
|
19
|
+
ARG PLAYWRIGHT_VERSION=1.63.0
|
|
20
|
+
|
|
21
|
+
# All dependencies, for the build and for the runner target.
|
|
22
|
+
FROM node:${NODE_VERSION}-bookworm-slim AS deps
|
|
23
|
+
WORKDIR /app
|
|
24
|
+
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
|
|
25
|
+
COPY package.json package-lock.json .npmrc ./
|
|
26
|
+
RUN npm ci --no-audit --no-fund
|
|
27
|
+
|
|
28
|
+
# Server (tsc to dist/) and client (vite to dist/web).
|
|
29
|
+
FROM deps AS build
|
|
30
|
+
COPY tsconfig.json tsconfig.client.json vite.config.ts ./
|
|
31
|
+
COPY src ./src
|
|
32
|
+
COPY client ./client
|
|
33
|
+
COPY scripts/copy-assets.mjs ./scripts/
|
|
34
|
+
RUN npx tsc -p tsconfig.json && node scripts/copy-assets.mjs && npx vite build
|
|
35
|
+
|
|
36
|
+
# Production dependencies only, for the app target.
|
|
37
|
+
FROM node:${NODE_VERSION}-bookworm-slim AS prod-deps
|
|
38
|
+
WORKDIR /app
|
|
39
|
+
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
|
|
40
|
+
COPY package.json package-lock.json .npmrc ./
|
|
41
|
+
RUN npm ci --omit=dev --no-audit --no-fund
|
|
42
|
+
|
|
43
|
+
# App target. LOCALDOST_DATA_DIR holds the SQLite database, VAPID keys, and artifacts.
|
|
44
|
+
FROM node:${NODE_VERSION}-bookworm-slim AS app
|
|
45
|
+
# HOST=0.0.0.0 needs LOCALDOST_TOKEN: without a token the server refuses a non-loopback address.
|
|
46
|
+
ENV NODE_ENV=production \
|
|
47
|
+
HOST=0.0.0.0 \
|
|
48
|
+
PORT=4319 \
|
|
49
|
+
LOCALDOST_DATA_DIR=/data
|
|
50
|
+
# git: GitHub checkouts for local runs. tini: reaps Playwright and git child processes.
|
|
51
|
+
RUN apt-get update \
|
|
52
|
+
&& apt-get install -y --no-install-recommends ca-certificates git tini \
|
|
53
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
54
|
+
WORKDIR /app
|
|
55
|
+
COPY --from=prod-deps --chown=root:root /app/node_modules ./node_modules
|
|
56
|
+
COPY --from=build --chown=root:root /app/dist ./dist
|
|
57
|
+
COPY --chown=root:root package.json ./
|
|
58
|
+
# demo/ holds the sample shop and payloads for LOCALDOST_DEMO=1. The client is in dist/web.
|
|
59
|
+
COPY --chown=root:root demo ./demo
|
|
60
|
+
# Guides for the in-app docs viewer (#/docs).
|
|
61
|
+
COPY --chown=root:root docs ./docs
|
|
62
|
+
COPY --chown=root:root README.md ./
|
|
63
|
+
RUN mkdir -p /data && chown node:node /data
|
|
64
|
+
USER node
|
|
65
|
+
# /data is the volume (compose.yml and docs/DEPLOY.md mount it). No VOLUME line: Railway's builder refuses it.
|
|
66
|
+
EXPOSE 4319
|
|
67
|
+
# /api/setup sits behind the bearer token when LOCALDOST_TOKEN is set, so the probe sends it.
|
|
68
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
|
69
|
+
CMD ["node", "-e", "fetch('http://127.0.0.1:'+(process.env.PORT||4319)+'/api/setup',{headers:process.env.LOCALDOST_TOKEN?{authorization:'Bearer '+process.env.LOCALDOST_TOKEN}:{}}).then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"]
|
|
70
|
+
ENTRYPOINT ["/usr/bin/tini", "--"]
|
|
71
|
+
CMD ["node", "dist/index.js"]
|
|
72
|
+
|
|
73
|
+
# Runner target, and the default because it is the last stage. Railway builds the last stage.
|
|
74
|
+
# The Playwright v1.63 noble image ships Node 24 and the browsers in /ms-playwright.
|
|
75
|
+
FROM mcr.microsoft.com/playwright:v${PLAYWRIGHT_VERSION}-noble AS runner
|
|
76
|
+
# HOST=0.0.0.0 needs LOCALDOST_TOKEN: without a token the server refuses a non-loopback address.
|
|
77
|
+
ENV NODE_ENV=production \
|
|
78
|
+
HOST=0.0.0.0 \
|
|
79
|
+
PORT=4319 \
|
|
80
|
+
LOCALDOST_DATA_DIR=/data \
|
|
81
|
+
PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
|
|
82
|
+
RUN apt-get update \
|
|
83
|
+
&& apt-get install -y --no-install-recommends ca-certificates git tini \
|
|
84
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
85
|
+
# The server and the test runs it spawns run as qadots, which owns /app and /data. The browsers in
|
|
86
|
+
# /ms-playwright stay owned by root and are made readable by every user.
|
|
87
|
+
RUN useradd --system --create-home --home-dir /home/qadots --uid 10001 --shell /usr/sbin/nologin qadots \
|
|
88
|
+
&& mkdir -p /app /data \
|
|
89
|
+
&& chown qadots:qadots /app /data \
|
|
90
|
+
&& chmod -R a+rX /ms-playwright
|
|
91
|
+
WORKDIR /app
|
|
92
|
+
# Full node_modules: the runner spawns `npx playwright test`, and generated specs import @playwright/test from here.
|
|
93
|
+
COPY --from=deps --chown=qadots:qadots /app/node_modules ./node_modules
|
|
94
|
+
COPY --from=build --chown=qadots:qadots /app/dist ./dist
|
|
95
|
+
COPY --chown=qadots:qadots package.json ./
|
|
96
|
+
COPY --chown=qadots:qadots demo ./demo
|
|
97
|
+
# Guides for the in-app docs viewer (#/docs).
|
|
98
|
+
COPY --chown=qadots:qadots docs ./docs
|
|
99
|
+
COPY --chown=qadots:qadots README.md ./
|
|
100
|
+
# Railway mounts the volume as root and starts the container as root (RAILWAY_RUN_UID=0). The
|
|
101
|
+
# entrypoint then hands /data to qadots and drops to that user. Docker and Compose start as qadots.
|
|
102
|
+
COPY --chmod=0755 scripts/docker-entrypoint.sh /usr/local/bin/qadots-entrypoint
|
|
103
|
+
USER qadots
|
|
104
|
+
EXPOSE 4319
|
|
105
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
|
106
|
+
CMD ["node", "-e", "fetch('http://127.0.0.1:'+(process.env.PORT||4319)+'/api/setup',{headers:process.env.LOCALDOST_TOKEN?{authorization:'Bearer '+process.env.LOCALDOST_TOKEN}:{}}).then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"]
|
|
107
|
+
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/qadots-entrypoint"]
|
|
108
|
+
CMD ["node", "dist/index.js"]
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Huy Tieu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,276 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# localdost
|
|
4
|
+
|
|
5
|
+
### Always-on QA agents that watch every merge, ticket, and prod URL
|
|
6
|
+
|
|
7
|
+
[Get started](#get-started) · [Overview](#overview) · [Architecture](#architecture) · [Features](#features) · [Docs](#docs) · [Contributing](#contributing)
|
|
8
|
+
|
|
9
|
+
[](https://github.com/duonghaijoe/localdost/actions/workflows/ci.yml)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
[](#features)
|
|
12
|
+
|
|
13
|
+
Self-hosted. Runs with no accounts in demo mode. Bring your own Claude login or Anthropic key for real verdicts.
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
<sub>Real runs on a demo shop, sped up and trimmed as captioned. Full walkthrough: [localdost-walkthrough.mp4](docs/demos/localdost-walkthrough.mp4). Recording notes: [docs/demos](docs/demos/README.md).</sub>
|
|
20
|
+
|
|
21
|
+
## Overview
|
|
22
|
+
|
|
23
|
+
localdost gives your team a few QA helpers that never sleep. Each helper is a **dot**. A dot reads every pull request, every merge, every new ticket, and your health checks, runs your tests, and tells you on your phone when something needs you. Think of a colleague who reads every PR and every new Jira ticket, and texts you only when checkout breaks.
|
|
24
|
+
|
|
25
|
+
Every outward action, such as a PR comment, a check run, or a ticket comment, passes a rule gate first. You decide per action kind whether the dot acts, acts only when asked, asks first, or hands the job to you. Approvals wait in the Inbox of the phone app.
|
|
26
|
+
|
|
27
|
+
localdost is one Node process and one SQLite file on your machine or your server. Without credentials, every integration runs in demo mode: outward actions go to an outbox that you can read in the app, and a mock model writes canned verdicts.
|
|
28
|
+
|
|
29
|
+
### Dots and Watches
|
|
30
|
+
|
|
31
|
+
A dot holds one **Watch**: a GitHub repo, a Jira or Linear project, the production URLs it is responsible for, and a test command. The Watch also carries the dot's mission, when to notify you, and what it must never do, in your own words. Role presets (product area, QA lead, release guard, ticket reviewer, prod watcher) fill in the mission and the rules for a common job and switch on the stages it needs. One server runs many dots, and each dot has its own memory, rules, and chat.
|
|
32
|
+
|
|
33
|
+
### PR review with what to test
|
|
34
|
+
|
|
35
|
+
On every PR and every merge, the dot scopes the changed lines, maps them to impact areas, collects signals (untouched tests, removed assertions, changed routes, selector drift), and applies ten QA lenses such as money, auth, dates, and migrations. A reviewer model pass and a verifier model pass then produce risks with code citations and a **What to test** checklist. The review lands in one sticky PR comment and in a check run with line annotations. Ticking a checklist item in the comment records a manual test result on the run. Details: [docs/PR-REVIEW.md](docs/PR-REVIEW.md).
|
|
36
|
+
|
|
37
|
+

|
|
38
|
+
|
|
39
|
+
### Live test runs
|
|
40
|
+
|
|
41
|
+
After a merge, the dot picks the Playwright specs that match the changed paths plus your smoke tests, runs them, and retries failures to separate flaky tests from real breaks. The run page streams each step live, shows browser frames during the run, and keeps screenshots, traces, videos, and the JSON report. Runs execute in your checkout, in a Docker container, or against the bundled sample shop. Details: [docs/SANDBOX.md](docs/SANDBOX.md).
|
|
42
|
+
|
|
43
|
+

|
|
44
|
+
|
|
45
|
+
### AI-Vision cases
|
|
46
|
+
|
|
47
|
+
A dot can also run natural-language browser cases next to Playwright, on an AI-Vision server (Veesan) or the open-source Midscene CLI. Each What to test item from the PR review that has no existing test becomes one case, and test ideas from a ticket review of a ticket the PR names fill the rest. The cases run on `pr_check` and `post_merge`, and their verdicts, screenshots, and report links merge into the same run and checklist as the Playwright results. Details: [docs/SANDBOX.md](docs/SANDBOX.md#ai-vision-cases).
|
|
48
|
+
|
|
49
|
+
### Ticket review
|
|
50
|
+
|
|
51
|
+
A new Jira or Linear ticket gets a score for how ready it is. Tickets that score 30 or more get a review: risks, open questions, gaps in the acceptance criteria, test ideas, and existing tests that the change may break. The dot drafts a ticket comment, and by default the draft waits in your Inbox. It also checks the test cases and automated specs you already have, from any ticket, that the new ticket changes: a case that needs an update gets a draft version, a case the ticket makes obsolete gets a retire draft in your Inbox, and nothing is changed until you decide. Details: [docs/TRACKERS.md](docs/TRACKERS.md).
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
### Outage watch
|
|
56
|
+
|
|
57
|
+
HTTP probes and browser probes check your production URLs on an interval. Three failures in a row open an outage: the dot looks at merges from the last 24 hours, names a suspected cause, and pushes a high-urgency alert. A recovery notice follows when the probe passes again. Atlassian Statuspage URLs of your vendors feed the same flow. A daily digest sums up runs, flaky specs, tickets, and incidents.
|
|
58
|
+
|
|
59
|
+
### Ask-first rules and the Inbox
|
|
60
|
+
|
|
61
|
+
Each action kind has one of four levels: `act`, `act_when_asked`, `ask`, or `hand_off`. The defaults let a dot run tests, post PR comments and check runs, and send pushes on its own. Ticket comments, new issues, MCP tools that change data, and report edits ask first. Reverts go to a person. An auto-review pass can move an `act` to `ask` when a draft looks risky. In the Inbox you approve, edit, or reject the exact draft. A pending approval expires after 24 hours.
|
|
62
|
+
|
|
63
|
+
### Phone app with chat and calls
|
|
64
|
+
|
|
65
|
+
The app is a React PWA that you add to your Home Screen. It has Dots, Feed, Inbox, Chat, Reports, and Settings. Chat with a dot about its runs, ask it to rerun tests, or ask whether prod is up. Push-to-talk and read-aloud use browser speech. With `OPENAI_API_KEY` set, a call uses OpenAI Realtime over WebRTC instead. Details: [docs/VOICE.md](docs/VOICE.md).
|
|
66
|
+
|
|
67
|
+
### Slack
|
|
68
|
+
|
|
69
|
+
Mention the bot in a thread and the dot named in the message, or the dot that owns the channel, answers in the thread. Outage and digest notices post to the dot's channel. Slack connects over Socket Mode, so it needs no public URL. Details: [docs/SLACK.md](docs/SLACK.md).
|
|
70
|
+
|
|
71
|
+
### MCP connections
|
|
72
|
+
|
|
73
|
+
Connect any MCP server over HTTP or stdio and attach it to a dot. Read-only tools run directly in chat. A tool that changes data is an outward action and goes through the rule gate like a PR comment. Presets add an AI-Vision server (Veesan) or the open-source Midscene MCP server in one step, with only the env var names they declare, so a dot's chat can find cases, start a run after approval, and read the verdicts. Details: [docs/CONNECTIONS.md](docs/CONNECTIONS.md).
|
|
74
|
+
|
|
75
|
+
### Reports
|
|
76
|
+
|
|
77
|
+
Save any run or digest as a report page. Edit it in the app, or chat with the dot about the page and let it propose edits, which ask first by default.
|
|
78
|
+
|
|
79
|
+
## Architecture
|
|
80
|
+
|
|
81
|
+
```mermaid
|
|
82
|
+
flowchart LR
|
|
83
|
+
subgraph Triggers
|
|
84
|
+
GHW[GitHub webhook]
|
|
85
|
+
GHP[GitHub poller]
|
|
86
|
+
TRW[Jira and Linear webhooks]
|
|
87
|
+
LNP[Linear poller]
|
|
88
|
+
PRB[HTTP and browser probes]
|
|
89
|
+
STP[Statuspage poller]
|
|
90
|
+
SCH[Digest scheduler]
|
|
91
|
+
end
|
|
92
|
+
GHW --> NRM[webhooks.ts: verify, normalize, dedupe]
|
|
93
|
+
GHP --> NRM
|
|
94
|
+
TRW --> NRM
|
|
95
|
+
LNP --> NRM
|
|
96
|
+
NRM --> Q[(SQLite job queue)]
|
|
97
|
+
PRB --> Q
|
|
98
|
+
STP --> Q
|
|
99
|
+
SCH --> Q
|
|
100
|
+
Q --> FL[Flows: pr_check, post_merge, ci_failure, ticket_review, outage, recovery, digest, rerun]
|
|
101
|
+
FL --> REV[Review prep: scope, signals, lenses, impact]
|
|
102
|
+
REV --> LLM[Model backend: claude-cli, codex-cli, anthropic, mock]
|
|
103
|
+
FL --> LLM
|
|
104
|
+
FL --> RUN[Test runner: local, docker, demo, AI-Vision]
|
|
105
|
+
RUN --> ART[(Artifacts in the data folder)]
|
|
106
|
+
FL --> GATE{Rules gate}
|
|
107
|
+
GATE -- act --> EXT[GitHub, Jira, Linear, Slack]
|
|
108
|
+
GATE -- ask --> INB[Inbox approvals]
|
|
109
|
+
GATE -- no credentials --> OUT[(Outbox)]
|
|
110
|
+
FL --> PUSH[Web push and ntfy]
|
|
111
|
+
FL --> BUS[Live event bus]
|
|
112
|
+
BUS --> SSE[GET /api/live]
|
|
113
|
+
SSE --> PWA[React PWA]
|
|
114
|
+
PWA --> CHAT[POST /api/chat]
|
|
115
|
+
CHAT --> LLM
|
|
116
|
+
CHAT --> MCP[MCP connections]
|
|
117
|
+
PWA --> CALL[POST /api/call/session]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Every trigger becomes a `TriggerEvent` with a dedupe key, so a webhook delivery and a poll of the same commit or ticket queue one job. The queue lives in SQLite and runs two jobs at a time. Each running job holds a lease. When the server stops mid-run, the run ends as interrupted and you can rerun it. The server code is in `src/`, the PWA in `client/`, and the build contract in [SPEC.md](SPEC.md).
|
|
121
|
+
|
|
122
|
+
## Get started
|
|
123
|
+
|
|
124
|
+
localdost needs Node 24.
|
|
125
|
+
|
|
126
|
+
### Demo in one command
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
git clone https://github.com/duonghaijoe/localdost && cd localdost && npm install && npm run demo
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Open http://localhost:4319. The demo seeds a dot named "Checkout" that watches `demo/shop-web`, Jira project `SHOP`, and a sample shop on http://localhost:4320. In the app, open Settings and press a Simulate button: PR merged, PR opened, ticket created, outage, or CI failure. A simulated merge runs real Playwright tests against the sample shop. One spec passes and one fails on a seeded bug, and the dot reports the failure with a verdict. The same simulations work from a shell:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
curl -X POST http://localhost:4319/api/simulate/pr_merged
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Start a team server
|
|
139
|
+
|
|
140
|
+
One person sets a team server up, once. It takes four commands and ends in the setup flow of the app:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
git clone https://github.com/duonghaijoe/localdost && cd localdost
|
|
144
|
+
npm ci
|
|
145
|
+
npm run build
|
|
146
|
+
LOCALDOST_TOKEN=$(openssl rand -hex 24) LOCALDOST_PUBLIC_URL=https://localdost.example.com npm start
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`LOCALDOST_TOKEN` is the token every person needs to open the server. Keep it where you can read it again. `LOCALDOST_PUBLIC_URL` is the https address your team opens, and the address GitHub sends webhooks to. Leave it out and the dot polls GitHub instead, which works but misses CI failures, preview deployments, and `/localdost review` comments. With no preview of a PR, its tests run against the dot's base URL (a build of shared QA work), and the report says so; the dot setting `prTestTarget` can skip those tests instead, see [PR tests without a preview](docs/SETUP.md#pr-tests-without-a-preview). With a token set, `npm start` listens on all interfaces. Put https in front of it, or use a tunnel. [docs/DEPLOY.md](docs/DEPLOY.md) covers Railway, Docker Compose, and a tunnel to your own machine.
|
|
150
|
+
|
|
151
|
+
Back up the data folder before the pilot starts: the database, `secret.key`, and `vapid.json`. A backup without `secret.key` cannot decrypt the tokens saved in Setup. [Back up and restore](docs/DEPLOY.md#back-up-and-restore) has the commands for Docker Compose, Node with a start script, Railway, and Kubernetes, and `localdost doctor --restore-check <folder>` checks a backup. [Upgrade](docs/DEPLOY.md#upgrade) covers a new tag: pick it, read the CHANGELOG, wait until `localdost doctor --idle` exits 0, back up, switch, and roll back from that backup if needed.
|
|
152
|
+
|
|
153
|
+
Open the address. A new server shows the Join screen, which also asks **Admin? Enter the server token**: paste `LOCALDOST_TOKEN` and the **setup flow** opens: Welcome (a team server or your laptop, with a check of the token and the public URL), Event delivery, Model, GitHub, Repos with a role and a PR scope each, Tracker (GitHub Issues first), Tests per repo, Slack, Rules with a shadow week, Create dot, and a first review that posts nothing until you say so. A reload keeps you in the flow, and the **Getting started** link in the sidebar brings you back to it until you finish or close it. Each step is described in [docs/SETUP.md](docs/SETUP.md#start-a-team-server).
|
|
154
|
+
|
|
155
|
+
### Connect your services in the app
|
|
156
|
+
|
|
157
|
+
Start the server, open the app, and open **Setup**. Each service has a **Connect** button: sign in to the model with your Claude subscription or an Anthropic API key, connect GitHub with the GitHub CLI login, a GitHub App that Setup creates for you, or a token, and paste keys for Linear, Jira, Slack, and voice. **Test** checks each one before you save it. Saved keys are encrypted in the data folder and never sent back to the browser. Environment variables still work and win over saved values. The guides open inside the app: [docs/SETUP.md](docs/SETUP.md).
|
|
158
|
+
|
|
159
|
+
### Set up with a coding agent in one prompt
|
|
160
|
+
|
|
161
|
+
Open a coding agent (Claude Code, Codex, Cursor) in the repo you want a dot for, and paste:
|
|
162
|
+
|
|
163
|
+
```text
|
|
164
|
+
Set up localdost for this repo. Clone https://github.com/duonghaijoe/localdost to ~/localdost if it is not there, then follow ~/localdost/AGENTS.md. Never ask me to paste a secret into the chat: tell me which command to run or which variable to export.
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The agent follows [AGENTS.md](AGENTS.md): it builds localdost, runs `localdost init --yes` in your repo, fixes what `localdost doctor` reports, and starts the server. It stops for you at each browser login (`gh auth login`, `claude auth login`). Add "and host it on Railway" to the prompt to deploy it too.
|
|
168
|
+
|
|
169
|
+
The same steps by hand:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
cd ~/localdost && npm ci && npm run build && npm link # once
|
|
173
|
+
cd ~/code/your-repo
|
|
174
|
+
localdost init # detects the repo, tests, GitHub, Claude, tracker; writes .env.localdost with no secrets
|
|
175
|
+
localdost doctor # one line per service with a fix command; exits 1 until the required ones work
|
|
176
|
+
localdost start # http://localhost:4319
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
`localdost init` turns on poll mode, so GitHub and Linear work without a public webhook URL.
|
|
180
|
+
|
|
181
|
+
### Docker or Railway
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
LOCALDOST_TOKEN=$(openssl rand -hex 24) docker compose up -d --build
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
The image listens on all interfaces, so it needs `LOCALDOST_TOKEN` and refuses to start without one. Keep the token in `.env` next to `compose.yml` so you can read it again. Railway, Docker Compose with test runs, and a cloudflared tunnel to your own machine are in [docs/DEPLOY.md](docs/DEPLOY.md).
|
|
188
|
+
|
|
189
|
+
### Network and token
|
|
190
|
+
|
|
191
|
+
Without `LOCALDOST_TOKEN`, the server listens on `127.0.0.1` only, whatever the default `HOST` would be. In that state `/api` also answers only requests whose `Host` header names a loopback address, so a tunnel or a DNS-rebinding page gets 403. A non-loopback `HOST` such as `0.0.0.0` without a token stops the server at boot. With a token set and `HOST` unset, the server listens on `0.0.0.0`, and every `/api` call needs `Authorization: Bearer <token>`. Set the token before you open the server to your LAN, a tunnel, or the internet.
|
|
192
|
+
|
|
193
|
+
### Docs
|
|
194
|
+
|
|
195
|
+
| Topic | Doc |
|
|
196
|
+
|---|---|
|
|
197
|
+
| The setup flow of a team server, connecting services in the app, every setting, model backends, poll mode, troubleshooting | [docs/SETUP.md](docs/SETUP.md) |
|
|
198
|
+
| GitHub App, PAT, or polling | [docs/GITHUB.md](docs/GITHUB.md) |
|
|
199
|
+
| Jira and Linear | [docs/TRACKERS.md](docs/TRACKERS.md) |
|
|
200
|
+
| Slack | [docs/SLACK.md](docs/SLACK.md) |
|
|
201
|
+
| MCP connections | [docs/CONNECTIONS.md](docs/CONNECTIONS.md) |
|
|
202
|
+
| Test runners, live view, artifacts, fork safety | [docs/SANDBOX.md](docs/SANDBOX.md) |
|
|
203
|
+
| Voice | [docs/VOICE.md](docs/VOICE.md) |
|
|
204
|
+
| PR review for users | [docs/PR-REVIEW.md](docs/PR-REVIEW.md) |
|
|
205
|
+
| Hosting | [docs/DEPLOY.md](docs/DEPLOY.md) |
|
|
206
|
+
| HTTP API | [docs/API-V2.md](docs/API-V2.md) and [SPEC.md](SPEC.md) |
|
|
207
|
+
| PR review design | [docs/PR-REVIEW-QA.md](docs/PR-REVIEW-QA.md) |
|
|
208
|
+
|
|
209
|
+
## Data and privacy
|
|
210
|
+
|
|
211
|
+
localdost sends no telemetry. It keeps its state in the data folder (`LOCALDOST_DATA_DIR`, default `data/`, or `.localdost/data` under `localdost start`): the SQLite database, the web push keys, run artifacts, review checkouts, and "Not a risk" eval candidates. Data leaves the machine only for the services you configure:
|
|
212
|
+
|
|
213
|
+
| Recipient | When | What it receives |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| Anthropic | `LOCALDOST_LLM=claude-cli` or `anthropic` | Prompts: diffs, PR descriptions, ticket text, test results and log tails, dot memory, chat messages. The PR review masks common secret shapes in diff lines first. The `claude` CLI runs with its built-in tools off; a chat turn attaches only the local localdost chat tools as an MCP server. The PR review starts it with an allowlisted environment. Other calls remove the GitHub, Jira, Linear, ntfy, and push credentials and `LOCALDOST_TOKEN` from its environment |
|
|
216
|
+
| OpenAI | `LOCALDOST_LLM=codex-cli` | The same prompts as the Anthropic row, through the `codex` CLI and your ChatGPT login. The CLI runs read-only, with shell, browser, and plugins off, no MCP server except the local localdost chat tools in a chat turn, and an allowlisted environment |
|
|
217
|
+
| Your AI-Vision server, or the model behind Midscene | `runner.aivision` is set on a dot | Case titles and steps from the PR review and ticket test ideas, the start URL. The engine drives a browser against that URL and sends screenshots to its own model |
|
|
218
|
+
| GitHub, Jira, Linear | Their credentials are set | API reads with your credentials, plus the comments, check runs, and statuses the dot posts |
|
|
219
|
+
| Slack | `SLACK_APP_TOKEN` and `SLACK_BOT_TOKEN` are set | Chat answers and notices |
|
|
220
|
+
| Your browser's push service (Apple, Google, or Mozilla) | You turn on alerts in the app | Notification title and body |
|
|
221
|
+
| ntfy.sh, or your `NTFY_URL` | `NTFY_TOPIC` is set | Notification title, body, and a link |
|
|
222
|
+
| OpenAI | `OPENAI_API_KEY` is set and you start a call | Call audio and the dot's call instructions |
|
|
223
|
+
| Your browser vendor | A voice call in browser mode | Speech recognition audio, depending on the browser |
|
|
224
|
+
| MCP servers you add | A chat uses one of their tools | The tool input |
|
|
225
|
+
| mcr.microsoft.com and the npm registry | Docker runner mode | Image pulls and `npm ci` inside the test container |
|
|
226
|
+
|
|
227
|
+
The mock model (`LOCALDOST_LLM=mock`) sends nothing anywhere. Demo mode with no credentials stays on the machine, except the browser push service when you turn on alerts.
|
|
228
|
+
|
|
229
|
+
## Features
|
|
230
|
+
|
|
231
|
+
The status column says how each part was checked. **Verified live** means it ran against the real service during dogfooding. **Real run, local** means automated tests run it for real on the machine with no outside service. **Fixture-tested** means unit tests run it against recorded payloads, fakes, or mocks. **No automated test** means only the code exists.
|
|
232
|
+
|
|
233
|
+
| Area | What it does | Status |
|
|
234
|
+
|---|---|---|
|
|
235
|
+
| Claude CLI backend | Verdicts, scores, reviews, and chat through `claude -p` with your Claude login | Verified live |
|
|
236
|
+
| Codex CLI backend | Verdicts, scores, reviews, chat, and the PR review through `codex exec` with your ChatGPT login | Verified live (analyze and a QA review pass on an eval fixture) |
|
|
237
|
+
| Anthropic API backend | The same through `ANTHROPIC_API_KEY` | Fixture-tested |
|
|
238
|
+
| GitHub PAT | Polling of commits and PRs, commit statuses | Verified live |
|
|
239
|
+
| GitHub PAT | Sticky PR comments, job logs, contents reads | Fixture-tested |
|
|
240
|
+
| GitHub App | Installation tokens, check runs with annotations | Fixture-tested |
|
|
241
|
+
| GitHub webhooks | Signatures, normalizers, checklist ticks from comment edits | Fixture-tested |
|
|
242
|
+
| Linear API | Personal API key, polling for new issues, issue reads | Verified live |
|
|
243
|
+
| Linear webhooks and comments | Signature and timestamp check, ticket comments | Fixture-tested |
|
|
244
|
+
| Jira Cloud | Webhooks, REST v3 reads, ADF comments | Fixture-tested |
|
|
245
|
+
| PR review | Scoping, signals, lenses, impact, reviewer and verifier passes, sticky comment, check run | Fixture-tested: 17 eval fixtures through the mock backend, 5 of them golden cases from real misses. `npm run eval:qa-review` runs them against a live model |
|
|
246
|
+
| Ticket review | Score, review, gated comment | Fixture-tested |
|
|
247
|
+
| Impact on existing tests | Finds the cases and specs a ticket changes, drafts a new case version or a retire draft | Fixture-tested: 4 stories through the mock backend |
|
|
248
|
+
| Demo runner and local runner | Real Playwright runs, live steps, browser frames, artifacts | Real run, local (e2e suite against the sample shop) |
|
|
249
|
+
| Docker runner | Tests in a Playwright container with a read-only mount | Fixture-tested (fork guard). No test against a Docker daemon |
|
|
250
|
+
| AI-Vision runner | Natural-language cases from the PR review and ticket test ideas on an AI-Vision server, its CLI, or the Midscene CLI | Verified live against a local AI-Vision server; fixture-tested (fake server and fake CLI) |
|
|
251
|
+
| Browser probes | Playwright page load, selector wait, screenshot on failure | Real run, local |
|
|
252
|
+
| HTTP probes, Statuspage, outage and recovery | Interval checks, three-strike outage, recovery notice | Fixture-tested |
|
|
253
|
+
| Rules gate and Inbox | Four levels, auto-review, approvals with edit and expiry | Fixture-tested, plus e2e in the demo |
|
|
254
|
+
| PWA | Dots, Feed, Run, Inbox, Chat, Reports, Settings, Setup screens | Real run, local (Playwright e2e at phone and desktop sizes) |
|
|
255
|
+
| Web push and ntfy | Alerts to the phone | No automated test |
|
|
256
|
+
| Slack | Socket Mode mentions, notices | Fixture-tested (fake Web API client) |
|
|
257
|
+
| MCP connections | HTTP and stdio servers, tool calls through the gate | Fixture-tested (in-memory transport) |
|
|
258
|
+
| MCP presets | AI-Vision and Midscene presets, env name passthrough, read-only tool lists | Verified live over stdio with the AI-Vision MCP server; Midscene preset not run |
|
|
259
|
+
| Voice | Browser speech, OpenAI Realtime token minting | Fixture-tested (mocked OpenAI) |
|
|
260
|
+
| Reports | Save a run as a page, edit, chat proposals | Fixture-tested, plus e2e |
|
|
261
|
+
|
|
262
|
+
localdost is alpha software. Expect breaking changes to the database schema and the API before 1.0.
|
|
263
|
+
|
|
264
|
+
## Credits
|
|
265
|
+
|
|
266
|
+
localdost follows the product shape of [OpenDots](https://github.com/CopilotKit/OpenDots) by CopilotKit: a team of specialist dots with rules, an Inbox, chat, calls, Slack, and MCP connections. This README borrows its layout. [docs/PARITY.md](docs/PARITY.md) maps each OpenDots feature to its localdost version.
|
|
267
|
+
|
|
268
|
+
The PR review adapts the review prompt structure, change scoping, file classifiers, five review lenses, and the script-check rules from [OpenQodex](https://github.com/openqodex/openqodex), under the Apache License 2.0. [NOTICE](NOTICE) lists the adapted files, and [LICENSES/Apache-2.0.txt](LICENSES/Apache-2.0.txt) holds the license text.
|
|
269
|
+
|
|
270
|
+
## Contributing
|
|
271
|
+
|
|
272
|
+
Read [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup, the test commands, and the writing rules. Report security issues as described in [SECURITY.md](SECURITY.md). Everyone in the project follows the [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
MIT. See [LICENSE](LICENSE). Material adapted from OpenQodex stays under the Apache License 2.0, as [NOTICE](NOTICE) describes.
|
package/bin/localdost.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// localdost CLI entry. In a checkout with dev dependencies it runs the TypeScript source through
|
|
3
|
+
// tsx, so the CLI never runs a stale build. In an install without src/ or tsx (the Docker image,
|
|
4
|
+
// `npm ci --omit=dev`) it runs the compiled CLI from dist/.
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const root = fileURLToPath(new URL('..', import.meta.url));
|
|
9
|
+
const source = `${root}src/cli/index.ts`;
|
|
10
|
+
const built = `${root}dist/cli/index.js`;
|
|
11
|
+
|
|
12
|
+
let register;
|
|
13
|
+
if (existsSync(source) && !process.env.LOCALDOST_USE_DIST) {
|
|
14
|
+
try {
|
|
15
|
+
({ register } = await import('tsx/esm/api'));
|
|
16
|
+
} catch {
|
|
17
|
+
/* no dev dependencies: use dist */
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (register) {
|
|
22
|
+
register();
|
|
23
|
+
await import(pathToFileURL(source).href);
|
|
24
|
+
} else if (existsSync(built)) {
|
|
25
|
+
await import(pathToFileURL(built).href);
|
|
26
|
+
} else {
|
|
27
|
+
console.error('localdost: no build found. Run `npm ci && npm run build` in the localdost folder.');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|