agent-relay 1.2.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/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/cli/index.js +218 -1
- package/dist/cloud/api/billing.js +30 -9
- 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/git.js +24 -3
- package/dist/cloud/api/onboarding.js +15 -2
- package/dist/cloud/api/repos.d.ts +1 -0
- package/dist/cloud/api/repos.js +186 -0
- package/dist/cloud/api/webhooks.d.ts +1 -0
- package/dist/cloud/api/webhooks.js +149 -0
- package/dist/cloud/api/workspaces.js +97 -6
- package/dist/cloud/billing/plans.js +19 -19
- package/dist/cloud/provisioner/index.d.ts +32 -0
- package/dist/cloud/provisioner/index.js +362 -21
- package/dist/cloud/server.js +6 -1
- package/dist/cloud/services/nango.d.ts +60 -0
- package/dist/cloud/services/nango.js +153 -0
- package/dist/cloud/services/planLimits.d.ts +22 -0
- package/dist/cloud/services/planLimits.js +58 -5
- package/dist/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/_next/static/chunks/699-3b1cd6618a45d259.js +1 -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-56a8b4616a90dc43.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-3eac37ea6f5dd153.js → page-c22d080201cbd9fb.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/metrics/{page-1081dd190a331a91.js → page-67a3e98d9a43a6ed.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/{page-daf87e86f783f980.js → page-77e9c65420a06cfb.js} +1 -1
- 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-fee4ed1709070bcd.js → page-68d34f50baa8ab6b.js} +1 -1
- 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-97850e03d723ea8c.js → main-ed4e1fb6f29c34cf.js} +1 -1
- 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 -1
- package/dist/dashboard/out/app.txt +2 -2
- package/dist/dashboard/out/connect-repos.html +1 -1
- package/dist/dashboard/out/connect-repos.txt +2 -2
- 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 +2 -2
- package/dist/dashboard/out/login.txt +2 -2
- 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 -1
- package/dist/dashboard/out/providers.txt +2 -2
- package/dist/dashboard/out/signup.html +2 -2
- package/dist/dashboard/out/signup.txt +2 -2
- package/package.json +2 -11
- 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/cli-pty-runner.d.ts.map +0 -1
- package/dist/cloud/api/cli-pty-runner.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/generic-webhooks.d.ts.map +0 -1
- package/dist/cloud/api/generic-webhooks.js.map +0 -1
- package/dist/cloud/api/git.d.ts.map +0 -1
- package/dist/cloud/api/git.js.map +0 -1
- package/dist/cloud/api/github-app.d.ts.map +0 -1
- package/dist/cloud/api/github-app.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/monitoring.d.ts.map +0 -1
- package/dist/cloud/api/monitoring.js.map +0 -1
- package/dist/cloud/api/nango-auth.d.ts.map +0 -1
- package/dist/cloud/api/nango-auth.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/policy.d.ts.map +0 -1
- package/dist/cloud/api/policy.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/test-helpers.d.ts.map +0 -1
- package/dist/cloud/api/test-helpers.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/webhooks.d.ts.map +0 -1
- package/dist/cloud/api/webhooks.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/auto-scaler.d.ts.map +0 -1
- package/dist/cloud/services/auto-scaler.js.map +0 -1
- package/dist/cloud/services/capacity-manager.d.ts.map +0 -1
- package/dist/cloud/services/capacity-manager.js.map +0 -1
- package/dist/cloud/services/ci-agent-spawner.d.ts.map +0 -1
- package/dist/cloud/services/ci-agent-spawner.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/index.d.ts.map +0 -1
- package/dist/cloud/services/index.js.map +0 -1
- package/dist/cloud/services/mention-handler.d.ts.map +0 -1
- package/dist/cloud/services/mention-handler.js.map +0 -1
- package/dist/cloud/services/nango.d.ts.map +0 -1
- package/dist/cloud/services/nango.js.map +0 -1
- package/dist/cloud/services/persistence.d.ts.map +0 -1
- package/dist/cloud/services/persistence.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/services/scaling-orchestrator.d.ts.map +0 -1
- package/dist/cloud/services/scaling-orchestrator.js.map +0 -1
- package/dist/cloud/services/scaling-policy.d.ts.map +0 -1
- package/dist/cloud/services/scaling-policy.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/cloud/webhooks/index.d.ts.map +0 -1
- package/dist/cloud/webhooks/index.js.map +0 -1
- package/dist/cloud/webhooks/parsers/github.d.ts.map +0 -1
- package/dist/cloud/webhooks/parsers/github.js.map +0 -1
- package/dist/cloud/webhooks/parsers/index.d.ts.map +0 -1
- package/dist/cloud/webhooks/parsers/index.js.map +0 -1
- package/dist/cloud/webhooks/parsers/linear.d.ts.map +0 -1
- package/dist/cloud/webhooks/parsers/linear.js.map +0 -1
- package/dist/cloud/webhooks/parsers/slack.d.ts.map +0 -1
- package/dist/cloud/webhooks/parsers/slack.js.map +0 -1
- package/dist/cloud/webhooks/responders/github.d.ts.map +0 -1
- package/dist/cloud/webhooks/responders/github.js.map +0 -1
- package/dist/cloud/webhooks/responders/index.d.ts.map +0 -1
- package/dist/cloud/webhooks/responders/index.js.map +0 -1
- package/dist/cloud/webhooks/responders/linear.d.ts.map +0 -1
- package/dist/cloud/webhooks/responders/linear.js.map +0 -1
- package/dist/cloud/webhooks/responders/slack.d.ts.map +0 -1
- package/dist/cloud/webhooks/responders/slack.js.map +0 -1
- package/dist/cloud/webhooks/router.d.ts.map +0 -1
- package/dist/cloud/webhooks/router.js.map +0 -1
- package/dist/cloud/webhooks/rules-engine.d.ts.map +0 -1
- package/dist/cloud/webhooks/rules-engine.js.map +0 -1
- package/dist/cloud/webhooks/types.d.ts.map +0 -1
- package/dist/cloud/webhooks/types.js.map +0 -1
- package/dist/continuity/formatter.d.ts.map +0 -1
- package/dist/continuity/formatter.js.map +0 -1
- package/dist/continuity/handoff-store.d.ts.map +0 -1
- package/dist/continuity/handoff-store.js.map +0 -1
- package/dist/continuity/index.d.ts.map +0 -1
- package/dist/continuity/index.js.map +0 -1
- package/dist/continuity/ledger-store.d.ts.map +0 -1
- package/dist/continuity/ledger-store.js.map +0 -1
- package/dist/continuity/manager.d.ts.map +0 -1
- package/dist/continuity/manager.js.map +0 -1
- package/dist/continuity/parser.d.ts.map +0 -1
- package/dist/continuity/parser.js.map +0 -1
- package/dist/continuity/types.d.ts.map +0 -1
- package/dist/continuity/types.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/cli-auth.d.ts.map +0 -1
- package/dist/daemon/cli-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/services/browser-testing.d.ts.map +0 -1
- package/dist/daemon/services/browser-testing.js.map +0 -1
- package/dist/daemon/services/container-spawner.d.ts.map +0 -1
- package/dist/daemon/services/container-spawner.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/480-2d4111711d4e473c.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/766-c3a14283c88d815b.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/page-7120be68bea622f3.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-dc2e3a1a22478efc.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/layout-2433bb48965f4333.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-4d72d5a5d8a9b618.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-b68a681526eb145e.js +0 -1
- package/dist/dashboard/out/_next/static/css/411ce23ffeae9f76.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/emitter.d.ts.map +0 -1
- package/dist/hooks/emitter.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/registry.d.ts.map +0 -1
- package/dist/hooks/registry.js.map +0 -1
- package/dist/hooks/trajectory-hooks.d.ts.map +0 -1
- package/dist/hooks/trajectory-hooks.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/memory/adapters/index.d.ts.map +0 -1
- package/dist/memory/adapters/index.js.map +0 -1
- package/dist/memory/adapters/inmemory.d.ts.map +0 -1
- package/dist/memory/adapters/inmemory.js.map +0 -1
- package/dist/memory/adapters/supermemory.d.ts.map +0 -1
- package/dist/memory/adapters/supermemory.js.map +0 -1
- package/dist/memory/factory.d.ts.map +0 -1
- package/dist/memory/factory.js.map +0 -1
- package/dist/memory/index.d.ts.map +0 -1
- package/dist/memory/index.js.map +0 -1
- package/dist/memory/memory-hooks.d.ts.map +0 -1
- package/dist/memory/memory-hooks.js.map +0 -1
- package/dist/memory/service.d.ts.map +0 -1
- package/dist/memory/service.js.map +0 -1
- package/dist/memory/types.d.ts.map +0 -1
- package/dist/memory/types.js.map +0 -1
- package/dist/policy/agent-policy.d.ts.map +0 -1
- package/dist/policy/agent-policy.js.map +0 -1
- package/dist/policy/cloud-policy-fetcher.d.ts.map +0 -1
- package/dist/policy/cloud-policy-fetcher.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/crash-insights.d.ts.map +0 -1
- package/dist/resiliency/crash-insights.js.map +0 -1
- package/dist/resiliency/gossip-health.d.ts.map +0 -1
- package/dist/resiliency/gossip-health.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/leader-watchdog.d.ts.map +0 -1
- package/dist/resiliency/leader-watchdog.js.map +0 -1
- package/dist/resiliency/logger.d.ts.map +0 -1
- package/dist/resiliency/logger.js.map +0 -1
- package/dist/resiliency/memory-monitor.d.ts.map +0 -1
- package/dist/resiliency/memory-monitor.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/stateless-lead.d.ts.map +0 -1
- package/dist/resiliency/stateless-lead.js.map +0 -1
- package/dist/resiliency/supervisor.d.ts.map +0 -1
- package/dist/resiliency/supervisor.js.map +0 -1
- package/dist/shared/cli-auth-config.d.ts.map +0 -1
- package/dist/shared/cli-auth-config.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/trajectory/config.d.ts.map +0 -1
- package/dist/trajectory/config.js.map +0 -1
- package/dist/trajectory/index.d.ts.map +0 -1
- package/dist/trajectory/index.js.map +0 -1
- package/dist/trajectory/integration.d.ts.map +0 -1
- package/dist/trajectory/integration.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/shared.d.ts.map +0 -1
- package/dist/wrapper/shared.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/CLOUD-ARCHITECTURE.md +0 -804
- package/docs/CLOUD-ONBOARDING-DESIGN.md +0 -1983
- package/docs/CONTRIBUTING.md +0 -151
- package/docs/HOOKS_API.md +0 -394
- package/docs/INTEGRATION-GUIDE.md +0 -926
- package/docs/PROTOCOL.md +0 -325
- package/docs/WRAPPER_EVENTS.md +0 -358
- package/docs/agent-policy-snippet.md +0 -40
- package/docs/agent-relay-protocol.md +0 -238
- package/docs/agent-relay-snippet.md +0 -174
- package/docs/archive/CHANGELOG.md +0 -11
- package/docs/archive/CLI-SIMPLIFICATION-COMPLETE.md +0 -48
- package/docs/archive/DESIGN_BRIDGE_STAFFING.md +0 -878
- package/docs/archive/DESIGN_V2.md +0 -1079
- package/docs/archive/EXECUTIVE_SUMMARY.md +0 -358
- package/docs/archive/MONETIZATION.md +0 -1679
- package/docs/archive/PROPOSAL-trajectories.md +0 -1582
- package/docs/archive/ROADMAP.md +0 -329
- package/docs/archive/SCALING_ANALYSIS.md +0 -280
- package/docs/archive/TESTING_PRESENCE_FEATURES.md +0 -327
- package/docs/archive/TMUX_IMPLEMENTATION_NOTES.md +0 -364
- package/docs/archive/TMUX_IMPROVEMENTS.md +0 -968
- package/docs/archive/dashboard-v2-plan.md +0 -179
- package/docs/archive/removable-code-analysis.md +0 -24
- package/docs/competitive/GASTOWN.md +0 -451
- package/docs/competitive/MCP_AGENT_MAIL.md +0 -389
- package/docs/competitive/OVERVIEW.md +0 -898
- package/docs/competitive/README.md +0 -34
- package/docs/competitive/TMUX_ORCHESTRATOR.md +0 -605
- package/docs/dashboard.png +0 -0
- package/docs/design/ci-failure-webhooks.md +0 -812
- package/docs/design/comprehensive-integrations.md +0 -238
- package/docs/design/e2b-sandbox-integration.md +0 -504
- package/docs/design/github-app-permissions.md +0 -264
- package/docs/guides/CLOUD.md +0 -236
- package/docs/guides/LOCAL.md +0 -535
- package/docs/guides/SELF-HOSTED.md +0 -494
- package/docs/local-testing.md +0 -428
- package/docs/proposals/continuous-claude-integration.md +0 -622
- package/docs/proposals/custom-commands.md +0 -368
- package/docs/proposals/shadow-as-subagent.md +0 -765
- package/docs/proposals/slack-bot-integration.md +0 -1457
- package/docs/tasks/global-skills-system.tasks.md +0 -230
- package/docs/tasks/webhook-integrations.tasks.md +0 -184
- package/docs/tasks/workspace-capabilities.tasks.md +0 -121
- package/docs/testing/RESILIENCY-TEST-PLAN-2026-01-01.md +0 -366
- package/scripts/cloud-setup.sh +0 -96
- 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/manual-qa.sh +0 -293
- package/scripts/run-cloud-qa.sh +0 -220
- package/scripts/test-cli-auth/Dockerfile +0 -44
- package/scripts/test-cli-auth/Dockerfile.real +0 -79
- package/scripts/test-cli-auth/README.md +0 -286
- package/scripts/test-cli-auth/ci-test-real-clis.ts +0 -251
- package/scripts/test-cli-auth/ci-test-runner.ts +0 -263
- package/scripts/test-cli-auth/mock-cli.sh +0 -147
- package/scripts/test-cli-auth/package.json +0 -14
- package/scripts/test-cli-auth/test-oauth-flow.ts +0 -220
- package/scripts/test-pty-input-auto.js +0 -222
- package/scripts/test-pty-input.js +0 -150
- package/scripts/tictactoe-setup.sh +0 -181
- /package/dist/dashboard/out/_next/static/chunks/{117-b100311aff8d5c61.js → 117-f7b8ab0809342e77.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/{648-a13d3c2b1be45466.js → 648-5cc6e1921389a58a.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/{724-73c1ee5f60abe860.js → 724-2dae7627550ab88f.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/app/_not-found/{page-a4973f3e3c82fb67.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/{H5aWG0udPB4iOUIl_gytz → wPgKJtcOmTFLpUncDg16A}/_buildManifest.js +0 -0
- /package/dist/dashboard/out/_next/static/{H5aWG0udPB4iOUIl_gytz → wPgKJtcOmTFLpUncDg16A}/_ssgManifest.js +0 -0
package/dist/cloud/api/repos.js
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
* Repos API Routes
|
|
3
3
|
*
|
|
4
4
|
* GitHub repository management - list, import, sync.
|
|
5
|
+
* Includes Nango-based GitHub permission checking for dashboard access control.
|
|
5
6
|
*/
|
|
6
7
|
import { Router } from 'express';
|
|
7
8
|
import { requireAuth } from './auth.js';
|
|
8
9
|
import { db } from '../db/index.js';
|
|
10
|
+
import { nangoService } from '../services/nango.js';
|
|
9
11
|
export const reposRouter = Router();
|
|
10
12
|
// All routes require authentication
|
|
11
13
|
reposRouter.use(requireAuth);
|
|
@@ -311,4 +313,188 @@ reposRouter.get('/search', async (req, res) => {
|
|
|
311
313
|
res.status(500).json({ error: 'Failed to search repositories' });
|
|
312
314
|
}
|
|
313
315
|
});
|
|
316
|
+
// ============================================================================
|
|
317
|
+
// Nango-based GitHub Permission APIs (for dashboard access control)
|
|
318
|
+
// ============================================================================
|
|
319
|
+
/**
|
|
320
|
+
* GET /api/repos/check-access/:owner/:repo
|
|
321
|
+
* Check if authenticated user has access to a specific GitHub repository.
|
|
322
|
+
* Uses Nango proxy with user's GitHub OAuth token.
|
|
323
|
+
*
|
|
324
|
+
* Response:
|
|
325
|
+
* - hasAccess: boolean - Whether user can access this repo
|
|
326
|
+
* - permission: 'admin' | 'write' | 'read' | 'none' - User's permission level
|
|
327
|
+
* - repository: Repository details if user has access
|
|
328
|
+
*
|
|
329
|
+
* Use this for dashboard access control - grant access if hasAccess is true.
|
|
330
|
+
*/
|
|
331
|
+
reposRouter.get('/check-access/:owner/:repo', async (req, res) => {
|
|
332
|
+
const userId = req.session.userId;
|
|
333
|
+
const { owner, repo } = req.params;
|
|
334
|
+
if (!owner || !repo) {
|
|
335
|
+
return res.status(400).json({ error: 'Owner and repo parameters are required' });
|
|
336
|
+
}
|
|
337
|
+
try {
|
|
338
|
+
// Get user's Nango connection ID
|
|
339
|
+
const user = await db.users.findById(userId);
|
|
340
|
+
if (!user) {
|
|
341
|
+
return res.status(404).json({ error: 'User not found' });
|
|
342
|
+
}
|
|
343
|
+
if (!user.nangoConnectionId) {
|
|
344
|
+
return res.status(400).json({
|
|
345
|
+
error: 'GitHub not connected via Nango',
|
|
346
|
+
code: 'NANGO_NOT_CONNECTED',
|
|
347
|
+
message: 'Please reconnect your GitHub account',
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
// Check access via Nango proxy
|
|
351
|
+
const accessResult = await nangoService.checkUserRepoAccess(user.nangoConnectionId, owner, repo);
|
|
352
|
+
res.json({
|
|
353
|
+
hasAccess: accessResult.hasAccess,
|
|
354
|
+
permission: accessResult.permission,
|
|
355
|
+
repository: accessResult.repository,
|
|
356
|
+
// Include user info for dashboard context
|
|
357
|
+
checkedBy: {
|
|
358
|
+
userId: user.id,
|
|
359
|
+
githubUsername: user.githubUsername,
|
|
360
|
+
},
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
console.error('Error checking repo access:', error);
|
|
365
|
+
res.status(500).json({ error: 'Failed to check repository access' });
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
/**
|
|
369
|
+
* GET /api/repos/accessible
|
|
370
|
+
* List all GitHub repositories the authenticated user has access to.
|
|
371
|
+
* Uses Nango proxy with user's GitHub OAuth token.
|
|
372
|
+
*
|
|
373
|
+
* Query params:
|
|
374
|
+
* - page: Page number (default: 1)
|
|
375
|
+
* - perPage: Results per page (default: 100, max: 100)
|
|
376
|
+
* - type: Filter by type (all, owner, public, private, member)
|
|
377
|
+
* - sort: Sort by (created, updated, pushed, full_name)
|
|
378
|
+
*
|
|
379
|
+
* Use this to determine which dashboards/workspaces a user can access.
|
|
380
|
+
*/
|
|
381
|
+
reposRouter.get('/accessible', async (req, res) => {
|
|
382
|
+
const userId = req.session.userId;
|
|
383
|
+
const { page, perPage, type, sort } = req.query;
|
|
384
|
+
try {
|
|
385
|
+
// Get user's Nango connection ID
|
|
386
|
+
const user = await db.users.findById(userId);
|
|
387
|
+
if (!user) {
|
|
388
|
+
return res.status(404).json({ error: 'User not found' });
|
|
389
|
+
}
|
|
390
|
+
if (!user.nangoConnectionId) {
|
|
391
|
+
return res.status(400).json({
|
|
392
|
+
error: 'GitHub not connected via Nango',
|
|
393
|
+
code: 'NANGO_NOT_CONNECTED',
|
|
394
|
+
message: 'Please reconnect your GitHub account',
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
// List accessible repos via Nango proxy
|
|
398
|
+
const result = await nangoService.listUserAccessibleRepos(user.nangoConnectionId, {
|
|
399
|
+
page: page ? parseInt(page, 10) : undefined,
|
|
400
|
+
perPage: perPage ? Math.min(parseInt(perPage, 10), 100) : undefined,
|
|
401
|
+
type: type,
|
|
402
|
+
sort: sort,
|
|
403
|
+
});
|
|
404
|
+
res.json({
|
|
405
|
+
repositories: result.repositories,
|
|
406
|
+
pagination: {
|
|
407
|
+
page: page ? parseInt(page, 10) : 1,
|
|
408
|
+
perPage: perPage ? Math.min(parseInt(perPage, 10), 100) : 100,
|
|
409
|
+
hasMore: result.hasMore,
|
|
410
|
+
},
|
|
411
|
+
// Include user info for context
|
|
412
|
+
checkedBy: {
|
|
413
|
+
userId: user.id,
|
|
414
|
+
githubUsername: user.githubUsername,
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
console.error('Error listing accessible repos:', error);
|
|
420
|
+
res.status(500).json({ error: 'Failed to list accessible repositories' });
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
/**
|
|
424
|
+
* POST /api/repos/check-access-bulk
|
|
425
|
+
* Check access to multiple repositories at once.
|
|
426
|
+
* Useful for determining which workspaces a user can view.
|
|
427
|
+
*
|
|
428
|
+
* Body:
|
|
429
|
+
* - repositories: Array of "owner/repo" strings
|
|
430
|
+
*
|
|
431
|
+
* Response:
|
|
432
|
+
* - results: Array of { fullName, hasAccess, permission }
|
|
433
|
+
*/
|
|
434
|
+
reposRouter.post('/check-access-bulk', async (req, res) => {
|
|
435
|
+
const userId = req.session.userId;
|
|
436
|
+
const { repositories } = req.body;
|
|
437
|
+
if (!repositories || !Array.isArray(repositories)) {
|
|
438
|
+
return res.status(400).json({ error: 'repositories array is required' });
|
|
439
|
+
}
|
|
440
|
+
if (repositories.length > 50) {
|
|
441
|
+
return res.status(400).json({ error: 'Maximum 50 repositories per request' });
|
|
442
|
+
}
|
|
443
|
+
try {
|
|
444
|
+
// Get user's Nango connection ID
|
|
445
|
+
const user = await db.users.findById(userId);
|
|
446
|
+
if (!user) {
|
|
447
|
+
return res.status(404).json({ error: 'User not found' });
|
|
448
|
+
}
|
|
449
|
+
if (!user.nangoConnectionId) {
|
|
450
|
+
return res.status(400).json({
|
|
451
|
+
error: 'GitHub not connected via Nango',
|
|
452
|
+
code: 'NANGO_NOT_CONNECTED',
|
|
453
|
+
message: 'Please reconnect your GitHub account',
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
// Check access for each repo (in parallel with concurrency limit)
|
|
457
|
+
const results = [];
|
|
458
|
+
// Process in batches of 10 to avoid rate limiting
|
|
459
|
+
const batchSize = 10;
|
|
460
|
+
for (let i = 0; i < repositories.length; i += batchSize) {
|
|
461
|
+
const batch = repositories.slice(i, i + batchSize);
|
|
462
|
+
const batchResults = await Promise.all(batch.map(async (fullName) => {
|
|
463
|
+
try {
|
|
464
|
+
const [owner, repo] = fullName.split('/');
|
|
465
|
+
if (!owner || !repo) {
|
|
466
|
+
return { fullName, hasAccess: false, error: 'Invalid repository format' };
|
|
467
|
+
}
|
|
468
|
+
const accessResult = await nangoService.checkUserRepoAccess(user.nangoConnectionId, owner, repo);
|
|
469
|
+
return {
|
|
470
|
+
fullName,
|
|
471
|
+
hasAccess: accessResult.hasAccess,
|
|
472
|
+
permission: accessResult.permission,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
catch (_err) {
|
|
476
|
+
return { fullName, hasAccess: false, error: 'Check failed' };
|
|
477
|
+
}
|
|
478
|
+
}));
|
|
479
|
+
results.push(...batchResults);
|
|
480
|
+
}
|
|
481
|
+
const accessibleCount = results.filter(r => r.hasAccess).length;
|
|
482
|
+
res.json({
|
|
483
|
+
results,
|
|
484
|
+
summary: {
|
|
485
|
+
total: repositories.length,
|
|
486
|
+
accessible: accessibleCount,
|
|
487
|
+
denied: repositories.length - accessibleCount,
|
|
488
|
+
},
|
|
489
|
+
checkedBy: {
|
|
490
|
+
userId: user.id,
|
|
491
|
+
githubUsername: user.githubUsername,
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
catch (error) {
|
|
496
|
+
console.error('Error checking bulk repo access:', error);
|
|
497
|
+
res.status(500).json({ error: 'Failed to check repository access' });
|
|
498
|
+
}
|
|
499
|
+
});
|
|
314
500
|
//# sourceMappingURL=repos.js.map
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Webhook API Routes
|
|
3
3
|
*
|
|
4
4
|
* Handles GitHub App webhooks for installation events.
|
|
5
|
+
* Also provides workspace webhook forwarding for external integrations.
|
|
5
6
|
*/
|
|
6
7
|
export declare const webhooksRouter: import("express-serve-static-core").Router;
|
|
7
8
|
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -2,12 +2,161 @@
|
|
|
2
2
|
* Webhook API Routes
|
|
3
3
|
*
|
|
4
4
|
* Handles GitHub App webhooks for installation events.
|
|
5
|
+
* Also provides workspace webhook forwarding for external integrations.
|
|
5
6
|
*/
|
|
6
7
|
import { Router } from 'express';
|
|
7
8
|
import crypto from 'crypto';
|
|
8
9
|
import { getConfig } from '../config.js';
|
|
9
10
|
import { db } from '../db/index.js';
|
|
10
11
|
export const webhooksRouter = Router();
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Workspace Webhook Forwarding
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Convert workspace public URL to internal Fly.io URL
|
|
17
|
+
*/
|
|
18
|
+
function getWorkspaceInternalUrl(publicUrl) {
|
|
19
|
+
const isOnFly = !!process.env.FLY_APP_NAME;
|
|
20
|
+
let url = publicUrl.replace(/\/$/, '');
|
|
21
|
+
if (isOnFly && url.includes('.fly.dev')) {
|
|
22
|
+
// Use Fly.io internal networking
|
|
23
|
+
// ar-583f273b.fly.dev -> http://ar-583f273b.internal:3888
|
|
24
|
+
// .internal uses IPv6 and works by default for apps in the same org
|
|
25
|
+
const appName = url.match(/https?:\/\/([^.]+)\.fly\.dev/)?.[1];
|
|
26
|
+
if (appName) {
|
|
27
|
+
url = `http://${appName}.internal:3888`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return url;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Wake a suspended Fly.io workspace machine
|
|
34
|
+
*/
|
|
35
|
+
async function wakeWorkspaceMachine(workspaceId) {
|
|
36
|
+
const workspace = await db.workspaces.findById(workspaceId);
|
|
37
|
+
if (!workspace?.computeId)
|
|
38
|
+
return false;
|
|
39
|
+
const appName = `ar-${workspaceId.substring(0, 8)}`;
|
|
40
|
+
const apiToken = process.env.FLY_API_TOKEN;
|
|
41
|
+
if (!apiToken) {
|
|
42
|
+
console.warn('[webhooks] FLY_API_TOKEN not set, cannot wake machine');
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const response = await fetch(`https://api.machines.dev/v1/apps/${appName}/machines/${workspace.computeId}/start`, {
|
|
47
|
+
method: 'POST',
|
|
48
|
+
headers: { Authorization: `Bearer ${apiToken}` },
|
|
49
|
+
});
|
|
50
|
+
if (response.ok) {
|
|
51
|
+
console.log(`[webhooks] Started workspace machine ${workspace.computeId}`);
|
|
52
|
+
// Wait a bit for machine to start
|
|
53
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
// 200 OK means already running
|
|
57
|
+
if (response.status === 200) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
console.warn(`[webhooks] Failed to start machine: ${response.status}`);
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error('[webhooks] Error waking machine:', error);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* POST /api/webhooks/workspace/:workspaceId/*
|
|
70
|
+
* Forward webhooks to a specific workspace
|
|
71
|
+
*
|
|
72
|
+
* External services can send webhooks to:
|
|
73
|
+
* https://agent-relay.com/api/webhooks/workspace/{workspaceId}/your/path
|
|
74
|
+
*
|
|
75
|
+
* This will be forwarded to:
|
|
76
|
+
* http://{workspace-internal}/webhooks/your/path
|
|
77
|
+
*/
|
|
78
|
+
// Handler for workspace webhook forwarding - matches any path under /workspace/:workspaceId
|
|
79
|
+
async function handleWorkspaceWebhook(req, res) {
|
|
80
|
+
// Extract workspaceId from URL path
|
|
81
|
+
const pathMatch = req.originalUrl.match(/\/workspace\/([^/]+)\/?(.*)$/);
|
|
82
|
+
if (!pathMatch) {
|
|
83
|
+
res.status(400).json({ error: 'Invalid workspace webhook URL' });
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const workspaceId = pathMatch[1];
|
|
87
|
+
const forwardPath = pathMatch[2] || '';
|
|
88
|
+
console.log(`[webhooks] Forwarding to workspace ${workspaceId}: ${req.method} /${forwardPath}`);
|
|
89
|
+
try {
|
|
90
|
+
// Find the workspace
|
|
91
|
+
const workspace = await db.workspaces.findById(workspaceId);
|
|
92
|
+
if (!workspace) {
|
|
93
|
+
res.status(404).json({ error: 'Workspace not found' });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!workspace.publicUrl) {
|
|
97
|
+
res.status(400).json({ error: 'Workspace has no public URL' });
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// Try to wake the machine if it might be suspended
|
|
101
|
+
if (workspace.status === 'running' || workspace.status === 'suspended') {
|
|
102
|
+
await wakeWorkspaceMachine(workspaceId);
|
|
103
|
+
}
|
|
104
|
+
// Get internal URL for server-to-server communication
|
|
105
|
+
const internalUrl = getWorkspaceInternalUrl(workspace.publicUrl);
|
|
106
|
+
const targetUrl = `${internalUrl}/webhooks/${forwardPath}`;
|
|
107
|
+
console.log(`[webhooks] Forwarding to: ${targetUrl}`);
|
|
108
|
+
// Forward the request with original headers and body
|
|
109
|
+
const forwardHeaders = {};
|
|
110
|
+
// Copy relevant headers
|
|
111
|
+
const headersToForward = [
|
|
112
|
+
'content-type',
|
|
113
|
+
'x-hub-signature-256',
|
|
114
|
+
'x-hub-signature',
|
|
115
|
+
'x-github-event',
|
|
116
|
+
'x-github-delivery',
|
|
117
|
+
'x-gitlab-token',
|
|
118
|
+
'x-gitlab-event',
|
|
119
|
+
'user-agent',
|
|
120
|
+
];
|
|
121
|
+
for (const header of headersToForward) {
|
|
122
|
+
const value = req.get(header);
|
|
123
|
+
if (value) {
|
|
124
|
+
forwardHeaders[header] = value;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Add workspace context header
|
|
128
|
+
forwardHeaders['x-forwarded-for-workspace'] = workspaceId;
|
|
129
|
+
forwardHeaders['x-original-host'] = req.get('host') || '';
|
|
130
|
+
// Get raw body if available, otherwise use JSON stringified body
|
|
131
|
+
const rawBody = req.rawBody || JSON.stringify(req.body);
|
|
132
|
+
const response = await fetch(targetUrl, {
|
|
133
|
+
method: req.method,
|
|
134
|
+
headers: forwardHeaders,
|
|
135
|
+
body: ['GET', 'HEAD'].includes(req.method) ? undefined : rawBody,
|
|
136
|
+
});
|
|
137
|
+
// Forward response back
|
|
138
|
+
const responseBody = await response.text();
|
|
139
|
+
res.status(response.status);
|
|
140
|
+
// Copy response headers
|
|
141
|
+
response.headers.forEach((value, key) => {
|
|
142
|
+
if (!['content-encoding', 'transfer-encoding', 'content-length'].includes(key.toLowerCase())) {
|
|
143
|
+
res.set(key, value);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
res.send(responseBody);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
console.error(`[webhooks] Error forwarding to workspace ${workspaceId}:`, error);
|
|
150
|
+
res.status(502).json({
|
|
151
|
+
error: 'Failed to forward webhook to workspace',
|
|
152
|
+
details: error.message,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// TODO: Re-enable workspace webhook forwarding once route pattern issue is resolved
|
|
157
|
+
// The newer path-to-regexp version doesn't support wildcard patterns like /workspace/*
|
|
158
|
+
// See: https://git.new/pathToRegexpError
|
|
159
|
+
// webhooksRouter.all('/workspace/*', handleWorkspaceWebhook);
|
|
11
160
|
// GitHub webhook signature verification
|
|
12
161
|
function verifyGitHubSignature(payload, signature) {
|
|
13
162
|
if (!signature)
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
import { Router } from 'express';
|
|
7
7
|
import { requireAuth } from './auth.js';
|
|
8
8
|
import { db } from '../db/index.js';
|
|
9
|
-
import { getProvisioner } from '../provisioner/index.js';
|
|
9
|
+
import { getProvisioner, getProvisioningStage } from '../provisioner/index.js';
|
|
10
10
|
import { checkWorkspaceLimit } from './middleware/planLimits.js';
|
|
11
|
+
import { getConfig } from '../config.js';
|
|
11
12
|
export const workspacesRouter = Router();
|
|
12
13
|
// All routes require authentication
|
|
13
14
|
workspacesRouter.use(requireAuth);
|
|
@@ -267,7 +268,17 @@ workspacesRouter.get('/:id/status', async (req, res) => {
|
|
|
267
268
|
}
|
|
268
269
|
const provisioner = getProvisioner();
|
|
269
270
|
const status = await provisioner.getStatus(id);
|
|
270
|
-
|
|
271
|
+
// Include provisioning progress info if it exists (even after status changes to 'running')
|
|
272
|
+
// This allows the frontend to see all stages including 'complete'
|
|
273
|
+
const provisioningProgress = getProvisioningStage(id);
|
|
274
|
+
res.json({
|
|
275
|
+
status,
|
|
276
|
+
provisioning: provisioningProgress ? {
|
|
277
|
+
stage: provisioningProgress.stage,
|
|
278
|
+
startedAt: provisioningProgress.startedAt,
|
|
279
|
+
elapsedMs: Date.now() - provisioningProgress.startedAt,
|
|
280
|
+
} : null,
|
|
281
|
+
});
|
|
271
282
|
}
|
|
272
283
|
catch (error) {
|
|
273
284
|
console.error('Error getting workspace status:', error);
|
|
@@ -376,6 +387,77 @@ workspacesRouter.post('/:id/repos', async (req, res) => {
|
|
|
376
387
|
res.status(500).json({ error: 'Failed to add repositories' });
|
|
377
388
|
}
|
|
378
389
|
});
|
|
390
|
+
/**
|
|
391
|
+
* POST /api/workspaces/:id/autoscale
|
|
392
|
+
* Trigger auto-scaling based on current agent count
|
|
393
|
+
* Supports both user session auth and workspace token auth
|
|
394
|
+
* Called by workspace container when spawning new agents
|
|
395
|
+
*/
|
|
396
|
+
workspacesRouter.post('/:id/autoscale', async (req, res) => {
|
|
397
|
+
const { id } = req.params;
|
|
398
|
+
const { agentCount } = req.body;
|
|
399
|
+
if (typeof agentCount !== 'number' || agentCount < 0) {
|
|
400
|
+
return res.status(400).json({ error: 'agentCount must be a non-negative number' });
|
|
401
|
+
}
|
|
402
|
+
try {
|
|
403
|
+
const workspace = await db.workspaces.findById(id);
|
|
404
|
+
if (!workspace) {
|
|
405
|
+
return res.status(404).json({ error: 'Workspace not found' });
|
|
406
|
+
}
|
|
407
|
+
// Verify auth: either user session or workspace token
|
|
408
|
+
const userId = req.session?.userId;
|
|
409
|
+
const authHeader = req.get('authorization');
|
|
410
|
+
if (userId) {
|
|
411
|
+
// User session auth
|
|
412
|
+
if (workspace.userId !== userId) {
|
|
413
|
+
return res.status(403).json({ error: 'Unauthorized' });
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
else if (authHeader?.startsWith('Bearer ')) {
|
|
417
|
+
// Workspace token auth (for calls from within the workspace)
|
|
418
|
+
const crypto = await import('crypto');
|
|
419
|
+
const config = getConfig();
|
|
420
|
+
const providedToken = authHeader.slice(7);
|
|
421
|
+
const expectedToken = crypto.default
|
|
422
|
+
.createHmac('sha256', config.sessionSecret)
|
|
423
|
+
.update(`workspace:${id}`)
|
|
424
|
+
.digest('hex');
|
|
425
|
+
const isValid = crypto.default.timingSafeEqual(Buffer.from(providedToken), Buffer.from(expectedToken));
|
|
426
|
+
if (!isValid) {
|
|
427
|
+
return res.status(401).json({ error: 'Invalid workspace token' });
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
return res.status(401).json({ error: 'Authentication required' });
|
|
432
|
+
}
|
|
433
|
+
const provisioner = getProvisioner();
|
|
434
|
+
const currentTier = await provisioner.getCurrentTier(id);
|
|
435
|
+
const recommendedTier = provisioner.getRecommendedTier(agentCount);
|
|
436
|
+
// Check if scaling is needed
|
|
437
|
+
if (recommendedTier.memoryMb <= currentTier.memoryMb) {
|
|
438
|
+
return res.json({
|
|
439
|
+
scaled: false,
|
|
440
|
+
currentTier: currentTier.name,
|
|
441
|
+
message: 'Current tier is sufficient',
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
// Perform the scale-up (respects plan limits)
|
|
445
|
+
const result = await provisioner.autoScale(id, agentCount);
|
|
446
|
+
res.json({
|
|
447
|
+
scaled: result.scaled,
|
|
448
|
+
previousTier: result.currentTier || currentTier.name,
|
|
449
|
+
newTier: result.targetTier || currentTier.name,
|
|
450
|
+
reason: result.reason,
|
|
451
|
+
message: result.scaled
|
|
452
|
+
? `Scaled up to ${result.targetTier} tier`
|
|
453
|
+
: result.reason || 'Scaling not required',
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
catch (error) {
|
|
457
|
+
console.error('Error auto-scaling workspace:', error);
|
|
458
|
+
res.status(500).json({ error: 'Failed to auto-scale workspace' });
|
|
459
|
+
}
|
|
460
|
+
});
|
|
379
461
|
/**
|
|
380
462
|
* POST /api/workspaces/:id/domain
|
|
381
463
|
* Add or update custom domain (Premium feature - Team/Enterprise only)
|
|
@@ -424,7 +506,7 @@ workspacesRouter.post('/:id/domain', async (req, res) => {
|
|
|
424
506
|
instructions: {
|
|
425
507
|
type: 'CNAME',
|
|
426
508
|
name: domain,
|
|
427
|
-
value: workspace.publicUrl?.replace('https://', '') || `${id}.
|
|
509
|
+
value: workspace.publicUrl?.replace('https://', '') || `${id}.agent-relay.com`,
|
|
428
510
|
ttl: 300,
|
|
429
511
|
},
|
|
430
512
|
verifyEndpoint: `/api/workspaces/${id}/domain/verify`,
|
|
@@ -458,7 +540,7 @@ workspacesRouter.post('/:id/domain/verify', async (req, res) => {
|
|
|
458
540
|
const dns = await import('dns').then(m => m.promises);
|
|
459
541
|
try {
|
|
460
542
|
const records = await dns.resolveCname(workspace.customDomain);
|
|
461
|
-
const expectedTarget = workspace.publicUrl?.replace('https://', '') || `${id}.
|
|
543
|
+
const expectedTarget = workspace.publicUrl?.replace('https://', '') || `${id}.agent-relay.com`;
|
|
462
544
|
if (records.some(r => r.includes(expectedTarget) || r.includes('agentrelay'))) {
|
|
463
545
|
// DNS is configured, now provision SSL cert
|
|
464
546
|
await db.workspaces.updateCustomDomainStatus(id, 'verifying');
|
|
@@ -600,10 +682,19 @@ workspacesRouter.all('/:id/proxy/{*proxyPath}', async (req, res) => {
|
|
|
600
682
|
return res.status(400).json({ error: 'Workspace is not running' });
|
|
601
683
|
}
|
|
602
684
|
// Determine the internal URL for proxying
|
|
603
|
-
// When running inside Docker
|
|
685
|
+
// When running inside Docker or Fly.io, use internal networking
|
|
604
686
|
let targetBaseUrl = workspace.publicUrl;
|
|
605
687
|
const runningInDocker = process.env.RUNNING_IN_DOCKER === 'true';
|
|
606
|
-
|
|
688
|
+
const runningOnFly = !!process.env.FLY_APP_NAME;
|
|
689
|
+
if (runningOnFly && targetBaseUrl.includes('.fly.dev')) {
|
|
690
|
+
// Use Fly.io internal networking (.internal uses IPv6, works by default)
|
|
691
|
+
// ar-583f273b.fly.dev -> http://ar-583f273b.internal:3888
|
|
692
|
+
const appName = targetBaseUrl.match(/https?:\/\/([^.]+)\.fly\.dev/)?.[1];
|
|
693
|
+
if (appName) {
|
|
694
|
+
targetBaseUrl = `http://${appName}.internal:3888`;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
else if (runningInDocker && workspace.computeId && targetBaseUrl.includes('localhost')) {
|
|
607
698
|
// Replace localhost URL with container name for Docker networking
|
|
608
699
|
// workspace.computeId is the container name (e.g., "ar-abc12345")
|
|
609
700
|
// The workspace port is 3888 inside the container
|
|
@@ -10,15 +10,15 @@ export const BILLING_PLANS = {
|
|
|
10
10
|
free: {
|
|
11
11
|
id: 'free',
|
|
12
12
|
name: 'Free',
|
|
13
|
-
description: '
|
|
13
|
+
description: 'Try AI agent workflows with limited access',
|
|
14
14
|
priceMonthly: 0,
|
|
15
15
|
priceYearly: 0,
|
|
16
16
|
limits: {
|
|
17
|
-
maxWorkspaces:
|
|
18
|
-
maxAgentsPerWorkspace:
|
|
17
|
+
maxWorkspaces: 1,
|
|
18
|
+
maxAgentsPerWorkspace: 2,
|
|
19
19
|
maxTeamMembers: 1,
|
|
20
20
|
maxStorageGB: 1,
|
|
21
|
-
maxComputeHoursPerMonth:
|
|
21
|
+
maxComputeHoursPerMonth: 5, // Limited to 5 hours/month
|
|
22
22
|
customDomains: false,
|
|
23
23
|
prioritySupport: false,
|
|
24
24
|
sla: false,
|
|
@@ -27,27 +27,27 @@ export const BILLING_PLANS = {
|
|
|
27
27
|
sessionPersistence: false,
|
|
28
28
|
},
|
|
29
29
|
features: [
|
|
30
|
-
'
|
|
31
|
-
'Up to
|
|
32
|
-
'
|
|
33
|
-
'
|
|
30
|
+
'1 workspace',
|
|
31
|
+
'Up to 2 agents',
|
|
32
|
+
'5 compute hours/month',
|
|
33
|
+
'Shared CPU (may throttle)',
|
|
34
34
|
'Community support',
|
|
35
35
|
],
|
|
36
36
|
},
|
|
37
37
|
pro: {
|
|
38
38
|
id: 'pro',
|
|
39
39
|
name: 'Pro',
|
|
40
|
-
description: 'For professional developers
|
|
41
|
-
priceMonthly:
|
|
42
|
-
priceYearly:
|
|
40
|
+
description: 'For professional developers building with AI agents',
|
|
41
|
+
priceMonthly: 4900, // $49/month
|
|
42
|
+
priceYearly: 47000, // $470/year (2 months free)
|
|
43
43
|
stripePriceIdMonthly: process.env.STRIPE_PRO_MONTHLY_PRICE_ID,
|
|
44
44
|
stripePriceIdYearly: process.env.STRIPE_PRO_YEARLY_PRICE_ID,
|
|
45
45
|
limits: {
|
|
46
|
-
maxWorkspaces:
|
|
47
|
-
maxAgentsPerWorkspace:
|
|
48
|
-
maxTeamMembers:
|
|
46
|
+
maxWorkspaces: 5,
|
|
47
|
+
maxAgentsPerWorkspace: 5,
|
|
48
|
+
maxTeamMembers: 3,
|
|
49
49
|
maxStorageGB: 10,
|
|
50
|
-
maxComputeHoursPerMonth:
|
|
50
|
+
maxComputeHoursPerMonth: 50,
|
|
51
51
|
customDomains: true,
|
|
52
52
|
prioritySupport: false,
|
|
53
53
|
sla: false,
|
|
@@ -56,11 +56,11 @@ export const BILLING_PLANS = {
|
|
|
56
56
|
sessionPersistence: true,
|
|
57
57
|
},
|
|
58
58
|
features: [
|
|
59
|
-
'Up to
|
|
60
|
-
'Up to
|
|
61
|
-
'
|
|
59
|
+
'Up to 5 workspaces',
|
|
60
|
+
'Up to 5 agents per workspace',
|
|
61
|
+
'50 compute hours/month',
|
|
62
62
|
'10 GB storage',
|
|
63
|
-
'
|
|
63
|
+
'3 team members',
|
|
64
64
|
'Custom domains',
|
|
65
65
|
'Session persistence',
|
|
66
66
|
'Email support',
|
|
@@ -4,6 +4,16 @@
|
|
|
4
4
|
* One-click provisioning for compute resources (Fly.io, Railway, Docker).
|
|
5
5
|
*/
|
|
6
6
|
import { Workspace } from '../db/index.js';
|
|
7
|
+
export type ProvisioningStage = 'creating' | 'networking' | 'secrets' | 'machine' | 'booting' | 'health' | 'complete';
|
|
8
|
+
interface ProvisioningProgress {
|
|
9
|
+
stage: ProvisioningStage;
|
|
10
|
+
startedAt: number;
|
|
11
|
+
updatedAt: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get the current provisioning stage for a workspace
|
|
15
|
+
*/
|
|
16
|
+
export declare function getProvisioningStage(workspaceId: string): ProvisioningProgress | null;
|
|
7
17
|
export interface ProvisionConfig {
|
|
8
18
|
userId: string;
|
|
9
19
|
name: string;
|
|
@@ -30,6 +40,7 @@ export interface ResourceTier {
|
|
|
30
40
|
cpuCores: number;
|
|
31
41
|
memoryMb: number;
|
|
32
42
|
maxAgents: number;
|
|
43
|
+
cpuKind: 'shared' | 'performance';
|
|
33
44
|
}
|
|
34
45
|
export declare const RESOURCE_TIERS: Record<string, ResourceTier>;
|
|
35
46
|
/**
|
|
@@ -40,8 +51,13 @@ export declare class WorkspaceProvisioner {
|
|
|
40
51
|
constructor();
|
|
41
52
|
/**
|
|
42
53
|
* Provision a new workspace (one-click)
|
|
54
|
+
* Returns immediately with 'provisioning' status and runs actual provisioning in background
|
|
43
55
|
*/
|
|
44
56
|
provision(config: ProvisionConfig): Promise<ProvisionResult>;
|
|
57
|
+
/**
|
|
58
|
+
* Run the actual provisioning work asynchronously
|
|
59
|
+
*/
|
|
60
|
+
private runProvisioningAsync;
|
|
45
61
|
/**
|
|
46
62
|
* Deprovision a workspace
|
|
47
63
|
*/
|
|
@@ -70,6 +86,22 @@ export declare class WorkspaceProvisioner {
|
|
|
70
86
|
* Get current resource tier for a workspace
|
|
71
87
|
*/
|
|
72
88
|
getCurrentTier(workspaceId: string): Promise<ResourceTier>;
|
|
89
|
+
/**
|
|
90
|
+
* Get recommended tier based on agent count
|
|
91
|
+
* Uses 1.5-2GB per agent as baseline for Claude Code
|
|
92
|
+
*/
|
|
93
|
+
getRecommendedTier(agentCount: number): ResourceTier;
|
|
94
|
+
/**
|
|
95
|
+
* Auto-scale workspace based on current agent count
|
|
96
|
+
* Respects plan limits - free tier cannot scale, others have max tier limits
|
|
97
|
+
* Returns { scaled: boolean, reason?: string }
|
|
98
|
+
*/
|
|
99
|
+
autoScale(workspaceId: string, currentAgentCount: number): Promise<{
|
|
100
|
+
scaled: boolean;
|
|
101
|
+
reason?: string;
|
|
102
|
+
currentTier?: string;
|
|
103
|
+
targetTier?: string;
|
|
104
|
+
}>;
|
|
73
105
|
}
|
|
74
106
|
export declare function getProvisioner(): WorkspaceProvisioner;
|
|
75
107
|
//# sourceMappingURL=index.d.ts.map
|