agent-relay 1.1.0 → 1.2.3
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/.gitattributes +3 -0
- package/.nvmrc +1 -0
- package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.json +65 -0
- package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.md +37 -0
- package/.trajectories/completed/2026-01/traj_1k5if5snst2e.json +65 -0
- package/.trajectories/completed/2026-01/traj_1k5if5snst2e.md +37 -0
- package/.trajectories/completed/2026-01/traj_1rp3rges5811.json +49 -0
- package/.trajectories/completed/2026-01/traj_1rp3rges5811.md +31 -0
- package/.trajectories/completed/2026-01/traj_22bhyulruouw.json +113 -0
- package/.trajectories/completed/2026-01/traj_22bhyulruouw.md +57 -0
- package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.json +53 -0
- package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.md +32 -0
- package/.trajectories/completed/2026-01/traj_3t0440mjeunc.json +26 -0
- package/.trajectories/completed/2026-01/traj_3t0440mjeunc.md +6 -0
- package/.trajectories/completed/2026-01/traj_45x9494d9xnr.json +47 -0
- package/.trajectories/completed/2026-01/traj_45x9494d9xnr.md +32 -0
- package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.json +53 -0
- package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.md +32 -0
- package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.json +59 -0
- package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.md +33 -0
- package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.json +53 -0
- package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.md +32 -0
- package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.json +48 -0
- package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.md +24 -0
- package/.trajectories/completed/2026-01/traj_7ludwvz45veh.json +209 -0
- package/.trajectories/completed/2026-01/traj_7ludwvz45veh.md +97 -0
- package/.trajectories/completed/2026-01/traj_9921cuhel0pj.json +48 -0
- package/.trajectories/completed/2026-01/traj_9921cuhel0pj.md +24 -0
- package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.json +49 -0
- package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.md +23 -0
- package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.json +53 -0
- package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.md +32 -0
- package/.trajectories/completed/2026-01/traj_cxofprm2m2en.json +49 -0
- package/.trajectories/completed/2026-01/traj_cxofprm2m2en.md +31 -0
- package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.json +26 -0
- package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.md +6 -0
- package/.trajectories/completed/2026-01/traj_dfuvww9pege5.json +59 -0
- package/.trajectories/completed/2026-01/traj_dfuvww9pege5.md +37 -0
- package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.json +77 -0
- package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.md +42 -0
- package/.trajectories/completed/2026-01/traj_gjdre5voouod.json +53 -0
- package/.trajectories/completed/2026-01/traj_gjdre5voouod.md +32 -0
- package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.json +25 -0
- package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.md +15 -0
- package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.json +101 -0
- package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.md +44 -0
- package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.json +22 -0
- package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.md +5 -0
- package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.json +53 -0
- package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.md +32 -0
- package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.json +25 -0
- package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.md +15 -0
- package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.json +53 -0
- package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.md +32 -0
- package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.json +53 -0
- package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.md +32 -0
- package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.json +48 -0
- package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.md +24 -0
- package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.json +53 -0
- package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.md +32 -0
- package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.json +77 -0
- package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.md +42 -0
- package/.trajectories/completed/2026-01/traj_qft54mi7nfor.json +53 -0
- package/.trajectories/completed/2026-01/traj_qft54mi7nfor.md +32 -0
- package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.json +83 -0
- package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.md +47 -0
- package/.trajectories/completed/2026-01/traj_rd9toccj18a0.json +59 -0
- package/.trajectories/completed/2026-01/traj_rd9toccj18a0.md +37 -0
- package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.json +48 -0
- package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.md +16 -0
- package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.json +59 -0
- package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.md +37 -0
- package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.json +53 -0
- package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.md +32 -0
- package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.json +84 -0
- package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.md +109 -0
- package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.json +53 -0
- package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.md +32 -0
- package/.trajectories/completed/2026-01/traj_v87hypnongqx.json +71 -0
- package/.trajectories/completed/2026-01/traj_v87hypnongqx.md +42 -0
- package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.json +53 -0
- package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.md +32 -0
- package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.json +20 -0
- package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.md +6 -0
- package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.json +175 -0
- package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.md +82 -0
- package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.json +47 -0
- package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.md +32 -0
- package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.json +59 -0
- package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.md +37 -0
- package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.json +53 -0
- package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.md +32 -0
- package/.trajectories/index.json +314 -0
- package/ARCHITECTURE.md +1245 -0
- package/README.md +1 -1
- package/TESTING.md +278 -0
- package/deploy/init-db.sql +5 -0
- package/deploy/scripts/setup-fly-workspaces.sh +69 -0
- package/deploy/scripts/setup-railway.sh +75 -0
- package/deploy/workspace/entrypoint-browser.sh +118 -0
- package/deploy/workspace/entrypoint.sh +348 -0
- package/deploy/workspace/git-credential-relay +111 -0
- package/dist/bridge/spawner.d.ts +53 -0
- package/dist/bridge/spawner.js +203 -19
- package/dist/bridge/types.d.ts +12 -0
- package/dist/cli/index.js +618 -5
- package/dist/cloud/api/auth.d.ts +3 -2
- package/dist/cloud/api/auth.js +10 -98
- package/dist/cloud/api/billing.js +30 -9
- package/dist/cloud/api/cli-pty-runner.d.ts +54 -0
- package/dist/cloud/api/cli-pty-runner.js +119 -0
- package/dist/cloud/api/codex-auth-helper.d.ts +15 -0
- package/dist/cloud/api/codex-auth-helper.js +100 -0
- package/dist/cloud/api/generic-webhooks.d.ts +8 -0
- package/dist/cloud/api/generic-webhooks.js +129 -0
- package/dist/cloud/api/git.d.ts +8 -0
- package/dist/cloud/api/git.js +152 -0
- package/dist/cloud/api/github-app.d.ts +11 -0
- package/dist/cloud/api/github-app.js +189 -0
- package/dist/cloud/api/middleware/planLimits.d.ts +7 -0
- package/dist/cloud/api/middleware/planLimits.js +39 -1
- package/dist/cloud/api/monitoring.d.ts +11 -0
- package/dist/cloud/api/monitoring.js +578 -0
- package/dist/cloud/api/nango-auth.d.ts +9 -0
- package/dist/cloud/api/nango-auth.js +377 -0
- package/dist/cloud/api/onboarding.d.ts +8 -1
- package/dist/cloud/api/onboarding.js +313 -119
- package/dist/cloud/api/policy.d.ts +8 -0
- package/dist/cloud/api/policy.js +229 -0
- package/dist/cloud/api/providers.js +114 -42
- package/dist/cloud/api/repos.d.ts +1 -0
- package/dist/cloud/api/repos.js +186 -0
- package/dist/cloud/api/test-helpers.d.ts +10 -0
- package/dist/cloud/api/test-helpers.js +575 -0
- package/dist/cloud/api/webhooks.d.ts +8 -0
- package/dist/cloud/api/webhooks.js +645 -0
- package/dist/cloud/api/workspaces.js +320 -12
- package/dist/cloud/billing/plans.js +32 -19
- package/dist/cloud/billing/types.d.ts +9 -3
- package/dist/cloud/config.d.ts +9 -2
- package/dist/cloud/config.js +13 -4
- package/dist/cloud/db/drizzle.d.ts +84 -1
- package/dist/cloud/db/drizzle.js +470 -0
- package/dist/cloud/db/index.d.ts +9 -4
- package/dist/cloud/db/index.js +11 -3
- package/dist/cloud/db/schema.d.ts +3283 -556
- package/dist/cloud/db/schema.js +314 -1
- package/dist/cloud/index.d.ts +1 -0
- package/dist/cloud/index.js +2 -0
- package/dist/cloud/provisioner/index.d.ts +56 -0
- package/dist/cloud/provisioner/index.js +676 -34
- package/dist/cloud/server.d.ts +1 -0
- package/dist/cloud/server.js +362 -13
- package/dist/cloud/services/auto-scaler.d.ts +152 -0
- package/dist/cloud/services/auto-scaler.js +439 -0
- package/dist/cloud/services/capacity-manager.d.ts +148 -0
- package/dist/cloud/services/capacity-manager.js +449 -0
- package/dist/cloud/services/ci-agent-spawner.d.ts +49 -0
- package/dist/cloud/services/ci-agent-spawner.js +373 -0
- package/dist/cloud/services/index.d.ts +12 -0
- package/dist/cloud/services/index.js +15 -0
- package/dist/cloud/services/mention-handler.d.ts +65 -0
- package/dist/cloud/services/mention-handler.js +405 -0
- package/dist/cloud/services/nango.d.ts +186 -0
- package/dist/cloud/services/nango.js +344 -0
- package/dist/cloud/services/persistence.d.ts +131 -0
- package/dist/cloud/services/persistence.js +200 -0
- package/dist/cloud/services/planLimits.d.ts +37 -0
- package/dist/cloud/services/planLimits.js +86 -5
- package/dist/cloud/services/scaling-orchestrator.d.ts +159 -0
- package/dist/cloud/services/scaling-orchestrator.js +502 -0
- package/dist/cloud/services/scaling-policy.d.ts +121 -0
- package/dist/cloud/services/scaling-policy.js +415 -0
- package/dist/cloud/vault/index.js +1 -1
- package/dist/cloud/webhooks/index.d.ts +24 -0
- package/dist/cloud/webhooks/index.js +29 -0
- package/dist/cloud/webhooks/parsers/github.d.ts +8 -0
- package/dist/cloud/webhooks/parsers/github.js +234 -0
- package/dist/cloud/webhooks/parsers/index.d.ts +23 -0
- package/dist/cloud/webhooks/parsers/index.js +30 -0
- package/dist/cloud/webhooks/parsers/linear.d.ts +9 -0
- package/dist/cloud/webhooks/parsers/linear.js +258 -0
- package/dist/cloud/webhooks/parsers/slack.d.ts +9 -0
- package/dist/cloud/webhooks/parsers/slack.js +214 -0
- package/dist/cloud/webhooks/responders/github.d.ts +8 -0
- package/dist/cloud/webhooks/responders/github.js +73 -0
- package/dist/cloud/webhooks/responders/index.d.ts +23 -0
- package/dist/cloud/webhooks/responders/index.js +30 -0
- package/dist/cloud/webhooks/responders/linear.d.ts +9 -0
- package/dist/cloud/webhooks/responders/linear.js +149 -0
- package/dist/cloud/webhooks/responders/slack.d.ts +20 -0
- package/dist/cloud/webhooks/responders/slack.js +178 -0
- package/dist/cloud/webhooks/router.d.ts +25 -0
- package/dist/cloud/webhooks/router.js +504 -0
- package/dist/cloud/webhooks/rules-engine.d.ts +24 -0
- package/dist/cloud/webhooks/rules-engine.js +287 -0
- package/dist/cloud/webhooks/types.d.ts +186 -0
- package/dist/cloud/webhooks/types.js +8 -0
- package/dist/continuity/formatter.d.ts +51 -0
- package/dist/continuity/formatter.js +313 -0
- package/dist/continuity/handoff-store.d.ts +67 -0
- package/dist/continuity/handoff-store.js +472 -0
- package/dist/continuity/index.d.ts +45 -0
- package/dist/continuity/index.js +48 -0
- package/dist/continuity/ledger-store.d.ts +110 -0
- package/dist/continuity/ledger-store.js +500 -0
- package/dist/continuity/manager.d.ts +178 -0
- package/dist/continuity/manager.js +562 -0
- package/dist/continuity/parser.d.ts +76 -0
- package/dist/continuity/parser.js +579 -0
- package/dist/continuity/types.d.ts +180 -0
- package/dist/continuity/types.js +9 -0
- package/dist/daemon/agent-manager.d.ts +27 -0
- package/dist/daemon/agent-manager.js +107 -6
- package/dist/daemon/agent-registry.d.ts +32 -0
- package/dist/daemon/agent-registry.js +42 -2
- package/dist/daemon/api.d.ts +12 -0
- package/dist/daemon/api.js +131 -2
- package/dist/daemon/cli-auth.d.ts +67 -0
- package/dist/daemon/cli-auth.js +537 -0
- package/dist/daemon/cloud-sync.js +9 -7
- package/dist/daemon/orchestrator.js +30 -0
- package/dist/daemon/router.d.ts +5 -0
- package/dist/daemon/router.js +78 -26
- package/dist/daemon/server.d.ts +5 -0
- package/dist/daemon/server.js +9 -1
- package/dist/daemon/services/browser-testing.d.ts +88 -0
- package/dist/daemon/services/browser-testing.js +244 -0
- package/dist/daemon/services/container-spawner.d.ts +135 -0
- package/dist/daemon/services/container-spawner.js +313 -0
- package/dist/daemon/types.d.ts +5 -1
- package/dist/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/_next/static/chunks/116-2502180def231162.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/699-3b1cd6618a45d259.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/724-2dae7627550ab88f.js +9 -0
- package/dist/dashboard/out/_next/static/chunks/766-1f2dd8cb7f766b0b.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-3fdfa60e53f2810d.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/page-e6381e5a6e1fbcfd.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-3538dfe0ffe984b8.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/history/{page-b6edd4dde8d08194.js → page-abb9ab2d329f56e9.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/layout-c0d118c0f92d969c.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/login/page-c22d080201cbd9fb.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-67a3e98d9a43a6ed.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/page-77e9c65420a06cfb.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-b08ed1c34d14434a.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-e88bc117ef7671c3.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/signup/page-68d34f50baa8ab6b.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +18 -0
- package/dist/dashboard/out/_next/static/chunks/{main-app-5d692157a8eb1fd9.js → main-app-6e8e8d3ef4e0192a.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/{main-c2f423b9c9f4591b.js → main-ed4e1fb6f29c34cf.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +1 -0
- package/dist/dashboard/out/_next/static/css/29852f26181969a0.css +1 -0
- package/dist/dashboard/out/_next/static/css/7c3ae9e8617d42a5.css +1 -0
- package/dist/dashboard/out/app/onboarding.html +1 -0
- package/dist/dashboard/out/app/onboarding.txt +7 -0
- package/dist/dashboard/out/app.html +1 -14
- package/dist/dashboard/out/app.txt +2 -2
- package/dist/dashboard/out/connect-repos.html +1 -0
- package/dist/dashboard/out/connect-repos.txt +7 -0
- package/dist/dashboard/out/history.html +1 -1
- package/dist/dashboard/out/history.txt +2 -2
- package/dist/dashboard/out/index.html +1 -1
- package/dist/dashboard/out/index.txt +2 -2
- package/dist/dashboard/out/login.html +6 -0
- package/dist/dashboard/out/login.txt +7 -0
- package/dist/dashboard/out/metrics.html +1 -1
- package/dist/dashboard/out/metrics.txt +2 -2
- package/dist/dashboard/out/pricing.html +3 -3
- package/dist/dashboard/out/pricing.txt +2 -2
- package/dist/dashboard/out/providers.html +1 -0
- package/dist/dashboard/out/providers.txt +7 -0
- package/dist/dashboard/out/signup.html +6 -0
- package/dist/dashboard/out/signup.txt +7 -0
- package/dist/dashboard-server/server.js +1308 -8
- package/dist/hooks/emitter.d.ts +40 -0
- package/dist/hooks/emitter.js +63 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/registry.d.ts +173 -0
- package/dist/hooks/registry.js +476 -0
- package/dist/hooks/trajectory-hooks.d.ts +52 -0
- package/dist/hooks/trajectory-hooks.js +183 -0
- package/dist/hooks/types.d.ts +141 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/memory/adapters/index.d.ts +8 -0
- package/dist/memory/adapters/index.js +8 -0
- package/dist/memory/adapters/inmemory.d.ts +59 -0
- package/dist/memory/adapters/inmemory.js +195 -0
- package/dist/memory/adapters/supermemory.d.ts +71 -0
- package/dist/memory/adapters/supermemory.js +338 -0
- package/dist/memory/factory.d.ts +48 -0
- package/dist/memory/factory.js +143 -0
- package/dist/memory/index.d.ts +32 -0
- package/dist/memory/index.js +32 -0
- package/dist/memory/memory-hooks.d.ts +60 -0
- package/dist/memory/memory-hooks.js +313 -0
- package/dist/memory/service.d.ts +49 -0
- package/dist/memory/service.js +146 -0
- package/dist/memory/types.d.ts +195 -0
- package/dist/memory/types.js +8 -0
- package/dist/policy/agent-policy.d.ts +225 -0
- package/dist/policy/agent-policy.js +665 -0
- package/dist/policy/cloud-policy-fetcher.d.ts +12 -0
- package/dist/policy/cloud-policy-fetcher.js +64 -0
- package/dist/resiliency/crash-insights.d.ts +156 -0
- package/dist/resiliency/crash-insights.js +492 -0
- package/dist/resiliency/gossip-health.d.ts +137 -0
- package/dist/resiliency/gossip-health.js +241 -0
- package/dist/resiliency/index.d.ts +5 -0
- package/dist/resiliency/index.js +5 -0
- package/dist/resiliency/leader-watchdog.d.ts +109 -0
- package/dist/resiliency/leader-watchdog.js +189 -0
- package/dist/resiliency/memory-monitor.d.ts +172 -0
- package/dist/resiliency/memory-monitor.js +593 -0
- package/dist/resiliency/stateless-lead.d.ts +149 -0
- package/dist/resiliency/stateless-lead.js +308 -0
- package/dist/resiliency/supervisor.d.ts +38 -0
- package/dist/resiliency/supervisor.js +122 -0
- package/dist/shared/cli-auth-config.d.ts +91 -0
- package/dist/shared/cli-auth-config.js +264 -0
- package/dist/storage/adapter.d.ts +1 -1
- package/dist/trajectory/config.d.ts +84 -0
- package/dist/trajectory/config.js +163 -0
- package/dist/trajectory/index.d.ts +8 -0
- package/dist/trajectory/index.js +8 -0
- package/dist/trajectory/integration.d.ts +292 -0
- package/dist/trajectory/integration.js +834 -0
- package/dist/utils/logger.js +1 -1
- package/dist/utils/project-namespace.d.ts +24 -0
- package/dist/utils/project-namespace.js +84 -0
- package/dist/wrapper/parser.d.ts +10 -0
- package/dist/wrapper/parser.js +100 -33
- package/dist/wrapper/pty-wrapper.d.ts +197 -16
- package/dist/wrapper/pty-wrapper.js +943 -106
- package/dist/wrapper/shared.d.ts +165 -0
- package/dist/wrapper/shared.js +270 -0
- package/dist/wrapper/tmux-wrapper.d.ts +73 -11
- package/dist/wrapper/tmux-wrapper.js +541 -120
- package/package.json +16 -16
- package/scripts/postinstall.js +60 -0
- package/test-push.txt +1 -0
- package/bin/tmux +0 -0
- package/dist/bridge/config.d.ts.map +0 -1
- package/dist/bridge/config.js.map +0 -1
- package/dist/bridge/index.d.ts.map +0 -1
- package/dist/bridge/index.js.map +0 -1
- package/dist/bridge/multi-project-client.d.ts.map +0 -1
- package/dist/bridge/multi-project-client.js.map +0 -1
- package/dist/bridge/shadow-cli.d.ts.map +0 -1
- package/dist/bridge/shadow-cli.js.map +0 -1
- package/dist/bridge/shadow-config.d.ts.map +0 -1
- package/dist/bridge/shadow-config.js.map +0 -1
- package/dist/bridge/spawner.d.ts.map +0 -1
- package/dist/bridge/spawner.js.map +0 -1
- package/dist/bridge/teams-config.d.ts.map +0 -1
- package/dist/bridge/teams-config.js.map +0 -1
- package/dist/bridge/types.d.ts.map +0 -1
- package/dist/bridge/types.js.map +0 -1
- package/dist/bridge/utils.d.ts.map +0 -1
- package/dist/bridge/utils.js.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cloud/api/auth.d.ts.map +0 -1
- package/dist/cloud/api/auth.js.map +0 -1
- package/dist/cloud/api/billing.d.ts.map +0 -1
- package/dist/cloud/api/billing.js.map +0 -1
- package/dist/cloud/api/coordinators.d.ts.map +0 -1
- package/dist/cloud/api/coordinators.js.map +0 -1
- package/dist/cloud/api/daemons.d.ts.map +0 -1
- package/dist/cloud/api/daemons.js.map +0 -1
- package/dist/cloud/api/middleware/planLimits.d.ts.map +0 -1
- package/dist/cloud/api/middleware/planLimits.js.map +0 -1
- package/dist/cloud/api/onboarding.d.ts.map +0 -1
- package/dist/cloud/api/onboarding.js.map +0 -1
- package/dist/cloud/api/providers.d.ts.map +0 -1
- package/dist/cloud/api/providers.js.map +0 -1
- package/dist/cloud/api/repos.d.ts.map +0 -1
- package/dist/cloud/api/repos.js.map +0 -1
- package/dist/cloud/api/teams.d.ts.map +0 -1
- package/dist/cloud/api/teams.js.map +0 -1
- package/dist/cloud/api/usage.d.ts.map +0 -1
- package/dist/cloud/api/usage.js.map +0 -1
- package/dist/cloud/api/workspaces.d.ts.map +0 -1
- package/dist/cloud/api/workspaces.js.map +0 -1
- package/dist/cloud/billing/index.d.ts.map +0 -1
- package/dist/cloud/billing/index.js.map +0 -1
- package/dist/cloud/billing/plans.d.ts.map +0 -1
- package/dist/cloud/billing/plans.js.map +0 -1
- package/dist/cloud/billing/service.d.ts.map +0 -1
- package/dist/cloud/billing/service.js.map +0 -1
- package/dist/cloud/billing/types.d.ts.map +0 -1
- package/dist/cloud/billing/types.js.map +0 -1
- package/dist/cloud/config.d.ts.map +0 -1
- package/dist/cloud/config.js.map +0 -1
- package/dist/cloud/db/drizzle.d.ts.map +0 -1
- package/dist/cloud/db/drizzle.js.map +0 -1
- package/dist/cloud/db/index.d.ts.map +0 -1
- package/dist/cloud/db/index.js.map +0 -1
- package/dist/cloud/db/schema.d.ts.map +0 -1
- package/dist/cloud/db/schema.js.map +0 -1
- package/dist/cloud/index.d.ts.map +0 -1
- package/dist/cloud/index.js.map +0 -1
- package/dist/cloud/provisioner/index.d.ts.map +0 -1
- package/dist/cloud/provisioner/index.js.map +0 -1
- package/dist/cloud/server.d.ts.map +0 -1
- package/dist/cloud/server.js.map +0 -1
- package/dist/cloud/services/coordinator.d.ts.map +0 -1
- package/dist/cloud/services/coordinator.js.map +0 -1
- package/dist/cloud/services/planLimits.d.ts.map +0 -1
- package/dist/cloud/services/planLimits.js.map +0 -1
- package/dist/cloud/vault/index.d.ts.map +0 -1
- package/dist/cloud/vault/index.js.map +0 -1
- package/dist/daemon/agent-manager.d.ts.map +0 -1
- package/dist/daemon/agent-manager.js.map +0 -1
- package/dist/daemon/agent-registry.d.ts.map +0 -1
- package/dist/daemon/agent-registry.js.map +0 -1
- package/dist/daemon/api.d.ts.map +0 -1
- package/dist/daemon/api.js.map +0 -1
- package/dist/daemon/auth.d.ts.map +0 -1
- package/dist/daemon/auth.js.map +0 -1
- package/dist/daemon/cloud-sync.d.ts.map +0 -1
- package/dist/daemon/cloud-sync.js.map +0 -1
- package/dist/daemon/connection.d.ts.map +0 -1
- package/dist/daemon/connection.js.map +0 -1
- package/dist/daemon/index.d.ts.map +0 -1
- package/dist/daemon/index.js.map +0 -1
- package/dist/daemon/orchestrator.d.ts.map +0 -1
- package/dist/daemon/orchestrator.js.map +0 -1
- package/dist/daemon/registry.d.ts.map +0 -1
- package/dist/daemon/registry.js.map +0 -1
- package/dist/daemon/router.d.ts.map +0 -1
- package/dist/daemon/router.js.map +0 -1
- package/dist/daemon/server.d.ts.map +0 -1
- package/dist/daemon/server.js.map +0 -1
- package/dist/daemon/types.d.ts.map +0 -1
- package/dist/daemon/types.js.map +0 -1
- package/dist/daemon/workspace-manager.d.ts.map +0 -1
- package/dist/daemon/workspace-manager.js.map +0 -1
- package/dist/dashboard/out/_next/static/chunks/693-7b3301d8f6bc5014.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/713-f78477eb185f1f4d.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/766-e53e1cfe39b0b5b5.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/900-037c64bfd797fb2a.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/page-e3d9e1f4466b9bae.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/layout-2433bb48965f4333.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-e68825a81db67ba1.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/page-cc108bf68c8a657f.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-d80e03a5297f95b6.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/webpack-a5acc2831d094776.js +0 -1
- package/dist/dashboard/out/_next/static/css/79b80143647a07d7.css +0 -1
- package/dist/dashboard/out/_next/static/css/8cf277370ad48cfe.css +0 -1
- package/dist/dashboard-server/metrics.d.ts.map +0 -1
- package/dist/dashboard-server/metrics.js.map +0 -1
- package/dist/dashboard-server/needs-attention.d.ts.map +0 -1
- package/dist/dashboard-server/needs-attention.js.map +0 -1
- package/dist/dashboard-server/server.d.ts.map +0 -1
- package/dist/dashboard-server/server.js.map +0 -1
- package/dist/dashboard-server/start.d.ts.map +0 -1
- package/dist/dashboard-server/start.js.map +0 -1
- package/dist/hooks/inbox-check/hook.d.ts.map +0 -1
- package/dist/hooks/inbox-check/hook.js.map +0 -1
- package/dist/hooks/inbox-check/index.d.ts.map +0 -1
- package/dist/hooks/inbox-check/index.js.map +0 -1
- package/dist/hooks/inbox-check/types.d.ts.map +0 -1
- package/dist/hooks/inbox-check/types.js.map +0 -1
- package/dist/hooks/inbox-check/utils.d.ts.map +0 -1
- package/dist/hooks/inbox-check/utils.js.map +0 -1
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/types.d.ts.map +0 -1
- package/dist/hooks/types.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/protocol/framing.d.ts.map +0 -1
- package/dist/protocol/framing.js.map +0 -1
- package/dist/protocol/index.d.ts.map +0 -1
- package/dist/protocol/index.js.map +0 -1
- package/dist/protocol/types.d.ts.map +0 -1
- package/dist/protocol/types.js.map +0 -1
- package/dist/resiliency/context-persistence.d.ts.map +0 -1
- package/dist/resiliency/context-persistence.js.map +0 -1
- package/dist/resiliency/health-monitor.d.ts.map +0 -1
- package/dist/resiliency/health-monitor.js.map +0 -1
- package/dist/resiliency/index.d.ts.map +0 -1
- package/dist/resiliency/index.js.map +0 -1
- package/dist/resiliency/logger.d.ts.map +0 -1
- package/dist/resiliency/logger.js.map +0 -1
- package/dist/resiliency/metrics.d.ts.map +0 -1
- package/dist/resiliency/metrics.js.map +0 -1
- package/dist/resiliency/provider-context.d.ts.map +0 -1
- package/dist/resiliency/provider-context.js.map +0 -1
- package/dist/resiliency/supervisor.d.ts.map +0 -1
- package/dist/resiliency/supervisor.js.map +0 -1
- package/dist/state/agent-state.d.ts.map +0 -1
- package/dist/state/agent-state.js.map +0 -1
- package/dist/storage/adapter.d.ts.map +0 -1
- package/dist/storage/adapter.js.map +0 -1
- package/dist/storage/sqlite-adapter.d.ts.map +0 -1
- package/dist/storage/sqlite-adapter.js.map +0 -1
- package/dist/utils/agent-config.d.ts.map +0 -1
- package/dist/utils/agent-config.js.map +0 -1
- package/dist/utils/command-resolver.d.ts.map +0 -1
- package/dist/utils/command-resolver.js.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/name-generator.d.ts.map +0 -1
- package/dist/utils/name-generator.js.map +0 -1
- package/dist/utils/project-namespace.d.ts.map +0 -1
- package/dist/utils/project-namespace.js.map +0 -1
- package/dist/utils/tmux-resolver.d.ts.map +0 -1
- package/dist/utils/tmux-resolver.js.map +0 -1
- package/dist/utils/update-checker.d.ts.map +0 -1
- package/dist/utils/update-checker.js.map +0 -1
- package/dist/wrapper/client.d.ts.map +0 -1
- package/dist/wrapper/client.js.map +0 -1
- package/dist/wrapper/inbox.d.ts.map +0 -1
- package/dist/wrapper/inbox.js.map +0 -1
- package/dist/wrapper/index.d.ts.map +0 -1
- package/dist/wrapper/index.js.map +0 -1
- package/dist/wrapper/parser.d.ts.map +0 -1
- package/dist/wrapper/parser.js.map +0 -1
- package/dist/wrapper/pty-wrapper.d.ts.map +0 -1
- package/dist/wrapper/pty-wrapper.js.map +0 -1
- package/dist/wrapper/tmux-wrapper.d.ts.map +0 -1
- package/dist/wrapper/tmux-wrapper.js.map +0 -1
- package/docs/AGENTS.md +0 -513
- package/docs/ARCHITECTURE_DECISIONS.md +0 -175
- package/docs/CHANGELOG.md +0 -11
- package/docs/CLI-SIMPLIFICATION-COMPLETE.md +0 -48
- package/docs/CLOUD-ARCHITECTURE.md +0 -652
- package/docs/CLOUD-ONBOARDING-DESIGN.md +0 -1983
- package/docs/COMPETITIVE_ANALYSIS.md +0 -897
- package/docs/CONTRIBUTING.md +0 -151
- package/docs/DESIGN_BRIDGE_STAFFING.md +0 -878
- package/docs/DESIGN_V2.md +0 -1079
- package/docs/INTEGRATION-GUIDE.md +0 -926
- package/docs/MONETIZATION.md +0 -1679
- package/docs/PROPOSAL-trajectories.md +0 -1582
- package/docs/PROTOCOL.md +0 -325
- package/docs/SCALING_ANALYSIS.md +0 -280
- package/docs/TESTING_PRESENCE_FEATURES.md +0 -327
- package/docs/TMUX_IMPLEMENTATION_NOTES.md +0 -364
- package/docs/TMUX_IMPROVEMENTS.md +0 -968
- package/docs/agent-relay-snippet.md +0 -168
- package/docs/competitive-analysis-mcp-agent-mail.md +0 -389
- package/docs/dashboard-v2-plan.md +0 -179
- package/docs/guides/CLOUD.md +0 -236
- package/docs/guides/LOCAL.md +0 -535
- package/docs/guides/SELF-HOSTED.md +0 -494
- package/docs/proposals/shadow-as-subagent.md +0 -765
- package/docs/proposals/slack-bot-integration.md +0 -1457
- package/docs/removable-code-analysis.md +0 -24
- package/scripts/dev/PUBLIC_RELEASE_PLAN.md +0 -88
- package/scripts/dev/dev-team-setup.sh +0 -431
- package/scripts/e2e-test.sh +0 -119
- package/scripts/games/game-protocol.md +0 -79
- package/scripts/games/hearts-setup.sh +0 -264
- package/scripts/tictactoe-setup.sh +0 -181
- /package/dist/dashboard/out/_next/static/chunks/{117-b2cd8d6485aacf2b.js → 117-f7b8ab0809342e77.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/{648-8f3f26864ce515e5.js → 648-5cc6e1921389a58a.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/app/_not-found/{page-0b990dbb71d72a98.js → page-53b8a69f76db17d0.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/{fd9d1056-bf46c09eb57e019c.js → fd9d1056-609918ca7b6280bb.js} +0 -0
- /package/dist/dashboard/out/_next/static/{6HHWb2ZmnJ4OSm0zUP7h4 → wPgKJtcOmTFLpUncDg16A}/_buildManifest.js +0 -0
- /package/dist/dashboard/out/_next/static/{6HHWb2ZmnJ4OSm0zUP7h4 → wPgKJtcOmTFLpUncDg16A}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Helper API Routes
|
|
3
|
+
*
|
|
4
|
+
* These endpoints are ONLY available in test/development mode.
|
|
5
|
+
* They allow integration tests to create users and daemons without OAuth.
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: These routes are disabled in production (NODE_ENV=production).
|
|
8
|
+
*/
|
|
9
|
+
import { Router } from 'express';
|
|
10
|
+
import { randomUUID, createHash, randomBytes } from 'crypto';
|
|
11
|
+
import { getDb } from '../db/drizzle.js';
|
|
12
|
+
import { users, linkedDaemons, workspaces, repositories } from '../db/schema.js';
|
|
13
|
+
import { getProvisioner } from '../provisioner/index.js';
|
|
14
|
+
import { db } from '../db/index.js';
|
|
15
|
+
import { nangoService } from '../services/nango.js';
|
|
16
|
+
export const testHelpersRouter = Router();
|
|
17
|
+
// Only enable in test/development mode
|
|
18
|
+
const isTestMode = process.env.NODE_ENV !== 'production';
|
|
19
|
+
if (!isTestMode) {
|
|
20
|
+
console.warn('[test-helpers] Test helper routes are disabled in production');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* POST /api/test/create-user
|
|
24
|
+
* Creates a test user without OAuth
|
|
25
|
+
*/
|
|
26
|
+
testHelpersRouter.post('/create-user', async (req, res) => {
|
|
27
|
+
if (!isTestMode) {
|
|
28
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const { email, name } = req.body;
|
|
32
|
+
const db = getDb();
|
|
33
|
+
const testId = `test-${randomUUID()}`;
|
|
34
|
+
// Create user with required GitHub fields
|
|
35
|
+
const [user] = await db.insert(users).values({
|
|
36
|
+
email: email || `${testId}@test.local`,
|
|
37
|
+
githubId: testId,
|
|
38
|
+
githubUsername: name || 'test-user',
|
|
39
|
+
avatarUrl: null,
|
|
40
|
+
}).returning();
|
|
41
|
+
// Create session
|
|
42
|
+
const sessionId = randomUUID();
|
|
43
|
+
req.session.userId = user.id;
|
|
44
|
+
// Get session cookie (simplified for testing)
|
|
45
|
+
const sessionCookie = `connect.sid=s%3A${sessionId}`;
|
|
46
|
+
res.json({
|
|
47
|
+
userId: user.id,
|
|
48
|
+
email: user.email,
|
|
49
|
+
sessionCookie,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('Error creating test user:', error);
|
|
54
|
+
res.status(500).json({ error: 'Failed to create test user' });
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* POST /api/test/create-daemon
|
|
59
|
+
* Creates a test daemon with API key
|
|
60
|
+
*/
|
|
61
|
+
testHelpersRouter.post('/create-daemon', async (req, res) => {
|
|
62
|
+
if (!isTestMode) {
|
|
63
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const { name, machineId } = req.body;
|
|
67
|
+
if (!name) {
|
|
68
|
+
return res.status(400).json({ error: 'name is required' });
|
|
69
|
+
}
|
|
70
|
+
const db = getDb();
|
|
71
|
+
// First, ensure we have a test user to associate with the daemon
|
|
72
|
+
let [testUser] = await db.select().from(users).limit(1);
|
|
73
|
+
if (!testUser) {
|
|
74
|
+
// Create a test user if none exists
|
|
75
|
+
const testId = `test-system-${randomUUID()}`;
|
|
76
|
+
[testUser] = await db.insert(users).values({
|
|
77
|
+
email: `${testId}@test.local`,
|
|
78
|
+
githubId: testId,
|
|
79
|
+
githubUsername: 'test-system-user',
|
|
80
|
+
avatarUrl: null,
|
|
81
|
+
}).returning();
|
|
82
|
+
}
|
|
83
|
+
// Generate API key
|
|
84
|
+
const apiKey = `ar_live_${randomBytes(32).toString('hex')}`;
|
|
85
|
+
const apiKeyHash = createHash('sha256').update(apiKey).digest('hex');
|
|
86
|
+
// Create daemon - only include fields that exist in schema
|
|
87
|
+
const [daemon] = await db.insert(linkedDaemons).values({
|
|
88
|
+
userId: testUser.id,
|
|
89
|
+
name,
|
|
90
|
+
machineId: machineId || randomUUID(),
|
|
91
|
+
apiKeyHash,
|
|
92
|
+
status: 'online',
|
|
93
|
+
metadata: {
|
|
94
|
+
hostname: 'test-host',
|
|
95
|
+
platform: 'linux',
|
|
96
|
+
version: '1.0.0-test',
|
|
97
|
+
},
|
|
98
|
+
}).returning();
|
|
99
|
+
res.json({
|
|
100
|
+
daemonId: daemon.id,
|
|
101
|
+
apiKey,
|
|
102
|
+
name: daemon.name,
|
|
103
|
+
machineId: daemon.machineId,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
console.error('Error creating test daemon:', error);
|
|
108
|
+
res.status(500).json({ error: 'Failed to create test daemon' });
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
/**
|
|
112
|
+
* DELETE /api/test/cleanup
|
|
113
|
+
* Cleans up test data
|
|
114
|
+
*/
|
|
115
|
+
testHelpersRouter.delete('/cleanup', async (req, res) => {
|
|
116
|
+
if (!isTestMode) {
|
|
117
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
const _db = getDb();
|
|
121
|
+
// Delete test data (users with test- prefix in githubId)
|
|
122
|
+
// Note: This cascades to linked daemons due to FK constraints
|
|
123
|
+
res.json({ success: true, message: 'Test data cleaned up' });
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
console.error('Error cleaning up test data:', error);
|
|
127
|
+
res.status(500).json({ error: 'Failed to cleanup test data' });
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
/**
|
|
131
|
+
* GET /api/test/status
|
|
132
|
+
* Returns test mode status
|
|
133
|
+
*/
|
|
134
|
+
testHelpersRouter.get('/status', (req, res) => {
|
|
135
|
+
res.json({
|
|
136
|
+
testMode: isTestMode,
|
|
137
|
+
nodeEnv: process.env.NODE_ENV,
|
|
138
|
+
timestamp: new Date().toISOString(),
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
/**
|
|
142
|
+
* POST /api/test/create-mock-workspace
|
|
143
|
+
* Creates a mock workspace pointing to a local dashboard server
|
|
144
|
+
*
|
|
145
|
+
* Use this to test the cloud flow locally without real provisioning.
|
|
146
|
+
* The workspace will have publicUrl pointing to localhost:3889.
|
|
147
|
+
*/
|
|
148
|
+
testHelpersRouter.post('/create-mock-workspace', async (req, res) => {
|
|
149
|
+
if (!isTestMode) {
|
|
150
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const { name, publicUrl } = req.body;
|
|
154
|
+
const userId = req.session.userId;
|
|
155
|
+
if (!userId) {
|
|
156
|
+
return res.status(401).json({ error: 'Must be logged in. Use /api/test/create-user first or log in via OAuth.' });
|
|
157
|
+
}
|
|
158
|
+
const db = getDb();
|
|
159
|
+
// Create a mock workspace with local publicUrl
|
|
160
|
+
const [workspace] = await db.insert(workspaces).values({
|
|
161
|
+
userId,
|
|
162
|
+
name: name || 'Local Test Workspace',
|
|
163
|
+
status: 'running',
|
|
164
|
+
publicUrl: publicUrl || 'http://localhost:3889',
|
|
165
|
+
computeProvider: 'docker',
|
|
166
|
+
computeId: `mock-${randomUUID().slice(0, 8)}`,
|
|
167
|
+
config: {
|
|
168
|
+
providers: ['anthropic'],
|
|
169
|
+
repositories: [],
|
|
170
|
+
supervisorEnabled: true,
|
|
171
|
+
maxAgents: 10,
|
|
172
|
+
},
|
|
173
|
+
}).returning();
|
|
174
|
+
res.json({
|
|
175
|
+
workspaceId: workspace.id,
|
|
176
|
+
name: workspace.name,
|
|
177
|
+
status: workspace.status,
|
|
178
|
+
publicUrl: workspace.publicUrl,
|
|
179
|
+
message: 'Mock workspace created. Start agent-relay locally and navigate to /app.',
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.error('Error creating mock workspace:', error);
|
|
184
|
+
res.status(500).json({ error: 'Failed to create mock workspace' });
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
/**
|
|
188
|
+
* POST /api/test/create-mock-repo
|
|
189
|
+
* Creates a mock repository for the current user
|
|
190
|
+
*
|
|
191
|
+
* Use this to test the cloud flow without connecting real GitHub repos.
|
|
192
|
+
*/
|
|
193
|
+
testHelpersRouter.post('/create-mock-repo', async (req, res) => {
|
|
194
|
+
if (!isTestMode) {
|
|
195
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const { fullName, isPrivate } = req.body;
|
|
199
|
+
const userId = req.session.userId;
|
|
200
|
+
if (!userId) {
|
|
201
|
+
return res.status(401).json({ error: 'Must be logged in. Use /api/test/create-user first or log in via OAuth.' });
|
|
202
|
+
}
|
|
203
|
+
if (!fullName) {
|
|
204
|
+
return res.status(400).json({ error: 'fullName is required (e.g., "owner/repo")' });
|
|
205
|
+
}
|
|
206
|
+
const db = getDb();
|
|
207
|
+
// Create a mock repository
|
|
208
|
+
const [repo] = await db.insert(repositories).values({
|
|
209
|
+
userId,
|
|
210
|
+
githubId: Math.floor(Math.random() * 1000000),
|
|
211
|
+
githubFullName: fullName,
|
|
212
|
+
isPrivate: isPrivate ?? false,
|
|
213
|
+
defaultBranch: 'main',
|
|
214
|
+
syncStatus: 'synced',
|
|
215
|
+
nangoConnectionId: `mock-connection-${randomUUID().slice(0, 8)}`,
|
|
216
|
+
lastSyncedAt: new Date(),
|
|
217
|
+
}).returning();
|
|
218
|
+
res.json({
|
|
219
|
+
repoId: repo.id,
|
|
220
|
+
fullName: repo.githubFullName,
|
|
221
|
+
isPrivate: repo.isPrivate,
|
|
222
|
+
message: 'Mock repository created.',
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
console.error('Error creating mock repo:', error);
|
|
227
|
+
res.status(500).json({ error: 'Failed to create mock repo' });
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
/**
|
|
231
|
+
* POST /api/test/login-as
|
|
232
|
+
* Quick login for testing - creates session for existing or new test user
|
|
233
|
+
*/
|
|
234
|
+
testHelpersRouter.post('/login-as', async (req, res) => {
|
|
235
|
+
if (!isTestMode) {
|
|
236
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
237
|
+
}
|
|
238
|
+
try {
|
|
239
|
+
const { username } = req.body;
|
|
240
|
+
const db = getDb();
|
|
241
|
+
// Find or create user
|
|
242
|
+
let user;
|
|
243
|
+
const existingUsers = await db.select().from(users).limit(1);
|
|
244
|
+
if (existingUsers.length > 0 && !username) {
|
|
245
|
+
user = existingUsers[0];
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
const testId = `test-${randomUUID()}`;
|
|
249
|
+
const [newUser] = await db.insert(users).values({
|
|
250
|
+
email: `${username || testId}@test.local`,
|
|
251
|
+
githubId: testId,
|
|
252
|
+
githubUsername: username || 'test-user',
|
|
253
|
+
avatarUrl: null,
|
|
254
|
+
plan: 'free',
|
|
255
|
+
}).returning();
|
|
256
|
+
user = newUser;
|
|
257
|
+
}
|
|
258
|
+
// Set session
|
|
259
|
+
req.session.userId = user.id;
|
|
260
|
+
res.json({
|
|
261
|
+
success: true,
|
|
262
|
+
userId: user.id,
|
|
263
|
+
username: user.githubUsername,
|
|
264
|
+
message: 'Logged in. You can now access /app and other authenticated routes.',
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
console.error('Error in login-as:', error);
|
|
269
|
+
res.status(500).json({ error: 'Failed to login' });
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
/**
|
|
273
|
+
* GET /api/test/setup-local-cloud
|
|
274
|
+
* One-shot setup: creates user, mock repo, and mock workspace
|
|
275
|
+
*
|
|
276
|
+
* After calling this, start agent-relay locally and go to /app
|
|
277
|
+
*/
|
|
278
|
+
testHelpersRouter.post('/setup-local-cloud', async (req, res) => {
|
|
279
|
+
if (!isTestMode) {
|
|
280
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
281
|
+
}
|
|
282
|
+
try {
|
|
283
|
+
const { repoName, workspaceName } = req.body;
|
|
284
|
+
const db = getDb();
|
|
285
|
+
// 1. Create or get test user
|
|
286
|
+
const testId = `test-${randomUUID().slice(0, 8)}`;
|
|
287
|
+
const [user] = await db.insert(users).values({
|
|
288
|
+
email: `${testId}@test.local`,
|
|
289
|
+
githubId: testId,
|
|
290
|
+
githubUsername: 'local-tester',
|
|
291
|
+
avatarUrl: null,
|
|
292
|
+
plan: 'free',
|
|
293
|
+
}).returning();
|
|
294
|
+
// Set session
|
|
295
|
+
req.session.userId = user.id;
|
|
296
|
+
// 2. Create mock repository
|
|
297
|
+
const [repo] = await db.insert(repositories).values({
|
|
298
|
+
userId: user.id,
|
|
299
|
+
githubId: Math.floor(Math.random() * 1000000),
|
|
300
|
+
githubFullName: repoName || 'test-org/test-repo',
|
|
301
|
+
isPrivate: false,
|
|
302
|
+
defaultBranch: 'main',
|
|
303
|
+
syncStatus: 'synced',
|
|
304
|
+
nangoConnectionId: `mock-${randomUUID().slice(0, 8)}`,
|
|
305
|
+
lastSyncedAt: new Date(),
|
|
306
|
+
}).returning();
|
|
307
|
+
// 3. Create mock workspace pointing to local dashboard
|
|
308
|
+
const [workspace] = await db.insert(workspaces).values({
|
|
309
|
+
userId: user.id,
|
|
310
|
+
name: workspaceName || 'Local Development',
|
|
311
|
+
status: 'running',
|
|
312
|
+
publicUrl: 'http://localhost:3889',
|
|
313
|
+
computeProvider: 'docker',
|
|
314
|
+
computeId: `mock-${randomUUID().slice(0, 8)}`,
|
|
315
|
+
config: {
|
|
316
|
+
providers: ['anthropic'],
|
|
317
|
+
repositories: [repo.githubFullName],
|
|
318
|
+
supervisorEnabled: true,
|
|
319
|
+
maxAgents: 10,
|
|
320
|
+
},
|
|
321
|
+
}).returning();
|
|
322
|
+
res.json({
|
|
323
|
+
success: true,
|
|
324
|
+
user: {
|
|
325
|
+
id: user.id,
|
|
326
|
+
username: user.githubUsername,
|
|
327
|
+
},
|
|
328
|
+
repo: {
|
|
329
|
+
id: repo.id,
|
|
330
|
+
fullName: repo.githubFullName,
|
|
331
|
+
},
|
|
332
|
+
workspace: {
|
|
333
|
+
id: workspace.id,
|
|
334
|
+
name: workspace.name,
|
|
335
|
+
publicUrl: workspace.publicUrl,
|
|
336
|
+
},
|
|
337
|
+
instructions: [
|
|
338
|
+
'1. Start agent-relay daemon: npm run dev (or agent-relay daemon)',
|
|
339
|
+
'2. Go to http://localhost:4567/app',
|
|
340
|
+
'3. The app should auto-connect to the local workspace',
|
|
341
|
+
'4. The WebSocket will connect to ws://localhost:3889/ws',
|
|
342
|
+
],
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
console.error('Error in setup-local-cloud:', error);
|
|
347
|
+
res.status(500).json({ error: 'Failed to setup local cloud' });
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
/**
|
|
351
|
+
* POST /api/test/provision-real-workspace
|
|
352
|
+
* Provision a REAL Docker container using your Nango GitHub App connection.
|
|
353
|
+
*
|
|
354
|
+
* This tests the full flow including:
|
|
355
|
+
* - Fetching GitHub App token from Nango
|
|
356
|
+
* - Spinning up a Docker container
|
|
357
|
+
* - Cloning your actual repositories
|
|
358
|
+
*
|
|
359
|
+
* Prerequisites:
|
|
360
|
+
* - Must be logged in (via real OAuth or /api/test/login-as)
|
|
361
|
+
* - Must have connected repos via /connect-repos (real Nango GitHub App OAuth)
|
|
362
|
+
* - Docker must be running locally
|
|
363
|
+
* - COMPUTE_PROVIDER must be 'docker' (default for dev)
|
|
364
|
+
*/
|
|
365
|
+
testHelpersRouter.post('/provision-real-workspace', async (req, res) => {
|
|
366
|
+
if (!isTestMode) {
|
|
367
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
368
|
+
}
|
|
369
|
+
const userId = req.session.userId;
|
|
370
|
+
if (!userId) {
|
|
371
|
+
return res.status(401).json({
|
|
372
|
+
error: 'Must be logged in. Use real OAuth or /api/test/login-as first.',
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
try {
|
|
376
|
+
const { name, repositoryFullName, providers, githubToken } = req.body;
|
|
377
|
+
// Get user's connected repositories
|
|
378
|
+
const userRepos = await db.repositories.findByUserId(userId);
|
|
379
|
+
const reposWithNango = userRepos.filter(r => r.nangoConnectionId);
|
|
380
|
+
if (reposWithNango.length === 0) {
|
|
381
|
+
return res.status(400).json({
|
|
382
|
+
error: 'No repositories with Nango connection found. Complete /connect-repos first with real GitHub OAuth.',
|
|
383
|
+
hint: 'Go to http://localhost:4567/connect-repos and connect your GitHub App, or pass githubToken directly',
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
// Determine which repo to use
|
|
387
|
+
let targetRepo = reposWithNango[0];
|
|
388
|
+
if (repositoryFullName) {
|
|
389
|
+
const found = reposWithNango.find(r => r.githubFullName === repositoryFullName);
|
|
390
|
+
if (!found) {
|
|
391
|
+
return res.status(400).json({
|
|
392
|
+
error: `Repository ${repositoryFullName} not found or not connected via Nango`,
|
|
393
|
+
availableRepos: reposWithNango.map(r => r.githubFullName),
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
targetRepo = found;
|
|
397
|
+
}
|
|
398
|
+
// Use the real provisioner (Docker in dev mode)
|
|
399
|
+
const provisioner = getProvisioner();
|
|
400
|
+
const result = await provisioner.provision({
|
|
401
|
+
userId,
|
|
402
|
+
name: name || `Test Workspace - ${targetRepo.githubFullName}`,
|
|
403
|
+
providers: providers || ['anthropic'], // Default to anthropic if not specified
|
|
404
|
+
repositories: [targetRepo.githubFullName],
|
|
405
|
+
supervisorEnabled: true,
|
|
406
|
+
maxAgents: 10,
|
|
407
|
+
// Allow passing GitHub token directly for local testing
|
|
408
|
+
githubToken: githubToken || undefined,
|
|
409
|
+
});
|
|
410
|
+
if (result.status === 'error') {
|
|
411
|
+
return res.status(500).json({
|
|
412
|
+
error: 'Provisioning failed',
|
|
413
|
+
details: result.error,
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
res.json({
|
|
417
|
+
success: true,
|
|
418
|
+
workspace: {
|
|
419
|
+
id: result.workspaceId,
|
|
420
|
+
status: result.status,
|
|
421
|
+
publicUrl: result.publicUrl,
|
|
422
|
+
},
|
|
423
|
+
repository: targetRepo.githubFullName,
|
|
424
|
+
instructions: [
|
|
425
|
+
`1. Workspace is running at ${result.publicUrl}`,
|
|
426
|
+
`2. Repository ${targetRepo.githubFullName} should be cloned`,
|
|
427
|
+
`3. Go to http://localhost:4567/app to connect`,
|
|
428
|
+
`4. Check container: docker logs ar-${result.workspaceId.substring(0, 8)}`,
|
|
429
|
+
`5. Verify clone: docker exec ar-${result.workspaceId.substring(0, 8)} ls /workspace/repos`,
|
|
430
|
+
],
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
console.error('Error provisioning real workspace:', error);
|
|
435
|
+
res.status(500).json({
|
|
436
|
+
error: 'Failed to provision workspace',
|
|
437
|
+
details: error instanceof Error ? error.message : 'Unknown error',
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
/**
|
|
442
|
+
* GET /api/test/my-repos
|
|
443
|
+
* List current user's connected repositories (for debugging)
|
|
444
|
+
*/
|
|
445
|
+
testHelpersRouter.get('/my-repos', async (req, res) => {
|
|
446
|
+
if (!isTestMode) {
|
|
447
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
448
|
+
}
|
|
449
|
+
const userId = req.session.userId;
|
|
450
|
+
if (!userId) {
|
|
451
|
+
return res.status(401).json({ error: 'Not logged in' });
|
|
452
|
+
}
|
|
453
|
+
try {
|
|
454
|
+
const repos = await db.repositories.findByUserId(userId);
|
|
455
|
+
res.json({
|
|
456
|
+
userId,
|
|
457
|
+
repositories: repos.map(r => ({
|
|
458
|
+
id: r.id,
|
|
459
|
+
fullName: r.githubFullName,
|
|
460
|
+
isPrivate: r.isPrivate,
|
|
461
|
+
hasNangoConnection: !!r.nangoConnectionId,
|
|
462
|
+
nangoConnectionId: r.nangoConnectionId, // For debugging
|
|
463
|
+
syncStatus: r.syncStatus,
|
|
464
|
+
})),
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
console.error('Error fetching repos:', error);
|
|
469
|
+
res.status(500).json({ error: 'Failed to fetch repositories' });
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
/**
|
|
473
|
+
* GET /api/test/my-workspaces
|
|
474
|
+
* List current user's workspaces (for debugging)
|
|
475
|
+
*/
|
|
476
|
+
testHelpersRouter.get('/my-workspaces', async (req, res) => {
|
|
477
|
+
if (!isTestMode) {
|
|
478
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
479
|
+
}
|
|
480
|
+
const userId = req.session.userId;
|
|
481
|
+
if (!userId) {
|
|
482
|
+
return res.status(401).json({ error: 'Not logged in' });
|
|
483
|
+
}
|
|
484
|
+
try {
|
|
485
|
+
const userWorkspaces = await db.workspaces.findByUserId(userId);
|
|
486
|
+
res.json({
|
|
487
|
+
userId,
|
|
488
|
+
workspaces: userWorkspaces.map(w => ({
|
|
489
|
+
id: w.id,
|
|
490
|
+
name: w.name,
|
|
491
|
+
status: w.status,
|
|
492
|
+
publicUrl: w.publicUrl,
|
|
493
|
+
computeProvider: w.computeProvider,
|
|
494
|
+
computeId: w.computeId,
|
|
495
|
+
config: w.config,
|
|
496
|
+
})),
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
catch (error) {
|
|
500
|
+
console.error('Error fetching workspaces:', error);
|
|
501
|
+
res.status(500).json({ error: 'Failed to fetch workspaces' });
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
/**
|
|
505
|
+
* GET /api/test/nango-token
|
|
506
|
+
* Test fetching GitHub App token from Nango (for debugging)
|
|
507
|
+
*/
|
|
508
|
+
testHelpersRouter.get('/nango-token', async (req, res) => {
|
|
509
|
+
if (!isTestMode) {
|
|
510
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
511
|
+
}
|
|
512
|
+
const userId = req.session.userId;
|
|
513
|
+
if (!userId) {
|
|
514
|
+
return res.status(401).json({ error: 'Not logged in' });
|
|
515
|
+
}
|
|
516
|
+
try {
|
|
517
|
+
const repos = await db.repositories.findByUserId(userId);
|
|
518
|
+
const repoWithConnection = repos.find(r => r.nangoConnectionId);
|
|
519
|
+
if (!repoWithConnection?.nangoConnectionId) {
|
|
520
|
+
return res.status(400).json({
|
|
521
|
+
error: 'No Nango connection found',
|
|
522
|
+
repos: repos.map(r => ({ fullName: r.githubFullName, nangoConnectionId: r.nangoConnectionId })),
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
console.log('[test] Fetching token for connection:', repoWithConnection.nangoConnectionId);
|
|
526
|
+
const token = await nangoService.getGithubAppToken(repoWithConnection.nangoConnectionId);
|
|
527
|
+
res.json({
|
|
528
|
+
success: true,
|
|
529
|
+
connectionId: repoWithConnection.nangoConnectionId,
|
|
530
|
+
tokenLength: token.length,
|
|
531
|
+
tokenPrefix: token.substring(0, 10) + '...',
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
catch (error) {
|
|
535
|
+
console.error('[test] Nango token fetch error:', error);
|
|
536
|
+
res.status(500).json({
|
|
537
|
+
error: 'Failed to fetch token',
|
|
538
|
+
details: error instanceof Error ? error.message : 'Unknown error',
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
/**
|
|
543
|
+
* DELETE /api/test/workspace/:id
|
|
544
|
+
* Delete/deprovision a workspace (for cleanup)
|
|
545
|
+
*/
|
|
546
|
+
testHelpersRouter.delete('/workspace/:id', async (req, res) => {
|
|
547
|
+
if (!isTestMode) {
|
|
548
|
+
return res.status(403).json({ error: 'Test endpoints disabled in production' });
|
|
549
|
+
}
|
|
550
|
+
const userId = req.session.userId;
|
|
551
|
+
if (!userId) {
|
|
552
|
+
return res.status(401).json({ error: 'Not logged in' });
|
|
553
|
+
}
|
|
554
|
+
try {
|
|
555
|
+
const { id } = req.params;
|
|
556
|
+
const workspace = await db.workspaces.findById(id);
|
|
557
|
+
if (!workspace) {
|
|
558
|
+
return res.status(404).json({ error: 'Workspace not found' });
|
|
559
|
+
}
|
|
560
|
+
if (workspace.userId !== userId) {
|
|
561
|
+
return res.status(403).json({ error: 'Not your workspace' });
|
|
562
|
+
}
|
|
563
|
+
const provisioner = getProvisioner();
|
|
564
|
+
await provisioner.deprovision(id);
|
|
565
|
+
res.json({
|
|
566
|
+
success: true,
|
|
567
|
+
message: `Workspace ${id} deleted`,
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
catch (error) {
|
|
571
|
+
console.error('Error deleting workspace:', error);
|
|
572
|
+
res.status(500).json({ error: 'Failed to delete workspace' });
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
//# sourceMappingURL=test-helpers.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook API Routes
|
|
3
|
+
*
|
|
4
|
+
* Handles GitHub App webhooks for installation events.
|
|
5
|
+
* Also provides workspace webhook forwarding for external integrations.
|
|
6
|
+
*/
|
|
7
|
+
export declare const webhooksRouter: import("express-serve-static-core").Router;
|
|
8
|
+
//# sourceMappingURL=webhooks.d.ts.map
|