conductor-oss 0.18.3 → 0.18.4
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/package.json +5 -5
- package/web/.next/standalone/packages/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/packages/web/.next/app-path-routes-manifest.json +1 -1
- package/web/.next/standalone/packages/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/packages/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/packages/web/.next/routes-manifest.json +6 -6
- package/web/.next/standalone/packages/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/packages/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_not-found/page/server-reference-manifest.json +7 -7
- package/web/.next/standalone/packages/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_not-found.rsc +3 -3
- package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/access/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/access/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/agents/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/agents/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/app-update/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/app-update/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/attachments/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/attachments/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/boards/comments/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/boards/comments/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/boards/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/boards/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/config/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/config/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/context-files/open/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/context-files/open/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/context-files/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/context-files/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/events/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/events/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/executor/health/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/executor/health/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/filesystem/directory/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/filesystem/directory/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/filesystem/pick-directory/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/filesystem/pick-directory/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/github/repos/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/github/repos/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/github/webhook/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/github/webhook/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/health/boards/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/health/boards/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/health/sessions/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/health/sessions/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/notifications/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/preferences/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/preferences/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/remote-access/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/remote-access/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/repositories/[id]/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/repositories/[id]/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/repositories/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/actions/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/actions/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/archive/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/archive/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/checks/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/checks/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/diff/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/diff/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feedback/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feedback/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/files/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/files/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/interrupt/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/interrupt/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/kill/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/kill/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/output/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/output/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/dom/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/dom/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/screenshot/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/screenshot/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/restore/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/restore/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/snapshot/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/snapshot/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/token/route/app-paths-manifest.json +3 -0
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/token/route.js +10 -0
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/{connection → token}/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/token/route_client-reference-manifest.js +2 -0
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/spawn/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/spawn/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/branches/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/branches/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/route.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/route.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/page/react-loadable-manifest.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/page/server-reference-manifest.json +7 -7
- package/web/.next/standalone/packages/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page/react-loadable-manifest.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page/server-reference-manifest.json +7 -7
- package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page/server-reference-manifest.json +7 -7
- package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/unlock/page/server-reference-manifest.json +7 -7
- package/web/.next/standalone/packages/web/.next/server/app/unlock/page.js.nft.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/app/unlock/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/app-paths-manifest.json +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/26076_server_app_api_sessions_[id]_terminal_token_route_actions_9c4b3c06.js +3 -0
- package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__63017d21._.js +3 -0
- package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__f56e5b36._.js → [root-of-the-server]__9279c912._.js} +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/_2c837d66._.js +80 -0
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__379d412d._.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{[root-of-the-server]__20d5f3d2._.js → [root-of-the-server]__443ba186._.js} +2 -2
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{[root-of-the-server]__c92de424._.js → [root-of-the-server]__742dad30._.js} +2 -2
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__749fe4b2._.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{[root-of-the-server]__7e8cb25c._.js → [root-of-the-server]__a8fa29c1._.js} +2 -2
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_0e1412de._.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_532f707d._.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_69e05fca._.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_80efe193._.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_9bf43d8d._.js +3 -0
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_c0f0e227._.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_f36ddaa9._.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{node_modules_0c16b10c._.js → node_modules_91aa5708._.js} +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@clerk_nextjs_dist_esm_app-router_3964db17._.js +3 -0
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@clerk_nextjs_dist_esm_app-router_5c863a0e._.js +3 -0
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{node_modules_ec4cd8a2._.js → node_modules_be1275d0._.js} +1 -1
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_components_sessions_SessionTerminal_tsx_eaf9458b._.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/functions-config-manifest.json +2 -2
- package/web/.next/standalone/packages/web/.next/server/pages/404.html +1 -1
- package/web/.next/standalone/packages/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/packages/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/packages/web/.next/server/server-reference-manifest.json +8 -8
- package/web/.next/{static/chunks/995113d11fe53a63.js → standalone/packages/web/.next/static/chunks/179d5fdedb569ec3.js} +1 -1
- package/web/.next/standalone/packages/web/.next/static/chunks/{1bdd2123a45ba58c.js → 2037d1500c64fbef.js} +1 -1
- package/web/.next/standalone/packages/web/.next/static/chunks/{c9f2a58585434ce0.js → 3ad6d404d5657604.js} +1 -1
- package/web/.next/standalone/packages/web/.next/static/chunks/4d288f280972fd06.js +1 -0
- package/web/.next/standalone/packages/web/.next/static/chunks/97e7e5343941de65.js +1 -0
- package/web/.next/standalone/packages/web/.next/static/chunks/{962bd9b2967657d6.js → ab8cea4266d5034c.js} +1 -1
- package/web/.next/{static/chunks/7d66c96327f5fd43.js → standalone/packages/web/.next/static/chunks/b2b84b9e8ccbeafa.js} +1 -1
- package/web/.next/standalone/packages/web/.next/static/chunks/b9a43bac36046bf9.js +138 -0
- package/web/.next/{static/chunks/1a90fb2f85154bcc.js → standalone/packages/web/.next/static/chunks/d1cbb83a98e765b5.js} +1 -1
- package/web/.next/standalone/packages/web/.next/static/chunks/{27756dc916c1e477.js → f2fea305b6822999.js} +1 -1
- package/web/.next/standalone/packages/web/.next/static/chunks/f48f57293e98e0d8.js +1 -0
- package/web/.next/standalone/packages/web/.next/static/chunks/fe52c44944adc7f2.js +1 -0
- package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/terminal/token/route.ts +13 -0
- package/web/.next/standalone/packages/web/src/components/sessions/SessionTerminal.tsx +77 -39
- package/web/.next/standalone/packages/web/src/components/sessions/sessionTerminalUtils.test.ts +0 -122
- package/web/.next/standalone/packages/web/src/components/sessions/sessionTerminalUtils.ts +0 -220
- package/web/.next/standalone/packages/web/src/components/sessions/terminal/terminalApi.ts +89 -87
- package/web/.next/standalone/packages/web/src/components/sessions/terminal/terminalCache.ts +2 -73
- package/web/.next/standalone/packages/web/src/components/sessions/terminal/terminalConstants.ts +0 -8
- package/web/.next/standalone/packages/web/src/components/sessions/terminal/terminalTypes.ts +0 -19
- package/web/.next/standalone/packages/web/src/components/sessions/terminal/ttydClient.ts +122 -27
- package/web/.next/standalone/packages/web/src/components/sessions/terminal/useTtydConnection.ts +9 -12
- package/web/.next/{standalone/packages/web/.next/static/chunks/995113d11fe53a63.js → static/chunks/179d5fdedb569ec3.js} +1 -1
- package/web/.next/static/chunks/{1bdd2123a45ba58c.js → 2037d1500c64fbef.js} +1 -1
- package/web/.next/static/chunks/{c9f2a58585434ce0.js → 3ad6d404d5657604.js} +1 -1
- package/web/.next/static/chunks/4d288f280972fd06.js +1 -0
- package/web/.next/static/chunks/97e7e5343941de65.js +1 -0
- package/web/.next/static/chunks/{962bd9b2967657d6.js → ab8cea4266d5034c.js} +1 -1
- package/web/.next/{standalone/packages/web/.next/static/chunks/7d66c96327f5fd43.js → static/chunks/b2b84b9e8ccbeafa.js} +1 -1
- package/web/.next/static/chunks/b9a43bac36046bf9.js +138 -0
- package/web/.next/{standalone/packages/web/.next/static/chunks/1a90fb2f85154bcc.js → static/chunks/d1cbb83a98e765b5.js} +1 -1
- package/web/.next/static/chunks/{27756dc916c1e477.js → f2fea305b6822999.js} +1 -1
- package/web/.next/static/chunks/f48f57293e98e0d8.js +1 -0
- package/web/.next/static/chunks/fe52c44944adc7f2.js +1 -0
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/connection/route/app-paths-manifest.json +0 -3
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/connection/route.js +0 -10
- package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/connection/route_client-reference-manifest.js +0 -2
- package/web/.next/standalone/packages/web/.next/server/chunks/26076_server_app_api_sessions_[id]_terminal_connection_route_actions_46c114ee.js +0 -3
- package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1029f927._.js +0 -3
- package/web/.next/standalone/packages/web/.next/server/chunks/_24c4e75d._.js +0 -80
- package/web/.next/standalone/packages/web/.next/server/chunks/_3d39aff4._.js +0 -80
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_7db952ae._.js +0 -3
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@clerk_nextjs_dist_esm_app-router_8f8a4bec._.js +0 -3
- package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@clerk_nextjs_dist_esm_app-router_b92af890._.js +0 -3
- package/web/.next/standalone/packages/web/.next/static/chunks/1382eff030c401e3.js +0 -1
- package/web/.next/standalone/packages/web/.next/static/chunks/1e6e51cb4f906baa.js +0 -1
- package/web/.next/standalone/packages/web/.next/static/chunks/7630100be1c763fc.js +0 -1
- package/web/.next/standalone/packages/web/.next/static/chunks/dbd9fbeb4e10c4dc.js +0 -1
- package/web/.next/standalone/packages/web/.next/static/chunks/df2796ef26c6da4f.js +0 -138
- package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/terminal/connection/route.test.ts +0 -343
- package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/terminal/connection/route.ts +0 -120
- package/web/.next/static/chunks/1382eff030c401e3.js +0 -1
- package/web/.next/static/chunks/1e6e51cb4f906baa.js +0 -1
- package/web/.next/static/chunks/7630100be1c763fc.js +0 -1
- package/web/.next/static/chunks/dbd9fbeb4e10c4dc.js +0 -1
- package/web/.next/static/chunks/df2796ef26c6da4f.js +0 -138
- /package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/{connection → token}/route/build-manifest.json +0 -0
- /package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/{connection → token}/route/server-reference-manifest.json +0 -0
- /package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/terminal/{connection → token}/route.js.map +0 -0
- /package/web/.next/standalone/packages/web/.next/static/{bfEstB7nf2ym3CDoSi2cy → O7I3Iz18_tPidBRAWeKh8}/_buildManifest.js +0 -0
- /package/web/.next/standalone/packages/web/.next/static/{bfEstB7nf2ym3CDoSi2cy → O7I3Iz18_tPidBRAWeKh8}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/packages/web/.next/static/{bfEstB7nf2ym3CDoSi2cy → O7I3Iz18_tPidBRAWeKh8}/_ssgManifest.js +0 -0
- /package/web/.next/static/{bfEstB7nf2ym3CDoSi2cy → O7I3Iz18_tPidBRAWeKh8}/_buildManifest.js +0 -0
- /package/web/.next/static/{bfEstB7nf2ym3CDoSi2cy → O7I3Iz18_tPidBRAWeKh8}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{bfEstB7nf2ym3CDoSi2cy → O7I3Iz18_tPidBRAWeKh8}/_ssgManifest.js +0 -0
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { NextRequest } from "next/server";
|
|
6
|
-
import {
|
|
7
|
-
clearRemoteAccessRuntimeState,
|
|
8
|
-
writeRemoteAccessRuntimeState,
|
|
9
|
-
} from "@/lib/remoteAccessRuntime";
|
|
10
|
-
import { GET } from "./route";
|
|
11
|
-
|
|
12
|
-
const originalBackendUrl = process.env.CONDUCTOR_BACKEND_URL;
|
|
13
|
-
const originalConfigPath = process.env.CO_CONFIG_PATH;
|
|
14
|
-
const originalWorkspace = process.env.CONDUCTOR_WORKSPACE;
|
|
15
|
-
const originalRequireAuth = process.env.CONDUCTOR_REQUIRE_AUTH;
|
|
16
|
-
const originalDefaultRole = process.env.CONDUCTOR_ACCESS_DEFAULT_ROLE;
|
|
17
|
-
const originalRemoteAccessRuntimePath =
|
|
18
|
-
process.env.CONDUCTOR_REMOTE_ACCESS_RUNTIME_PATH;
|
|
19
|
-
const originalRemoteAccessToken = process.env.CONDUCTOR_REMOTE_ACCESS_TOKEN;
|
|
20
|
-
const originalRemoteSessionSecret = process.env.CONDUCTOR_REMOTE_SESSION_SECRET;
|
|
21
|
-
const originalFetch = global.fetch;
|
|
22
|
-
|
|
23
|
-
type TerminalConnectionPayload = {
|
|
24
|
-
ptyWsUrl: string | null;
|
|
25
|
-
interactive: boolean;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
function resetEnv(): void {
|
|
29
|
-
delete process.env.CONDUCTOR_BACKEND_URL;
|
|
30
|
-
process.env.CO_CONFIG_PATH =
|
|
31
|
-
"/tmp/conductor-terminal-connection-route-test-config-does-not-exist.yaml";
|
|
32
|
-
process.env.CONDUCTOR_WORKSPACE = "terminal-connection-route-test-workspace";
|
|
33
|
-
process.env.CONDUCTOR_REQUIRE_AUTH = "";
|
|
34
|
-
delete process.env.CONDUCTOR_ACCESS_DEFAULT_ROLE;
|
|
35
|
-
delete process.env.CONDUCTOR_REMOTE_ACCESS_TOKEN;
|
|
36
|
-
delete process.env.CONDUCTOR_REMOTE_SESSION_SECRET;
|
|
37
|
-
process.env.CONDUCTOR_REMOTE_ACCESS_RUNTIME_PATH = join(
|
|
38
|
-
tmpdir(),
|
|
39
|
-
"conductor-terminal-connection-route-runtime.json"
|
|
40
|
-
);
|
|
41
|
-
clearRemoteAccessRuntimeState();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
type MockSessionConnectionFetchOptions = {
|
|
45
|
-
id: string;
|
|
46
|
-
token?: {
|
|
47
|
-
token?: string | null;
|
|
48
|
-
required?: boolean;
|
|
49
|
-
expiresInSeconds?: number | null;
|
|
50
|
-
error?: string;
|
|
51
|
-
};
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
function setMockSessionConnectionFetch({
|
|
55
|
-
id,
|
|
56
|
-
token,
|
|
57
|
-
}: MockSessionConnectionFetchOptions): void {
|
|
58
|
-
const terminalTokenUrl = `/api/sessions/${encodeURIComponent(
|
|
59
|
-
id
|
|
60
|
-
)}/terminal/token`;
|
|
61
|
-
global.fetch = (async (input: string | Request | URL) => {
|
|
62
|
-
const url =
|
|
63
|
-
typeof input === "string" || input instanceof URL
|
|
64
|
-
? new URL(input)
|
|
65
|
-
: new URL(input.url);
|
|
66
|
-
if (url.pathname === terminalTokenUrl) {
|
|
67
|
-
if (token === undefined) {
|
|
68
|
-
throw new Error("terminal token lookup should not run for this test");
|
|
69
|
-
}
|
|
70
|
-
return new Response(JSON.stringify(token), {
|
|
71
|
-
status: 200,
|
|
72
|
-
headers: { "Content-Type": "application/json" },
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
throw new Error(
|
|
77
|
-
`Unexpected fetch in terminal connection route test: ${url.pathname}`
|
|
78
|
-
);
|
|
79
|
-
}) as typeof fetch;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function assertJsonResponse(
|
|
83
|
-
response: Response
|
|
84
|
-
): Promise<TerminalConnectionPayload> {
|
|
85
|
-
return response.json() as Promise<TerminalConnectionPayload>;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
test.afterEach(() => {
|
|
89
|
-
resetEnv();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
test.after(() => {
|
|
93
|
-
if (originalBackendUrl === undefined) {
|
|
94
|
-
delete process.env.CONDUCTOR_BACKEND_URL;
|
|
95
|
-
} else {
|
|
96
|
-
process.env.CONDUCTOR_BACKEND_URL = originalBackendUrl;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (originalConfigPath === undefined) {
|
|
100
|
-
delete process.env.CO_CONFIG_PATH;
|
|
101
|
-
} else {
|
|
102
|
-
process.env.CO_CONFIG_PATH = originalConfigPath;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (originalWorkspace === undefined) {
|
|
106
|
-
delete process.env.CONDUCTOR_WORKSPACE;
|
|
107
|
-
} else {
|
|
108
|
-
process.env.CONDUCTOR_WORKSPACE = originalWorkspace;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (originalRequireAuth === undefined) {
|
|
112
|
-
delete process.env.CONDUCTOR_REQUIRE_AUTH;
|
|
113
|
-
} else {
|
|
114
|
-
process.env.CONDUCTOR_REQUIRE_AUTH = originalRequireAuth;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (originalDefaultRole === undefined) {
|
|
118
|
-
delete process.env.CONDUCTOR_ACCESS_DEFAULT_ROLE;
|
|
119
|
-
} else {
|
|
120
|
-
process.env.CONDUCTOR_ACCESS_DEFAULT_ROLE = originalDefaultRole;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (originalRemoteAccessRuntimePath === undefined) {
|
|
124
|
-
delete process.env.CONDUCTOR_REMOTE_ACCESS_RUNTIME_PATH;
|
|
125
|
-
} else {
|
|
126
|
-
process.env.CONDUCTOR_REMOTE_ACCESS_RUNTIME_PATH =
|
|
127
|
-
originalRemoteAccessRuntimePath;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (originalRemoteAccessToken === undefined) {
|
|
131
|
-
delete process.env.CONDUCTOR_REMOTE_ACCESS_TOKEN;
|
|
132
|
-
} else {
|
|
133
|
-
process.env.CONDUCTOR_REMOTE_ACCESS_TOKEN = originalRemoteAccessToken;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (originalRemoteSessionSecret === undefined) {
|
|
137
|
-
delete process.env.CONDUCTOR_REMOTE_SESSION_SECRET;
|
|
138
|
-
} else {
|
|
139
|
-
process.env.CONDUCTOR_REMOTE_SESSION_SECRET = originalRemoteSessionSecret;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
global.fetch = originalFetch;
|
|
143
|
-
clearRemoteAccessRuntimeState();
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
test("GET returns ptyWsUrl and interactive for loopback dashboard requests", async () => {
|
|
147
|
-
resetEnv();
|
|
148
|
-
process.env.CONDUCTOR_BACKEND_URL = "http://127.0.0.1:4749";
|
|
149
|
-
|
|
150
|
-
global.fetch = (async (input: string | Request | URL) => {
|
|
151
|
-
const url =
|
|
152
|
-
typeof input === "string" || input instanceof URL
|
|
153
|
-
? new URL(input)
|
|
154
|
-
: new URL(input.url);
|
|
155
|
-
if (url.pathname.includes("/terminal/token")) {
|
|
156
|
-
return new Response(JSON.stringify({ required: false }), {
|
|
157
|
-
status: 200,
|
|
158
|
-
headers: { "Content-Type": "application/json" },
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
throw new Error(`Unexpected fetch: ${url.pathname}`);
|
|
162
|
-
}) as typeof fetch;
|
|
163
|
-
|
|
164
|
-
try {
|
|
165
|
-
const response = await GET(
|
|
166
|
-
new NextRequest(
|
|
167
|
-
"http://127.0.0.1:3000/api/sessions/session-1/terminal/connection"
|
|
168
|
-
),
|
|
169
|
-
{ params: Promise.resolve({ id: "session-1" }) }
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
assert.equal(response.status, 200);
|
|
173
|
-
const payload = await assertJsonResponse(response);
|
|
174
|
-
|
|
175
|
-
assert.equal(
|
|
176
|
-
payload.ptyWsUrl,
|
|
177
|
-
"ws://127.0.0.1:4749/api/sessions/session-1/terminal/ws?protocol=ttyd"
|
|
178
|
-
);
|
|
179
|
-
assert.equal(payload.interactive, true);
|
|
180
|
-
} finally {
|
|
181
|
-
global.fetch = originalFetch;
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test("GET returns null ptyWsUrl for viewers without operator access", async () => {
|
|
186
|
-
resetEnv();
|
|
187
|
-
process.env.CONDUCTOR_BACKEND_URL = "http://127.0.0.1:4749";
|
|
188
|
-
process.env.CONDUCTOR_ACCESS_DEFAULT_ROLE = "viewer";
|
|
189
|
-
|
|
190
|
-
writeRemoteAccessRuntimeState({
|
|
191
|
-
status: "ready",
|
|
192
|
-
provider: "tailscale",
|
|
193
|
-
publicUrl: "https://laptop.tailnet.ts.net",
|
|
194
|
-
localUrl: "http://127.0.0.1:3000",
|
|
195
|
-
accessToken: null,
|
|
196
|
-
sessionSecret: null,
|
|
197
|
-
tunnelPid: null,
|
|
198
|
-
logPath: null,
|
|
199
|
-
lastError: null,
|
|
200
|
-
startedAt: new Date().toISOString(),
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
const request = new NextRequest(
|
|
205
|
-
"https://laptop.tailnet.ts.net/api/sessions/session-1/terminal/connection",
|
|
206
|
-
{
|
|
207
|
-
headers: {
|
|
208
|
-
"Tailscale-User-Login": "viewer@example.com",
|
|
209
|
-
},
|
|
210
|
-
}
|
|
211
|
-
);
|
|
212
|
-
const response = await GET(request, {
|
|
213
|
-
params: Promise.resolve({ id: "session-1" }),
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
assert.equal(response.status, 200);
|
|
217
|
-
const payload = await assertJsonResponse(response);
|
|
218
|
-
|
|
219
|
-
assert.equal(payload.ptyWsUrl, null);
|
|
220
|
-
assert.equal(payload.interactive, false);
|
|
221
|
-
} finally {
|
|
222
|
-
global.fetch = originalFetch;
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
test("GET appends a control token to the direct PTY websocket when auth is required", async () => {
|
|
227
|
-
resetEnv();
|
|
228
|
-
process.env.CONDUCTOR_BACKEND_URL = "http://127.0.0.1:4749";
|
|
229
|
-
process.env.CONDUCTOR_REQUIRE_AUTH = "true";
|
|
230
|
-
|
|
231
|
-
setMockSessionConnectionFetch({
|
|
232
|
-
id: "session-1",
|
|
233
|
-
token: {
|
|
234
|
-
required: true,
|
|
235
|
-
token: "signed-terminal-token",
|
|
236
|
-
expiresInSeconds: 60,
|
|
237
|
-
},
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
try {
|
|
241
|
-
const response = await GET(
|
|
242
|
-
new NextRequest(
|
|
243
|
-
"http://127.0.0.1:3000/api/sessions/session-1/terminal/connection"
|
|
244
|
-
),
|
|
245
|
-
{ params: Promise.resolve({ id: "session-1" }) }
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
assert.equal(response.status, 200);
|
|
249
|
-
const payload = await assertJsonResponse(response);
|
|
250
|
-
assert.equal(
|
|
251
|
-
payload.ptyWsUrl,
|
|
252
|
-
"ws://127.0.0.1:4749/api/sessions/session-1/terminal/ws?protocol=ttyd&token=signed-terminal-token"
|
|
253
|
-
);
|
|
254
|
-
assert.equal(payload.interactive, true);
|
|
255
|
-
} finally {
|
|
256
|
-
global.fetch = originalFetch;
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
test("GET falls back to ptyWsUrl without token when token fetch fails", async () => {
|
|
261
|
-
resetEnv();
|
|
262
|
-
process.env.CONDUCTOR_BACKEND_URL = "http://127.0.0.1:4749";
|
|
263
|
-
|
|
264
|
-
global.fetch = (async () => {
|
|
265
|
-
throw new Error("token endpoint unreachable");
|
|
266
|
-
}) as typeof fetch;
|
|
267
|
-
|
|
268
|
-
try {
|
|
269
|
-
const response = await GET(
|
|
270
|
-
new NextRequest(
|
|
271
|
-
"http://127.0.0.1:3000/api/sessions/session-1/terminal/connection"
|
|
272
|
-
),
|
|
273
|
-
{ params: Promise.resolve({ id: "session-1" }) }
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
assert.equal(response.status, 200);
|
|
277
|
-
const payload = await assertJsonResponse(response);
|
|
278
|
-
|
|
279
|
-
assert.equal(
|
|
280
|
-
payload.ptyWsUrl,
|
|
281
|
-
"ws://127.0.0.1:4749/api/sessions/session-1/terminal/ws?protocol=ttyd"
|
|
282
|
-
);
|
|
283
|
-
assert.equal(payload.interactive, true);
|
|
284
|
-
} finally {
|
|
285
|
-
global.fetch = originalFetch;
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
test("GET uses wss: protocol when backend URL is https", async () => {
|
|
290
|
-
resetEnv();
|
|
291
|
-
process.env.CONDUCTOR_BACKEND_URL = "https://backend.example.com:4749";
|
|
292
|
-
|
|
293
|
-
writeRemoteAccessRuntimeState({
|
|
294
|
-
status: "ready",
|
|
295
|
-
provider: "tailscale",
|
|
296
|
-
publicUrl: "https://dashboard.example.com",
|
|
297
|
-
localUrl: "http://127.0.0.1:3000",
|
|
298
|
-
accessToken: null,
|
|
299
|
-
sessionSecret: null,
|
|
300
|
-
tunnelPid: null,
|
|
301
|
-
logPath: null,
|
|
302
|
-
lastError: null,
|
|
303
|
-
startedAt: new Date().toISOString(),
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
global.fetch = (async (input: string | Request | URL) => {
|
|
307
|
-
const url =
|
|
308
|
-
typeof input === "string" || input instanceof URL
|
|
309
|
-
? new URL(input)
|
|
310
|
-
: new URL(input.url);
|
|
311
|
-
if (url.pathname.includes("/terminal/token")) {
|
|
312
|
-
return new Response(JSON.stringify({ required: false }), {
|
|
313
|
-
status: 200,
|
|
314
|
-
headers: { "Content-Type": "application/json" },
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
throw new Error(`Unexpected fetch: ${url.pathname}`);
|
|
318
|
-
}) as typeof fetch;
|
|
319
|
-
|
|
320
|
-
try {
|
|
321
|
-
const response = await GET(
|
|
322
|
-
new NextRequest(
|
|
323
|
-
"https://dashboard.example.com/api/sessions/session-1/terminal/connection",
|
|
324
|
-
{
|
|
325
|
-
headers: {
|
|
326
|
-
"Tailscale-User-Login": "dev@example.com",
|
|
327
|
-
},
|
|
328
|
-
}
|
|
329
|
-
),
|
|
330
|
-
{ params: Promise.resolve({ id: "session-1" }) }
|
|
331
|
-
);
|
|
332
|
-
|
|
333
|
-
assert.equal(response.status, 200);
|
|
334
|
-
const payload = await assertJsonResponse(response);
|
|
335
|
-
assert.equal(
|
|
336
|
-
payload.ptyWsUrl,
|
|
337
|
-
"wss://backend.example.com:4749/api/sessions/session-1/terminal/ws?protocol=ttyd"
|
|
338
|
-
);
|
|
339
|
-
assert.equal(payload.interactive, true);
|
|
340
|
-
} finally {
|
|
341
|
-
global.fetch = originalFetch;
|
|
342
|
-
}
|
|
343
|
-
});
|
package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/terminal/connection/route.ts
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { roleMeetsRequirement } from "@/lib/accessControl";
|
|
2
|
-
import {
|
|
3
|
-
getDashboardAccess,
|
|
4
|
-
guardApiAccess,
|
|
5
|
-
} from "@/lib/auth";
|
|
6
|
-
import { buildForwardedAccessHeaders } from "@/lib/guardedRustProxy";
|
|
7
|
-
import { NextResponse } from "next/server";
|
|
8
|
-
|
|
9
|
-
export const dynamic = "force-dynamic";
|
|
10
|
-
export const runtime = "nodejs";
|
|
11
|
-
|
|
12
|
-
type TerminalTokenPayload = {
|
|
13
|
-
token?: string | null;
|
|
14
|
-
required?: boolean;
|
|
15
|
-
expiresInSeconds?: number | null;
|
|
16
|
-
error?: string;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
function resolveBackendTerminalWsUrl(backendUrl: string, id: string): URL {
|
|
20
|
-
const wsUrl = new URL(backendUrl);
|
|
21
|
-
wsUrl.protocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
22
|
-
wsUrl.pathname = `/api/sessions/${encodeURIComponent(id)}/terminal/ws`;
|
|
23
|
-
wsUrl.search = "";
|
|
24
|
-
return wsUrl;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Resolve the direct ttyd WebSocket URL for a session.
|
|
29
|
-
* Always asks the backend whether a terminal token is required — the backend
|
|
30
|
-
* is the single source of truth for access-control decisions.
|
|
31
|
-
*/
|
|
32
|
-
async function resolvePtyWsUrl(
|
|
33
|
-
request: Request,
|
|
34
|
-
backendUrl: string,
|
|
35
|
-
id: string
|
|
36
|
-
): Promise<string> {
|
|
37
|
-
const wsUrl = resolveBackendTerminalWsUrl(backendUrl, id);
|
|
38
|
-
wsUrl.searchParams.set("protocol", "ttyd");
|
|
39
|
-
|
|
40
|
-
const tokenUrl = new URL(
|
|
41
|
-
`/api/sessions/${encodeURIComponent(id)}/terminal/token`,
|
|
42
|
-
backendUrl
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
let payload: TerminalTokenPayload | null = null;
|
|
46
|
-
try {
|
|
47
|
-
const response = await fetch(tokenUrl, {
|
|
48
|
-
method: "GET",
|
|
49
|
-
headers: await buildForwardedAccessHeaders(request),
|
|
50
|
-
cache: "no-store",
|
|
51
|
-
signal: request.signal,
|
|
52
|
-
});
|
|
53
|
-
payload = (await response.json().catch(() => null)) as
|
|
54
|
-
| TerminalTokenPayload
|
|
55
|
-
| null;
|
|
56
|
-
if (!response.ok) {
|
|
57
|
-
throw new Error(
|
|
58
|
-
payload?.error ?? `Failed to resolve terminal token: ${response.status}`
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
} catch (err) {
|
|
62
|
-
console.warn("[Terminal Connection] Token fetch failed, proceeding without token:", {
|
|
63
|
-
error: err instanceof Error ? err.message : String(err),
|
|
64
|
-
});
|
|
65
|
-
return wsUrl.toString();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (payload?.required !== true) {
|
|
69
|
-
return wsUrl.toString();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const token =
|
|
73
|
-
typeof payload.token === "string" ? payload.token.trim() : "";
|
|
74
|
-
if (!token) {
|
|
75
|
-
throw new Error("Terminal token response did not include a control token");
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
wsUrl.searchParams.set("token", token);
|
|
79
|
-
return wsUrl.toString();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export async function GET(
|
|
83
|
-
request: Request,
|
|
84
|
-
context: { params: Promise<{ id: string }> }
|
|
85
|
-
): Promise<Response> {
|
|
86
|
-
const denied = await guardApiAccess(request, "viewer");
|
|
87
|
-
if (denied) return denied;
|
|
88
|
-
|
|
89
|
-
const { id } = await context.params;
|
|
90
|
-
const access = await getDashboardAccess(request);
|
|
91
|
-
const interactive = access.role
|
|
92
|
-
? roleMeetsRequirement(access.role, "operator")
|
|
93
|
-
: false;
|
|
94
|
-
|
|
95
|
-
if (!interactive) {
|
|
96
|
-
return NextResponse.json({
|
|
97
|
-
ptyWsUrl: null,
|
|
98
|
-
interactive: false,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const configuredBackendUrl = process.env.CONDUCTOR_BACKEND_URL?.trim();
|
|
103
|
-
const backendUrl = configuredBackendUrl || "http://127.0.0.1:4749";
|
|
104
|
-
|
|
105
|
-
let ptyWsUrl: string | null = null;
|
|
106
|
-
try {
|
|
107
|
-
ptyWsUrl = await resolvePtyWsUrl(request, backendUrl, id);
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.warn("[Terminal Connection] Failed to resolve direct terminal websocket URL", {
|
|
110
|
-
error: error instanceof Error ? error.message : String(error),
|
|
111
|
-
backendUrl,
|
|
112
|
-
sessionId: id,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return NextResponse.json({
|
|
117
|
-
ptyWsUrl,
|
|
118
|
-
interactive: true,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,57965,e=>{"use strict";e.i(47167);var t=e.i(43476),n=e.i(71645),r=e.i(61653),r=r,l=e.i(64659),s=e.i(31278),i=e.i(16715),o=e.i(55436),c=e.i(14764),u=e.i(37727),a=e.i(11077),d=e.i(14466);function h(e,t=2){let n=e.buffer.active,r=Math.max(0,n.baseY-n.viewportY);return{followOutput:r<=t,scrollGap:r}}function f(e,t){if(t.followOutput)return void e.scrollToBottom();let n=Math.max(0,e.buffer.active.baseY-t.scrollGap)-e.buffer.active.viewportY;0!==n&&e.scrollLines(n)}var m=e.i(33489);let w=new Set(["queued","spawning","running","working","needs_input","stuck"]),p=new Set(["done","needs_input","stuck","errored","terminated","killed"]),b="u">typeof navigator&&/Mobi|Android|iPhone|iPad/i.test(navigator.userAgent)?2e3:1e4,g=new Map,v=new Map;function x(e,t){for(;e.size>t;){let t=e.keys().next().value;if(!t)break;e.delete(t)}}function y(e){let t=v.get(e);return t?Date.now()-t.updatedAt>432e5?(v.delete(e),null):t:null}async function k(e){let t,n=(t=g.get(e))?t.expiresAt<=Date.now()?(g.delete(e),null):t.value:null;if(n)return n;let r=await fetch(`/api/sessions/${encodeURIComponent(e)}/terminal/connection`,{cache:"no-store"}),l=await r.json().catch(()=>null);if(!r.ok)throw Error(l?.error??`Failed to resolve terminal connection: ${r.status}`);let s={ptyWsUrl:"string"==typeof l?.ptyWsUrl&&l.ptyWsUrl.trim().length>0?l.ptyWsUrl.trim():null,interactive:l?.interactive===!0};return g.delete(e),g.set(e,{value:s,expiresAt:Date.now()+5e3}),x(g,2),s}let E=null,S=null,C=null,R=null,T=null,L={highWater:10,lowWater:4};class N{socket=null;terminal;flowControl;callbacks;pending=0;textEncoder=new TextEncoder;textDecoder=new TextDecoder("utf-8",{fatal:!1});constructor(e,t=L,n={}){this.terminal=e,this.flowControl=t,this.callbacks=n}connect(e,t,n){return new Promise((r,l)=>{try{this.socket&&(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onclose=null,this.socket.onerror=null,this.socket.close(1e3,"Reconnecting"),this.socket=null);let s=function(e){if(e.startsWith("ws://")||e.startsWith("wss://"))return e;if(e.startsWith("/")){let t="https:"===window.location.protocol?"wss:":"ws:";return`${t}//${window.location.host}${e}`}if(e.startsWith("http://")||e.startsWith("https://")){let t=e.startsWith("https://")?"wss:":"ws:",n=e.indexOf("/",e.indexOf("//")+2),r=e.substring(e.indexOf("//")+2,n),l=e.substring(n);return`${t}//${r}${l}`}return e}(e);this.socket=new WebSocket(s),this.socket.binaryType="arraybuffer";let i=setTimeout(()=>{this.socket&&this.socket.readyState!==WebSocket.OPEN&&this.socket.readyState!==WebSocket.CLOSED&&(this.socket.close(),l(Error("WebSocket connection timeout")))},1e4);this.socket.onopen=()=>{clearTimeout(i);let e=JSON.stringify({columns:t??this.terminal.cols??120,rows:n??this.terminal.rows??40});this.socket?.send(this.textEncoder.encode(e)),this.callbacks.onConnected?.(),r()},this.socket.onmessage=e=>{this.handleMessage(e.data)},this.socket.onclose=e=>{clearTimeout(i),this.socket=null,this.callbacks.onDisconnected?.(e.code,e.reason||""),l(Error(`WebSocket closed: ${e.code}`))},this.socket.onerror=()=>{clearTimeout(i),this.callbacks.onError?.("WebSocket connection failed"),l(Error("WebSocket connection failed"))}}catch(e){l(e)}})}disconnect(){this.socket&&(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onclose=null,this.socket.onerror=null,this.socket.close(1e3,"Normal closure"),this.socket=null)}sendInput(e){let t;if(this.isConnected()){if("string"==typeof e){let n=new Uint8Array(3*e.length+1);n[0]=48;let r=this.textEncoder.encodeInto(e,n.subarray(1));t=n.subarray(0,(r.written??0)+1)}else(t=new Uint8Array(e.length+1))[0]=48,t.set(e,1);this.socket?.send(t)}}sendResize(e,t){if(!this.isConnected())return;let n=JSON.stringify({columns:Math.max(1,e),rows:Math.max(1,t)}),r=this.textEncoder.encode(n),l=new Uint8Array(1+r.length);l[0]=49,l.set(r,1),this.socket?.send(l)}isConnected(){return null!==this.socket&&this.socket.readyState===WebSocket.OPEN}handleMessage(e){let t=new Uint8Array(e);if(0===t.length)return;let n=t[0],r=t.subarray(1);switch(n){case 48:this.writeOutput(r);break;case 49:try{this.callbacks.onTitle?.(this.textDecoder.decode(r))}catch{}break;case 50:try{this.callbacks.onPreferences?.(JSON.parse(this.textDecoder.decode(r)))}catch{}}}paused=!1;writeOutput(e){let{highWater:t,lowWater:n}=this.flowControl;if(this.terminal){if(e.byteLength<1024)return void this.terminal.write(e);this.terminal.write(e,()=>{this.pending=Math.max(this.pending-1,0),this.paused&&this.pending<n&&(this.paused=!1,this.sendResume())}),this.pending++,!this.paused&&this.pending>=t&&(this.paused=!0,this.sendPause())}}sendPause(){this.isConnected()&&this.socket?.send(new Uint8Array([50]))}sendResume(){this.isConnected()&&this.socket?.send(new Uint8Array([51]))}}function A({sessionId:A,agentName:M,projectId:j,sessionModel:z,sessionReasoningEffort:$,sessionState:W,active:D,pendingInsert:F,immersiveMobileMode:O=!1}){let B=(0,n.useRef)(null),P=(0,n.useRef)(null),H=(0,n.useRef)(null),U=(0,n.useRef)(null),Y=(0,n.useRef)(null),I=(0,n.useRef)(null),_=(0,n.useRef)(null),K=(0,n.useRef)(null),V=(0,n.useRef)(W),q=(0,n.useRef)(D),J=(0,n.useRef)("u"<typeof document||!document.hidden),Q=(0,n.useRef)(0),X=(0,n.useRef)(!1),G=y(A),[Z,ee]=(0,n.useState)(!1),[et,en]=(0,n.useState)(null),[er,el]=(0,n.useState)(!0),[es,ei]=(0,n.useState)(()=>G?.searchOpen??!1),[eo,ec]=(0,n.useState)(()=>G?.searchQuery??""),[eu,ea]=(0,n.useState)(()=>"u"<typeof document||!document.hidden),[ed,eh]=(0,n.useState)(null),[ef,em]=(0,n.useState)(null),[ew,ep]=(0,n.useState)(""),[eb,eg]=(0,n.useState)(!1),[ev,ex]=(0,n.useState)(null),ey=(0,n.useRef)(null),ek=(0,n.useMemo)(()=>("string"==typeof ed&&ed.trim().length>0?ed:W).trim().toLowerCase(),[W,ed]);V.current=ek,q.current=D;let eE=w.has(ek),eS=eE&&D&&eu;X.current=eE,J.current=eu;let{isConnected:eC,isConnecting:eR,error:eT,sendInput:eL,sendResize:eN}=function(e){let{terminal:t,fitAddon:r,ptyWsUrl:l,enabled:s=!0,onConnectionReady:i,onConnectionError:o,onConnectionClosed:c}=e,u=(0,n.useRef)(null),[a,d]=(0,n.useState)(!1),[h,f]=(0,n.useState)(!1),[m,w]=(0,n.useState)(null),p=(0,n.useRef)(0),b=(0,n.useRef)(null),g=(0,n.useRef)(i),v=(0,n.useRef)(o),x=(0,n.useRef)(c);g.current=i,v.current=o,x.current=c;let y=(0,n.useRef)(l);(0,n.useEffect)(()=>{l!==y.current&&(y.current=l,w(null),d(!1),f(!1))},[l]),(0,n.useEffect)(()=>{if(!s||!t)return;let e=new N(t,L,{onTitle:e=>{try{document.title=e}catch{}},onPreferences:()=>{},onConnected:()=>{p.current=0,d(!0),f(!1),w(null),g.current?.()},onDisconnected:(e,t)=>{if(d(!1),f(!1),x.current?.(e,t),1e3!==e&&p.current<5){p.current++;let e=Math.min(300*Math.pow(2,p.current-1),1600);w(Error("Reconnecting…")),b.current=setTimeout(()=>{b.current=null,w(null)},e)}},onError:e=>{let t=Error(`Terminal error: ${e}`);w(t),v.current?.(t)}});return u.current=e,()=>{e.disconnect(),u.current=null,b.current&&(clearTimeout(b.current),b.current=null)}},[s,t]),(0,n.useEffect)(()=>{if(!t||!u.current)return;let e=t.onData(e=>{u.current?.sendInput(e)});return()=>e.dispose()},[t]),(0,n.useEffect)(()=>{if(!t||!r||!u.current)return;let e=t.onResize(({cols:e,rows:t})=>{u.current?.sendResize(e,t)});return()=>e.dispose()},[t,r]);let k=(0,n.useCallback)(async()=>{if(l&&u.current&&!a&&!h){f(!0),w(null);try{let e=t?.cols??120,n=t?.rows??40;await u.current.connect(l,e,n)}catch(t){let e=t instanceof Error?t:Error(String(t));w(e),f(!1),v.current?.(e)}}},[l,a,h,t]),E=(0,n.useCallback)(()=>{u.current?.disconnect(),d(!1)},[]),S=(0,n.useCallback)(e=>{u.current?.sendInput(e)},[]),C=(0,n.useCallback)((e,t)=>{u.current?.sendResize(e,t)},[]);return(0,n.useEffect)(()=>{if(!s||!l||!t||a||h||m)return;let e=setTimeout(()=>{k()},0);return()=>clearTimeout(e)},[s,l,a,h,m,k,t]),{isConnected:a,isConnecting:h,error:m,connect:k,disconnect:E,sendInput:S,sendResize:C}}({terminal:H.current,fitAddon:U.current,ptyWsUrl:et,enabled:null!==et&&X.current&&J.current}),eA=eE&&er&&eC,{pendingResizeSyncRef:eM,lastSyncedTerminalSizeRef:ej,lastObservedContainerSizeRef:ez,lastViewportOptionKeyRef:e$,pendingViewportRestoreRef:eW,preferredFocusTargetRef:eD,restoreFocusOnRecoveryRef:eF,showScrollToBottom:eO,setShowScrollToBottom:eB,syncTerminalDimensions:eP,scheduleRendererRecovery:eH,clearScheduledRecovery:eU,clearVisibilityRecoveryTimers:eY,applyViewportRestore:eI,updateScrollState:e_,rememberTerminalViewport:eK,rememberFocusedSurface:eV,restorePreferredFocus:eq}=function(e,t,r,l,s,i,o,c){let u=(0,n.useRef)(!0),a=(0,n.useRef)(null),d=(0,n.useRef)(null),m=(0,n.useRef)(null),w=(0,n.useRef)(c),p=(0,n.useRef)(null),b=(0,n.useRef)("none"),g=(0,n.useRef)(!1),v=(0,n.useRef)(!0),x=(0,n.useRef)(null),y=(0,n.useRef)(null),k=(0,n.useRef)(0),E=(0,n.useRef)(!1),S=(0,n.useRef)([]),[C,R]=(0,n.useState)(!1),T=(0,n.useCallback)(()=>{if("u"<typeof document)return b.current;let e=document.activeElement;return e?s.current&&e===s.current?"resume":l.current&&l.current.contains(e)?"terminal":"none":"none"},[l,s]),L=(0,n.useCallback)(()=>{let e=T();return"none"===e?g.current=!1:(b.current=e,g.current=!0),e},[T]),N=(0,n.useCallback)(()=>{if("u"<typeof document||document.hidden||!v.current||!g.current)return;let e=b.current;if("resume"===e)return void s.current?.focus();if("terminal"===e)try{t.current?.focus()}catch{}},[s,t]),A=(0,n.useCallback)(()=>{let e=t.current;e?R(!h(e).followOutput):R(!1)},[t]),M=(0,n.useCallback)(()=>{let n=t.current;!n||w.current&&p.current!==e||(w.current=h(n))},[e,t]),j=(0,n.useCallback)((e,t)=>{let n=w.current;if(n){f(e,n),w.current=h(e);return}f(e,t),w.current=h(e)},[]),z=(0,n.useCallback)(e=>{let n=t.current;if(!n)return;let r=Math.max(1,n.cols),l=Math.max(1,n.rows),s=`${r}x${l}`,c=a.current;(e||u.current||c!==s)&&i(r,l).then(e=>{if(!e){u.current=!0;return}u.current=!1,a.current=s}).catch(e=>{u.current=!0,a.current===s&&(a.current=c),o(e instanceof Error?e.message:"Failed to resize terminal")})},[i,o,t]),$=(0,n.useCallback)(e=>{let n=t.current,s=r.current,i=l.current;if(!n||!s||!i)return;let o=window.getComputedStyle(i);if("none"===o.display||"hidden"===o.visibility)return;let c=i.getBoundingClientRect();if(c.width<=1||c.height<=1)return;let a=h(n),d=n.cols,f=n.rows;try{s.fit()}catch{return}let m=function(e,t,n){let r=t.getBoundingClientRect();if(r.width<=1||r.height<=1)return null;let l=n.proposeDimensions();return l&&l.cols&&l.rows?{cols:Math.max(2,l.cols),rows:Math.max(1,l.rows)}:null}(0,i,s);m&&(n.cols!==m.cols||n.rows!==m.rows)&&n.resize(m.cols,m.rows),e&&n.refresh(0,Math.max(0,n.rows-1)),(e||n.cols!==d||n.rows!==f||u.current)&&z(e||u.current),j(n,a),A(),N()},[j,l,r,N,z,t,A]),W=(0,n.useCallback)(()=>{null!==x.current&&(window.cancelAnimationFrame(x.current),x.current=null),null!==y.current&&(window.clearTimeout(y.current),y.current=null),E.current=!1},[]),D=(0,n.useCallback)(()=>{for(let e of S.current)window.clearTimeout(e);S.current=[]},[]),F=(0,n.useCallback)(e=>{E.current||=e,null===x.current&&(x.current=window.requestAnimationFrame(()=>{x.current=null;let e=Date.now();if(e-k.current<120){let t=120-(e-k.current);null!==y.current&&window.clearTimeout(y.current),y.current=window.setTimeout(()=>{y.current=null,F(E.current)},t+1);return}k.current=e;let t=E.current;E.current=!1,$(t)}))},[$]);return{pendingResizeSyncRef:u,lastSyncedTerminalSizeRef:a,lastObservedContainerSizeRef:d,lastViewportOptionKeyRef:m,pendingViewportRestoreRef:w,preferredFocusTargetRef:b,restoreFocusOnRecoveryRef:g,showScrollToBottom:C,setShowScrollToBottom:R,syncTerminalDimensions:z,scheduleRendererRecovery:F,clearScheduledRecovery:W,clearVisibilityRecoveryTimers:D,applyViewportRestore:j,updateScrollState:A,rememberTerminalViewport:M,rememberFocusedSurface:L,restorePreferredFocus:N}}(A,H,U,P,K,(0,n.useCallback)(async(e,t)=>!!eC&&(eN(e,t),!0),[eC,eN]),(0,n.useCallback)(()=>{},[]),G?.viewport??null),{searchRef:eJ,runSearch:eQ}=function({searchOpen:t,searchQuery:r,termRef:l}){let s=(0,n.useRef)(null);(0,n.useEffect)(()=>{if(!t||!l.current||s.current)return;let n=!1;return(!S&&(S=e.A(64183).catch(e=>{throw S=null,e})),S).then(e=>{if(n||!l.current||s.current)return;let t=new e.SearchAddon;l.current.loadAddon(t),s.current=t}).catch(()=>{}),()=>{n=!0}},[t,l]);let i=(0,n.useCallback)(e=>{let t=s.current;t&&0!==r.trim().length&&("next"===e?t.findNext(r,{incremental:!0,caseSensitive:!1}):t.findPrevious(r,{incremental:!0,caseSensitive:!1}))},[r]);return{searchRef:s,runSearch:i}}({searchOpen:es,searchQuery:eo,termRef:H}),eX=(0,n.useMemo)(()=>{if(O&&ef&&!(ef<=0))return{height:`${ef}px`,minHeight:`${ef}px`}},[O,ef]),eG=(0,n.useRef)(e_),eZ=(0,n.useRef)(eH);(0,n.useEffect)(()=>{eG.current=e_},[e_]),(0,n.useEffect)(()=>{eZ.current=eH},[eH]);let e0=(0,n.useEffectEvent)(()=>{let e=H.current,t=e&&function(e){let t=e.buffer.active;if(t.baseY>0)return!0;for(let n=0;n<e.rows;n+=1){let e=t.getLine(n);if(e&&e.translateToString(!0).trim().length>0)return!0}return!1}(e)?h(e):eW.current;eW.current=t,v.delete(A),v.set(A,{...{message:"",searchOpen:es,searchQuery:eo,helperPanelOpen:!1,viewport:t},updatedAt:Date.now()}),x(v,4)});(0,n.useEffect)(()=>{e0()},[e0,es,eo]),(0,n.useEffect)(()=>()=>{e0()},[e0]),(0,n.useEffect)(()=>{if(!O||!window.visualViewport){let e=()=>{let e=B.current;if(!e)return;let t=(0,m.calculateMobileTerminalViewportMetrics)(window.innerHeight,window.innerHeight,0,e.getBoundingClientRect().top);em(e=>e===t.usableHeight?e:t.usableHeight)};return e(),window.addEventListener("resize",e),window.addEventListener("orientationchange",e),()=>{window.removeEventListener("resize",e),window.removeEventListener("orientationchange",e)}}let e=window.visualViewport,t=null,n=()=>{null!==t&&window.cancelAnimationFrame(t),t=window.requestAnimationFrame(()=>{t=null;let n=B.current;if(!n)return;let r=(0,m.calculateMobileTerminalViewportMetrics)(window.innerHeight,e.height,e.offsetTop,n.getBoundingClientRect().top);em(e=>e===r.usableHeight?e:r.usableHeight),q.current&&eH(!1)})};return n(),e.addEventListener("resize",n),e.addEventListener("scroll",n),window.addEventListener("resize",n),window.addEventListener("orientationchange",n),()=>{null!==t&&window.cancelAnimationFrame(t),e.removeEventListener("resize",n),e.removeEventListener("scroll",n),window.removeEventListener("resize",n),window.removeEventListener("orientationchange",n)}},[O,eH]),(0,n.useEffect)(()=>{let e=y(A);Q.current=0,ej.current=null,eM.current=!0,eD.current="none",eF.current=!1,eU(),ez.current=null,e$.current=null,eW.current=e?.viewport??null,el(!0),ei(e?.searchOpen??!1),ec(e?.searchQuery??""),eB(!1),eh(null),em(null),en(null),H.current?.reset(),e_()},[A]),(0,n.useEffect)(()=>{eh(null)},[W]),(0,n.useEffect)(()=>{let e=!0;return eE&&eS?(g.delete(A),(async()=>{try{let t=await k(A);if(!e)return;en(t.ptyWsUrl),el(t.interactive)}catch(t){if(!e)return;console.error("Failed to resolve terminal connection:",t)}})(),()=>{e=!1}):()=>{e=!1}},[eE,A,eS]);let e1=(0,n.useEffectEvent)(e=>{eC&&eL(e)}),e2=(0,n.useEffectEvent)(()=>{eK(),e_()}),e3=(0,n.useEffectEvent)((e,t)=>{if(!q.current)return;let n=(0,m.getSessionTerminalViewportOptions)(window.innerWidth),r=`${n.fontFamily}:${n.fontSize}:${n.lineHeight}`,l=`${Math.round(t.contentRect.width)}x${Math.round(t.contentRect.height)}`;if(ez.current===l&&e$.current===r)return;ez.current=l,e$.current=r;let s=!1;try{e.options.fontFamily!==n.fontFamily&&(e.options.fontFamily=n.fontFamily,s=!0),e.options.fontSize!==n.fontSize&&(e.options.fontSize=n.fontSize,s=!0),e.options.lineHeight!==n.lineHeight&&(e.options.lineHeight=n.lineHeight,s=!0)}catch{return}eH(s)});(0,n.useEffect)(()=>{let t=null,n=null,r=!0;async function l(){let l;if(!D||!P.current||!r)return;let[s,i]=await (!E&&(E=Promise.all([e.A(37138),e.A(59439)]).catch(e=>{throw E=null,e})),E);if(!r||!P.current)return;let o=document.documentElement.classList.contains("light"),c=(0,m.getSessionTerminalViewportOptions)(window.innerWidth),u=(l="function"==typeof window.matchMedia&&window.matchMedia("(pointer: coarse)").matches,(0,m.detectMobileTerminalInputRail)(window.innerWidth,l,navigator.maxTouchPoints)),a={allowProposedApi:!0,allowTransparency:!1,cursorBlink:!0,cursorStyle:"block",cursorInactiveStyle:"outline",disableStdin:!X.current,drawBoldTextInBrightColors:!0,fontFamily:c.fontFamily,fontSize:c.fontSize,fontWeight:"400",fontWeightBold:"700",fastScrollSensitivity:4,lineHeight:c.lineHeight,scrollSensitivity:1.1,scrollback:b,theme:(0,d.getTerminalTheme)(o),scrollbar:{showScrollbar:!u}};t=new s.Terminal(a),n=new i.FitAddon,t.loadAddon(n),t.open(P.current),n.fit(),(!C&&(C=e.A(33035).catch(e=>{throw C=null,e})),C).then(e=>{if(!r||H.current!==t)return;let n=new e.WebglAddon;n.onContextLoss(()=>{n.dispose()}),t.loadAddon(n)}).catch(()=>{}),(!R&&(R=e.A(239).catch(e=>{throw R=null,e})),R).then(e=>{if(!r||H.current!==t)return;let n=new e.Unicode11Addon;t.loadAddon(n),t.unicode.activeVersion="11"}).catch(()=>{}),(!T&&(T=e.A(16091).catch(e=>{throw T=null,e})),T).then(e=>{if(!r||H.current!==t)return;let n=new e.WebLinksAddon;t.loadAddon(n)}).catch(()=>{}),H.current=t,U.current=n,ej.current=null,eM.current=!0,ez.current=`${Math.round(P.current.clientWidth)}x${Math.round(P.current.clientHeight)}`,e$.current=`${c.fontFamily}:${c.fontSize}:${c.lineHeight}`,t.options.disableStdin=!X.current,ee(!0),eG.current(),I.current=t.onData(e=>{e1(e)}),_.current=t.onScroll(()=>{e2()}),Y.current=new ResizeObserver(e=>{let n=e[0];n&&t&&e3(t,n)}),Y.current.observe(P.current),eZ.current(!0)}return D?(l(),()=>{r=!1,t&&(eW.current=h(t)),I.current?.dispose(),I.current=null,_.current?.dispose(),_.current=null,Y.current?.disconnect(),Y.current=null,t&&t.dispose(),H.current=null,U.current=null,eJ.current=null,ej.current=null,ez.current=null,e$.current=null,eM.current=!0,ee(!1)}):(ee(!1),()=>{r=!1})},[A,D]),(0,n.useEffect)(()=>{let e=H.current;e&&(e.options.disableStdin=!eE||!er)},[eE,er]),(0,n.useEffect)(()=>{if("u"<typeof document||!("fonts"in document))return;let e=!1;return document.fonts.ready.then(()=>{!e&&q.current&&(ez.current=null,e$.current=null,eM.current=!0,eH(!0))}),()=>{e=!0}},[O,ez,e$,eM,eH,A]),(0,n.useEffect)(()=>{let e=H.current?.element;e&&(e.classList.add("session-terminal-xterm"),e.classList.toggle("session-terminal-xterm-mobile",O),ez.current=null,e$.current=null,eM.current=!0,eH(!0))},[O,ez,e$,eM,eH,Z]),(0,n.useEffect)(()=>{if(!D)return;ez.current=null,e$.current=null,eM.current=!0,eH(!0);let e=window.setTimeout(()=>{eH(!0)},150);return()=>{window.clearTimeout(e)}},[D,O,eH]),(0,n.useEffect)(()=>{},[D,eC,eR,eT,eE,er,eu,et,A,D,eS,Z]),(0,n.useEffect)(()=>{let e=()=>{(ea(!document.hidden),document.hidden)?eV():eH(!1)},t=()=>{ea(!document.hidden),eH(!1)};return document.addEventListener("visibilitychange",e),window.addEventListener("focus",t),()=>{document.removeEventListener("visibilitychange",e),window.removeEventListener("focus",t)}},[eV,eH]),(0,n.useEffect)(()=>{let e=()=>{eV()};return document.addEventListener("focusin",e),()=>{document.removeEventListener("focusin",e)}},[eV]),(0,n.useEffect)(()=>()=>{eU(),eY()},[]),(0,n.useEffect)(()=>{if(F&&!(F.nonce<=Q.current)&&(Q.current=F.nonce,eA)){let e=F.inlineText.trim();e.length>0&&eL(`${e} `)}},[eA,F,eL]);let e5=(0,n.useCallback)(()=>{let e=H.current;if(e&&(eD.current="terminal",eF.current=!0,e.scrollToBottom(),e_(),q.current))try{e.focus()}catch{return}},[eD,eF,e_]),e4=(0,n.useCallback)(()=>{if(eD.current="terminal",eF.current=!0,!eE)return;let e=H.current;if(e){try{e.focus()}catch{return}eH(!1)}},[eE,eD,eF,eH]),e8=(0,n.useCallback)(e=>{"touch"!==e.pointerType&&e4()},[e4]),e6=(0,n.useCallback)(e=>{let t=H.current;if(!t||e.ctrlKey||e.metaKey||e.defaultPrevented||t.buffer.active.baseY<=0)return;let n=e.deltaY;0===e.deltaMode?n=e.deltaY/18:2===e.deltaMode&&(n=e.deltaY*Math.max(1,t.rows-1));let r=n>0?Math.ceil(n):Math.floor(n);0!==r&&(t.scrollLines(r),e_(),e.preventDefault())},[e_]);(0,n.useEffect)(()=>{let e=P.current;if(!e)return;let t=e=>{e6(e)},n=null,r=!1,l=0,s=0,i=0,o=null,c=()=>{null!==o&&(cancelAnimationFrame(o),o=null)},u=()=>{let e=H.current;if(!e||.3>Math.abs(s)){o=null,e_();return}let t=Math.trunc((l+=s)/16);0!==t&&(l-=16*t,e.scrollLines(t)),s*=.92,o=requestAnimationFrame(u)},a=e=>{c(),1===e.touches.length&&(n=e.touches[0].clientY,i=e.timeStamp,r=!1,l=0,s=0)},d=e=>{let t=H.current;if(!t||null===n||1!==e.touches.length)return;let o=e.touches[0].clientY,c=n-o,u=e.timeStamp,a=u-i;if(t.buffer.active.baseY>0){r=!0;let n=Math.trunc((l+=c)/16);if(0!==n&&(l-=16*n,t.scrollLines(n)),a>0){let e=c/a*16;s=0===s?e:.6*e+.4*s}e.preventDefault()}n=o,i=u},h=()=>{r||null===n?r&&Math.abs(s)>=.3&&(o=requestAnimationFrame(u)):e4(),n=null,r=!1,e_()};return e.addEventListener("wheel",t,{passive:!1}),e.addEventListener("touchstart",a,{passive:!0}),e.addEventListener("touchmove",d,{passive:!1}),e.addEventListener("touchend",h,{passive:!0}),e.addEventListener("touchcancel",h,{passive:!0}),()=>{c(),e.removeEventListener("wheel",t),e.removeEventListener("touchstart",a),e.removeEventListener("touchmove",d),e.removeEventListener("touchend",h),e.removeEventListener("touchcancel",h)}},[e6,e4,e_]);let e7=(0,n.useCallback)(()=>{ei(!1),ec(""),eq()},[eq]),e9=!O&&p.has(ek),te=(0,n.useCallback)(async()=>{let e=ew.trim();if(0!==e.length&&!eb){eg(!0),ex(null);try{let t=await fetch(`/api/sessions/${encodeURIComponent(A)}/actions`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"send",message:e})});if(!t.ok){let e=await t.json().catch(()=>null);throw Error(e?.error??`Failed to send message (${t.status})`)}ep("")}catch(e){ex(e instanceof Error?e.message:"Failed to send message")}finally{eg(!1)}}},[ew,eb,A]),tt=(0,n.useCallback)(e=>{e.preventDefault(),te()},[te]);return(0,t.jsxs)("div",{ref:B,style:eX,className:O?"group/terminal relative flex h-full min-h-0 min-w-0 w-full flex-1 flex-col overflow-hidden bg-[#060404]":"group/terminal relative flex h-full min-h-0 min-w-0 w-full flex-1 flex-col overflow-hidden rounded-none border-0 bg-[#060404] lg:rounded-[14px] lg:border lg:border-white/10 lg:shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]",children:[es?(0,t.jsxs)("div",{className:"absolute right-2 top-2 z-10 flex max-w-[calc(100%-1rem)] items-center rounded bg-[#141010]/95 pl-2 pr-0.5 shadow-lg ring-1 ring-white/10 backdrop-blur sm:right-3 sm:top-3 sm:max-w-[calc(100%-1.5rem)]",children:[(0,t.jsx)(o.Search,{className:"h-3.5 w-3.5 text-[#8e847d]"}),(0,t.jsx)("input",{value:eo,onChange:e=>ec(e.target.value),onKeyDown:e=>{"Enter"===e.key?(e.preventDefault(),eQ(e.shiftKey?"prev":"next")):"Escape"===e.key&&(e.preventDefault(),e7())},placeholder:"Find",className:"h-6 w-24 min-w-0 bg-transparent px-2 text-[11px] text-[#efe8e1] outline-none placeholder:text-[#7d746e] sm:w-28 sm:text-[12px]"}),(0,t.jsx)(a.Button,{type:"button",size:"icon",variant:"ghost",className:"h-8 w-8 sm:h-6 sm:w-6 text-[#c9c0b7]",onClick:()=>eQ("prev"),"aria-label":"Find previous",children:(0,t.jsx)("span",{className:"text-[11px]",children:"↑"})}),(0,t.jsx)(a.Button,{type:"button",size:"icon",variant:"ghost",className:"h-8 w-8 sm:h-6 sm:w-6 text-[#c9c0b7]",onClick:()=>eQ("next"),"aria-label":"Find next",children:(0,t.jsx)("span",{className:"text-[11px]",children:"↓"})}),(0,t.jsx)(a.Button,{type:"button",size:"icon",variant:"ghost",className:"h-8 w-8 sm:h-6 sm:w-6 text-[#c9c0b7]",onClick:e7,"aria-label":"Close search",children:(0,t.jsx)(u.X,{className:"h-3.5 w-3.5"})})]}):(0,t.jsxs)("div",{className:`absolute right-2 top-2 z-10 flex items-center gap-1.5 transition-opacity sm:right-3 sm:top-3 sm:gap-2 ${eC?"opacity-0 group-hover/terminal:opacity-100 focus-within:opacity-100":"opacity-100"}`,children:[eC?null:(0,t.jsx)(a.Button,{type:"button",size:"icon",variant:"ghost",className:`pointer-events-auto h-10 w-10 sm:h-7 sm:w-7 rounded-full border backdrop-blur-sm ${eT?"border-[#ff8f7a]/25 bg-[#2a1616]/92 text-[#ff8f7a] hover:bg-[#351b1b]":"border-white/10 bg-[#141010]/92 text-[#c9c0b7] hover:bg-[#201818]"}`,disabled:!0,"aria-label":"Connecting... (auto-managed by TTyD)",children:eR?(0,t.jsx)(s.Loader2,{className:"h-3.5 w-3.5 animate-spin"}):eT?(0,t.jsx)(r.default,{className:"h-3.5 w-3.5"}):(0,t.jsx)(i.RefreshCw,{className:"h-3.5 w-3.5"})}),(0,t.jsx)(a.Button,{type:"button",size:"icon",variant:"ghost",className:"pointer-events-auto h-10 w-10 sm:h-7 sm:w-7 rounded-full border border-white/10 bg-[#141010]/92 text-[#c9c0b7] backdrop-blur-sm hover:bg-[#201818]",onClick:()=>ei(!0),"aria-label":"Search terminal",children:(0,t.jsx)(o.Search,{className:"h-3.5 w-3.5"})})]}),(0,t.jsx)("div",{className:O?"min-h-0 min-w-0 flex-1 overflow-hidden px-0 pb-0 pt-0 w-full":"min-h-0 min-w-0 flex-1 overflow-hidden px-1.5 pb-0 pt-0.5 lg:px-1.5 lg:pb-1 lg:pt-3 w-full",children:(0,t.jsx)("div",{ref:P,className:"h-full w-full min-w-0 max-w-full overflow-hidden touch-pan-y",style:O?{width:"calc(100% - 24px)",marginLeft:12,marginRight:12}:void 0,onClick:e4,onPointerDown:e8})}),eO?(0,t.jsx)("div",{className:"pointer-events-none absolute left-1/2 z-10 -translate-x-1/2",style:{bottom:`calc(${e9?60:12}px + env(safe-area-inset-bottom))`},children:(0,t.jsxs)(a.Button,{type:"button",size:"sm",variant:"ghost",className:"pointer-events-auto h-9 rounded-full border border-white/10 bg-[#141010]/92 px-3 text-[#efe8e1] shadow-[0_14px_28px_rgba(0,0,0,0.38)] backdrop-blur-sm hover:bg-[#201818]",onClick:e5,"aria-label":"Scroll to bottom",children:[(0,t.jsx)(l.ChevronDown,{className:"h-4 w-4"}),(0,t.jsx)("span",{className:"ml-1 text-[11px] uppercase tracking-[0.16em]",children:"Jump to latest"})]})}):null,e9?(0,t.jsxs)("div",{className:"absolute inset-x-0 bottom-0 z-10 border-t border-white/12 bg-[#161212] backdrop-blur-sm [padding-bottom:env(safe-area-inset-bottom)]",children:[ev?(0,t.jsxs)("div",{className:"flex items-center gap-1.5 px-3 pt-1.5 text-[11px] text-[#ff8f7a]",children:[(0,t.jsx)(r.default,{className:"h-3 w-3 shrink-0"}),(0,t.jsx)("span",{className:"truncate",children:ev}),(0,t.jsx)("button",{type:"button",className:"ml-auto shrink-0 text-[#8e847d] hover:text-[#c9c0b7]",onClick:()=>ex(null),children:(0,t.jsx)(u.X,{className:"h-3 w-3"})})]}):null,(0,t.jsxs)("form",{onSubmit:tt,className:"flex items-center gap-2 px-2 py-2 lg:px-3",children:[(0,t.jsx)("input",{ref:ey,value:ew,onChange:e=>ep(e.target.value),placeholder:"Send a follow-up message…",disabled:eb,className:"h-8 min-w-0 flex-1 rounded-md border border-white/10 bg-[#0c0808] px-2.5 text-[12px] text-[#efe8e1] outline-none placeholder:text-[#7d746e] focus:border-white/20 disabled:opacity-50",onKeyDown:e=>{"Escape"===e.key&&(e.preventDefault(),e.currentTarget.blur())}}),(0,t.jsx)(a.Button,{type:"submit",size:"icon",variant:"ghost",disabled:eb||0===ew.trim().length,className:"h-8 w-8 shrink-0 rounded-md border border-white/10 bg-[#0c0808] text-[#c9c0b7] hover:bg-[#201818] disabled:opacity-30","aria-label":"Send message",children:eb?(0,t.jsx)(s.Loader2,{className:"h-3.5 w-3.5 animate-spin"}):(0,t.jsx)(c.Send,{className:"h-3.5 w-3.5"})})]})]}):null]})}e.s(["SessionTerminal",()=>A,"default",0,A],57965)},3934,e=>{e.n(e.i(57965))}]);
|