@bugmole/cli 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. package/.bugmole.env.example +20 -0
  2. package/LICENSE +7 -0
  3. package/README.md +293 -0
  4. package/TESTING.md +117 -0
  5. package/bugmole.config.yaml +39 -0
  6. package/package.json +85 -0
  7. package/scripts/billing/paypal-setup.mjs +121 -0
  8. package/scripts/bugmole-continue.ts +318 -0
  9. package/scripts/bugmole-init.ts +188 -0
  10. package/scripts/bugmole.cjs +17 -0
  11. package/scripts/bugmole.test.ts +344 -0
  12. package/scripts/bugmole.ts +657 -0
  13. package/scripts/ensure-maestro.cjs +79 -0
  14. package/scripts/ios-tunnel-keeper.sh +45 -0
  15. package/scripts/ios-wda-keeper.sh +66 -0
  16. package/scripts/sync-plan-catalog.d.mts +3 -0
  17. package/scripts/sync-plan-catalog.mjs +16 -0
  18. package/scripts/ui-parity-diff.py +65 -0
  19. package/scripts/ui-parity-requirements.txt +1 -0
  20. package/scripts/verify-manage-to-plans.mts +194 -0
  21. package/spec/app-ui-audit.schema.json +176 -0
  22. package/spec/blockers.yaml +79 -0
  23. package/spec/bugs.index.json +42 -0
  24. package/spec/design-dna.schema.json +38 -0
  25. package/spec/domain_rules.yaml +24 -0
  26. package/spec/flows/flow_manage-to-plans-64c3c61b.yaml +8 -0
  27. package/spec/flows/flow_screen-to-evidence-6c3ab309.yaml +7 -0
  28. package/spec/journey_graph.yaml +126 -0
  29. package/spec/journeys.graph.json +2618 -0
  30. package/spec/plans/dashboard-smoke.flow.yaml +20 -0
  31. package/spec/plans/example.flow.yaml +99 -0
  32. package/spec/plans/flow_api-keys-to-logout-7396cd5d.flow.yaml +33 -0
  33. package/spec/plans/flow_api-keys-to-screen-157e10a6.flow.yaml +33 -0
  34. package/spec/plans/flow_manage-to-audits-176c1eb8.flow.yaml +33 -0
  35. package/spec/plans/flow_manage-to-blockers-633282c8.flow.yaml +112 -0
  36. package/spec/plans/flow_manage-to-devices-ad57e202.flow.yaml +33 -0
  37. package/spec/plans/flow_manage-to-logout-86c54656.flow.yaml +33 -0
  38. package/spec/plans/flow_manage-to-manage-resource-action-6325f99a.flow.yaml +185 -0
  39. package/spec/plans/flow_manage-to-parity-issues-01fa2579.flow.yaml +34 -0
  40. package/spec/plans/flow_manage-to-plans-64c3c61b.flow.yaml +123 -0
  41. package/spec/plans/flow_manage-to-screen-6857f915.flow.yaml +106 -0
  42. package/spec/plans/flow_manage-to-tasks-c5791c95.flow.yaml +33 -0
  43. package/spec/plans/flow_profile-to-screen-6045aa3d.flow.yaml +33 -0
  44. package/spec/plans/flow_register-to-api-auth-login-460a9cc8.flow.yaml +34 -0
  45. package/spec/plans/flow_screen-to-audits-07666356.flow.yaml +33 -0
  46. package/spec/plans/flow_screen-to-blockers-091d258b.flow.yaml +33 -0
  47. package/spec/plans/flow_screen-to-devices-cad72f75.flow.yaml +33 -0
  48. package/spec/plans/flow_screen-to-evidence-6c3ab309.flow.yaml +126 -0
  49. package/spec/plans/flow_screen-to-parity-issues-2218e3ad.flow.yaml +34 -0
  50. package/spec/plans/flow_screen-to-plans-8232a94f.flow.yaml +33 -0
  51. package/spec/plans/flow_screen-to-tasks-540671d1.flow.yaml +33 -0
  52. package/spec/plans/login.flow.yaml +22 -0
  53. package/spec/plans/owner-operations.flow.yaml +20 -0
  54. package/spec/project_config.yaml +55 -0
  55. package/spec/roles.yaml +30 -0
  56. package/spec/schema.md +394 -0
  57. package/spec/test-case-results.schema.json +62 -0
  58. package/spec/test-cases.schema.json +85 -0
  59. package/spec/ui-parity-audit.schema.json +194 -0
  60. package/spec/ui-reverse-engineering.schema.json +94 -0
  61. package/src/billing/plan-catalog.test.ts +46 -0
  62. package/src/billing/plan-catalog.ts +199 -0
  63. package/src/integrations/aws-sigv4.test.ts +42 -0
  64. package/src/integrations/aws-sigv4.ts +72 -0
  65. package/src/integrations/device-farm.ts +155 -0
  66. package/src/integrations/github-app.test.ts +57 -0
  67. package/src/integrations/github-app.ts +143 -0
  68. package/src/integrations/gitlab.ts +81 -0
  69. package/src/integrations/temp-email.test.ts +123 -0
  70. package/src/integrations/temp-email.ts +175 -0
  71. package/src/integrations/testflight-feedback.test.ts +51 -0
  72. package/src/integrations/testflight-feedback.ts +173 -0
  73. package/src/integrations/webdriver-client.ts +131 -0
  74. package/src/mcp/server.test.ts +1220 -0
  75. package/src/mcp/server.ts +3064 -0
  76. package/src/mcp/write-test-cases.test.ts +287 -0
  77. package/src/registry/api-key-client.ts +39 -0
  78. package/src/registry/control-plane-client.ts +212 -0
  79. package/src/registry/migrations/0001_registry.sql +47 -0
  80. package/src/registry/migrations/0002_device_authorizations.sql +23 -0
  81. package/src/registry/migrations/0003_project_environments.sql +25 -0
  82. package/src/registry/migrations/0004_device_authorization_email.sql +1 -0
  83. package/src/registry/migrations/0005_testing_control_plane.sql +55 -0
  84. package/src/registry/migrations/0006_workspaces.sql +36 -0
  85. package/src/registry/migrations/0007_project_apps.sql +26 -0
  86. package/src/registry/migrations/0008_agent_tasks.sql +30 -0
  87. package/src/registry/migrations/0009_journey_revisions.sql +17 -0
  88. package/src/registry/migrations/0010_agent_task_journey.sql +2 -0
  89. package/src/registry/migrations/0011_run_journey_revision.sql +1 -0
  90. package/src/registry/migrations/0012_canonical_flow_execution.sql +10 -0
  91. package/src/registry/migrations/0013_device_sessions.sql +22 -0
  92. package/src/registry/migrations/0014_agent_task_step.sql +1 -0
  93. package/src/registry/migrations/0015_agent_task_attempts.sql +6 -0
  94. package/src/registry/migrations/0016_github_issue_tracker.sql +54 -0
  95. package/src/registry/migrations/0017_run_targets.sql +7 -0
  96. package/src/registry/migrations/0018_run_fix_from.sql +4 -0
  97. package/src/registry/migrations/0019_workspace_flags.sql +9 -0
  98. package/src/registry/migrations/0020_orgs.sql +40 -0
  99. package/src/registry/migrations/0021_billing_core.sql +58 -0
  100. package/src/registry/migrations/0022_cloud_runners.sql +19 -0
  101. package/src/registry/migrations/0023_signup.sql +4 -0
  102. package/src/registry/migrations/0024_billing.sql +67 -0
  103. package/src/registry/migrations/0025_notifications.sql +47 -0
  104. package/src/registry/migrations/0026_repo_bindings.sql +28 -0
  105. package/src/registry/migrations/0027_feedback.sql +29 -0
  106. package/src/registry/migrations/0028_devices.sql +48 -0
  107. package/src/registry/migrations/0029_sso.sql +31 -0
  108. package/src/registry/migrations/0030_workspace_domains.sql +18 -0
  109. package/src/registry/migrations/0031_gitlab_and_teams.sql +45 -0
  110. package/src/registry/migrations/0032_personas.sql +15 -0
  111. package/src/registry/migrations/0033_bugmole_rename.sql +11 -0
  112. package/src/registry/task-scheduling.test.ts +100 -0
  113. package/src/registry/task-scheduling.ts +80 -0
  114. package/src/registry-worker/ai/platform-model.ts +77 -0
  115. package/src/registry-worker/ai/routes.test.ts +88 -0
  116. package/src/registry-worker/ai/routes.ts +90 -0
  117. package/src/registry-worker/artifacts.test.ts +98 -0
  118. package/src/registry-worker/artifacts.ts +85 -0
  119. package/src/registry-worker/billing/billing-core.test.ts +175 -0
  120. package/src/registry-worker/billing/checkout-routes.ts +209 -0
  121. package/src/registry-worker/billing/enforcement.ts +69 -0
  122. package/src/registry-worker/billing/entitlements.ts +108 -0
  123. package/src/registry-worker/billing/ledger.ts +186 -0
  124. package/src/registry-worker/billing/paypal/api.ts +259 -0
  125. package/src/registry-worker/billing/paypal/client.ts +91 -0
  126. package/src/registry-worker/billing/paypal/provider.ts +143 -0
  127. package/src/registry-worker/billing/paypal.test.ts +466 -0
  128. package/src/registry-worker/billing/provider.ts +114 -0
  129. package/src/registry-worker/billing/routes.ts +66 -0
  130. package/src/registry-worker/billing/subscriptions.ts +780 -0
  131. package/src/registry-worker/billing/thresholds.ts +107 -0
  132. package/src/registry-worker/core.ts +308 -0
  133. package/src/registry-worker/devices/devices.test.ts +185 -0
  134. package/src/registry-worker/devices/policy.ts +71 -0
  135. package/src/registry-worker/devices/routes.ts +453 -0
  136. package/src/registry-worker/domains/domains.test.ts +210 -0
  137. package/src/registry-worker/domains/routes.ts +139 -0
  138. package/src/registry-worker/domains.ts +88 -0
  139. package/src/registry-worker/email/sender.ts +75 -0
  140. package/src/registry-worker/env.d.ts +14716 -0
  141. package/src/registry-worker/features.ts +20 -0
  142. package/src/registry-worker/feedback/feedback.test.ts +230 -0
  143. package/src/registry-worker/feedback/format.ts +148 -0
  144. package/src/registry-worker/feedback/routes.ts +386 -0
  145. package/src/registry-worker/flags.ts +39 -0
  146. package/src/registry-worker/github/checks.test.ts +177 -0
  147. package/src/registry-worker/github/checks.ts +374 -0
  148. package/src/registry-worker/gitlab/checks.test.ts +141 -0
  149. package/src/registry-worker/gitlab/checks.ts +349 -0
  150. package/src/registry-worker/hooks.ts +54 -0
  151. package/src/registry-worker/index.ts +2077 -0
  152. package/src/registry-worker/jobs/index.ts +29 -0
  153. package/src/registry-worker/jobs/retention.ts +68 -0
  154. package/src/registry-worker/mcp/mcp.test.ts +355 -0
  155. package/src/registry-worker/mcp/routes.ts +215 -0
  156. package/src/registry-worker/mcp/token.ts +126 -0
  157. package/src/registry-worker/mcp/tools.ts +563 -0
  158. package/src/registry-worker/notifications/alerts.ts +212 -0
  159. package/src/registry-worker/notifications/notifications.test.ts +298 -0
  160. package/src/registry-worker/notifications/outbox.ts +83 -0
  161. package/src/registry-worker/notifications/routes.ts +280 -0
  162. package/src/registry-worker/notifications/secrets.ts +49 -0
  163. package/src/registry-worker/notifications/slack.ts +96 -0
  164. package/src/registry-worker/notifications/teams.ts +46 -0
  165. package/src/registry-worker/org/audit.ts +116 -0
  166. package/src/registry-worker/org/routes.test.ts +163 -0
  167. package/src/registry-worker/org/routes.ts +302 -0
  168. package/src/registry-worker/personas/personas.test.ts +78 -0
  169. package/src/registry-worker/personas/routes.ts +100 -0
  170. package/src/registry-worker/repo-triggers.ts +20 -0
  171. package/src/registry-worker/routes/index.ts +74 -0
  172. package/src/registry-worker/run-events.ts +24 -0
  173. package/src/registry-worker/runner/dispatch.ts +219 -0
  174. package/src/registry-worker/runner/jobs.ts +43 -0
  175. package/src/registry-worker/runner/metering.ts +82 -0
  176. package/src/registry-worker/runner/policy.ts +59 -0
  177. package/src/registry-worker/runner/routes.ts +171 -0
  178. package/src/registry-worker/runner/runner.test.ts +358 -0
  179. package/src/registry-worker/runner/tokens.ts +93 -0
  180. package/src/registry-worker/runs.test.ts +60 -0
  181. package/src/registry-worker/signup/policy.ts +57 -0
  182. package/src/registry-worker/signup/routes.ts +106 -0
  183. package/src/registry-worker/signup/signup.test.ts +81 -0
  184. package/src/registry-worker/sso/aegis.ts +141 -0
  185. package/src/registry-worker/sso/membership.ts +157 -0
  186. package/src/registry-worker/sso/routes.ts +458 -0
  187. package/src/registry-worker/sso/sso.test.ts +344 -0
  188. package/src/registry-worker/testing/d1-shim.ts +180 -0
  189. package/src/registry-worker/testing/harness.ts +137 -0
  190. package/src/runner-worker/index.ts +108 -0
  191. package/src/runtime/ai-analysis.ts +97 -0
  192. package/src/runtime/ai-exploration.test.ts +32 -0
  193. package/src/runtime/ai-exploration.ts +69 -0
  194. package/src/runtime/ai-repair.ts +74 -0
  195. package/src/runtime/ai-work.test.ts +99 -0
  196. package/src/runtime/android-screen-record.test.ts +75 -0
  197. package/src/runtime/android-screen-record.ts +192 -0
  198. package/src/runtime/app-understanding.test.ts +123 -0
  199. package/src/runtime/app-understanding.ts +201 -0
  200. package/src/runtime/appium-driver.test.ts +179 -0
  201. package/src/runtime/appium-driver.ts +295 -0
  202. package/src/runtime/blocker-resolution.test.ts +113 -0
  203. package/src/runtime/blocker-resolution.ts +111 -0
  204. package/src/runtime/browser-matrix.integration.test.ts +212 -0
  205. package/src/runtime/browser-matrix.test.ts +143 -0
  206. package/src/runtime/browser-matrix.ts +200 -0
  207. package/src/runtime/canonical-flow.test.ts +52 -0
  208. package/src/runtime/config-validate.ts +185 -0
  209. package/src/runtime/continuous-execution.ts +291 -0
  210. package/src/runtime/cursor-applescript.ts +573 -0
  211. package/src/runtime/cursor-cli-driver.test.ts +78 -0
  212. package/src/runtime/cursor-cli-driver.ts +156 -0
  213. package/src/runtime/cursor-driver-example.ts +117 -0
  214. package/src/runtime/cursor-driver-index.ts +65 -0
  215. package/src/runtime/cursor-driver-init.ts +277 -0
  216. package/src/runtime/cursor-driver-run.test.ts +15 -0
  217. package/src/runtime/cursor-driver-run.ts +323 -0
  218. package/src/runtime/cursor-driver.ts +332 -0
  219. package/src/runtime/cursor-llm-example.ts +90 -0
  220. package/src/runtime/cursor-llm.ts +206 -0
  221. package/src/runtime/cursor-mcp-monitor.ts +386 -0
  222. package/src/runtime/device-clouds/browserstack.ts +73 -0
  223. package/src/runtime/device-clouds/device-farm.ts +52 -0
  224. package/src/runtime/device-clouds/index.ts +92 -0
  225. package/src/runtime/device-clouds/kobiton.ts +70 -0
  226. package/src/runtime/device-clouds/targets.ts +44 -0
  227. package/src/runtime/device-clouds/types.ts +62 -0
  228. package/src/runtime/diff-proposal.ts +84 -0
  229. package/src/runtime/discovery-task.test.ts +29 -0
  230. package/src/runtime/discovery-task.ts +284 -0
  231. package/src/runtime/driver-recovery.ts +69 -0
  232. package/src/runtime/driver.ts +79 -0
  233. package/src/runtime/environment.test.ts +104 -0
  234. package/src/runtime/environment.ts +137 -0
  235. package/src/runtime/executor.test.ts +509 -0
  236. package/src/runtime/executor.ts +921 -0
  237. package/src/runtime/explorer.test.ts +101 -0
  238. package/src/runtime/explorer.ts +1013 -0
  239. package/src/runtime/failure-analysis.test.ts +111 -0
  240. package/src/runtime/failure-analysis.ts +272 -0
  241. package/src/runtime/fixtures/fake-maestro.sh +36 -0
  242. package/src/runtime/flow-language.test.ts +268 -0
  243. package/src/runtime/flow-language.ts +414 -0
  244. package/src/runtime/init-wizard.ts +354 -0
  245. package/src/runtime/ios-screen-record.test.ts +68 -0
  246. package/src/runtime/ios-screen-record.ts +155 -0
  247. package/src/runtime/journey-editor.ts +452 -0
  248. package/src/runtime/journey-evidence.test.ts +161 -0
  249. package/src/runtime/journey-evidence.ts +180 -0
  250. package/src/runtime/journey-graph.test.ts +257 -0
  251. package/src/runtime/journey-graph.ts +170 -0
  252. package/src/runtime/legacy-names.ts +32 -0
  253. package/src/runtime/llm-example.ts +105 -0
  254. package/src/runtime/llm.ts +527 -0
  255. package/src/runtime/local-browser.test.ts +45 -0
  256. package/src/runtime/local-browser.ts +48 -0
  257. package/src/runtime/local-registry-stub.test.ts +325 -0
  258. package/src/runtime/local-registry-stub.ts +803 -0
  259. package/src/runtime/maestro-driver.test.ts +84 -0
  260. package/src/runtime/maestro-driver.ts +209 -0
  261. package/src/runtime/mole-voice.ts +21 -0
  262. package/src/runtime/nav-crawl.test.ts +100 -0
  263. package/src/runtime/nav-crawl.ts +153 -0
  264. package/src/runtime/pipeline.test.ts +405 -0
  265. package/src/runtime/pipeline.ts +833 -0
  266. package/src/runtime/planner.test.ts +37 -0
  267. package/src/runtime/planner.ts +274 -0
  268. package/src/runtime/platform-ai.ts +76 -0
  269. package/src/runtime/playwright-driver.test.ts +93 -0
  270. package/src/runtime/playwright-driver.ts +620 -0
  271. package/src/runtime/project-spec.ts +140 -0
  272. package/src/runtime/record-run-verdicts.ts +68 -0
  273. package/src/runtime/reporter.test.ts +56 -0
  274. package/src/runtime/reporter.ts +158 -0
  275. package/src/runtime/reset.test.ts +44 -0
  276. package/src/runtime/reset.ts +61 -0
  277. package/src/runtime/reviewer.test.ts +73 -0
  278. package/src/runtime/reviewer.ts +158 -0
  279. package/src/runtime/run-job.ts +136 -0
  280. package/src/runtime/run-once.test.ts +207 -0
  281. package/src/runtime/run-once.ts +168 -0
  282. package/src/runtime/run.ts +132 -0
  283. package/src/runtime/screen-recording.ts +34 -0
  284. package/src/runtime/serve-gateway.test.ts +74 -0
  285. package/src/runtime/serve-gateway.ts +164 -0
  286. package/src/runtime/serve-worker.test.ts +23 -0
  287. package/src/runtime/serve-worker.ts +278 -0
  288. package/src/runtime/site-discovery.test.ts +168 -0
  289. package/src/runtime/site-discovery.ts +308 -0
  290. package/src/runtime/target-runner.ts +144 -0
  291. package/src/runtime/test-case-verdicts.test.ts +94 -0
  292. package/src/runtime/test-case-verdicts.ts +120 -0
  293. package/src/runtime/ui-reverse-engineering/coordinator.test.ts +59 -0
  294. package/src/runtime/ui-reverse-engineering/coordinator.ts +391 -0
  295. package/src/runtime/ui-reverse-engineering/types.ts +197 -0
  296. package/src/runtime/web-suite.test.ts +97 -0
  297. package/src/runtime/web-suite.ts +176 -0
  298. package/src/storage/create-object-store.ts +144 -0
  299. package/src/storage/keys.ts +34 -0
  300. package/src/storage/local-artifact-server.test.ts +314 -0
  301. package/src/storage/local-artifact-server.ts +357 -0
  302. package/src/storage/object-store.test.ts +28 -0
  303. package/src/storage/object-store.ts +101 -0
  304. package/src/storage/registry-object-store.ts +88 -0
  305. package/src/storage/remote-object-store.ts +104 -0
  306. package/src/storage/storage-directory.test.ts +43 -0
  307. package/src/storage/storage-directory.ts +24 -0
  308. package/tsconfig.json +24 -0
