@37chengshan/ompweb 0.3.5
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/.next/BUILD_ID +1 -0
- package/.next/app-path-routes-manifest.json +66 -0
- package/.next/build-manifest.json +20 -0
- package/.next/export-marker.json +6 -0
- package/.next/images-manifest.json +68 -0
- package/.next/next-minimal-server.js.nft.json +1 -0
- package/.next/next-server.js.nft.json +1 -0
- package/.next/package.json +1 -0
- package/.next/prerender-manifest.json +189 -0
- package/.next/react-loadable-manifest.json +499 -0
- package/.next/required-server-files.js +364 -0
- package/.next/required-server-files.json +364 -0
- package/.next/routes-manifest.json +513 -0
- package/.next/server/app/_global-error/page.js +31 -0
- package/.next/server/app/_global-error/page.js.nft.json +1 -0
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_global-error.html +1 -0
- package/.next/server/app/_global-error.meta +27 -0
- package/.next/server/app/_global-error.rsc +15 -0
- package/.next/server/app/_global-error.segments/_full.segment.rsc +15 -0
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +21 -0
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
- package/.next/server/app/_not-found/page.js +1 -0
- package/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_not-found.html +1 -0
- package/.next/server/app/_not-found.meta +27 -0
- package/.next/server/app/_not-found.rsc +26 -0
- package/.next/server/app/_not-found.segments/_full.segment.rsc +26 -0
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +27 -0
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +8 -0
- package/.next/server/app/api/agent/[id]/bash-output/route.js +1 -0
- package/.next/server/app/api/agent/[id]/bash-output/route.js.nft.json +1 -0
- package/.next/server/app/api/agent/[id]/bash-output/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/agent/[id]/events/route.js +5 -0
- package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -0
- package/.next/server/app/api/agent/[id]/events/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/agent/[id]/route.js +1 -0
- package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -0
- package/.next/server/app/api/agent/[id]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/agent/new/route.js +1 -0
- package/.next/server/app/api/agent/new/route.js.nft.json +1 -0
- package/.next/server/app/api/agent/new/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/agent/running/events/route.js +3 -0
- package/.next/server/app/api/agent/running/events/route.js.nft.json +1 -0
- package/.next/server/app/api/agent/running/events/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/agents/route.js +1 -0
- package/.next/server/app/api/agents/route.js.nft.json +1 -0
- package/.next/server/app/api/agents/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/app-update/route.js +1 -0
- package/.next/server/app/api/app-update/route.js.nft.json +1 -0
- package/.next/server/app/api/app-update/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/auth/all-providers/route.js +1 -0
- package/.next/server/app/api/auth/all-providers/route.js.nft.json +1 -0
- package/.next/server/app/api/auth/all-providers/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/auth/api-key/[provider]/route.js +1 -0
- package/.next/server/app/api/auth/api-key/[provider]/route.js.nft.json +1 -0
- package/.next/server/app/api/auth/api-key/[provider]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/auth/login/[provider]/route.js +3 -0
- package/.next/server/app/api/auth/login/[provider]/route.js.nft.json +1 -0
- package/.next/server/app/api/auth/login/[provider]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/auth/logout/[provider]/route.js +1 -0
- package/.next/server/app/api/auth/logout/[provider]/route.js.nft.json +1 -0
- package/.next/server/app/api/auth/logout/[provider]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/auth/providers/route.js +1 -0
- package/.next/server/app/api/auth/providers/route.js.nft.json +1 -0
- package/.next/server/app/api/auth/providers/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/cwd/browse/route.js +1 -0
- package/.next/server/app/api/cwd/browse/route.js.nft.json +1 -0
- package/.next/server/app/api/cwd/browse/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/cwd/validate/route.js +1 -0
- package/.next/server/app/api/cwd/validate/route.js.nft.json +1 -0
- package/.next/server/app/api/cwd/validate/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/default-cwd/route.js +1 -0
- package/.next/server/app/api/default-cwd/route.js.nft.json +1 -0
- package/.next/server/app/api/default-cwd/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/file-index/route.js +1 -0
- package/.next/server/app/api/file-index/route.js.nft.json +1 -0
- package/.next/server/app/api/file-index/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/files/[...path]/route.js +49 -0
- package/.next/server/app/api/files/[...path]/route.js.nft.json +1 -0
- package/.next/server/app/api/files/[...path]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/git/diff/route.js +6 -0
- package/.next/server/app/api/git/diff/route.js.nft.json +1 -0
- package/.next/server/app/api/git/diff/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/git/status/route.js +6 -0
- package/.next/server/app/api/git/status/route.js.nft.json +1 -0
- package/.next/server/app/api/git/status/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/home/route.js +1 -0
- package/.next/server/app/api/home/route.js.nft.json +1 -0
- package/.next/server/app/api/home/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/mcp/route.js +4 -0
- package/.next/server/app/api/mcp/route.js.nft.json +1 -0
- package/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/model-roles/route.js +1 -0
- package/.next/server/app/api/model-roles/route.js.nft.json +1 -0
- package/.next/server/app/api/model-roles/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/models/fetch/route.js +1 -0
- package/.next/server/app/api/models/fetch/route.js.nft.json +1 -0
- package/.next/server/app/api/models/fetch/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/models/route.js +1 -0
- package/.next/server/app/api/models/route.js.nft.json +1 -0
- package/.next/server/app/api/models/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/models-config/catalog/route.js +1 -0
- package/.next/server/app/api/models-config/catalog/route.js.nft.json +1 -0
- package/.next/server/app/api/models-config/catalog/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/models-config/route.js +1 -0
- package/.next/server/app/api/models-config/route.js.nft.json +1 -0
- package/.next/server/app/api/models-config/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/models-config/test/route.js +1 -0
- package/.next/server/app/api/models-config/test/route.js.nft.json +1 -0
- package/.next/server/app/api/models-config/test/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/omp-settings/route.js +1 -0
- package/.next/server/app/api/omp-settings/route.js.nft.json +1 -0
- package/.next/server/app/api/omp-settings/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/omp-update/route.js +2 -0
- package/.next/server/app/api/omp-update/route.js.nft.json +1 -0
- package/.next/server/app/api/omp-update/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/omp-version/route.js +1 -0
- package/.next/server/app/api/omp-version/route.js.nft.json +1 -0
- package/.next/server/app/api/omp-version/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/plugins/route.js +1 -0
- package/.next/server/app/api/plugins/route.js.nft.json +1 -0
- package/.next/server/app/api/plugins/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/route.js +2 -0
- package/.next/server/app/api/projects/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/providers/enable/route.js +1 -0
- package/.next/server/app/api/providers/enable/route.js.nft.json +1 -0
- package/.next/server/app/api/providers/enable/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/reveal/route.js +1 -0
- package/.next/server/app/api/reveal/route.js.nft.json +1 -0
- package/.next/server/app/api/reveal/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/archive/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/archive/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/[id]/archive/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/auto-name/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/auto-name/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/[id]/auto-name/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/context/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/context/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/[id]/context/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/export/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/export/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/[id]/export/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/plan/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/plan/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/[id]/plan/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/[id]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/state/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/state/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/[id]/state/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/subagents/[subagentId]/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/subagents/[subagentId]/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/[id]/subagents/[subagentId]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/subagents/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/subagents/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/[id]/subagents/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/archive/route.js +1 -0
- package/.next/server/app/api/sessions/archive/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/archive/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/import/route.js +1 -0
- package/.next/server/app/api/sessions/import/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/import/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/route.js +1 -0
- package/.next/server/app/api/sessions/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/skills/check/route.js +1 -0
- package/.next/server/app/api/skills/check/route.js.nft.json +1 -0
- package/.next/server/app/api/skills/check/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/skills/install/route.js +1 -0
- package/.next/server/app/api/skills/install/route.js.nft.json +1 -0
- package/.next/server/app/api/skills/install/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/skills/route.js +4 -0
- package/.next/server/app/api/skills/route.js.nft.json +1 -0
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/skills/search/route.js +1 -0
- package/.next/server/app/api/skills/search/route.js.nft.json +1 -0
- package/.next/server/app/api/skills/search/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/skills/update/route.js +1 -0
- package/.next/server/app/api/skills/update/route.js.nft.json +1 -0
- package/.next/server/app/api/skills/update/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/terminal/input/route.js +8 -0
- package/.next/server/app/api/terminal/input/route.js.nft.json +1 -0
- package/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/terminal/open/route.js +1 -0
- package/.next/server/app/api/terminal/open/route.js.nft.json +1 -0
- package/.next/server/app/api/terminal/open/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/terminal/session/route.js +8 -0
- package/.next/server/app/api/terminal/session/route.js.nft.json +1 -0
- package/.next/server/app/api/terminal/session/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/terminal/stream/route.js +13 -0
- package/.next/server/app/api/terminal/stream/route.js.nft.json +1 -0
- package/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/web-auth/session/route.js +1 -0
- package/.next/server/app/api/web-auth/session/route.js.nft.json +1 -0
- package/.next/server/app/api/web-auth/session/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/route.js +1 -0
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -0
- package/.next/server/app/favicon.ico/route.js +1 -0
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -0
- package/.next/server/app/favicon.ico.body +0 -0
- package/.next/server/app/favicon.ico.meta +1 -0
- package/.next/server/app/index.html +1 -0
- package/.next/server/app/index.meta +21 -0
- package/.next/server/app/index.rsc +29 -0
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +28 -0
- package/.next/server/app/index.segments/_full.segment.rsc +29 -0
- package/.next/server/app/index.segments/_tree.segment.rsc +8 -0
- package/.next/server/app/login/page.js +1 -0
- package/.next/server/app/login/page.js.nft.json +1 -0
- package/.next/server/app/login/page_client-reference-manifest.js +1 -0
- package/.next/server/app/login.html +1 -0
- package/.next/server/app/login.meta +26 -0
- package/.next/server/app/login.rsc +29 -0
- package/.next/server/app/login.segments/_full.segment.rsc +29 -0
- package/.next/server/app/login.segments/_tree.segment.rsc +8 -0
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +28 -0
- package/.next/server/app/manifest.webmanifest/route.js +17 -0
- package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -0
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -0
- package/.next/server/app/manifest.webmanifest.body +1 -0
- package/.next/server/app/manifest.webmanifest.meta +1 -0
- package/.next/server/app/page.js +1 -0
- package/.next/server/app/page.js.nft.json +1 -0
- package/.next/server/app/page_client-reference-manifest.js +1 -0
- package/.next/server/app-paths-manifest.json +66 -0
- package/.next/server/chunks/1636.js +1 -0
- package/.next/server/chunks/1671.js +1 -0
- package/.next/server/chunks/1813.js +1 -0
- package/.next/server/chunks/2349.js +1 -0
- package/.next/server/chunks/3290.js +4 -0
- package/.next/server/chunks/3294.js +25 -0
- package/.next/server/chunks/3379.js +1 -0
- package/.next/server/chunks/3425.js +163 -0
- package/.next/server/chunks/3798.js +5 -0
- package/.next/server/chunks/4509.js +12 -0
- package/.next/server/chunks/4741.js +165 -0
- package/.next/server/chunks/5309.js +1 -0
- package/.next/server/chunks/6465.js +1 -0
- package/.next/server/chunks/7834.js +5 -0
- package/.next/server/chunks/7839.js +1 -0
- package/.next/server/chunks/8333.js +1 -0
- package/.next/server/functions-config-manifest.json +16 -0
- package/.next/server/instrumentation.js +1 -0
- package/.next/server/instrumentation.js.nft.json +1 -0
- package/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -0
- package/.next/server/middleware-manifest.json +6 -0
- package/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/.next/server/middleware.js +163 -0
- package/.next/server/middleware.js.nft.json +1 -0
- package/.next/server/next-font-manifest.js +1 -0
- package/.next/server/next-font-manifest.json +1 -0
- package/.next/server/pages/404.html +1 -0
- package/.next/server/pages/500.html +1 -0
- package/.next/server/pages-manifest.json +4 -0
- package/.next/server/prefetch-hints.json +53 -0
- package/.next/server/server-reference-manifest.js +1 -0
- package/.next/server/server-reference-manifest.json +1 -0
- package/.next/server/webpack-runtime.js +1 -0
- package/.next/static/cA3mF_wj2VN78irY68Wcm/_buildManifest.js +1 -0
- package/.next/static/cA3mF_wj2VN78irY68Wcm/_ssgManifest.js +1 -0
- package/.next/static/chunks/103.23142a67b02246a8.js +215 -0
- package/.next/static/chunks/1032.d9a9179233599785.js +1 -0
- package/.next/static/chunks/1063.775c442bdbeef08b.js +1 -0
- package/.next/static/chunks/1133.0f37525b2b215f36.js +1 -0
- package/.next/static/chunks/1327.09252bb80616cc3a.js +1 -0
- package/.next/static/chunks/1708.c3a1896e4cc9f8d9.js +1 -0
- package/.next/static/chunks/1781.9072b4c9586df549.js +1 -0
- package/.next/static/chunks/1ba63609.b2ae90f43319a29e.js +153 -0
- package/.next/static/chunks/202.95416cc0d8e6df0e.js +131 -0
- package/.next/static/chunks/2081.47b6e9391094055f.js +1 -0
- package/.next/static/chunks/2181.ba21239d3ac39f81.js +1 -0
- package/.next/static/chunks/2201.08d1cac24fc438ee.js +1 -0
- package/.next/static/chunks/2258.4defa30121ef44a5.js +1 -0
- package/.next/static/chunks/2325.23caf22075e51aa5.js +1 -0
- package/.next/static/chunks/2356.523277bb8c6bf72a.js +23 -0
- package/.next/static/chunks/2414.8b3662a85cd1b14e.js +1 -0
- package/.next/static/chunks/2418.b5d9e177e10a686e.js +1 -0
- package/.next/static/chunks/2480.cf27ca02e5b19761.js +24 -0
- package/.next/static/chunks/2539.c5a4f2fd8e421c70.js +41 -0
- package/.next/static/chunks/2584-20a03146e1e2db70.js +1 -0
- package/.next/static/chunks/2619.9431a3f48da8eef4.js +1 -0
- package/.next/static/chunks/268.ec500965c1761e26.js +80 -0
- package/.next/static/chunks/2695.b732ef1965253b3f.js +90 -0
- package/.next/static/chunks/2703.495a65ed14b2f094.js +36 -0
- package/.next/static/chunks/2821.934bcf60fbdc28c6.js +1 -0
- package/.next/static/chunks/3251.408c817adb161919.js +1 -0
- package/.next/static/chunks/3308.8e27b5c43a478f0d.js +73 -0
- package/.next/static/chunks/3336.a76f9485fe7cb762.js +1 -0
- package/.next/static/chunks/3606.ddd8065b4a3108bd.js +1 -0
- package/.next/static/chunks/370.8e8f3cf8eb0e29dd.js +1 -0
- package/.next/static/chunks/3716.72bf4c9d7325debd.js +1 -0
- package/.next/static/chunks/3794-d7cddff008311ab3.js +52 -0
- package/.next/static/chunks/394.475e54c848486e3a.js +1 -0
- package/.next/static/chunks/398.ffa02af9062a3950.js +77 -0
- package/.next/static/chunks/3995.eca0f5bef1fc3ae5.js +38 -0
- package/.next/static/chunks/4004.74b9bcf5478b1663.js +160 -0
- package/.next/static/chunks/4202.8440832386f023c7.js +226 -0
- package/.next/static/chunks/4238.6f102dcbcf2ae339.js +141 -0
- package/.next/static/chunks/4405.7a19458960a1058e.js +287 -0
- package/.next/static/chunks/4424.fd0c93a807a333e1.js +1 -0
- package/.next/static/chunks/4559.2e7ed39ea2757280.js +1 -0
- package/.next/static/chunks/484.c74eeb0fca9a9ddf.js +1 -0
- package/.next/static/chunks/4854.b64a1daa15899219.js +1 -0
- package/.next/static/chunks/4866.d1060b4faf2ae1e2.js +1 -0
- package/.next/static/chunks/4970.8a63b4953b0e4946.js +1 -0
- package/.next/static/chunks/4bd1b696-8a4ab4fdf0ae305a.js +1 -0
- package/.next/static/chunks/5020.9ac8d0dc8390bb6e.js +1 -0
- package/.next/static/chunks/5137.f163e94c74a94d01.js +1 -0
- package/.next/static/chunks/5165.2681017cd0bd291f.js +1 -0
- package/.next/static/chunks/5242.7b643c6b3394cac1.js +1 -0
- package/.next/static/chunks/5361.afc00ab2626bacbf.js +1 -0
- package/.next/static/chunks/5521.cfdf2cfc6db31407.js +1 -0
- package/.next/static/chunks/5526.ff46471041fdcb79.js +86 -0
- package/.next/static/chunks/5658.600b820420422057.js +1 -0
- package/.next/static/chunks/5681.dd0e66b0de16e54b.js +27 -0
- package/.next/static/chunks/6121.eb9023b1cbc78ee2.js +1 -0
- package/.next/static/chunks/6161.4836cd7d031026bf.js +1 -0
- package/.next/static/chunks/6195.8710aa41b2319dff.js +24 -0
- package/.next/static/chunks/6202.f4317cf0a48876f9.js +1 -0
- package/.next/static/chunks/6294.24f510c0c3e3714c.js +1 -0
- package/.next/static/chunks/6654.41440ef667144967.js +1 -0
- package/.next/static/chunks/6794.57bf1aff78682f3a.js +93 -0
- package/.next/static/chunks/7256.e07cf52d87d40252.js +1 -0
- package/.next/static/chunks/7268.2f59c671f26160f3.js +1 -0
- package/.next/static/chunks/7331.2add3c4e125a2dba.js +104 -0
- package/.next/static/chunks/7543.89f7b805ed0f2901.js +1 -0
- package/.next/static/chunks/8114.8a8fdee4c3b7fd4b.js +1 -0
- package/.next/static/chunks/8200.a36b9f8c983c6b9e.js +5 -0
- package/.next/static/chunks/852.60444b32fcbeb00c.js +1 -0
- package/.next/static/chunks/8673.8f38e67890334c5a.js +1 -0
- package/.next/static/chunks/869.7152372b662e31af.js +1 -0
- package/.next/static/chunks/8863.fa0320ea586efb3b.js +1 -0
- package/.next/static/chunks/8885.d9308c756376780b.js +79 -0
- package/.next/static/chunks/8901.e117d206a917bda0.js +1 -0
- package/.next/static/chunks/90542734.ae439f2382f58c51.js +1 -0
- package/.next/static/chunks/918.6a9bbe564e4a2d0f.js +115 -0
- package/.next/static/chunks/934.9006461bd0548660.js +1 -0
- package/.next/static/chunks/9365.a3e0e5ac101ccd02.js +1 -0
- package/.next/static/chunks/9522.c7c6e9c330f9ba6b.js +1 -0
- package/.next/static/chunks/9614.3221013d7f0af27f.js +64 -0
- package/.next/static/chunks/9698.4d09a99b9d99f3e5.js +148 -0
- package/.next/static/chunks/9705.40a82b97f214e28b.js +1 -0
- package/.next/static/chunks/973.9efc01efd9d768a5.js +8 -0
- package/.next/static/chunks/9754.d67dec946fc871d4.js +25 -0
- package/.next/static/chunks/9764.2669775c6e107a01.js +62 -0
- package/.next/static/chunks/9793.4567af813117ad25.js +1 -0
- package/.next/static/chunks/993e5495.598a97aa1337298f.js +62 -0
- package/.next/static/chunks/9974.9a0f79beca65e8c4.js +34 -0
- package/.next/static/chunks/9981.678c7bcc42f24571.js +1 -0
- package/.next/static/chunks/app/_global-error/page-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/_not-found/page-8753f2eb4b097627.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/bash-output/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/events/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/agent/new/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/agent/running/events/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/agents/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/app-update/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/auth/all-providers/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/auth/api-key/[provider]/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/auth/login/[provider]/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/[provider]/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/auth/providers/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/cwd/browse/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/cwd/validate/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/default-cwd/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/file-index/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/files/[...path]/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/git/diff/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/git/status/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/home/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/mcp/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/model-roles/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/models/fetch/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/models/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/models-config/catalog/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/models-config/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/models-config/test/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/omp-settings/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/omp-update/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/omp-version/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/plugins/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/projects/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/providers/enable/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/reveal/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/archive/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/context/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/export/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/plan/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/state/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/subagents/[subagentId]/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/subagents/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/archive/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/import/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/sessions/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/skills/check/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/skills/install/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/skills/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/skills/search/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/skills/update/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/terminal/input/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/terminal/open/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/terminal/session/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/terminal/stream/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/web-auth/session/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/error-9ba463bef8c2cf06.js +1 -0
- package/.next/static/chunks/app/global-error-871c4baa96801c4e.js +1 -0
- package/.next/static/chunks/app/layout-347584865a4cd886.js +1 -0
- package/.next/static/chunks/app/login/page-7a5cd8dbc1789d87.js +1 -0
- package/.next/static/chunks/app/manifest.webmanifest/route-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/app/page-833698058d71b603.js +1 -0
- package/.next/static/chunks/bf2ff291.244c8a7c1c14966a.js +122 -0
- package/.next/static/chunks/d3ac728e.7964f816a1ca64e5.js +1 -0
- package/.next/static/chunks/da12927c.476aa688a637649c.js +82 -0
- package/.next/static/chunks/db9d41be.27ee8fcc7bf00d70.js +1 -0
- package/.next/static/chunks/e868780c.0440c4cbaec74878.js +18 -0
- package/.next/static/chunks/framework-b33a8f5d57cd8d87.js +1 -0
- package/.next/static/chunks/main-354b27ede3eb835a.js +5 -0
- package/.next/static/chunks/main-app-14cb310088a8e6b1.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-48788bcdc79e1c9e.js +1 -0
- package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/.next/static/chunks/webpack-2a4b77ae5d80a8ba.js +1 -0
- package/.next/static/css/2f46e0db0d4a3aed.css +1 -0
- package/.next/static/css/5fe2a8af79a7efdf.css +1 -0
- package/.next/static/css/921bec6c70de20d4.css +1 -0
- package/.next/static/css/dda9acc8fa0835d6.css +1 -0
- package/.next/static/media/01bdb1c2bb2f530a-s.woff2 +0 -0
- package/.next/static/media/060fd7a2ba6f57dc-s.woff2 +0 -0
- package/.next/static/media/06d755a5cd3e2b96-s.woff2 +0 -0
- package/.next/static/media/09341845bc7215c3-s.woff2 +0 -0
- package/.next/static/media/09d8b46d011a8a55-s.woff2 +0 -0
- package/.next/static/media/0ac3ab6b6a54cd96-s.woff2 +0 -0
- package/.next/static/media/0cb7a0edc360425e-s.woff2 +0 -0
- package/.next/static/media/0de82041d2acf4c3-s.woff2 +0 -0
- package/.next/static/media/1249fbbadbb69451-s.woff2 +0 -0
- package/.next/static/media/15605e25b523335c-s.woff2 +0 -0
- package/.next/static/media/182682366c265526-s.woff2 +0 -0
- package/.next/static/media/1a3dce5cfb5f7760-s.woff2 +0 -0
- package/.next/static/media/1cdd02902f937a18-s.woff2 +0 -0
- package/.next/static/media/246116fa49278f72-s.woff2 +0 -0
- package/.next/static/media/2ad4a039dd2c0f35-s.woff2 +0 -0
- package/.next/static/media/2cd94acf7f6a8cd1-s.woff2 +0 -0
- package/.next/static/media/30af2a5bc088caeb-s.woff2 +0 -0
- package/.next/static/media/3117748ae3be552d-s.woff2 +0 -0
- package/.next/static/media/373befd5a68230ff-s.woff2 +0 -0
- package/.next/static/media/37ae20ae1d329cc2-s.woff2 +0 -0
- package/.next/static/media/3832bef2caf4f297-s.woff2 +0 -0
- package/.next/static/media/3b6ebd4dd223d8c1-s.woff2 +0 -0
- package/.next/static/media/3d165c286d94e27c-s.woff2 +0 -0
- package/.next/static/media/3da25081fc21e3b2-s.woff2 +0 -0
- package/.next/static/media/3eb545844a1630b6-s.woff2 +0 -0
- package/.next/static/media/41870aeb5505be99-s.woff2 +0 -0
- package/.next/static/media/45c8f5377f81d417-s.woff2 +0 -0
- package/.next/static/media/48d86e2f8821c61e-s.woff2 +0 -0
- package/.next/static/media/4957022da3161c6e-s.woff2 +0 -0
- package/.next/static/media/4be71ddc6c749643-s.woff2 +0 -0
- package/.next/static/media/4c4b3b30b6bcb2be-s.woff2 +0 -0
- package/.next/static/media/4dc4381bbf526d04-s.woff2 +0 -0
- package/.next/static/media/4eb0814ea9e22f45-s.woff2 +0 -0
- package/.next/static/media/4f86cf50532e0e9b-s.woff2 +0 -0
- package/.next/static/media/5022b11bb4a81e48-s.woff2 +0 -0
- package/.next/static/media/5080c55e2dccd63d-s.woff2 +0 -0
- package/.next/static/media/5348b1e69a651725-s.woff2 +0 -0
- package/.next/static/media/54c50561be23e605-s.woff2 +0 -0
- package/.next/static/media/567d6f765096ee76-s.woff2 +0 -0
- package/.next/static/media/58045d1f8695a418-s.woff2 +0 -0
- package/.next/static/media/591e43f23f51e5a5-s.woff2 +0 -0
- package/.next/static/media/5a274ddc03d9a5ab-s.woff2 +0 -0
- package/.next/static/media/5feee92221bb8605-s.woff2 +0 -0
- package/.next/static/media/6067d3f78ecc4535-s.woff2 +0 -0
- package/.next/static/media/61a11ca45429493a-s.woff2 +0 -0
- package/.next/static/media/63d030730737efae-s.woff2 +0 -0
- package/.next/static/media/641a7b8a5800ee0e-s.woff2 +0 -0
- package/.next/static/media/6bd056ddce336924-s.woff2 +0 -0
- package/.next/static/media/6dc0bae4a5666821-s.woff2 +0 -0
- package/.next/static/media/7513cc52807669ca-s.woff2 +0 -0
- package/.next/static/media/75ae81fea4aec8c5-s.woff2 +0 -0
- package/.next/static/media/77f6534b6a3eb37a-s.woff2 +0 -0
- package/.next/static/media/782d4006a26041e7-s.woff2 +0 -0
- package/.next/static/media/7c21074d9bafed1b-s.woff2 +0 -0
- package/.next/static/media/7d509f4f988023eb-s.woff2 +0 -0
- package/.next/static/media/7d58f39a50828c68-s.woff2 +0 -0
- package/.next/static/media/7db71cc013812f1c-s.woff2 +0 -0
- package/.next/static/media/7deddc85b7ffd1dc-s.p.woff2 +0 -0
- package/.next/static/media/7eb3f914ae6dd7a0-s.woff2 +0 -0
- package/.next/static/media/8051eb8307aa13c8-s.woff2 +0 -0
- package/.next/static/media/829dca987e1e010e-s.woff2 +0 -0
- package/.next/static/media/842f675c7a332a48-s.woff2 +0 -0
- package/.next/static/media/866e2e7b0cbc2cb4-s.woff2 +0 -0
- package/.next/static/media/86b38dc7f713ddda-s.woff2 +0 -0
- package/.next/static/media/8a3a66ae6bb27151-s.woff2 +0 -0
- package/.next/static/media/8b56b70f6d577d9f-s.woff2 +0 -0
- package/.next/static/media/8d93dbb77672da11-s.woff2 +0 -0
- package/.next/static/media/8f5c2d0a25b8f50c-s.woff2 +0 -0
- package/.next/static/media/916860560b9a2bc2-s.woff2 +0 -0
- package/.next/static/media/966e6d14b6c229fc-s.woff2 +0 -0
- package/.next/static/media/97ac91773d3121b2-s.p.woff2 +0 -0
- package/.next/static/media/9877fefe733dd250-s.woff2 +0 -0
- package/.next/static/media/9c57f4420502d43a-s.woff2 +0 -0
- package/.next/static/media/9cedd2ad7b0bcf3d-s.woff2 +0 -0
- package/.next/static/media/KaTeX_AMS-Regular.1608a09b.woff +0 -0
- package/.next/static/media/KaTeX_AMS-Regular.4aafdb68.ttf +0 -0
- package/.next/static/media/KaTeX_AMS-Regular.a79f1c31.woff2 +0 -0
- package/.next/static/media/KaTeX_Caligraphic-Bold.b6770918.woff +0 -0
- package/.next/static/media/KaTeX_Caligraphic-Bold.cce5b8ec.ttf +0 -0
- package/.next/static/media/KaTeX_Caligraphic-Bold.ec17d132.woff2 +0 -0
- package/.next/static/media/KaTeX_Caligraphic-Regular.07ef19e7.ttf +0 -0
- package/.next/static/media/KaTeX_Caligraphic-Regular.55fac258.woff2 +0 -0
- package/.next/static/media/KaTeX_Caligraphic-Regular.dad44a7f.woff +0 -0
- package/.next/static/media/KaTeX_Fraktur-Bold.9f256b85.woff +0 -0
- package/.next/static/media/KaTeX_Fraktur-Bold.b18f59e1.ttf +0 -0
- package/.next/static/media/KaTeX_Fraktur-Bold.d42a5579.woff2 +0 -0
- package/.next/static/media/KaTeX_Fraktur-Regular.7c187121.woff +0 -0
- package/.next/static/media/KaTeX_Fraktur-Regular.d3c882a6.woff2 +0 -0
- package/.next/static/media/KaTeX_Fraktur-Regular.ed38e79f.ttf +0 -0
- package/.next/static/media/KaTeX_Main-Bold.b74a1a8b.ttf +0 -0
- package/.next/static/media/KaTeX_Main-Bold.c3fb5ac2.woff2 +0 -0
- package/.next/static/media/KaTeX_Main-Bold.d181c465.woff +0 -0
- package/.next/static/media/KaTeX_Main-BoldItalic.6f2bb1df.woff2 +0 -0
- package/.next/static/media/KaTeX_Main-BoldItalic.70d8b0a5.ttf +0 -0
- package/.next/static/media/KaTeX_Main-BoldItalic.e3f82f9d.woff +0 -0
- package/.next/static/media/KaTeX_Main-Italic.47373d1e.ttf +0 -0
- package/.next/static/media/KaTeX_Main-Italic.8916142b.woff2 +0 -0
- package/.next/static/media/KaTeX_Main-Italic.9024d815.woff +0 -0
- package/.next/static/media/KaTeX_Main-Regular.0462f03b.woff2 +0 -0
- package/.next/static/media/KaTeX_Main-Regular.7f51fe03.woff +0 -0
- package/.next/static/media/KaTeX_Main-Regular.b7f8fe9b.ttf +0 -0
- package/.next/static/media/KaTeX_Math-BoldItalic.572d331f.woff2 +0 -0
- package/.next/static/media/KaTeX_Math-BoldItalic.a879cf83.ttf +0 -0
- package/.next/static/media/KaTeX_Math-BoldItalic.f1035d8d.woff +0 -0
- package/.next/static/media/KaTeX_Math-Italic.5295ba48.woff +0 -0
- package/.next/static/media/KaTeX_Math-Italic.939bc644.ttf +0 -0
- package/.next/static/media/KaTeX_Math-Italic.f28c23ac.woff2 +0 -0
- package/.next/static/media/KaTeX_SansSerif-Bold.8c5b5494.woff2 +0 -0
- package/.next/static/media/KaTeX_SansSerif-Bold.94e1e8dc.ttf +0 -0
- package/.next/static/media/KaTeX_SansSerif-Bold.bf59d231.woff +0 -0
- package/.next/static/media/KaTeX_SansSerif-Italic.3b1e59b3.woff2 +0 -0
- package/.next/static/media/KaTeX_SansSerif-Italic.7c9bc82b.woff +0 -0
- package/.next/static/media/KaTeX_SansSerif-Italic.b4c20c84.ttf +0 -0
- package/.next/static/media/KaTeX_SansSerif-Regular.74048478.woff +0 -0
- package/.next/static/media/KaTeX_SansSerif-Regular.ba21ed5f.woff2 +0 -0
- package/.next/static/media/KaTeX_SansSerif-Regular.d4d7ba48.ttf +0 -0
- package/.next/static/media/KaTeX_Script-Regular.03e9641d.woff2 +0 -0
- package/.next/static/media/KaTeX_Script-Regular.07505710.woff +0 -0
- package/.next/static/media/KaTeX_Script-Regular.fe9cbbe1.ttf +0 -0
- package/.next/static/media/KaTeX_Size1-Regular.e1e279cb.woff +0 -0
- package/.next/static/media/KaTeX_Size1-Regular.eae34984.woff2 +0 -0
- package/.next/static/media/KaTeX_Size1-Regular.fabc004a.ttf +0 -0
- package/.next/static/media/KaTeX_Size2-Regular.57727022.woff +0 -0
- package/.next/static/media/KaTeX_Size2-Regular.5916a24f.woff2 +0 -0
- package/.next/static/media/KaTeX_Size2-Regular.d6b476ec.ttf +0 -0
- package/.next/static/media/KaTeX_Size3-Regular.9acaf01c.woff +0 -0
- package/.next/static/media/KaTeX_Size3-Regular.a144ef58.ttf +0 -0
- package/.next/static/media/KaTeX_Size3-Regular.b4230e7e.woff2 +0 -0
- package/.next/static/media/KaTeX_Size4-Regular.10d95fd3.woff2 +0 -0
- package/.next/static/media/KaTeX_Size4-Regular.7a996c9d.woff +0 -0
- package/.next/static/media/KaTeX_Size4-Regular.fbccdabe.ttf +0 -0
- package/.next/static/media/KaTeX_Typewriter-Regular.6258592b.woff +0 -0
- package/.next/static/media/KaTeX_Typewriter-Regular.a8709e36.woff2 +0 -0
- package/.next/static/media/KaTeX_Typewriter-Regular.d97aaf4a.ttf +0 -0
- package/.next/static/media/a00fb5ef1ca68e5d-s.woff2 +0 -0
- package/.next/static/media/a171b1d72388367c-s.woff2 +0 -0
- package/.next/static/media/a310fb84e6868735-s.woff2 +0 -0
- package/.next/static/media/a53504b22c396db6-s.woff2 +0 -0
- package/.next/static/media/aabb87babcdda375-s.woff2 +0 -0
- package/.next/static/media/afe75c8050c8fd4e-s.woff2 +0 -0
- package/.next/static/media/b201193f76404e13-s.woff2 +0 -0
- package/.next/static/media/b20daecae68a588f-s.p.woff2 +0 -0
- package/.next/static/media/b2574bc564dca98d-s.woff2 +0 -0
- package/.next/static/media/b6a1339c290590d0-s.woff2 +0 -0
- package/.next/static/media/b6fe4b2295863fe4-s.woff2 +0 -0
- package/.next/static/media/bb8ff9c700288292-s.woff2 +0 -0
- package/.next/static/media/bc1ccfae4ae17995-s.woff2 +0 -0
- package/.next/static/media/be15c189f996aeb2-s.woff2 +0 -0
- package/.next/static/media/c0d1f6928a1dbc31-s.woff2 +0 -0
- package/.next/static/media/c36d8bb68a53eb60-s.woff2 +0 -0
- package/.next/static/media/c5db947ee2561e06-s.woff2 +0 -0
- package/.next/static/media/c77ac7f613b44045-s.woff2 +0 -0
- package/.next/static/media/ca73d0c74010e612-s.woff2 +0 -0
- package/.next/static/media/cfbad6ceeeca5c58-s.woff2 +0 -0
- package/.next/static/media/d24aebb82f01e48d-s.woff2 +0 -0
- package/.next/static/media/d2c6107607eb7d44-s.woff2 +0 -0
- package/.next/static/media/d2c7d5e8db7ce20a-s.woff2 +0 -0
- package/.next/static/media/d51f7558abc55aa6-s.woff2 +0 -0
- package/.next/static/media/da718921282f76d0-s.woff2 +0 -0
- package/.next/static/media/dae37106d788c7c9-s.woff2 +0 -0
- package/.next/static/media/e0d4cd45847004a4-s.woff2 +0 -0
- package/.next/static/media/e100c7a7874aebd9-s.woff2 +0 -0
- package/.next/static/media/e26dff18031f4a7e-s.woff2 +0 -0
- package/.next/static/media/e54d16b9f2c4535b-s.woff2 +0 -0
- package/.next/static/media/e5b759c1d5c42d99-s.woff2 +0 -0
- package/.next/static/media/ea21a07081db26d0-s.woff2 +0 -0
- package/.next/static/media/eaee7682c49bd1c2-s.woff2 +0 -0
- package/.next/static/media/ec14413c594b3356-s.p.woff2 +0 -0
- package/.next/static/media/ec408158b9e08aea-s.woff2 +0 -0
- package/.next/static/media/ee5d9aad76ea4c0a-s.woff2 +0 -0
- package/.next/static/media/efdbc7cff3271ee9-s.woff2 +0 -0
- package/.next/static/media/f128be4e72405705-s.woff2 +0 -0
- package/.next/static/media/fb6cfff6119f26e8-s.woff2 +0 -0
- package/.next/static/media/fd516adbc3328c82-s.woff2 +0 -0
- package/LICENSE +21 -0
- package/README.ja.md +139 -0
- package/README.md +194 -0
- package/README.zh-CN.md +177 -0
- package/bin/network-addresses.js +197 -0
- package/bin/node-version.js +35 -0
- package/bin/omp-web-options.js +86 -0
- package/bin/omp-web-security.test.mjs +9 -0
- package/bin/omp-web.js +147 -0
- package/bin/port-availability.js +27 -0
- package/bin/process-lifecycle.js +71 -0
- package/bin/process-lifecycle.test.mjs +83 -0
- package/next.config.ts +94 -0
- package/package.json +83 -0
- package/public/icon.png +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
4
|
+
const os = require("os");
|
|
5
|
+
|
|
6
|
+
const LOOPBACK_HOSTNAMES = new Set(["127.0.0.1", "localhost", "::1", "[::1]", "0:0:0:0:0:0:0:1", "[0:0:0:0:0:0:0:1]"]);
|
|
7
|
+
const WILDCARD_HOSTNAMES = new Set(["0.0.0.0", "::", "[::]", "0:0:0:0:0:0:0:0", "[0:0:0:0:0:0:0:0]", ""]);
|
|
8
|
+
|
|
9
|
+
function isWildcardHost(hostname) {
|
|
10
|
+
if (hostname == null) return true;
|
|
11
|
+
if (typeof hostname !== "string") return false;
|
|
12
|
+
return WILDCARD_HOSTNAMES.has(hostname.trim());
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isLoopbackHost(hostname) {
|
|
16
|
+
if (typeof hostname !== "string") return false;
|
|
17
|
+
const h = hostname.trim().toLowerCase();
|
|
18
|
+
if (h.startsWith("127.")) return true;
|
|
19
|
+
return LOOPBACK_HOSTNAMES.has(h);
|
|
20
|
+
}
|
|
21
|
+
function getBrowserUrl(hostname, port) {
|
|
22
|
+
if (isWildcardHost(hostname)) {
|
|
23
|
+
return `http://localhost:${port}`;
|
|
24
|
+
}
|
|
25
|
+
if (typeof hostname === "string" && hostname.includes(":") && !hostname.startsWith("[")) {
|
|
26
|
+
return `http://[${hostname}]:${port}`;
|
|
27
|
+
}
|
|
28
|
+
return `http://${hostname}:${port}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function isTailscaleAddress(ifaceName, address) {
|
|
32
|
+
if (typeof ifaceName === "string" && ifaceName.toLowerCase().includes("tailscale")) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
// Tailscale IPv4 uses CGNAT range 100.64.0.0/10 (100.64.0.0 to 100.127.255.255)
|
|
36
|
+
if (typeof address === "string") {
|
|
37
|
+
const parts = address.split(".").map(Number);
|
|
38
|
+
if (parts.length === 4 && parts[0] === 100 && parts[1] >= 64 && parts[1] <= 127) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isIgnoredAddress(ifaceName, address) {
|
|
46
|
+
if (!address || typeof address !== "string") return true;
|
|
47
|
+
// APIPA (Automatic Private IP Addressing: 169.254.0.0/16)
|
|
48
|
+
if (address.startsWith("169.254.")) return true;
|
|
49
|
+
// RFC 2544 benchmark / TUN proxy fake-ip range (198.18.0.0/15)
|
|
50
|
+
if (/^198\.(18|19)\./.test(address)) return true;
|
|
51
|
+
// Loopback
|
|
52
|
+
if (address.startsWith("127.")) return true;
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function isVirtualBridge(ifaceName) {
|
|
57
|
+
if (!ifaceName || typeof ifaceName !== "string") return false;
|
|
58
|
+
const name = ifaceName.toLowerCase();
|
|
59
|
+
return (
|
|
60
|
+
name.includes("vethernet") ||
|
|
61
|
+
name.includes("veth") ||
|
|
62
|
+
name.includes("wsl") ||
|
|
63
|
+
name.includes("docker") ||
|
|
64
|
+
name.includes("hyper-v") ||
|
|
65
|
+
name.includes("vmware") ||
|
|
66
|
+
name.includes("virtualbox") ||
|
|
67
|
+
name.includes("virbr")
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function isStandardPhysicalInterface(name) {
|
|
72
|
+
if (!name || typeof name !== "string") return false;
|
|
73
|
+
if (isVirtualBridge(name)) return false;
|
|
74
|
+
const lower = name.toLowerCase();
|
|
75
|
+
return (
|
|
76
|
+
lower.includes("以太网") ||
|
|
77
|
+
lower.includes("ethernet") ||
|
|
78
|
+
lower.includes("wi-fi") ||
|
|
79
|
+
lower.includes("wifi") ||
|
|
80
|
+
lower.includes("wlan") ||
|
|
81
|
+
lower.includes("无线") ||
|
|
82
|
+
/^en\d+$/.test(lower) ||
|
|
83
|
+
/^eth\d+$/.test(lower) ||
|
|
84
|
+
/^wlan\d+$/.test(lower) ||
|
|
85
|
+
/^enp\d+s\d+/.test(lower) ||
|
|
86
|
+
/^wlp\d+s\d+/.test(lower)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function getAccessibleAddresses({ hostname, port, interfaces = os.networkInterfaces() }) {
|
|
91
|
+
if (isLoopbackHost(hostname)) {
|
|
92
|
+
return {
|
|
93
|
+
entries: [{ label: "Local", url: `http://localhost:${port}` }],
|
|
94
|
+
hint: "use -H 0.0.0.0 to expose to the network",
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!isWildcardHost(hostname)) {
|
|
99
|
+
return {
|
|
100
|
+
entries: [{ label: "Network", url: `http://${hostname}:${port}` }],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const entries = [{ label: "Local", url: `http://localhost:${port}` }];
|
|
105
|
+
const lanEntries = [];
|
|
106
|
+
const tailscaleEntries = [];
|
|
107
|
+
const otherEntries = [];
|
|
108
|
+
const seenAddresses = new Set(["127.0.0.1", "localhost"]);
|
|
109
|
+
|
|
110
|
+
for (const [name, addrs] of Object.entries(interfaces)) {
|
|
111
|
+
if (!addrs || !Array.isArray(addrs)) continue;
|
|
112
|
+
for (const info of addrs) {
|
|
113
|
+
if (info.family !== "IPv4" && info.family !== 4) continue;
|
|
114
|
+
if (info.internal) continue;
|
|
115
|
+
const addr = info.address;
|
|
116
|
+
if (seenAddresses.has(addr)) continue;
|
|
117
|
+
if (isIgnoredAddress(name, addr)) continue;
|
|
118
|
+
|
|
119
|
+
seenAddresses.add(addr);
|
|
120
|
+
|
|
121
|
+
if (isTailscaleAddress(name, addr)) {
|
|
122
|
+
tailscaleEntries.push({
|
|
123
|
+
label: "Tailscale",
|
|
124
|
+
url: `http://${addr}:${port}`,
|
|
125
|
+
name,
|
|
126
|
+
address: addr,
|
|
127
|
+
});
|
|
128
|
+
} else if (isStandardPhysicalInterface(name)) {
|
|
129
|
+
lanEntries.push({
|
|
130
|
+
label: "Network",
|
|
131
|
+
url: `http://${addr}:${port}`,
|
|
132
|
+
name,
|
|
133
|
+
address: addr,
|
|
134
|
+
});
|
|
135
|
+
} else {
|
|
136
|
+
otherEntries.push({
|
|
137
|
+
label: name,
|
|
138
|
+
url: `http://${addr}:${port}`,
|
|
139
|
+
name,
|
|
140
|
+
address: addr,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
entries.push(...lanEntries, ...tailscaleEntries, ...otherEntries);
|
|
147
|
+
return { entries };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function formatAddressBanner({
|
|
151
|
+
version = "0.0.0",
|
|
152
|
+
entries = [],
|
|
153
|
+
hint,
|
|
154
|
+
passwordEnabled = false,
|
|
155
|
+
isTTY = process.stdout.isTTY,
|
|
156
|
+
}) {
|
|
157
|
+
const dim = isTTY ? (s) => `\x1b[90m${s}\x1b[0m` : (s) => s;
|
|
158
|
+
const bold = isTTY ? (s) => `\x1b[1m${s}\x1b[0m` : (s) => s;
|
|
159
|
+
const green = isTTY ? (s) => `\x1b[32m${s}\x1b[0m` : (s) => s;
|
|
160
|
+
const cyan = isTTY ? (s) => `\x1b[36m${s}\x1b[0m` : (s) => s;
|
|
161
|
+
|
|
162
|
+
const lines = [];
|
|
163
|
+
lines.push("");
|
|
164
|
+
lines.push(` ${bold("ompweb")} ${dim(`v${version}`)} ${green("is ready")}`);
|
|
165
|
+
lines.push("");
|
|
166
|
+
|
|
167
|
+
const maxLabelLen = Math.max(...entries.map((e) => e.label.length), hint ? 7 : 5);
|
|
168
|
+
for (const entry of entries) {
|
|
169
|
+
const padLabel = (entry.label + ":").padEnd(maxLabelLen + 2, " ");
|
|
170
|
+
lines.push(` ${green("➜")} ${bold(padLabel)} ${cyan(entry.url)}`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (hint) {
|
|
174
|
+
const padLabel = ("Network:").padEnd(maxLabelLen + 2, " ");
|
|
175
|
+
lines.push(` ${dim("➜")} ${dim(padLabel)} ${dim(hint)}`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (passwordEnabled) {
|
|
179
|
+
lines.push("");
|
|
180
|
+
lines.push(` ${dim("🔒 Password protection enabled (OMP_WEB_PASSWORD)")}`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
lines.push("");
|
|
184
|
+
return lines.join("\n");
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
module.exports = {
|
|
188
|
+
isWildcardHost,
|
|
189
|
+
isLoopbackHost,
|
|
190
|
+
getBrowserUrl,
|
|
191
|
+
isTailscaleAddress,
|
|
192
|
+
isIgnoredAddress,
|
|
193
|
+
isStandardPhysicalInterface,
|
|
194
|
+
isVirtualBridge,
|
|
195
|
+
getAccessibleAddresses,
|
|
196
|
+
formatAddressBanner,
|
|
197
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const MIN_NODE_VERSION = "22.19.0";
|
|
4
|
+
|
|
5
|
+
function parseNodeVersion(version) {
|
|
6
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)/.exec(version);
|
|
7
|
+
if (!match) return null;
|
|
8
|
+
return match.slice(1).map(Number);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function isNodeVersionSupported(version) {
|
|
12
|
+
const current = parseNodeVersion(version);
|
|
13
|
+
const minimum = parseNodeVersion(MIN_NODE_VERSION);
|
|
14
|
+
if (!current || !minimum) return false;
|
|
15
|
+
|
|
16
|
+
for (let index = 0; index < minimum.length; index += 1) {
|
|
17
|
+
if (current[index] > minimum[index]) return true;
|
|
18
|
+
if (current[index] < minimum[index]) return false;
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getUnsupportedNodeVersionMessage(version) {
|
|
24
|
+
return [
|
|
25
|
+
`ompweb requires Node.js ${MIN_NODE_VERSION} or newer.`,
|
|
26
|
+
`Current Node.js version: ${version}.`,
|
|
27
|
+
"Upgrade Node.js and try again: https://nodejs.org/",
|
|
28
|
+
].join("\n");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
MIN_NODE_VERSION,
|
|
33
|
+
getUnsupportedNodeVersionMessage,
|
|
34
|
+
isNodeVersionSupported,
|
|
35
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
4
|
+
const { parseArgs } = require("util");
|
|
5
|
+
|
|
6
|
+
const TRUE_VALUES = new Set(["1", "true", "yes", "on"]);
|
|
7
|
+
|
|
8
|
+
function isEnabled(value) {
|
|
9
|
+
return typeof value === "string" && TRUE_VALUES.has(value.trim().toLowerCase());
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
function printHelp() {
|
|
14
|
+
console.log(`Usage: ompweb [options]
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
-p, --port <port> Server port (default 30177, env PORT)
|
|
18
|
+
-H, --hostname <host> Bind hostname (default 127.0.0.1, env OMP_WEB_HOSTNAME)
|
|
19
|
+
--password <pass> Password for the web sign-in screen (env OMP_WEB_PASSWORD)
|
|
20
|
+
--no-open Do not open the browser automatically
|
|
21
|
+
-h, --help Show this help
|
|
22
|
+
--version Show version
|
|
23
|
+
|
|
24
|
+
Password:
|
|
25
|
+
ompweb --password "a-long-random-password"
|
|
26
|
+
# env-variable forms (POSIX, PowerShell, CMD handled uniformly)
|
|
27
|
+
OMP_WEB_PASSWORD="secret" ompweb
|
|
28
|
+
$env:OMP_WEB_PASSWORD="secret"; ompweb # PowerShell
|
|
29
|
+
set OMP_WEB_PASSWORD=secret&& ompweb # CMD
|
|
30
|
+
|
|
31
|
+
Security: use HTTPS via a trusted reverse proxy or VPN when binding to a
|
|
32
|
+
non-loopback hostname, so the password and session cookie stay private.`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function parseLaunchOptions(args = process.argv.slice(2), env = process.env) {
|
|
36
|
+
const { values: cliArgs } = parseArgs({
|
|
37
|
+
args,
|
|
38
|
+
options: {
|
|
39
|
+
port: { type: "string", short: "p" },
|
|
40
|
+
hostname: { type: "string", short: "H" },
|
|
41
|
+
password: { type: "string" },
|
|
42
|
+
help: { type: "boolean", short: "h" },
|
|
43
|
+
version: { type: "boolean" },
|
|
44
|
+
"no-open": { type: "boolean" },
|
|
45
|
+
},
|
|
46
|
+
strict: false,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// --password wins over env so Windows users without POSIX inline-env syntax have a first-class option.
|
|
50
|
+
const password = cliArgs.password ?? env.OMP_WEB_PASSWORD;
|
|
51
|
+
if (cliArgs.version) {
|
|
52
|
+
try {
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
54
|
+
const pkg = require("../package.json");
|
|
55
|
+
console.log(pkg.version ?? "0.0.0");
|
|
56
|
+
} catch { console.log("0.0.0"); }
|
|
57
|
+
return {
|
|
58
|
+
port: cliArgs.port ?? env.PORT ?? "30177",
|
|
59
|
+
hostname: cliArgs.hostname ?? env.OMP_WEB_HOSTNAME ?? "127.0.0.1",
|
|
60
|
+
password,
|
|
61
|
+
openBrowser: !cliArgs["no-open"] && !isEnabled(env.OMP_WEB_NO_OPEN),
|
|
62
|
+
version: true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// Expose help flag without exiting here — caller (bin/omp-web.js) decides
|
|
66
|
+
// whether to exit, keeping parseLaunchOptions testable. Print here so
|
|
67
|
+
// --help works even when the caller is a test.
|
|
68
|
+
if (cliArgs.help) {
|
|
69
|
+
printHelp();
|
|
70
|
+
return {
|
|
71
|
+
port: cliArgs.port ?? env.PORT ?? "30177",
|
|
72
|
+
hostname: cliArgs.hostname ?? env.OMP_WEB_HOSTNAME ?? "127.0.0.1",
|
|
73
|
+
password,
|
|
74
|
+
openBrowser: !cliArgs["no-open"] && !isEnabled(env.OMP_WEB_NO_OPEN),
|
|
75
|
+
help: true,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
port: cliArgs.port ?? env.PORT ?? "30177",
|
|
80
|
+
hostname: cliArgs.hostname ?? env.OMP_WEB_HOSTNAME ?? "127.0.0.1",
|
|
81
|
+
password,
|
|
82
|
+
openBrowser: !cliArgs["no-open"] && !isEnabled(env.OMP_WEB_NO_OPEN),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
module.exports = { parseLaunchOptions };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import test from "node:test";
|
|
4
|
+
|
|
5
|
+
test("launcher refuses unauthenticated non-loopback binds", async () => {
|
|
6
|
+
const source = await readFile(new URL("./omp-web.js", import.meta.url), "utf8");
|
|
7
|
+
assert.match(source, /Refusing to listen on/);
|
|
8
|
+
assert.match(source, /!passwordEnabled/);
|
|
9
|
+
});
|
package/bin/omp-web.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
5
|
+
const { getUnsupportedNodeVersionMessage, isNodeVersionSupported } = require("./node-version");
|
|
6
|
+
|
|
7
|
+
if (!isNodeVersionSupported(process.versions.node)) {
|
|
8
|
+
console.error(getUnsupportedNodeVersionMessage(process.versions.node));
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
13
|
+
const { spawn } = require("child_process");
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
15
|
+
const path = require("path");
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
17
|
+
const fs = require("fs");
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
19
|
+
const { parseLaunchOptions } = require("./omp-web-options");
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
21
|
+
const { isPortAvailable } = require("./port-availability");
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
23
|
+
const { wireChildProcessLifecycle } = require("./process-lifecycle");
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
25
|
+
const { getAccessibleAddresses, getBrowserUrl, formatAddressBanner, isLoopbackHost } = require("./network-addresses");
|
|
26
|
+
|
|
27
|
+
const pkgDir = path.join(__dirname, "..");
|
|
28
|
+
const nextDir = path.join(pkgDir, ".next");
|
|
29
|
+
|
|
30
|
+
// Resolve next's CLI entry directly to avoid relying on .bin symlinks (which
|
|
31
|
+
// may not exist when installed via npx).
|
|
32
|
+
let nextBin;
|
|
33
|
+
try {
|
|
34
|
+
nextBin = require.resolve("next/dist/bin/next", { paths: [pkgDir] });
|
|
35
|
+
} catch {
|
|
36
|
+
// Fallback: locate next package root and derive the bin path manually.
|
|
37
|
+
try {
|
|
38
|
+
const nextPkg = require.resolve("next/package.json", { paths: [pkgDir] });
|
|
39
|
+
nextBin = path.join(path.dirname(nextPkg), "dist", "bin", "next");
|
|
40
|
+
} catch {
|
|
41
|
+
nextBin = path.join(pkgDir, "node_modules", "next", "dist", "bin", "next");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let pkgVersion = "0.0.0";
|
|
46
|
+
try {
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
48
|
+
const pkg = require("../package.json");
|
|
49
|
+
pkgVersion = pkg.version ?? "0.0.0";
|
|
50
|
+
} catch { /* ignore */ }
|
|
51
|
+
|
|
52
|
+
const launchOptions = parseLaunchOptions();
|
|
53
|
+
if (launchOptions.help || launchOptions.version) {
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
const port = launchOptions.port;
|
|
57
|
+
const hostname = launchOptions.hostname;
|
|
58
|
+
const password = launchOptions.password;
|
|
59
|
+
const openBrowser = launchOptions.openBrowser;
|
|
60
|
+
// Propagate --password into the env for proxy.ts / lib/web-auth.ts and the spawned Next process.
|
|
61
|
+
if (password) process.env.OMP_WEB_PASSWORD = password;
|
|
62
|
+
const passwordEnabled = typeof password === "string" && password.length > 0;
|
|
63
|
+
if (!fs.existsSync(nextDir)) {
|
|
64
|
+
console.error("Build artifacts not found. Please report this issue.");
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!isLoopbackHost(hostname)) {
|
|
69
|
+
if (!passwordEnabled) {
|
|
70
|
+
console.error(`Refusing to listen on ${hostname} without OMP_WEB_PASSWORD (or --password). Set a strong password or bind to 127.0.0.1.`);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
console.warn(`Warning: ompweb is listening on ${hostname} over HTTP. Use HTTPS or a trusted VPN to protect the password and session cookie in transit.`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const nextArgs = ["start", "-p", port];
|
|
77
|
+
nextArgs.push("-H", hostname);
|
|
78
|
+
|
|
79
|
+
// Always run next's JS entry with node directly — avoids .bin symlink issues
|
|
80
|
+
// and path-with-spaces problems on Windows when shell: true is used.
|
|
81
|
+
const browserUrl = getBrowserUrl(hostname, port);
|
|
82
|
+
async function main() {
|
|
83
|
+
if (!await isPortAvailable(port, hostname)) {
|
|
84
|
+
console.error(`Port ${port} on ${hostname} is already in use.`);
|
|
85
|
+
console.error(`If ompweb is already running, open ${browserUrl}. Otherwise, stop the process using it or run: ompweb --port ${Number(port) + 1}`);
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const child = spawn(process.execPath, [nextBin, ...nextArgs], {
|
|
91
|
+
cwd: pkgDir,
|
|
92
|
+
stdio: ["inherit", "pipe", "inherit"],
|
|
93
|
+
env: {
|
|
94
|
+
...process.env,
|
|
95
|
+
OMP_WEB_PACKAGE_DIR: pkgDir,
|
|
96
|
+
OMP_WEB_LAUNCHER_PID: String(process.pid),
|
|
97
|
+
OMP_WEB_PORT: port,
|
|
98
|
+
OMP_WEB_HOSTNAME: hostname,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
wireChildProcessLifecycle(child);
|
|
102
|
+
|
|
103
|
+
let bannerPrinted = false;
|
|
104
|
+
let browserOpened = false;
|
|
105
|
+
let readyBuffer = "";
|
|
106
|
+
child.stdout.on("data", (chunk) => {
|
|
107
|
+
const text = chunk.toString();
|
|
108
|
+
process.stdout.write(text);
|
|
109
|
+
readyBuffer += text;
|
|
110
|
+
if (readyBuffer.length > 500) readyBuffer = readyBuffer.slice(-500);
|
|
111
|
+
if (readyBuffer.includes("Ready")) {
|
|
112
|
+
if (!bannerPrinted) {
|
|
113
|
+
bannerPrinted = true;
|
|
114
|
+
const { entries, hint } = getAccessibleAddresses({ hostname, port });
|
|
115
|
+
const banner = formatAddressBanner({
|
|
116
|
+
version: pkgVersion,
|
|
117
|
+
entries,
|
|
118
|
+
hint,
|
|
119
|
+
passwordEnabled,
|
|
120
|
+
isTTY: process.stdout.isTTY,
|
|
121
|
+
});
|
|
122
|
+
process.stdout.write(banner);
|
|
123
|
+
}
|
|
124
|
+
if (openBrowser && !browserOpened) {
|
|
125
|
+
browserOpened = true;
|
|
126
|
+
const isWindows = process.platform === "win32";
|
|
127
|
+
const isMac = process.platform === "darwin";
|
|
128
|
+
const openCmd = isWindows ? "explorer.exe" : isMac ? "open" : "xdg-open";
|
|
129
|
+
const opener = spawn(openCmd, [browserUrl], {
|
|
130
|
+
stdio: "ignore",
|
|
131
|
+
detached: true,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
opener.on("error", (error) => {
|
|
135
|
+
console.warn(`Could not open browser automatically: ${error.message}`);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
opener.unref();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
main().catch((error) => {
|
|
145
|
+
console.error(`Could not check whether ${browserUrl} is available: ${error.message}`);
|
|
146
|
+
process.exit(1);
|
|
147
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
4
|
+
const net = require("net");
|
|
5
|
+
|
|
6
|
+
function isPortAvailable(port, hostname) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
const server = net.createServer();
|
|
9
|
+
|
|
10
|
+
server.once("error", (error) => {
|
|
11
|
+
if (error.code === "EADDRINUSE") {
|
|
12
|
+
resolve(false);
|
|
13
|
+
} else {
|
|
14
|
+
reject(error);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
server.listen({ port: Number(port), host: hostname }, () => {
|
|
19
|
+
server.close((error) => {
|
|
20
|
+
if (error) reject(error);
|
|
21
|
+
else resolve(true);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = { isPortAvailable };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
4
|
+
const os = require("node:os");
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
6
|
+
const { spawn } = require("node:child_process");
|
|
7
|
+
|
|
8
|
+
const forwardedSignals = ["SIGINT", "SIGTERM"];
|
|
9
|
+
const shutdownTimeoutMs = 5_000;
|
|
10
|
+
|
|
11
|
+
function getSignalExitCode(signal) {
|
|
12
|
+
const signalNumber = signal ? os.constants.signals[signal] : undefined;
|
|
13
|
+
return typeof signalNumber === "number" ? 128 + signalNumber : 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function killChildTree(child, force, platform = process.platform) {
|
|
17
|
+
if (platform === "win32" && child.pid) {
|
|
18
|
+
const reaper = spawn("taskkill", ["/pid", String(child.pid), "/t", ...(force ? ["/f"] : [])], {
|
|
19
|
+
windowsHide: true,
|
|
20
|
+
stdio: "ignore",
|
|
21
|
+
});
|
|
22
|
+
reaper.once("error", () => {
|
|
23
|
+
try { child.kill(force ? "SIGKILL" : "SIGTERM"); } catch {}
|
|
24
|
+
});
|
|
25
|
+
reaper.unref?.();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try { child.kill(force ? "SIGKILL" : "SIGTERM"); } catch {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function wireChildProcessLifecycle(child, parentProcess = process, timeoutMs = shutdownTimeoutMs) {
|
|
33
|
+
const signalHandlers = new Map();
|
|
34
|
+
let shutdownTimer;
|
|
35
|
+
const platform = parentProcess.platform ?? process.platform;
|
|
36
|
+
|
|
37
|
+
const forceKill = () => killChildTree(child, true, platform);
|
|
38
|
+
|
|
39
|
+
for (const signal of forwardedSignals) {
|
|
40
|
+
const handler = () => {
|
|
41
|
+
if (shutdownTimer) {
|
|
42
|
+
forceKill();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
shutdownTimer = setTimeout(forceKill, timeoutMs);
|
|
47
|
+
shutdownTimer.unref?.();
|
|
48
|
+
try {
|
|
49
|
+
child.kill(signal);
|
|
50
|
+
} catch {
|
|
51
|
+
// Windows has limited signal support. Ask taskkill to terminate the
|
|
52
|
+
// child tree if the native signal could not be delivered.
|
|
53
|
+
if (platform === "win32") killChildTree(child, false, platform);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
signalHandlers.set(signal, handler);
|
|
57
|
+
parentProcess.on(signal, handler);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
child.once("exit", (code, signal) => {
|
|
61
|
+
if (shutdownTimer) clearTimeout(shutdownTimer);
|
|
62
|
+
|
|
63
|
+
for (const [forwardedSignal, handler] of signalHandlers) {
|
|
64
|
+
parentProcess.removeListener(forwardedSignal, handler);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
parentProcess.exit(code ?? getSignalExitCode(signal));
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = { wireChildProcessLifecycle };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { EventEmitter } from "node:events";
|
|
3
|
+
import test from "node:test";
|
|
4
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
5
|
+
|
|
6
|
+
import { wireChildProcessLifecycle } from "./process-lifecycle.js";
|
|
7
|
+
|
|
8
|
+
function createProcesses() {
|
|
9
|
+
const parent = new EventEmitter();
|
|
10
|
+
const child = new EventEmitter();
|
|
11
|
+
const forwardedSignals = [];
|
|
12
|
+
const exitCodes = [];
|
|
13
|
+
|
|
14
|
+
child.kill = (signal) => {
|
|
15
|
+
forwardedSignals.push(signal);
|
|
16
|
+
return true;
|
|
17
|
+
};
|
|
18
|
+
parent.exit = (code) => {
|
|
19
|
+
exitCodes.push(code);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return { parent, child, forwardedSignals, exitCodes };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
test("forwards the first shutdown signal and force-kills on repeated signals", () => {
|
|
26
|
+
const { parent, child, forwardedSignals } = createProcesses();
|
|
27
|
+
|
|
28
|
+
wireChildProcessLifecycle(child, parent);
|
|
29
|
+
parent.emit("SIGTERM");
|
|
30
|
+
parent.emit("SIGTERM");
|
|
31
|
+
parent.emit("SIGINT");
|
|
32
|
+
|
|
33
|
+
assert.deepEqual(forwardedSignals, ["SIGTERM", "SIGKILL", "SIGKILL"]);
|
|
34
|
+
child.emit("exit", null, "SIGKILL");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("propagates a child exit code and clears its shutdown wiring", async () => {
|
|
38
|
+
const { parent, child, forwardedSignals, exitCodes } = createProcesses();
|
|
39
|
+
const existingSigtermListener = () => {};
|
|
40
|
+
parent.on("SIGTERM", existingSigtermListener);
|
|
41
|
+
|
|
42
|
+
wireChildProcessLifecycle(child, parent, 10);
|
|
43
|
+
assert.equal(parent.listenerCount("SIGINT"), 1);
|
|
44
|
+
assert.equal(parent.listenerCount("SIGTERM"), 2);
|
|
45
|
+
|
|
46
|
+
parent.emit("SIGTERM");
|
|
47
|
+
child.emit("exit", 23, null);
|
|
48
|
+
await delay(20);
|
|
49
|
+
|
|
50
|
+
assert.deepEqual(exitCodes, [23]);
|
|
51
|
+
assert.equal(parent.listenerCount("SIGINT"), 0);
|
|
52
|
+
assert.deepEqual(parent.listeners("SIGTERM"), [existingSigtermListener]);
|
|
53
|
+
|
|
54
|
+
parent.emit("SIGTERM");
|
|
55
|
+
assert.deepEqual(forwardedSignals, ["SIGTERM"]);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("force-kills the child when graceful shutdown times out", async () => {
|
|
59
|
+
const { parent, child, forwardedSignals } = createProcesses();
|
|
60
|
+
|
|
61
|
+
wireChildProcessLifecycle(child, parent, 10);
|
|
62
|
+
parent.emit("SIGINT");
|
|
63
|
+
assert.deepEqual(forwardedSignals, ["SIGINT"]);
|
|
64
|
+
|
|
65
|
+
await delay(20);
|
|
66
|
+
|
|
67
|
+
assert.deepEqual(forwardedSignals, ["SIGINT", "SIGKILL"]);
|
|
68
|
+
child.emit("exit", null, "SIGKILL");
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test("uses conventional exit statuses for known child signals", () => {
|
|
72
|
+
for (const [signal, expectedExitCode] of [
|
|
73
|
+
["SIGTERM", 143],
|
|
74
|
+
["SIGKILL", 137],
|
|
75
|
+
]) {
|
|
76
|
+
const { parent, child, exitCodes } = createProcesses();
|
|
77
|
+
|
|
78
|
+
wireChildProcessLifecycle(child, parent);
|
|
79
|
+
child.emit("exit", null, signal);
|
|
80
|
+
|
|
81
|
+
assert.deepEqual(exitCodes, [expectedExitCode]);
|
|
82
|
+
}
|
|
83
|
+
});
|