agent-relay 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +3 -0
- package/.nvmrc +1 -0
- package/.trajectories/agent-relay-322-324.md +17 -0
- package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.json +49 -0
- package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.md +31 -0
- package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.json +125 -0
- package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.md +62 -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_33iuy72sezbk.json +49 -0
- package/.trajectories/completed/2026-01/traj_33iuy72sezbk.md +31 -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_5ammh5qtvklq.json +77 -0
- package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.md +42 -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_6mieijqyvaag.json +77 -0
- package/.trajectories/completed/2026-01/traj_6mieijqyvaag.md +42 -0
- package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.json +77 -0
- package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.md +42 -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_94gnp3k30goq.json +66 -0
- package/.trajectories/completed/2026-01/traj_94gnp3k30goq.md +36 -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_avqeghu6pz5a.json +40 -0
- package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.md +22 -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_dcsp9s8y01ra.json +121 -0
- package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.md +29 -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_fhx9irlckht6.json +53 -0
- package/.trajectories/completed/2026-01/traj_fhx9irlckht6.md +32 -0
- package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.json +101 -0
- package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.md +52 -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_hf81ey93uz6t.json +49 -0
- package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.md +31 -0
- package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.json +65 -0
- package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.md +37 -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_lq450ly148uw.json +49 -0
- package/.trajectories/completed/2026-01/traj_lq450ly148uw.md +31 -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_multi_server_arch.md +101 -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_psd9ob0j2ru3.json +27 -0
- package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.md +14 -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_ub8csuv3lcv4.json +53 -0
- package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.md +32 -0
- package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.json +186 -0
- package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.md +86 -0
- package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.json +77 -0
- package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.md +42 -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_v9dkdoxylyid.json +89 -0
- package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.md +47 -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_xy9vifpqet80.json +65 -0
- package/.trajectories/completed/2026-01/traj_xy9vifpqet80.md +37 -0
- package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.json +49 -0
- package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.md +31 -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/consolidate-settings-panel.md +24 -0
- package/.trajectories/gh-cli-user-token.md +26 -0
- package/.trajectories/index.json +468 -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/codex.config.toml +15 -0
- package/deploy/workspace/entrypoint-browser.sh +118 -0
- package/deploy/workspace/entrypoint.sh +508 -0
- package/deploy/workspace/git-credential-relay +126 -0
- package/dist/bridge/spawner.d.ts +7 -0
- package/dist/bridge/spawner.js +40 -9
- package/dist/bridge/types.d.ts +2 -0
- package/dist/cli/index.js +260 -1
- package/dist/cloud/api/admin.d.ts +8 -0
- package/dist/cloud/api/admin.js +212 -0
- package/dist/cloud/api/auth.js +8 -0
- package/dist/cloud/api/billing.d.ts +0 -10
- package/dist/cloud/api/billing.js +278 -67
- package/dist/cloud/api/codex-auth-helper.d.ts +21 -0
- package/dist/cloud/api/codex-auth-helper.js +307 -0
- package/dist/cloud/api/coordinators.js +402 -0
- package/dist/cloud/api/daemons.js +15 -11
- package/dist/cloud/api/git.js +127 -19
- package/dist/cloud/api/github-app.js +42 -8
- package/dist/cloud/api/nango-auth.js +297 -16
- package/dist/cloud/api/onboarding.js +112 -35
- package/dist/cloud/api/providers.js +12 -16
- package/dist/cloud/api/repos.d.ts +1 -0
- package/dist/cloud/api/repos.js +311 -49
- package/dist/cloud/api/test-helpers.js +40 -0
- package/dist/cloud/api/usage.js +13 -0
- package/dist/cloud/api/webhooks.d.ts +1 -0
- package/dist/cloud/api/webhooks.js +149 -0
- package/dist/cloud/api/workspaces.d.ts +18 -0
- package/dist/cloud/api/workspaces.js +1042 -21
- package/dist/cloud/billing/plans.js +19 -19
- package/dist/cloud/config.d.ts +8 -0
- package/dist/cloud/config.js +15 -0
- package/dist/cloud/db/drizzle.d.ts +5 -2
- package/dist/cloud/db/drizzle.js +27 -20
- package/dist/cloud/db/schema.d.ts +19 -51
- package/dist/cloud/db/schema.js +5 -4
- package/dist/cloud/index.d.ts +0 -1
- package/dist/cloud/index.js +0 -1
- package/dist/cloud/provisioner/index.d.ts +125 -1
- package/dist/cloud/provisioner/index.js +939 -53
- package/dist/cloud/server.js +161 -16
- package/dist/cloud/services/compute-enforcement.d.ts +57 -0
- package/dist/cloud/services/compute-enforcement.js +175 -0
- package/dist/cloud/services/index.d.ts +2 -0
- package/dist/cloud/services/index.js +4 -0
- package/dist/cloud/services/intro-expiration.d.ts +55 -0
- package/dist/cloud/services/intro-expiration.js +211 -0
- package/dist/cloud/services/nango.d.ts +74 -0
- package/dist/cloud/services/nango.js +218 -5
- package/dist/cloud/services/planLimits.d.ts +22 -0
- package/dist/cloud/services/planLimits.js +58 -5
- package/dist/cloud/services/ssh-security.d.ts +31 -0
- package/dist/cloud/services/ssh-security.js +63 -0
- package/dist/continuity/manager.d.ts +5 -0
- package/dist/continuity/manager.js +56 -2
- package/dist/daemon/api.d.ts +2 -0
- package/dist/daemon/api.js +214 -5
- package/dist/daemon/cli-auth.d.ts +13 -1
- package/dist/daemon/cli-auth.js +166 -47
- package/dist/daemon/connection.d.ts +7 -1
- package/dist/daemon/connection.js +15 -0
- package/dist/daemon/orchestrator.d.ts +2 -0
- package/dist/daemon/orchestrator.js +26 -0
- package/dist/daemon/repo-manager.d.ts +116 -0
- package/dist/daemon/repo-manager.js +384 -0
- package/dist/daemon/router.d.ts +60 -1
- package/dist/daemon/router.js +281 -20
- package/dist/daemon/user-directory.d.ts +111 -0
- package/dist/daemon/user-directory.js +233 -0
- package/dist/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/_next/static/T1tgCqVWHFIkV7ClEtzD7/_ssgManifest.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +9 -0
- package/dist/dashboard/out/_next/static/chunks/766-b54f0853794b78c3.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/83-b51836037078006c.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/891-6cd50de1224f70bb.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/899-bb19a9b3d9b39ea6.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-8939b0fc700f7eca.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/page-5af1b6b439858aa6.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-ac39dc0cc3c26fa7.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/{page-daf87e86f783f980.js → page-4a5938c18a11a654.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-ac3a6ac433fd6001.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-09f9caae98a18c09.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/{main-97850e03d723ea8c.js → main-2ee6beb2ae96d210.js} +1 -1
- package/dist/dashboard/out/_next/static/css/85d2af9c7ac74d62.css +1 -0
- package/dist/dashboard/out/_next/static/css/fe4b28883eeff359.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 +3 -3
- package/dist/dashboard/out/apple-icon.png +0 -0
- package/dist/dashboard/out/connect-repos.html +1 -1
- package/dist/dashboard/out/connect-repos.txt +3 -3
- package/dist/dashboard/out/history.html +1 -1
- package/dist/dashboard/out/history.txt +3 -3
- package/dist/dashboard/out/index.html +1 -1
- package/dist/dashboard/out/index.txt +3 -3
- package/dist/dashboard/out/login.html +2 -2
- package/dist/dashboard/out/login.txt +3 -3
- package/dist/dashboard/out/metrics.html +1 -1
- package/dist/dashboard/out/metrics.txt +3 -3
- package/dist/dashboard/out/pricing.html +3 -3
- package/dist/dashboard/out/pricing.txt +3 -3
- package/dist/dashboard/out/providers/setup/claude.html +1 -0
- package/dist/dashboard/out/providers/setup/claude.txt +8 -0
- package/dist/dashboard/out/providers/setup/codex.html +1 -0
- package/dist/dashboard/out/providers/setup/codex.txt +8 -0
- package/dist/dashboard/out/providers.html +1 -1
- package/dist/dashboard/out/providers.txt +3 -3
- package/dist/dashboard/out/signup.html +2 -2
- package/dist/dashboard/out/signup.txt +3 -3
- package/dist/dashboard-server/server.js +316 -12
- package/dist/dashboard-server/user-bridge.d.ts +103 -0
- package/dist/dashboard-server/user-bridge.js +189 -0
- package/dist/protocol/channels.d.ts +205 -0
- package/dist/protocol/channels.js +154 -0
- package/dist/protocol/types.d.ts +13 -1
- package/dist/resiliency/provider-context.js +2 -0
- package/dist/shared/cli-auth-config.d.ts +19 -0
- package/dist/shared/cli-auth-config.js +58 -2
- package/dist/utils/agent-config.js +1 -1
- package/dist/wrapper/auth-detection.d.ts +49 -0
- package/dist/wrapper/auth-detection.js +192 -0
- package/dist/wrapper/base-wrapper.d.ts +153 -0
- package/dist/wrapper/base-wrapper.js +393 -0
- package/dist/wrapper/client.d.ts +7 -1
- package/dist/wrapper/client.js +3 -0
- package/dist/wrapper/index.d.ts +1 -0
- package/dist/wrapper/index.js +4 -3
- package/dist/wrapper/pty-wrapper.d.ts +62 -84
- package/dist/wrapper/pty-wrapper.js +154 -180
- package/dist/wrapper/tmux-wrapper.d.ts +41 -66
- package/dist/wrapper/tmux-wrapper.js +90 -134
- package/package.json +5 -12
- package/scripts/postinstall.js +11 -155
- package/scripts/test-interactive-terminal.sh +248 -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/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 +0 -76
- package/dist/cloud/vault/index.d.ts.map +0 -1
- package/dist/cloud/vault/index.js +0 -219
- 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/H5aWG0udPB4iOUIl_gytz/_ssgManifest.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/480-2d4111711d4e473c.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/724-73c1ee5f60abe860.js +0 -9
- 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/metrics/page-1081dd190a331a91.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-b68a681526eb145e.js +0 -1
- package/dist/dashboard/out/_next/static/css/29852f26181969a0.css +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/{H5aWG0udPB4iOUIl_gytz → T1tgCqVWHFIkV7ClEtzD7}/_buildManifest.js +0 -0
- /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/app/_not-found/{page-a4973f3e3c82fb67.js → page-53b8a69f76db17d0.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/app/connect-repos/{page-dc2e3a1a22478efc.js → page-f45ecbc3e06134fc.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/app/history/{page-56a8b4616a90dc43.js → page-8c8bed33beb2bf1c.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/app/login/{page-3eac37ea6f5dd153.js → page-16f3b49e55b1e0ed.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/app/pricing/{page-4d72d5a5d8a9b618.js → page-982a7000fee44014.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/app/signup/{page-fee4ed1709070bcd.js → page-547dd0ca55ecd0ba.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/{fd9d1056-bf46c09eb57e019c.js → fd9d1056-609918ca7b6280bb.js} +0 -0
|
@@ -5,24 +5,121 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Router } from 'express';
|
|
7
7
|
import { getBillingService, getAllPlans, getPlan, comparePlans } from '../billing/index.js';
|
|
8
|
-
import { getConfig } from '../config.js';
|
|
8
|
+
import { getConfig, isAdminUser } from '../config.js';
|
|
9
|
+
import { db } from '../db/index.js';
|
|
10
|
+
import { requireAuth } from './auth.js';
|
|
11
|
+
import { getProvisioner, RESOURCE_TIERS } from '../provisioner/index.js';
|
|
12
|
+
import { getResourceTierForPlan } from '../services/planLimits.js';
|
|
9
13
|
export const billingRouter = Router();
|
|
10
14
|
/**
|
|
11
|
-
*
|
|
15
|
+
* Get the count of connected agents in a running workspace
|
|
16
|
+
* Returns 0 if workspace is not reachable or has no agents
|
|
12
17
|
*/
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
async function getWorkspaceAgentCount(publicUrl) {
|
|
19
|
+
try {
|
|
20
|
+
const controller = new AbortController();
|
|
21
|
+
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
22
|
+
const response = await fetch(`${publicUrl}/agents`, {
|
|
23
|
+
signal: controller.signal,
|
|
24
|
+
});
|
|
25
|
+
clearTimeout(timeout);
|
|
26
|
+
if (!response.ok)
|
|
27
|
+
return 0;
|
|
28
|
+
const data = await response.json();
|
|
29
|
+
return data.agents?.length ?? 0;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Workspace not reachable or error - assume no agents
|
|
33
|
+
return 0;
|
|
17
34
|
}
|
|
18
|
-
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resize user's workspaces to match their new plan tier
|
|
38
|
+
* Called after plan upgrade/downgrade to adjust compute resources
|
|
39
|
+
*
|
|
40
|
+
* Strategy:
|
|
41
|
+
* - Stopped workspaces: Resize immediately (no disruption)
|
|
42
|
+
* - Running workspaces with no agents: Resize immediately (safe to restart)
|
|
43
|
+
* - Running workspaces with agents: Save config for next restart (no agent disruption)
|
|
44
|
+
*
|
|
45
|
+
* Returns info about which workspaces were deferred so we can inform the user.
|
|
46
|
+
*/
|
|
47
|
+
async function resizeWorkspacesForPlan(userId, newPlan) {
|
|
48
|
+
const result = { resized: 0, deferred: [], failed: 0 };
|
|
49
|
+
try {
|
|
50
|
+
const workspaces = await db.workspaces.findByUserId(userId);
|
|
51
|
+
if (workspaces.length === 0)
|
|
52
|
+
return result;
|
|
53
|
+
const provisioner = getProvisioner();
|
|
54
|
+
const targetTierName = getResourceTierForPlan(newPlan);
|
|
55
|
+
const targetTier = RESOURCE_TIERS[targetTierName];
|
|
56
|
+
console.log(`[billing] Upgrading ${workspaces.length} workspace(s) for user ${userId.substring(0, 8)} to ${targetTierName}`);
|
|
57
|
+
for (const workspace of workspaces) {
|
|
58
|
+
if (workspace.status !== 'running' && workspace.status !== 'stopped') {
|
|
59
|
+
console.log(`[billing] Skipping workspace ${workspace.id.substring(0, 8)} (status: ${workspace.status})`);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
let skipRestart = false;
|
|
64
|
+
let agentCount = 0;
|
|
65
|
+
// For running workspaces: check if there are active agents
|
|
66
|
+
if (workspace.status === 'running' && workspace.publicUrl) {
|
|
67
|
+
agentCount = await getWorkspaceAgentCount(workspace.publicUrl);
|
|
68
|
+
if (agentCount > 0) {
|
|
69
|
+
// Has active agents - don't disrupt them
|
|
70
|
+
skipRestart = true;
|
|
71
|
+
console.log(`[billing] Workspace ${workspace.id.substring(0, 8)} has ${agentCount} active agent(s), deferring resize`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// No active agents - safe to restart immediately
|
|
75
|
+
console.log(`[billing] Workspace ${workspace.id.substring(0, 8)} has no active agents, proceeding with immediate resize`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
await provisioner.resize(workspace.id, targetTier, skipRestart);
|
|
79
|
+
if (skipRestart) {
|
|
80
|
+
console.log(`[billing] Queued resize for workspace ${workspace.id.substring(0, 8)} to ${targetTierName} (will apply on next restart)`);
|
|
81
|
+
result.deferred.push({
|
|
82
|
+
workspaceId: workspace.id,
|
|
83
|
+
workspaceName: workspace.name,
|
|
84
|
+
agentCount,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
console.log(`[billing] Resized workspace ${workspace.id.substring(0, 8)} to ${targetTierName}`);
|
|
89
|
+
result.resized++;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error(`[billing] Failed to resize workspace ${workspace.id}:`, error);
|
|
94
|
+
result.failed++;
|
|
95
|
+
// Continue with other workspaces even if one fails
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
console.error('[billing] Failed to resize workspaces:', error);
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
19
103
|
}
|
|
20
104
|
/**
|
|
21
105
|
* GET /api/billing/plans
|
|
22
106
|
* Get all available billing plans
|
|
23
107
|
*/
|
|
24
108
|
billingRouter.get('/plans', (req, res) => {
|
|
25
|
-
const
|
|
109
|
+
const rawPlans = getAllPlans();
|
|
110
|
+
// Transform plans to frontend format
|
|
111
|
+
const plans = rawPlans.map((plan) => ({
|
|
112
|
+
tier: plan.id,
|
|
113
|
+
name: plan.name,
|
|
114
|
+
description: plan.description,
|
|
115
|
+
price: {
|
|
116
|
+
monthly: plan.priceMonthly / 100, // Convert cents to dollars
|
|
117
|
+
yearly: plan.priceYearly / 100,
|
|
118
|
+
},
|
|
119
|
+
features: plan.features,
|
|
120
|
+
limits: plan.limits,
|
|
121
|
+
recommended: plan.id === 'pro',
|
|
122
|
+
}));
|
|
26
123
|
// Add publishable key for frontend
|
|
27
124
|
const config = getConfig();
|
|
28
125
|
res.json({
|
|
@@ -67,15 +164,38 @@ billingRouter.get('/compare', (req, res) => {
|
|
|
67
164
|
* Get current user's subscription status
|
|
68
165
|
*/
|
|
69
166
|
billingRouter.get('/subscription', requireAuth, async (req, res) => {
|
|
70
|
-
const
|
|
71
|
-
const billing = getBillingService();
|
|
167
|
+
const userId = req.session.userId;
|
|
72
168
|
try {
|
|
169
|
+
// Fetch user from database
|
|
170
|
+
const user = await db.users.findById(userId);
|
|
171
|
+
if (!user) {
|
|
172
|
+
return res.status(404).json({ error: 'User not found' });
|
|
173
|
+
}
|
|
174
|
+
// Admin users have special status - show their current plan without Stripe
|
|
175
|
+
if (isAdminUser(user.githubUsername)) {
|
|
176
|
+
return res.json({
|
|
177
|
+
tier: user.plan || 'enterprise',
|
|
178
|
+
subscription: null,
|
|
179
|
+
customer: null,
|
|
180
|
+
isAdmin: true,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
// If user doesn't have a Stripe customer ID, use the database plan value
|
|
184
|
+
// This handles manually-set plans and prevents hanging on Stripe API calls
|
|
185
|
+
if (!user.stripeCustomerId) {
|
|
186
|
+
return res.json({
|
|
187
|
+
tier: user.plan || 'free',
|
|
188
|
+
subscription: null,
|
|
189
|
+
customer: null,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
const billing = getBillingService();
|
|
73
193
|
// Get or create Stripe customer
|
|
74
194
|
const customerId = user.stripeCustomerId ||
|
|
75
|
-
await billing.getOrCreateCustomer(user.id, user.email, user.
|
|
76
|
-
// Save customer ID to
|
|
195
|
+
await billing.getOrCreateCustomer(user.id, user.email || '', user.githubUsername);
|
|
196
|
+
// Save customer ID to database if newly created
|
|
77
197
|
if (!user.stripeCustomerId) {
|
|
78
|
-
|
|
198
|
+
await db.users.update(userId, { stripeCustomerId: customerId });
|
|
79
199
|
}
|
|
80
200
|
// Get customer details
|
|
81
201
|
const customer = await billing.getCustomer(customerId);
|
|
@@ -87,8 +207,11 @@ billingRouter.get('/subscription', requireAuth, async (req, res) => {
|
|
|
87
207
|
});
|
|
88
208
|
return;
|
|
89
209
|
}
|
|
210
|
+
// Use Stripe subscription tier if active, otherwise fall back to database plan value
|
|
211
|
+
// This allows manual plan overrides in the database to take effect
|
|
212
|
+
const tier = customer.subscription?.tier || user.plan || 'free';
|
|
90
213
|
res.json({
|
|
91
|
-
tier
|
|
214
|
+
tier,
|
|
92
215
|
subscription: customer.subscription,
|
|
93
216
|
customer: {
|
|
94
217
|
id: customer.id,
|
|
@@ -109,7 +232,7 @@ billingRouter.get('/subscription', requireAuth, async (req, res) => {
|
|
|
109
232
|
* Create a checkout session for subscription
|
|
110
233
|
*/
|
|
111
234
|
billingRouter.post('/checkout', requireAuth, async (req, res) => {
|
|
112
|
-
const
|
|
235
|
+
const userId = req.session.userId;
|
|
113
236
|
const { tier, interval = 'month' } = req.body;
|
|
114
237
|
if (!tier || !['pro', 'team', 'enterprise'].includes(tier)) {
|
|
115
238
|
res.status(400).json({ error: 'Invalid tier' });
|
|
@@ -119,18 +242,44 @@ billingRouter.post('/checkout', requireAuth, async (req, res) => {
|
|
|
119
242
|
res.status(400).json({ error: 'Invalid billing interval' });
|
|
120
243
|
return;
|
|
121
244
|
}
|
|
122
|
-
const billing = getBillingService();
|
|
123
245
|
const config = getConfig();
|
|
124
246
|
try {
|
|
247
|
+
// Fetch user from database
|
|
248
|
+
const user = await db.users.findById(userId);
|
|
249
|
+
if (!user) {
|
|
250
|
+
return res.status(404).json({ error: 'User not found' });
|
|
251
|
+
}
|
|
252
|
+
// Admin users get free upgrades - skip Stripe entirely
|
|
253
|
+
if (isAdminUser(user.githubUsername)) {
|
|
254
|
+
// Update user plan directly
|
|
255
|
+
await db.users.update(userId, { plan: tier });
|
|
256
|
+
console.log(`[billing] Admin user ${user.githubUsername} upgraded to ${tier} (free)`);
|
|
257
|
+
// Resize workspaces to match new plan (wait for result to inform user)
|
|
258
|
+
const resizeResult = await resizeWorkspacesForPlan(userId, tier);
|
|
259
|
+
// Build success URL with deferred workspace info if any
|
|
260
|
+
let successUrl = `${config.appUrl}/billing/success?admin=true`;
|
|
261
|
+
if (resizeResult.deferred.length > 0) {
|
|
262
|
+
// Encode deferred workspaces info for the frontend to display
|
|
263
|
+
const deferredInfo = encodeURIComponent(JSON.stringify(resizeResult.deferred));
|
|
264
|
+
successUrl += `&deferred=${deferredInfo}`;
|
|
265
|
+
}
|
|
266
|
+
// Return a fake session that redirects to success
|
|
267
|
+
return res.json({
|
|
268
|
+
sessionId: 'admin-upgrade',
|
|
269
|
+
checkoutUrl: successUrl,
|
|
270
|
+
resizeResult, // Also include in response for API consumers
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
const billing = getBillingService();
|
|
125
274
|
// Get or create customer
|
|
126
275
|
const customerId = user.stripeCustomerId ||
|
|
127
|
-
await billing.getOrCreateCustomer(user.id, user.email, user.
|
|
128
|
-
// Save customer ID to
|
|
276
|
+
await billing.getOrCreateCustomer(user.id, user.email || '', user.githubUsername);
|
|
277
|
+
// Save customer ID to database
|
|
129
278
|
if (!user.stripeCustomerId) {
|
|
130
|
-
|
|
279
|
+
await db.users.update(userId, { stripeCustomerId: customerId });
|
|
131
280
|
}
|
|
132
281
|
// Create checkout session
|
|
133
|
-
const session = await billing.createCheckoutSession(customerId, tier, interval, `${config.
|
|
282
|
+
const session = await billing.createCheckoutSession(customerId, tier, interval, `${config.appUrl}/billing/success?session_id={CHECKOUT_SESSION_ID}`, `${config.appUrl}/billing/canceled`);
|
|
134
283
|
res.json(session);
|
|
135
284
|
}
|
|
136
285
|
catch (error) {
|
|
@@ -143,15 +292,19 @@ billingRouter.post('/checkout', requireAuth, async (req, res) => {
|
|
|
143
292
|
* Create a billing portal session for managing subscription
|
|
144
293
|
*/
|
|
145
294
|
billingRouter.post('/portal', requireAuth, async (req, res) => {
|
|
146
|
-
const
|
|
147
|
-
if (!user.stripeCustomerId) {
|
|
148
|
-
res.status(400).json({ error: 'No billing account found' });
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
const billing = getBillingService();
|
|
152
|
-
const config = getConfig();
|
|
295
|
+
const userId = req.session.userId;
|
|
153
296
|
try {
|
|
154
|
-
const
|
|
297
|
+
const user = await db.users.findById(userId);
|
|
298
|
+
if (!user) {
|
|
299
|
+
return res.status(404).json({ error: 'User not found' });
|
|
300
|
+
}
|
|
301
|
+
if (!user.stripeCustomerId) {
|
|
302
|
+
res.status(400).json({ error: 'No billing account found' });
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const billing = getBillingService();
|
|
306
|
+
const config = getConfig();
|
|
307
|
+
const session = await billing.createPortalSession(user.stripeCustomerId, `${config.appUrl}/billing`);
|
|
155
308
|
res.json(session);
|
|
156
309
|
}
|
|
157
310
|
catch (error) {
|
|
@@ -164,18 +317,22 @@ billingRouter.post('/portal', requireAuth, async (req, res) => {
|
|
|
164
317
|
* Change subscription tier
|
|
165
318
|
*/
|
|
166
319
|
billingRouter.post('/change', requireAuth, async (req, res) => {
|
|
167
|
-
const
|
|
320
|
+
const userId = req.session.userId;
|
|
168
321
|
const { tier, interval = 'month' } = req.body;
|
|
169
322
|
if (!tier || !['free', 'pro', 'team', 'enterprise'].includes(tier)) {
|
|
170
323
|
res.status(400).json({ error: 'Invalid tier' });
|
|
171
324
|
return;
|
|
172
325
|
}
|
|
173
|
-
if (!user.stripeCustomerId) {
|
|
174
|
-
res.status(400).json({ error: 'No billing account found' });
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
const billing = getBillingService();
|
|
178
326
|
try {
|
|
327
|
+
const user = await db.users.findById(userId);
|
|
328
|
+
if (!user) {
|
|
329
|
+
return res.status(404).json({ error: 'User not found' });
|
|
330
|
+
}
|
|
331
|
+
if (!user.stripeCustomerId) {
|
|
332
|
+
res.status(400).json({ error: 'No billing account found' });
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
const billing = getBillingService();
|
|
179
336
|
// Get current subscription
|
|
180
337
|
const customer = await billing.getCustomer(user.stripeCustomerId);
|
|
181
338
|
if (!customer?.subscription) {
|
|
@@ -202,13 +359,17 @@ billingRouter.post('/change', requireAuth, async (req, res) => {
|
|
|
202
359
|
* Cancel subscription at period end
|
|
203
360
|
*/
|
|
204
361
|
billingRouter.post('/cancel', requireAuth, async (req, res) => {
|
|
205
|
-
const
|
|
206
|
-
if (!user.stripeCustomerId) {
|
|
207
|
-
res.status(400).json({ error: 'No billing account found' });
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
const billing = getBillingService();
|
|
362
|
+
const userId = req.session.userId;
|
|
211
363
|
try {
|
|
364
|
+
const user = await db.users.findById(userId);
|
|
365
|
+
if (!user) {
|
|
366
|
+
return res.status(404).json({ error: 'User not found' });
|
|
367
|
+
}
|
|
368
|
+
if (!user.stripeCustomerId) {
|
|
369
|
+
res.status(400).json({ error: 'No billing account found' });
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const billing = getBillingService();
|
|
212
373
|
const customer = await billing.getCustomer(user.stripeCustomerId);
|
|
213
374
|
if (!customer?.subscription) {
|
|
214
375
|
res.status(400).json({ error: 'No active subscription' });
|
|
@@ -230,13 +391,17 @@ billingRouter.post('/cancel', requireAuth, async (req, res) => {
|
|
|
230
391
|
* Resume a canceled subscription
|
|
231
392
|
*/
|
|
232
393
|
billingRouter.post('/resume', requireAuth, async (req, res) => {
|
|
233
|
-
const
|
|
234
|
-
if (!user.stripeCustomerId) {
|
|
235
|
-
res.status(400).json({ error: 'No billing account found' });
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
const billing = getBillingService();
|
|
394
|
+
const userId = req.session.userId;
|
|
239
395
|
try {
|
|
396
|
+
const user = await db.users.findById(userId);
|
|
397
|
+
if (!user) {
|
|
398
|
+
return res.status(404).json({ error: 'User not found' });
|
|
399
|
+
}
|
|
400
|
+
if (!user.stripeCustomerId) {
|
|
401
|
+
res.status(400).json({ error: 'No billing account found' });
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
const billing = getBillingService();
|
|
240
405
|
const customer = await billing.getCustomer(user.stripeCustomerId);
|
|
241
406
|
if (!customer?.subscription) {
|
|
242
407
|
res.status(400).json({ error: 'No subscription to resume' });
|
|
@@ -259,13 +424,17 @@ billingRouter.post('/resume', requireAuth, async (req, res) => {
|
|
|
259
424
|
* Get user's invoices
|
|
260
425
|
*/
|
|
261
426
|
billingRouter.get('/invoices', requireAuth, async (req, res) => {
|
|
262
|
-
const
|
|
263
|
-
if (!user.stripeCustomerId) {
|
|
264
|
-
res.json({ invoices: [] });
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
const billing = getBillingService();
|
|
427
|
+
const userId = req.session.userId;
|
|
268
428
|
try {
|
|
429
|
+
const user = await db.users.findById(userId);
|
|
430
|
+
if (!user) {
|
|
431
|
+
return res.status(404).json({ error: 'User not found' });
|
|
432
|
+
}
|
|
433
|
+
// No Stripe customer = no invoices, skip Stripe call entirely
|
|
434
|
+
if (!user.stripeCustomerId) {
|
|
435
|
+
return res.json({ invoices: [] });
|
|
436
|
+
}
|
|
437
|
+
const billing = getBillingService();
|
|
269
438
|
const customer = await billing.getCustomer(user.stripeCustomerId);
|
|
270
439
|
res.json({ invoices: customer?.invoices || [] });
|
|
271
440
|
}
|
|
@@ -279,13 +448,17 @@ billingRouter.get('/invoices', requireAuth, async (req, res) => {
|
|
|
279
448
|
* Get upcoming invoice preview
|
|
280
449
|
*/
|
|
281
450
|
billingRouter.get('/upcoming', requireAuth, async (req, res) => {
|
|
282
|
-
const
|
|
283
|
-
if (!user.stripeCustomerId) {
|
|
284
|
-
res.json({ invoice: null });
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
const billing = getBillingService();
|
|
451
|
+
const userId = req.session.userId;
|
|
288
452
|
try {
|
|
453
|
+
const user = await db.users.findById(userId);
|
|
454
|
+
if (!user) {
|
|
455
|
+
return res.status(404).json({ error: 'User not found' });
|
|
456
|
+
}
|
|
457
|
+
if (!user.stripeCustomerId) {
|
|
458
|
+
res.json({ invoice: null });
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
const billing = getBillingService();
|
|
289
462
|
const invoice = await billing.getUpcomingInvoice(user.stripeCustomerId);
|
|
290
463
|
res.json({ invoice });
|
|
291
464
|
}
|
|
@@ -315,8 +488,14 @@ billingRouter.post('/webhook',
|
|
|
315
488
|
}
|
|
316
489
|
const billing = getBillingService();
|
|
317
490
|
try {
|
|
318
|
-
//
|
|
319
|
-
|
|
491
|
+
// Use the preserved raw body from express.json verify callback
|
|
492
|
+
// This is critical for Stripe signature verification - JSON.stringify(req.body) won't work
|
|
493
|
+
const rawBody = req.rawBody;
|
|
494
|
+
if (!rawBody) {
|
|
495
|
+
console.error('Raw body not available for Stripe webhook verification');
|
|
496
|
+
res.status(400).json({ error: 'Raw body not available' });
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
320
499
|
// Verify and parse event
|
|
321
500
|
const event = billing.verifyWebhookSignature(rawBody, sig);
|
|
322
501
|
// Process the event
|
|
@@ -330,16 +509,48 @@ billingRouter.post('/webhook',
|
|
|
330
509
|
// Handle specific events
|
|
331
510
|
switch (billingEvent.type) {
|
|
332
511
|
case 'subscription.created':
|
|
333
|
-
case 'subscription.updated':
|
|
334
|
-
//
|
|
335
|
-
|
|
336
|
-
|
|
512
|
+
case 'subscription.updated': {
|
|
513
|
+
// Extract subscription tier and update user's plan
|
|
514
|
+
if (billingEvent.userId) {
|
|
515
|
+
const subscription = billingEvent.data;
|
|
516
|
+
const tier = billing.getTierFromSubscription(subscription);
|
|
517
|
+
// Update user's plan in database
|
|
518
|
+
await db.users.update(billingEvent.userId, { plan: tier });
|
|
519
|
+
console.log(`Updated user ${billingEvent.userId} plan to: ${tier}`);
|
|
520
|
+
// Resize workspaces to match new plan (async, don't block webhook)
|
|
521
|
+
resizeWorkspacesForPlan(billingEvent.userId, tier).then((result) => {
|
|
522
|
+
if (result.deferred.length > 0) {
|
|
523
|
+
console.log(`[billing] User ${billingEvent.userId} upgrade: ${result.resized} resized, ${result.deferred.length} deferred (have active agents)`);
|
|
524
|
+
result.deferred.forEach((d) => {
|
|
525
|
+
console.log(`[billing] - "${d.workspaceName}" has ${d.agentCount} agent(s), will resize on next restart`);
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
console.log(`[billing] User ${billingEvent.userId} upgrade: all ${result.resized} workspace(s) resized immediately`);
|
|
530
|
+
}
|
|
531
|
+
}).catch((err) => {
|
|
532
|
+
console.error(`Failed to resize workspaces for user ${billingEvent.userId}:`, err);
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
else {
|
|
536
|
+
console.warn('Subscription event received without userId:', billingEvent.id);
|
|
537
|
+
}
|
|
337
538
|
break;
|
|
338
|
-
|
|
339
|
-
|
|
539
|
+
}
|
|
540
|
+
case 'subscription.canceled': {
|
|
541
|
+
// Reset user to free plan
|
|
542
|
+
if (billingEvent.userId) {
|
|
543
|
+
await db.users.update(billingEvent.userId, { plan: 'free' });
|
|
544
|
+
console.log(`User ${billingEvent.userId} subscription canceled, reset to free plan`);
|
|
545
|
+
// Resize workspaces down to free tier (async)
|
|
546
|
+
resizeWorkspacesForPlan(billingEvent.userId, 'free').catch((err) => {
|
|
547
|
+
console.error(`Failed to resize workspaces for user ${billingEvent.userId}:`, err);
|
|
548
|
+
});
|
|
549
|
+
}
|
|
340
550
|
break;
|
|
551
|
+
}
|
|
341
552
|
case 'invoice.payment_failed':
|
|
342
|
-
//
|
|
553
|
+
// Log payment failure (don't immediately downgrade - Stripe retries)
|
|
343
554
|
console.log('Payment failed for user:', billingEvent.userId);
|
|
344
555
|
break;
|
|
345
556
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Auth Helper API
|
|
3
|
+
*
|
|
4
|
+
* Provides endpoints for the `npx agent-relay codex-auth` CLI command.
|
|
5
|
+
* Uses SSH tunneling to forward localhost:1455 to the workspace container,
|
|
6
|
+
* allowing the Codex CLI's OAuth callback to work in remote/container environments.
|
|
7
|
+
*
|
|
8
|
+
* Flow:
|
|
9
|
+
* 1. CLI gets workspace SSH info via /tunnel-info
|
|
10
|
+
* 2. CLI establishes SSH tunnel: local:1455 -> container:1455
|
|
11
|
+
* 3. User completes OAuth, browser redirects to localhost:1455
|
|
12
|
+
* 4. Tunnel forwards to container's Codex CLI server
|
|
13
|
+
* 5. Codex CLI exchanges code for tokens internally
|
|
14
|
+
* 6. CLI polls for auth completion
|
|
15
|
+
*/
|
|
16
|
+
export declare const codexAuthHelperRouter: import("express-serve-static-core").Router;
|
|
17
|
+
/**
|
|
18
|
+
* Stop the cleanup interval. Call this on server shutdown.
|
|
19
|
+
*/
|
|
20
|
+
export declare function stopCodexAuthCleanup(): void;
|
|
21
|
+
//# sourceMappingURL=codex-auth-helper.d.ts.map
|