@@ -0,0 +1,20 @@
1
+ # Safe local template for Bugmole. Copy to .bugmole.env and fill values privately.
2
+ # Never commit .bugmole.env or credentials.
3
+ BUGMOLE_PROJECT_ID=bugmole
4
+ BUGMOLE_PROJECT_NAME=Bugmole
5
+ BUGMOLE_ENVIRONMENT=local
6
+ BUGMOLE_STORAGE_PROVIDER=local
7
+ BUGMOLE_LOCAL_ARTIFACTS_DIR=./qa/bugmole-runs
8
+
9
+ # Bugmole CLI registry and machine credential
10
+ BUGMOLE_REGISTRY_URL=https://api.bugmole.com
11
+ # Optional override for device-code onboarding.
12
+ BUGMOLE_DASHBOARD_URL=https://app.bugmole.com
13
+ # Keep this machine credential in the private .bugmole.env or a secret manager.
14
+ BUGMOLE_API_KEY=
15
+
16
+ # Optional LLM configuration
17
+ LLM_PROVIDER=manual
18
+ LLM_MODEL=manual-review
19
+ LLM_API_KEY=
20
+ LLM_BASE_URL=
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2026 The AI, Inc.
2
+
3
+ All rights reserved.
4
+
5
+ This software and its source code are proprietary and confidential. No license
6
+ or right to use, copy, modify, distribute, sublicense, or sell this software
7
+ is granted without prior written permission from The AI, Inc.
package/README.md ADDED
@@ -0,0 +1,293 @@
1
+ ## TestFlight feedback
2
+
3
+ The standalone Bugmole dashboard accepts normalized TestFlight feedback at
4
+ `POST /api/integrations/testflight/feedback` and displays the read-only local queue in its
5
+ TestFlight feedback panel. See `docs/testflight-feedback.md` for the payload, HMAC signature,
6
+ curl example, and production persistence limitations.
7
+
8
+ # @bugmole/cli
9
+
10
+ The `@bugmole/cli` package contains the Bugmole MCP framework and the typed project
11
+ configuration contract used by the standalone dashboard. The framework is
12
+ English-only; the rental product remains separate and Vietnamese-only.
13
+
14
+ The framework provides QA/MCP orchestration, typed project registries, browser evidence helpers, and autonomous smoke-testing workflows. It is maintained independently from the Arion rental application and its dashboard.
15
+
16
+ ## Root Repository Commands
17
+
18
+ ```bash
19
+ npm test
20
+ npm run bugmole:mcp
21
+ npm run bugmole:explore
22
+ npm run bugmole:report
23
+ not included in this repository
24
+ not included in this repository
25
+ ```
26
+
27
+ `npm test` runs the package's safe MCP/unit tests and does not require secrets. The moved dashboard lives in `apps/qa` and runs at `http://localhost:3020`:
28
+
29
+ ```bash
30
+ cd apps/qa
31
+ npm install
32
+ npm run dev
33
+ ```
34
+
35
+ Automated exploration modes may require the rental app to be running:
36
+
37
+ ```bash
38
+ npm run dev -- -p 3010
39
+ npm run bugmole:explore
40
+ ```
41
+
42
+ The published CLI exposes both `bugmole` (primary) and `bm` (alias) binaries.
43
+ Run the MCP server with either alias:
44
+
45
+ ```bash
46
+ npm install
47
+ npx bugmole --mcp
48
+ bugmole --mcp
49
+ bm --mcp
50
+ ```
51
+
52
+ ### Interactive initialization
53
+
54
+ Run the configuration wizard from the workspace you want to configure:
55
+
56
+ ```bash
57
+ bugmole init
58
+ # equivalent:
59
+ bugmole --init
60
+ npm run bugmole:init
61
+ ```
62
+
63
+ The wizard prompts for project id/name, environment, spec and evidence paths, artifact
64
+ directory, and storage provider (`local`, `gcs`, `s3`, or `r2`). Cloud providers additionally
65
+ prompt for non-secret bucket/region/account/endpoint identifiers. It writes `.bugmole/config.yaml`
66
+ and, when absent, `.bugmole.env`; credential fields contain only `REPLACE_ME` placeholders.
67
+ Existing configuration is shown as the default and is not overwritten without confirmation.
68
+
69
+ For CI or scripts, no prompt is opened:
70
+
71
+ ```bash
72
+ BUGMOLE_NON_INTERACTIVE=true bugmole init
73
+ bugmole init --non-interactive --storage-provider local --force
74
+ bugmole init --non-interactive --storage-provider r2 --bucket qa-artifacts --account-id ACCOUNT_ID
75
+ ```
76
+
77
+ Non-interactive mode keeps an existing config unless `--force` is supplied. It never reads,
78
+ prints, or stores credential values. `.bugmole.env` is ignored by git; use `.bugmole.env.example` as
79
+ the safe template for local/cloud variable names. `bugmole --mcp` remains non-interactive.
80
+
81
+ The legacy `--mode mcp` form remains accepted for compatibility. Cursor should
82
+ invoke the moved `scripts/bugmole.ts` entrypoint with `--mcp`.
83
+
84
+ ## Web suites
85
+
86
+ `--mode suite` runs a directory of Maestro-style flow files against a running web
87
+ app with the Playwright driver. It is deterministic: no LLM, no project
88
+ configuration, no registry — just flows, a base URL, and evidence.
89
+
90
+ ```bash
91
+ bugmole --mode suite --flows qa/flows --base-url http://localhost:3111 --project cinely
92
+ ```
93
+
94
+ Flows run in file-name order, so a numbered directory reads as one journey. Each
95
+ run writes per-flow screenshots, a video, a step log, and a `web-suite-report.json`
96
+ summary under the artifacts directory, and the process exits non-zero if any flow
97
+ failed or was blocked.
98
+
99
+ | Flag | Meaning |
100
+ | --- | --- |
101
+ | `--flows <dir>` | Flow directory (default `.maestro`) |
102
+ | `--base-url <url>` | Application base URL, or `BUGMOLE_BASE_URL` |
103
+ | `--project <id>` | Project id used in the evidence path |
104
+ | `--artifacts-dir <dir>` | Evidence directory (default `qa/bugmole-runs`) |
105
+ | `--grep <list>` | Only run flows whose file name contains one of these comma-separated substrings |
106
+ | `--share-session` | Keep one signed-in session across the whole suite |
107
+ | `--headed` | Run with a visible browser |
108
+
109
+ `assertVisible`/`assertNotVisible` check that an element is painted on screen.
110
+ `assertClickable` checks something stronger: that it is the actual hit-test
111
+ target at its own center point -- catching a bug class those cannot, where an
112
+ unrelated fixed-position element (a chat mascot, a floating action button, a
113
+ toast) is visually painted somewhere else but silently swallows the tap
114
+ because it sits on top in z-order.
115
+
116
+ Each flow gets its own browser context, so one journey cannot silently prop up
117
+ the next. `--share-session` opts into the opposite: cookies and local storage
118
+ carry forward, which is what a multi-step signed-in journey needs.
119
+
120
+ ### Flow vocabulary
121
+
122
+ The web driver interprets the Maestro subset that web journeys actually need:
123
+
124
+ `launchApp`, `stopApp`, `openLink` (absolute or relative to the base URL),
125
+ `tapOn` (plain text, or `{ text, index, optional }`), `inputText`, `eraseText`,
126
+ `pressKey`, `assertVisible`, `assertNotVisible`, `assertClickable` (plain text,
127
+ or `{ text, index, timeout }`), `extendedWaitUntil` (`visible` or `notVisible`
128
+ with a `timeout`), `scrollUntilVisible`, `wait`, `takeScreenshot`, `retry`
129
+ (`{ maxRetries, commands }`), `requestTempEmail`, and `openEmailLink`.
130
+
131
+ Two behaviors are worth knowing when authoring flows:
132
+
133
+ - **Assertions match what a person sees** — rendered text, the value typed into
134
+ a field, and a control's accessible name. Matching only rendered text would
135
+ report an edited form field as missing.
136
+ - **An uncaught page error fails the flow** even when every step passed, because
137
+ a journey that "passes" on a crashed page is not evidence. Set
138
+ `ignorePageErrors: true` in the flow header to opt out.
139
+
140
+ A header may declare `url`; when the driver target supplies a base URL, that
141
+ wins over a mobile `appId`, so device flows can be replayed on the web. It may
142
+ also declare `viewport: 390x844` (or `{ width, height }`) to pin the width a
143
+ layout is asserted at.
144
+
145
+ Screen-reader-only text -- content clipped to a 1x1 box -- is not treated as
146
+ visible, so a flow can assert that a visually-hidden label stayed hidden.
147
+
148
+ Only the `.*` wildcard idiom (e.g. `.*Falling For You.*`) is treated as a
149
+ regex pattern; every other character is matched literally. Real UI copy is
150
+ full of regex metacharacters -- periods, dollar signs, parentheses, plus
151
+ signs -- and a flow author should never have to escape ordinary text like
152
+ "$3.99" or "(USD)" to assert it.
153
+
154
+ ### Passwords and other secrets
155
+
156
+ Never write a real password into a flow. Reference it instead, and set it on
157
+ the machine that runs the flow:
158
+
159
+ ```yaml
160
+ - tapOn: "Password"
161
+ - inputText: "{{secret.APP_PASSWORD}}"
162
+ ```
163
+
164
+ ```bash
165
+ export BUGMOLE_FLOW_SECRET_APP_PASSWORD='…'
166
+ ```
167
+
168
+ `{{secret.NAME}}` reads only `BUGMOLE_FLOW_SECRET_NAME` -- a flow cannot read
169
+ any other environment variable -- and only `inputText` may use it, so a secret
170
+ is typed but never asserted, navigated to, or shown. Logs and step results
171
+ mask everything typed (`•••• (12 chars)`), email links are logged without
172
+ their query string, and the session a suite shares between flows
173
+ (`--share-session`) is deleted when the suite ends.
174
+
175
+ ### Real email, for real signup flows
176
+
177
+ `requestTempEmail` creates a genuinely receivable disposable inbox (via
178
+ [mail.tm](https://mail.tm)'s public API, not browser automation against a
179
+ temp-mail website -- several of those gate message content behind a CAPTCHA)
180
+ and binds its address to a name -- `tempEmail` by default -- that any later
181
+ step can reference as `{{tempEmail}}`:
182
+
183
+ ```yaml
184
+ - requestTempEmail
185
+ - openLink: "/signup"
186
+ - tapOn: "Email"
187
+ - inputText: "{{tempEmail}}"
188
+ - tapOn: "Password"
189
+ - inputText: "{{secret.SIGNUP_PASSWORD}}"
190
+ - tapOn: "Create account"
191
+ - openEmailLink:
192
+ from: "cinely.net"
193
+ subject: "Confirm"
194
+ match: "confirm"
195
+ timeout: 30000
196
+ ```
197
+
198
+ `openEmailLink` waits for a message at the bound inbox (optionally filtered
199
+ by `from` and/or `subject`, both substring/case-insensitive), pulls the first
200
+ link out of it -- or the first link whose URL or text contains `match` --
201
+ and navigates the page there. Real transactional email routes links through
202
+ the sending provider's own click-tracking redirect; this follows that
203
+ redirect exactly like a person clicking it in their real mail client would,
204
+ rather than trying to parse out the "real" destination underneath it. Give a
205
+ custom `as:` to either step to run more than one inbox in the same flow
206
+ (`requestTempEmail: "secondInbox"` / `openEmailLink: { as: "secondInbox" }`).
207
+
208
+ Every inbox created this way is deleted when the flow ends, pass or fail --
209
+ these are disposable by design, and a QA run must not accumulate live
210
+ mail.tm accounts every time it executes. What is **not** cleaned up
211
+ automatically is whatever your own application created because of the
212
+ signup (an auth user, a database row): that's application-specific, and
213
+ Bugmole has no way to know what your app did with the address it received.
214
+
215
+ This turned a real, live production bug (an auth confirmation link that
216
+ silently redirected to the wrong environment) from something that could only
217
+ be checked by a person manually driving a disposable-inbox website into a
218
+ flow that runs like any other.
219
+
220
+ ## Cloud worker
221
+
222
+ `Dockerfile.worker` builds a headless project worker that runs `bugmole serve` on Linux: it claims web runs from the registry, reads plans and flows from remote object storage, runs them with Playwright, and writes evidence back to that storage. It doesn't run agent tasks or drive devices. See `docs/cloud-worker.md` for configuration and limits.
223
+
224
+ ## Configuration
225
+
226
+ Defaults are defined in `bugmole.config.yaml`:
227
+
228
+ - Base URL QA: `http://localhost:3010`.
229
+ - Spec package: `spec`.
230
+ - Artifact runtime: `qa/bugmole-runs`.
231
+ - Current browser evidence manifest: `qa/browser-evidence.json`.
232
+ - Current screenshot evidence: `qa/screenshots`.
233
+
234
+ Never print `.env` values, service-role keys, webhook secrets, or LLM keys in QA logs. To run an LLM-backed mode, provide `LLM_PROVIDER`, `LLM_MODEL`, and `LLM_API_KEY` through a private local/CI environment.
235
+
236
+ Project registration uses the private `.bugmole.env` file for `BUGMOLE_API_KEY`;
237
+ the CLI does not load the dashboard or registry `.env`. The key is never
238
+ written to generated configuration or printed.
239
+
240
+ ## External QA UI
241
+
242
+ The read-only QA dashboard is maintained in `apps/qa`. It does not read `.env` in the browser
243
+ or write rental application data. With `AEGIS_AUTH_REQUIRED=true`, its server routes require an
244
+ existing Aegis identity and only expose authorized project context.
245
+
246
+ ## Multiple projects
247
+
248
+ The shared schema is in `projects/types.ts`. A project has an
249
+ `id`, display metadata, `environment.baseUrl`, `plans`, `testCases`,
250
+ `evidence`, `blockers`, an `evidenceRun`, and aggregate `stats`. The registry
251
+ helper in `projects/registry.ts` validates duplicate IDs.
252
+
253
+ The `arion-rent` project is assembled from the existing
254
+ `spec/*`, `QA_TEST_PLAN.md`, `QA_EVIDENCE.md`, and
255
+ `qa/browser-evidence.json` data in the Arion repository.
256
+ The `Bugmole` project (stable id `qa-framework`) covers this package and the
257
+ standalone dashboard using its own tests, specs, and documentation. It has no screenshot evidence
258
+ until a dedicated framework browser run captures it.
259
+
260
+ ### Copyable test-case references
261
+
262
+ Each standalone-dashboard test-case card and detail modal offers **Copy reference**. It copies
263
+ the stable project, environment, test-plan, and test-case IDs from the typed registry, plus names,
264
+ status, evidence/screenshot information, and a suggested coding-agent context block. See
265
+ `docs/test-case-references.md` for the exact format and clipboard fallback behavior. The prompt is
266
+ context for an agent request only; it does not imply automatic fixing.
267
+
268
+ To add a project, define a typed object in `projects`, give it a
269
+ unique stable `id`, set its environment, plans, test cases, blockers, and real
270
+ evidence references, then add it to the `createQaProjectRegistry([...])` call
271
+ used by the dashboard. This is a typed TypeScript configuration path; it
272
+ contains no secrets. Changes require restarting the QA dev server (and
273
+ rebuilding for production). There is no runtime persistence or authentication
274
+ for project configuration.
275
+
276
+ Each project declares one or more URL-only environments with a stable `id`,
277
+ display `name`, `baseUrl`, optional `apiUrl`, `isDefault`, and `status`
278
+ (`active`, `inactive`, or `planned`). Add local, staging, or production
279
+ environments to the project object; the dashboard selector and query state
280
+ derive from that list without UI changes. Evidence may optionally set
281
+ `environmentId`; evidence for another environment is not shown as current
282
+ proof, and missing evidence remains explicitly unavailable.
283
+
284
+ ## Arion Specs
285
+
286
+ The spec files are tailored to the current MVP:
287
+
288
+ - `spec/project_config.yaml`: route, manifest, and app startup configuration.
289
+ - `spec/journey_graph.yaml`: landing page, public booking, payments, owner dashboard, reporting, and webhooks.
290
+ - `spec/domain_rules.yaml`: Vietnamese rental-app copy, missing Supabase schema, private Storage, QR/bank transfer payments, and OM secret headers.
291
+ - `spec/blockers.yaml`: setup states, disabled forms, missing payment data, destructive confirmations, and the secret-output hard stop.
292
+
293
+ The Arion rental app and its QA dashboard remain in their own repository; this standalone package should reference external projects through explicit environment paths when needed.
package/TESTING.md ADDED
@@ -0,0 +1,117 @@
1
+ # MCP Server Testing
2
+
3
+ ## Overview
4
+
5
+ Comprehensive unit tests for all MCP tools to ensure they handle errors gracefully and never crash the server. The test suite covers:
6
+
7
+ - ✅ All Bugmole MCP tools (`bugmole_*`)
8
+ - ✅ Error handling and edge cases
9
+ - ✅ Path resolution (relative, absolute, with/without spec/ prefix)
10
+ - ✅ File operations (read, write, create directories)
11
+ - ✅ Environment variable handling
12
+ - ✅ JSON-RPC error format compliance
13
+
14
+ ## Running Tests
15
+
16
+ ```bash
17
+ # Run all MCP server tests
18
+ npm run test:mcp
19
+
20
+ # Run all tests (if more test files are added)
21
+ npm test
22
+ ```
23
+
24
+ From the workspace root, use `npm test` for this package and `not included in this repository`
25
+ to verify an external read-only QA UI. The QA UI runs with
26
+ `not included in this repository` on `http://localhost:3020`; the rental app remains separate at
27
+ the repo root and is normally explored on `http://localhost:3010`.
28
+
29
+ ## Test Coverage
30
+
31
+ ### bugmole_read_spec
32
+
33
+ - ✅ Reads existing spec files
34
+ - ✅ Handles file not found gracefully with helpful error messages
35
+ - ✅ Resolves paths with `spec/` prefix
36
+ - ✅ Handles absolute paths
37
+ - ✅ Tries multiple path resolution strategies
38
+ - ✅ Uses environment variables for project directory detection
39
+
40
+ ### bugmole_write_spec
41
+
42
+ - ✅ Writes spec files successfully
43
+ - ✅ Creates nested directories automatically
44
+ - ✅ Handles invalid file paths gracefully
45
+
46
+ ### bugmole_report_progress
47
+
48
+ - ✅ Creates progress report files
49
+ - ✅ Handles all status types (working, blocked, completed)
50
+
51
+ ### bugmole_commit_response
52
+
53
+ - ✅ Saves commit responses with all fields
54
+ - ✅ Always includes `next_steps` as array (never undefined)
55
+
56
+ ### bugmole_explore
57
+
58
+ - ✅ Returns error when not implemented (doesn't crash)
59
+ - ✅ Handles invalid URLs gracefully
60
+
61
+ ### bugmole_plan & bugmole_run
62
+
63
+ - ✅ Handle missing journeys/plans gracefully
64
+ - ✅ Don't crash on invalid inputs
65
+
66
+ ### Error Handling
67
+
68
+ - ✅ All tool calls wrapped in error handler
69
+ - ✅ Errors returned in JSON-RPC format
70
+ - ✅ Server never crashes on tool errors
71
+
72
+ ### Path Resolution
73
+
74
+ - ✅ Handles relative paths from different directories
75
+ - ✅ Uses environment variables (BUGMOLE_PROJECT_DIR, CURSOR_PROJECT_DIRECTORY)
76
+ - ✅ Tries multiple resolution strategies
77
+
78
+ ## Test Results
79
+
80
+ ```
81
+ ✅ 20 tests passing
82
+ ✅ 0 tests failing
83
+ ✅ All MCP tools covered
84
+ ```
85
+
86
+ ## Key Principles
87
+
88
+ 1. **Never Crash**: All tools must handle errors gracefully and return JSON-RPC error responses
89
+ 2. **Helpful Errors**: Error messages include debug information (paths tried, working directory, etc.)
90
+ 3. **Path Flexibility**: Tools try multiple path resolution strategies to find files
91
+ 4. **Robustness**: Tools handle missing files, invalid inputs, and edge cases without crashing
92
+
93
+ ## Adding New Tests
94
+
95
+ When adding new MCP tools:
96
+
97
+ 1. Add test cases in `src/mcp/server.test.ts`
98
+ 2. Test both success and failure scenarios
99
+ 3. Ensure errors are returned in JSON-RPC format
100
+ 4. Verify the server doesn't crash on any input
101
+ 5. Test path resolution if the tool reads/writes files
102
+
103
+ ## Continuous Integration
104
+
105
+ These tests should be run:
106
+
107
+ - Before committing changes to MCP tools
108
+ - In CI/CD pipeline
109
+ - When adding new MCP tools
110
+ - When fixing MCP tool bugs
111
+
112
+ ## Notes
113
+
114
+ - Tests use temporary directories that are cleaned up after execution
115
+ - All file operations are isolated to test directories
116
+ - Environment variables are restored after tests
117
+ - Tests can run in parallel (each uses its own temp directory)
@@ -0,0 +1,39 @@
1
+ version: 1
2
+ name: Bugmole MCP
3
+
4
+ runtime:
5
+ env: ${BUGMOLE_ENV:-sandbox}
6
+ workspace_id: ${BUGMOLE_WORKSPACE_ID:-default}
7
+ artifacts_dir: ${BUGMOLE_ARTIFACTS_DIR:-./qa/bugmole-runs}
8
+ spec_dir: ${BUGMOLE_SPEC_DIR:-./spec}
9
+
10
+ llm:
11
+ provider: ${LLM_PROVIDER:-manual}
12
+ api_key: ${LLM_API_KEY:-not-set}
13
+ model: ${LLM_MODEL:-manual-review}
14
+ base_url: ${LLM_BASE_URL}
15
+
16
+ mcp:
17
+ enabled: ${MCP_ENABLED:-true}
18
+ host: ${MCP_HOST:-127.0.0.1}
19
+ port: ${MCP_PORT:-3187}
20
+
21
+ execution:
22
+ driver: ${BUGMOLE_DRIVER:-maestro}
23
+ maestro:
24
+ command: ${MAESTRO_COMMAND:-maestro}
25
+ timeout_ms: ${MAESTRO_TIMEOUT_MS:-300000}
26
+ playwright:
27
+ base_url: ${PLAYWRIGHT_BASE_URL:-http://localhost:3010}
28
+ headless: ${PLAYWRIGHT_HEADLESS:-true}
29
+ retries:
30
+ step: 2
31
+ journey: 1
32
+
33
+ # Optional: Project directory to open in Cursor for testing
34
+ # If specified, will open a new Cursor window in this directory before running tests
35
+ cursor_driver:
36
+ # Self-QA explores the dashboard app under apps/qa, not the monorepo root,
37
+ # so that is the default — but this stays overridable, because the same
38
+ # config is used when pointing Bugmole at any other project.
39
+ project_directory: ${CURSOR_PROJECT_DIRECTORY:-apps/qa}
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@bugmole/cli",
3
+ "version": "0.4.0",
4
+ "private": false,
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "description": "Bugmole CLI and MCP server for autonomous QA and smoke testing.",
9
+ "type": "module",
10
+ "engines": {
11
+ "node": ">=22"
12
+ },
13
+ "main": "scripts/bugmole.ts",
14
+ "files": [
15
+ "scripts/",
16
+ "src/",
17
+ "spec/",
18
+ "LICENSE",
19
+ "README.md",
20
+ "TESTING.md",
21
+ ".bugmole.env.example",
22
+ "tsconfig.json",
23
+ "bugmole.config.yaml"
24
+ ],
25
+ "bin": {
26
+ "bugmole": "scripts/bugmole.cjs",
27
+ "bm": "scripts/bugmole.cjs"
28
+ },
29
+ "scripts": {
30
+ "postinstall": "node scripts/ensure-maestro.cjs",
31
+ "bugmole:mcp": "NODE_OPTIONS=--max-old-space-size=512 tsx --no-cache scripts/bugmole.ts --mcp",
32
+ "bugmole:explore": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole.ts --mode explore",
33
+ "bugmole:plan": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole.ts --mode plan",
34
+ "bugmole:run": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole.ts --mode run",
35
+ "bugmole:propose-diff": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole.ts --mode propose-diff",
36
+ "bugmole:review": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole.ts --mode review",
37
+ "bugmole:report": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole.ts --mode report",
38
+ "bugmole:cursor-driver": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole.ts --mode cursor-driver",
39
+ "bugmole:init-env": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole.ts --mode init-env",
40
+ "bugmole:init": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole.ts init",
41
+ "bugmole:cursor-init": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole-init.ts",
42
+ "bugmole:continue": "NODE_OPTIONS=--max-old-space-size=512 tsx scripts/bugmole-continue.ts",
43
+ "registry:dev": "wrangler dev --local",
44
+ "registry:deploy": "wrangler deploy",
45
+ "registry:migrate": "wrangler d1 migrations apply valkyrie-registry --remote",
46
+ "runner:dev": "wrangler dev -c wrangler.runner.jsonc",
47
+ "runner:deploy": "wrangler deploy -c wrangler.runner.jsonc",
48
+ "sync:catalog": "node scripts/sync-plan-catalog.mjs",
49
+ "test": "NODE_OPTIONS=--max-old-space-size=512 tsx --test --test-concurrency=1 scripts/bugmole.test.ts src/mcp/server.test.ts projects/registry.test.ts src/integrations/testflight-feedback.test.ts src/integrations/temp-email.test.ts src/storage/object-store.test.ts src/storage/local-artifact-server.test.ts src/storage/storage-directory.test.ts src/runtime/reset.test.ts src/runtime/serve-gateway.test.ts src/registry/task-scheduling.test.ts src/registry-worker/artifacts.test.ts src/registry-worker/runs.test.ts src/registry-worker/org/routes.test.ts src/registry-worker/billing/billing-core.test.ts src/registry-worker/billing/paypal.test.ts src/registry-worker/ai/routes.test.ts src/registry-worker/runner/runner.test.ts src/registry-worker/signup/signup.test.ts src/registry-worker/notifications/notifications.test.ts src/registry-worker/github/checks.test.ts src/registry-worker/gitlab/checks.test.ts src/registry-worker/personas/personas.test.ts src/registry-worker/feedback/feedback.test.ts src/registry-worker/devices/devices.test.ts src/registry-worker/domains/domains.test.ts src/registry-worker/sso/sso.test.ts src/registry-worker/mcp/mcp.test.ts src/integrations/github-app.test.ts src/runtime/run-once.test.ts src/runtime/appium-driver.test.ts src/integrations/aws-sigv4.test.ts src/runtime/ai-work.test.ts src/billing/plan-catalog.test.ts src/mcp/write-test-cases.test.ts src/runtime/pipeline.test.ts src/runtime/planner.test.ts src/runtime/test-case-verdicts.test.ts src/runtime/journey-graph.test.ts src/runtime/journey-evidence.test.ts src/runtime/local-browser.test.ts src/runtime/serve-worker.test.ts src/runtime/cursor-driver-run.test.ts src/runtime/explorer.test.ts src/runtime/nav-crawl.test.ts src/runtime/app-understanding.test.ts src/runtime/environment.test.ts src/runtime/blocker-resolution.test.ts src/runtime/ui-reverse-engineering/coordinator.test.ts src/runtime/maestro-driver.test.ts src/runtime/playwright-driver.test.ts src/runtime/flow-language.test.ts src/runtime/web-suite.test.ts src/runtime/canonical-flow.test.ts src/runtime/executor.test.ts src/runtime/ios-screen-record.test.ts src/runtime/android-screen-record.test.ts src/runtime/reviewer.test.ts src/runtime/reporter.test.ts src/runtime/cursor-cli-driver.test.ts src/runtime/local-registry-stub.test.ts src/runtime/browser-matrix.test.ts src/runtime/browser-matrix.integration.test.ts src/runtime/failure-analysis.test.ts src/runtime/site-discovery.test.ts src/runtime/ai-exploration.test.ts src/runtime/discovery-task.test.ts",
50
+ "test:mcp": "NODE_OPTIONS=--max-old-space-size=512 tsx --test --test-concurrency=1 scripts/bugmole.test.ts src/mcp/server.test.ts projects/registry.test.ts src/integrations/testflight-feedback.test.ts src/storage/object-store.test.ts src/runtime/maestro-driver.test.ts src/runtime/canonical-flow.test.ts",
51
+ "typecheck": "NODE_OPTIONS=--max-old-space-size=512 tsc --noEmit"
52
+ },
53
+ "keywords": [
54
+ "e2e",
55
+ "testing",
56
+ "qa",
57
+ "playwright",
58
+ "ai",
59
+ "automation"
60
+ ],
61
+ "author": "",
62
+ "license": "UNLICENSED",
63
+ "dependencies": {
64
+ "@aws-sdk/client-s3": "^3.1085.0",
65
+ "@aws-sdk/s3-request-presigner": "^3.1085.0",
66
+ "@google-cloud/storage": "^8.0.1",
67
+ "@types/ws": "^8.18.1",
68
+ "dotenv": "^17.4.2",
69
+ "playwright": "^1.62.1",
70
+ "tsx": "^4.7.0",
71
+ "ws": "^8.21.1",
72
+ "yaml": "^2.4.0"
73
+ },
74
+ "devDependencies": {
75
+ "@cloudflare/containers": "^0.3.7",
76
+ "@types/node": "^26.4.0",
77
+ "typescript": "^7.0.2",
78
+ "wrangler": "^4.110.0"
79
+ },
80
+ "overrides": {
81
+ "gaxios": {
82
+ "uuid": "^11.1.1"
83
+ }
84
+ }
85
+ }