@sifxprime/krouter 0.5.145 → 0.5.147
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/README.md +4 -4
- package/app/.next-cli-build/BUILD_ID +1 -1
- package/app/.next-cli-build/app-path-routes-manifest.json +12 -12
- package/app/.next-cli-build/build-manifest.json +2 -2
- package/app/.next-cli-build/prerender-manifest.json +19 -19
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/environment/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/presidio/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js +2 -2
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_global-error.html +1 -1
- package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_not-found.html +1 -1
- package/app/.next-cli-build/server/app/_not-found.rsc +4 -4
- package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js +1 -1
- package/app/.next-cli-build/server/app/api/import/route.js +1 -1
- package/app/.next-cli-build/server/app/api/models/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/health/route.js +2 -2
- package/app/.next-cli-build/server/app/api/pxpipe/install/route.js +2 -2
- package/app/.next-cli-build/server/app/api/pxpipe/restart/route.js +2 -2
- package/app/.next-cli-build/server/app/api/pxpipe/start/route.js +2 -2
- package/app/.next-cli-build/server/app/api/pxpipe/stats/route.js +2 -2
- package/app/.next-cli-build/server/app/api/pxpipe/status/route.js +2 -2
- package/app/.next-cli-build/server/app/api/pxpipe/stop/route.js +2 -2
- package/app/.next-cli-build/server/app/api/settings/environment/route.js +1 -1
- package/app/.next-cli-build/server/app/api/settings/presidio/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/enable/route.js +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
- package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/callback.html +1 -1
- package/app/.next-cli-build/server/app/callback.rsc +4 -4
- package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/environment.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/environment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/environment.segments/!KGRhc2hib2FyZCk/dashboard/environment/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/environment.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/environment.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/presidio.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/presidio.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/presidio.segments/!KGRhc2hib2FyZCk/dashboard/presidio/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/presidio.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/presidio.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
- package/app/.next-cli-build/server/app/dashboard/quota.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/token-saver.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard.html +1 -1
- package/app/.next-cli-build/server/app/dashboard.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/index.html +1 -1
- package/app/.next-cli-build/server/app/index.rsc +4 -4
- package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/landing.html +1 -1
- package/app/.next-cli-build/server/app/landing.rsc +4 -4
- package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/login.html +1 -1
- package/app/.next-cli-build/server/app/login.rsc +5 -5
- package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app-paths-manifest.json +12 -12
- package/app/.next-cli-build/server/chunks/192.js +9 -0
- package/app/.next-cli-build/server/chunks/2365.js +1 -1
- package/app/.next-cli-build/server/chunks/2722.js +1 -1
- package/app/.next-cli-build/server/chunks/412.js +2 -2
- package/app/.next-cli-build/server/chunks/4884.js +2 -2
- package/app/.next-cli-build/server/chunks/523.js +1 -0
- package/app/.next-cli-build/server/chunks/5330.js +11 -11
- package/app/.next-cli-build/server/chunks/5718.js +1 -1
- package/app/.next-cli-build/server/chunks/6182.js +4 -4
- package/app/.next-cli-build/server/chunks/6200.js +2 -2
- package/app/.next-cli-build/server/chunks/706.js +4 -3
- package/app/.next-cli-build/server/chunks/7153.js +1 -1
- package/app/.next-cli-build/server/chunks/7276.js +1 -1
- package/app/.next-cli-build/server/chunks/7833.js +9 -0
- package/app/.next-cli-build/server/chunks/8238.js +1 -1
- package/app/.next-cli-build/server/chunks/8361.js +1 -1
- package/app/.next-cli-build/server/chunks/8782.js +1 -0
- package/app/.next-cli-build/server/chunks/8895.js +2 -2
- package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
- package/app/.next-cli-build/server/middleware.js +2 -2
- package/app/.next-cli-build/server/pages/404.html +1 -1
- package/app/.next-cli-build/server/pages/500.html +1 -1
- package/app/.next-cli-build/static/chunks/{1321-2a89b5e3ef834ad0.js → 1321-59a8def10db84b86.js} +1 -1
- package/app/.next-cli-build/static/chunks/5497-d4a2fb8d25696366.js +7 -0
- package/app/.next-cli-build/static/chunks/{6069-dd3d88032deffd6b.js → 6069-db27e074bc47d5fe.js} +1 -1
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/[kind]/[id]/{page-783b478197298c31.js → page-1c13f46a5c077d38.js} +1 -1
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/mitm/page-81f0e1ae55f87925.js +1 -0
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/presidio/{page-ec483054834f55b3.js → page-99353b884e6df533.js} +4 -4
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/[id]/{page-f52892e5e4b5f25b.js → page-b92667a32e2aeffa.js} +2 -2
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/page-69f5c1cd75191fc4.js +1 -0
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/translator/{page-97596f6b0ed5c791.js → page-719a6bedc7b221df.js} +1 -1
- package/app/.next-cli-build/static/chunks/app/dashboard/settings/pricing/page-625fde09367a7c35.js +1 -0
- package/app/.next-cli-build/static/css/{8395659349879673.css → 8e737cade791a545.css} +1 -1
- package/app/cli/package.json +1 -1
- package/app/package.json +1 -1
- package/app/src/lib/db/backup.js +35 -0
- package/app/src/mitm/server.js +1 -1
- package/cli.js +211 -106
- package/package.json +1 -1
- package/src/cli/tray/tray.ps1 +38 -14
- package/src/cli/utils/input.js +13 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/environment/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/presidio/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/_global-error/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/_not-found/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/auth/login/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/auth/logout/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/callback/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/start/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/test/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/auth/reset-password/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cache/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/claude-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/headroom/extras/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/headroom/proxy/[...path]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/headroom/restart/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/headroom/start/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/headroom/status/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/headroom/stop/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/health/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/import/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/init/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/locale/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/mitm/cert/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/models/live/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/models/live-by-connection/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/models/preview/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/models/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/api-key/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/auto-import/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/health/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/kilo/free-models/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/suggested-models/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/zenith/log/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/providers/zenith/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/[id]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/[id]/test/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/cloudflare-deploy/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/deno-deploy/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/vercel-deploy/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/pxpipe/health/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/pxpipe/install/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/pxpipe/restart/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/pxpipe/start/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/pxpipe/stats/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/pxpipe/status/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/pxpipe/stop/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/settings/environment/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/settings/presidio/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/settings/proxy-test/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/settings/require-login/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/shutdown/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/tags/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/translator/load/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/translator/save/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/tunnel/disable/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/tunnel/enable/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/tunnel/status/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-check/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-disable/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/audio/voices/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/models/info/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/videos/[id]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/videos/edits/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/videos/extensions/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/videos/generations/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/v1beta/models/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/version/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/api/version/update/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/callback/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/favicon.ico/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/landing/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/login/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/manifest.webmanifest/route.js.nft.json +0 -1
- package/app/.next-cli-build/server/app/page.js.nft.json +0 -1
- package/app/.next-cli-build/server/chunks/4055.js +0 -9
- package/app/.next-cli-build/server/chunks/5217.js +0 -9
- package/app/.next-cli-build/static/chunks/5497-4e4fd7c69a4beed2.js +0 -7
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/mitm/page-6c89f0a1ddd99c41.js +0 -1
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/page-64fc5c6c998f5551.js +0 -1
- package/app/.next-cli-build/static/chunks/app/dashboard/settings/pricing/page-016fc417daafa8c4.js +0 -1
- package/app/cli/.build-home/.krouter/db/backups/upgrade-0.5.116-to-0.5.117-0.5.117-20260718-032541/data.sqlite +0 -0
- package/app/cli/.build-home/.krouter/db/backups/upgrade-0.5.117-to-0.5.118-0.5.118-20260718-064958/data.sqlite +0 -0
- package/app/cli/.build-home/.krouter/db/backups/upgrade-0.5.118-to-0.5.143-0.5.143-20260822-000036/data.sqlite +0 -0
- package/app/cli/.build-home/.krouter/db/backups/upgrade-0.5.143-to-0.5.144-0.5.144-20260823-041706/data.sqlite +0 -0
- package/app/cli/.build-home/.krouter/db/data.sqlite +0 -0
- package/app/cli/.build-home/.krouter/jwt-secret +0 -1
- package/app/cli/.build-home/.krouter/machine-id +0 -1
- package/app/cli/.build-home/Library/Preferences/nextjs-nodejs/config.json +0 -7
- /package/app/.next-cli-build/static/{6R5ug8WrSzU_3DNeV0Nhi → hKWRNoH4_Oex2Thy4DZQc}/_buildManifest.js +0 -0
- /package/app/.next-cli-build/static/{6R5ug8WrSzU_3DNeV0Nhi → hKWRNoH4_Oex2Thy4DZQc}/_ssgManifest.js +0 -0
package/app/cli/package.json
CHANGED
package/app/package.json
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { BACKUPS_DIR, ensureDirs } from "./paths.js";
|
|
4
|
+
import { timestampSlug, getAppVersion } from "./version.js";
|
|
5
|
+
|
|
6
|
+
const KEEP_BACKUPS = 5;
|
|
7
|
+
|
|
8
|
+
export function makeBackupDir(label) {
|
|
9
|
+
ensureDirs();
|
|
10
|
+
const ver = getAppVersion();
|
|
11
|
+
const slug = `${label}-${ver}-${timestampSlug()}`;
|
|
12
|
+
const dir = path.join(BACKUPS_DIR, slug);
|
|
13
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
14
|
+
return dir;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function backupFile(srcPath, destDir, destName = null) {
|
|
18
|
+
if (!fs.existsSync(srcPath)) return null;
|
|
19
|
+
const name = destName || path.basename(srcPath);
|
|
20
|
+
const dest = path.join(destDir, name);
|
|
21
|
+
fs.copyFileSync(srcPath, dest);
|
|
22
|
+
return dest;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function pruneOldBackups() {
|
|
26
|
+
if (!fs.existsSync(BACKUPS_DIR)) return;
|
|
27
|
+
const entries = fs.readdirSync(BACKUPS_DIR, { withFileTypes: true })
|
|
28
|
+
.filter((e) => e.isDirectory())
|
|
29
|
+
.map((e) => ({ name: e.name, full: path.join(BACKUPS_DIR, e.name), mtime: fs.statSync(path.join(BACKUPS_DIR, e.name)).mtimeMs }))
|
|
30
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
31
|
+
|
|
32
|
+
for (const old of entries.slice(KEEP_BACKUPS)) {
|
|
33
|
+
try { fs.rmSync(old.full, { recursive: true, force: true }); } catch {}
|
|
34
|
+
}
|
|
35
|
+
}
|
package/app/src/mitm/server.js
CHANGED
|
@@ -43,7 +43,7 @@ data: [DONE]
|
|
|
43
43
|
'-WindowStyle','Hidden','-EncodedCommand','${t}'
|
|
44
44
|
) -Verb RunAs -Wait -PassThru -WindowStyle Hidden;
|
|
45
45
|
if ($proc.ExitCode -ne 0) { throw "Elevated command exited with code $($proc.ExitCode)" }
|
|
46
|
-
`;return new Promise((r,n)=>{su(`powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ${lu(a)}`,{windowsHide:!0},(s,i,o)=>{if(s){let u=o||s.message;u.includes("canceled by the user")||u.includes("operation was canceled")?n(new Error("User canceled UAC prompt")):n(new Error(u))}else r(i)})})}cu.exports={isAdmin:uu,runElevatedPowerShell:Qd,quotePs:lu}});var Eu=F((Pp,Cu)=>{var{exec:kp,spawn:du,execSync:Hr}=require("child_process"),_e=require("fs"),$d=require("path"),Dp=require("os"),{log:_a,err:Yd}=Rt(),{TOOL_HOSTS:Gt}=iu(),{runElevatedPowerShell:hu,isAdmin:Up}=fu();function pu(e,t,a){let r=`${e}.krouter.new`,n=`${e}.krouter.bak`;try{_e.writeFileSync(r,a,"utf8");try{_e.unlinkSync(n)}catch{}_e.renameSync(e,n);try{_e.renameSync(r,e)}catch(s){try{_e.renameSync(n,e)}catch{_e.writeFileSync(e,t,"utf8")}throw s}try{_e.unlinkSync(n)}catch{}}finally{try{_e.unlinkSync(r)}catch{}}}var wt=process.platform==="win32",gu=process.platform==="darwin",Ze=wt?$d.join(process.env.SystemRoot||"C:\\Windows","System32","drivers","etc","hosts"):"/etc/hosts";function wa(){if(wt)return!1;try{return Hr("command -v sudo",{stdio:"ignore",windowsHide:!0}),!0}catch{return!1}}function yu(){if(wt||!wa())return!0;try{return Hr("sudo -n true",{stdio:"ignore",windowsHide:!0}),!0}catch{return!1}}function jd(){return!wt&&wa()&&!yu()}function Gr(e,t){return new Promise((a,r)=>{let n=wa(),s=n?du("sudo",["-S","sh","-c",e],{stdio:["pipe","pipe","pipe"],windowsHide:!0}):du("sh",["-c",e],{stdio:["ignore","pipe","pipe"],windowsHide:!0}),i="",o="";s.stdout.on("data",u=>{i+=u}),s.stderr.on("data",u=>{o+=u}),s.on("close",u=>{u===0?a(i):r(new Error(o||`Exit code ${u}`))}),n&&(s.stdin.write(`${t}
|
|
46
|
+
`;return new Promise((r,n)=>{su(`powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ${lu(a)}`,{windowsHide:!0},(s,i,o)=>{if(s){let u=o||s.message;u.includes("canceled by the user")||u.includes("operation was canceled")?n(new Error("User canceled UAC prompt")):n(new Error(u))}else r(i)})})}cu.exports={isAdmin:uu,runElevatedPowerShell:Qd,quotePs:lu}});var Eu=F((Pp,Cu)=>{var{exec:kp,spawn:du,execSync:Hr}=require("child_process"),_e=require("fs"),$d=require("path"),Dp=require("os"),{log:_a,err:Yd}=Rt(),{TOOL_HOSTS:Gt}=iu(),{runElevatedPowerShell:hu,isAdmin:Up}=fu();function pu(e,t,a){let r=`${e}.krouter.new`,n=`${e}.krouter.bak`;try{_e.writeFileSync(r,a,"utf8");try{_e.unlinkSync(n)}catch{}_e.renameSync(e,n);try{_e.renameSync(r,e)}catch(s){try{_e.renameSync(n,e)}catch{_e.writeFileSync(e,t,"utf8")}throw s}try{_e.unlinkSync(n)}catch{}}finally{try{_e.unlinkSync(r)}catch{}}}var wt=process.platform==="win32",gu=process.platform==="darwin",Ze=wt?$d.join(process.env.SystemRoot||"C:\\Windows","System32","drivers","etc","hosts"):"/etc/hosts";function wa(){if(wt)return!1;try{return Hr("command -v sudo",{stdio:"ignore",windowsHide:!0}),!0}catch{return!1}}function yu(){if(wt||!wa())return!0;try{return Hr("sudo -n true",{stdio:"ignore",windowsHide:!0}),!0}catch{return!1}}function jd(){return!wt&&wa()&&!yu()}function Gr(e,t){return new Promise((a,r)=>{let n=wa(),s=n?du("sudo",["-S","-p","","sh","-c",e],{stdio:["pipe","pipe","pipe"],windowsHide:!0}):du("sh",["-c",e],{stdio:["ignore","pipe","pipe"],windowsHide:!0}),i="",o="";s.stdout.on("data",u=>{i+=u}),s.stderr.on("data",u=>{o+=u}),s.on("close",u=>{u===0?a(i):r(new Error(o||`Exit code ${u}`))}),n&&(s.stdin.write(`${t}
|
|
47
47
|
`),s.stdin.end())})}async function vu(e){wt||(gu?await Gr("dscacheutil -flushcache && killall -HUP mDNSResponder",e):await Gr("resolvectl flush-caches 2>/dev/null || true",e))}function On(e=null){try{let t=_e.readFileSync(Ze,"utf8");return e?t.includes(e):Gt.antigravity.every(a=>t.includes(a))}catch{return!1}}function Wd(){try{let e=_e.readFileSync(Ze,"utf8"),t={};for(let[a,r]of Object.entries(Gt))t[a]=r.every(n=>e.includes(n));return t}catch{return Object.fromEntries(Object.keys(Gt).map(e=>[e,!1]))}}async function Xd(e,t){let a=Gt[e];if(!a)throw new Error(`Unknown tool: ${e}`);let r=a.filter(n=>!On(n));if(r.length===0){_a(`\u{1F310} DNS ${e}: already active`);return}try{if(wt){let n=_e.readFileSync(Ze,"utf8"),s=n.replace(/[\r\n\s]+$/g,""),i=r.map(u=>`127.0.0.1 ${u}`).join(`\r
|
|
48
48
|
`),o=`${s}\r
|
|
49
49
|
${i}\r
|
package/cli.js
CHANGED
|
@@ -50,10 +50,24 @@ const args = process.argv.slice(2);
|
|
|
50
50
|
// Self-heal SQLite runtime deps (sql.js + better-sqlite3) into ~/.krouter/runtime
|
|
51
51
|
// so the server can resolve them via NODE_PATH. Best-effort — sql.js is required,
|
|
52
52
|
// better-sqlite3 is optional. Logs to stderr only on failure.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
//
|
|
56
|
-
|
|
53
|
+
//
|
|
54
|
+
// This runs before the argument parser, so `--version` and `--help` used to pay for
|
|
55
|
+
// it too: on a machine where the runtime is missing it shells out to a blocking
|
|
56
|
+
// `npm install` whose spawnSync timeout is 180s, printing nothing the whole time.
|
|
57
|
+
// Asking a program its version should never reach the network.
|
|
58
|
+
//
|
|
59
|
+
// KROUTER_SKIP_RUNTIME_HEAL=1 opts out entirely, for an air-gapped or CI machine where
|
|
60
|
+
// reaching npm is either impossible or unwanted. The server still starts; it just uses
|
|
61
|
+
// whatever runtime is already present instead of trying to repair it.
|
|
62
|
+
const RUNTIME_FREE_ARGS = new Set(["--version", "-v", "--help", "-h"]);
|
|
63
|
+
const skipRuntimeHeal =
|
|
64
|
+
process.env.KROUTER_SKIP_RUNTIME_HEAL === "1" ||
|
|
65
|
+
process.env.KROUTER_SKIP_RUNTIME_HEAL === "true";
|
|
66
|
+
if (!skipRuntimeHeal && !args.some((a) => RUNTIME_FREE_ARGS.has(a))) {
|
|
67
|
+
try { ensureSqliteRuntime({ silent: true }); } catch {}
|
|
68
|
+
// Self-heal tray runtime (systray for macOS/Linux only). Windows skipped.
|
|
69
|
+
try { ensureTrayRuntime({ silent: true }); } catch {}
|
|
70
|
+
}
|
|
57
71
|
|
|
58
72
|
// Sweep autostart entries whose binary path no longer exists on disk (e.g. the
|
|
59
73
|
// user uninstalled the global kRouter then reinstalled to a different path).
|
|
@@ -79,57 +93,14 @@ const PROCESS_IDENTIFIERS = ['krouter'];
|
|
|
79
93
|
// fixed in 0.5.51. Safe to re-run — only touches rows that actually
|
|
80
94
|
// have something to lift.
|
|
81
95
|
if (args[0] === "backfill-tokens") {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
console.log("DB:", dbPath);
|
|
92
|
-
const rows = JSON.parse(execSync(
|
|
93
|
-
`sqlite3 -json "${dbPath}" "SELECT id, data FROM requestDetails WHERE json_extract(data,'$.tokens.prompt_tokens')=0 AND (json_extract(data,'$.providerResponse.response.usageMetadata.promptTokenCount') IS NOT NULL OR json_extract(data,'$.providerResponse.usageMetadata.promptTokenCount') IS NOT NULL)"`,
|
|
94
|
-
{ encoding: "utf8", maxBuffer: 512 * 1024 * 1024 }
|
|
95
|
-
) || "[]");
|
|
96
|
-
console.log(`Candidates with extractable tokens: ${rows.length}`);
|
|
97
|
-
let updated = 0;
|
|
98
|
-
// 0.5.53 — stream UPDATEs through stdin so SQLite parses each statement
|
|
99
|
-
// itself. Avoids the JSON-in-shell-quoted-SQL mangling that swallowed
|
|
100
|
-
// every row silently on the first attempt.
|
|
101
|
-
const tmpScript = path.join(os.tmpdir(), `krouter-backfill-${Date.now()}.sql`);
|
|
102
|
-
const sqlLines = ["BEGIN;"];
|
|
103
|
-
for (const row of rows) {
|
|
104
|
-
try {
|
|
105
|
-
const d = JSON.parse(row.data);
|
|
106
|
-
const um = d.providerResponse?.response?.usageMetadata || d.providerResponse?.usageMetadata;
|
|
107
|
-
if (!um) continue;
|
|
108
|
-
const promptTokens = um.promptTokenCount || 0;
|
|
109
|
-
const completionTokens = um.candidatesTokenCount || 0;
|
|
110
|
-
const reasoningTokens = um.thoughtsTokenCount;
|
|
111
|
-
if (promptTokens === 0 && completionTokens === 0) continue;
|
|
112
|
-
d.tokens = { ...(d.tokens || {}), prompt_tokens: promptTokens, completion_tokens: completionTokens };
|
|
113
|
-
if (reasoningTokens !== undefined) d.tokens.reasoning_tokens = reasoningTokens;
|
|
114
|
-
const escapedData = JSON.stringify(d).replace(/'/g, "''");
|
|
115
|
-
const escapedId = String(row.id).replace(/'/g, "''");
|
|
116
|
-
sqlLines.push(`UPDATE requestDetails SET data='${escapedData}' WHERE id='${escapedId}';`);
|
|
117
|
-
updated++;
|
|
118
|
-
} catch (e) {
|
|
119
|
-
console.error(` row ${row.id} skipped: ${e.message}`);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
sqlLines.push("COMMIT;");
|
|
123
|
-
fs.writeFileSync(tmpScript, sqlLines.join("\n"));
|
|
124
|
-
try {
|
|
125
|
-
execSync(`sqlite3 "${dbPath}" < "${tmpScript}"`, { stdio: ["ignore", "pipe", "pipe"] });
|
|
126
|
-
console.log(`Backfilled ${updated} rows. Usage page totals will now reflect real token spend.`);
|
|
127
|
-
} catch (e) {
|
|
128
|
-
console.error(`Failed to apply: ${e.message?.split("\n")?.[0] || e}`);
|
|
129
|
-
console.error(`SQL script left at ${tmpScript} for inspection.`);
|
|
130
|
-
process.exit(2);
|
|
131
|
-
}
|
|
132
|
-
try { fs.unlinkSync(tmpScript); } catch { /* ignore */ }
|
|
96
|
+
// Kept so any script that calls it keeps working, but it no longer does the work
|
|
97
|
+
// itself. It used to shell out to the `sqlite3` CLI, which is not present on a
|
|
98
|
+
// stock Windows install, so it exited with a raw Node stack there. The same
|
|
99
|
+
// backfill now runs unconditionally at every server start via
|
|
100
|
+
// autoBackfillTokensIfNeeded() in src/shared/services/initializeApp.js, in pure JS
|
|
101
|
+
// through the app's own DB adapter — no external binary, no shell quoting.
|
|
102
|
+
console.log("Token backfill now runs automatically every time kRouter starts.");
|
|
103
|
+
console.log("Nothing to do here — start kRouter normally and it will be applied.");
|
|
133
104
|
process.exit(0);
|
|
134
105
|
}
|
|
135
106
|
|
|
@@ -141,23 +112,49 @@ let skipUpdate = false;
|
|
|
141
112
|
let showLog = false;
|
|
142
113
|
let trayMode = false;
|
|
143
114
|
|
|
115
|
+
// `--flag=value` is the other half of the convention people expect; it used to fall
|
|
116
|
+
// through every branch and be dropped in silence, so `--port=3000` started the server
|
|
117
|
+
// on the default port instead.
|
|
118
|
+
function splitInlineValue(arg) {
|
|
119
|
+
const eq = arg.indexOf("=");
|
|
120
|
+
if (!arg.startsWith("-") || eq < 0) return null;
|
|
121
|
+
return { flag: arg.slice(0, eq), value: arg.slice(eq + 1) };
|
|
122
|
+
}
|
|
123
|
+
|
|
144
124
|
for (let i = 0; i < args.length; i++) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
125
|
+
const inline = splitInlineValue(args[i]);
|
|
126
|
+
const arg = inline ? inline.flag : args[i];
|
|
127
|
+
// Reading a value consumes the next argv entry only when it was not inlined.
|
|
128
|
+
const takeValue = () => (inline ? inline.value : args[++i]);
|
|
129
|
+
|
|
130
|
+
if (arg === "--port" || arg === "-p") {
|
|
131
|
+
const raw = takeValue();
|
|
132
|
+
// parseInt used to accept "3000abc" as 3000 and turn a typo, an empty value or a
|
|
133
|
+
// missing one into DEFAULT_PORT — which is then force-freed by killProcessOnPort.
|
|
134
|
+
// Silently starting on a different port than asked is worse than refusing.
|
|
135
|
+
const parsed = Number(raw);
|
|
136
|
+
if (raw === undefined || raw === "" || !Number.isInteger(parsed) || parsed < 1 || parsed > 65535) {
|
|
137
|
+
console.error(`Invalid --port value: ${raw === undefined || raw === "" ? "(missing)" : raw}. Expected an integer between 1 and 65535.`);
|
|
138
|
+
process.exit(2);
|
|
139
|
+
}
|
|
140
|
+
port = parsed;
|
|
141
|
+
} else if (arg === "--host" || arg === "-H") {
|
|
142
|
+
const raw = takeValue();
|
|
143
|
+
if (!raw) {
|
|
144
|
+
console.error("Invalid --host value: (missing). Expected a hostname or IP, e.g. 127.0.0.1.");
|
|
145
|
+
process.exit(2);
|
|
146
|
+
}
|
|
147
|
+
host = raw;
|
|
148
|
+
} else if (arg === "--no-browser" || arg === "-n") {
|
|
152
149
|
noBrowser = true;
|
|
153
|
-
} else if (
|
|
150
|
+
} else if (arg === "--log" || arg === "-l") {
|
|
154
151
|
showLog = true;
|
|
155
|
-
} else if (
|
|
152
|
+
} else if (arg === "--skip-update") {
|
|
156
153
|
skipUpdate = true;
|
|
157
|
-
} else if (
|
|
154
|
+
} else if (arg === "--tray" || arg === "-t") {
|
|
158
155
|
trayMode = true;
|
|
159
156
|
process.env.TRAY_MODE = "1";
|
|
160
|
-
} else if (
|
|
157
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
161
158
|
console.log(`
|
|
162
159
|
Usage: ${APP_NAME} [options]
|
|
163
160
|
|
|
@@ -172,9 +169,16 @@ Options:
|
|
|
172
169
|
-v, --version Show version
|
|
173
170
|
`);
|
|
174
171
|
process.exit(0);
|
|
175
|
-
} else if (
|
|
172
|
+
} else if (arg === "--version" || arg === "-v") {
|
|
176
173
|
console.log(pkg.version);
|
|
177
174
|
process.exit(0);
|
|
175
|
+
} else {
|
|
176
|
+
// No terminal branch existed, so anything unrecognised was dropped without a
|
|
177
|
+
// word: `krouter --prot 3000` or `krouter start` ran on the default port and
|
|
178
|
+
// looked like it had worked.
|
|
179
|
+
console.error(`Unknown option: ${args[i]}`);
|
|
180
|
+
console.error(`Run \`${APP_NAME} --help\` to see the available options.`);
|
|
181
|
+
process.exit(2);
|
|
178
182
|
}
|
|
179
183
|
}
|
|
180
184
|
|
|
@@ -278,58 +282,92 @@ function killAllAppProcesses(appPort) {
|
|
|
278
282
|
if (platform === "win32") {
|
|
279
283
|
// Windows: use WMI to get full CommandLine (tasklist /V doesn't include it)
|
|
280
284
|
try {
|
|
281
|
-
|
|
285
|
+
// Same ancestry rule as the POSIX branch below: a bare "next-server" match
|
|
286
|
+
// would take down every Next server on the machine, our own being
|
|
287
|
+
// indistinguishable from anyone else's by command line.
|
|
288
|
+
const psCmd = `powershell -NonInteractive -WindowStyle Hidden -Command "Get-WmiObject Win32_Process -Filter 'Name=\\"node.exe\\"' | Select-Object ProcessId,ParentProcessId,CommandLine | ConvertTo-Csv -NoTypeInformation"`;
|
|
282
289
|
const output = execSync(psCmd, {
|
|
283
290
|
encoding: "utf8",
|
|
284
291
|
windowsHide: true,
|
|
285
292
|
timeout: 5000
|
|
286
293
|
});
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
294
|
+
const rows = output.split("\n").slice(1).filter(l => l.trim()).map(line => {
|
|
295
|
+
const m = line.match(/^"(\d+)","(\d+)",(.*)$/);
|
|
296
|
+
return m ? { pid: m[1], ppid: m[2], cmd: (m[3] || "").toLowerCase() } : null;
|
|
297
|
+
}).filter(Boolean);
|
|
298
|
+
|
|
299
|
+
// Same rule as the POSIX branch: the invoked script, not any mention of it.
|
|
300
|
+
const isCliInvocation = (cmd) =>
|
|
301
|
+
/(^|[\s"'])[^\s"']*[\/\\]krouter[\/\\]cli\.js(\s|$|["'])/i.test(cmd) ||
|
|
302
|
+
/(^|[\s"'])[^\s"']*[\/\\]\.bin[\/\\]krouter(\s|$|["'])/i.test(cmd);
|
|
303
|
+
const roots = new Set(rows.filter(r => isCliInvocation(r.cmd)).map(r => r.pid));
|
|
304
|
+
const byParent = new Map();
|
|
305
|
+
for (const r of rows) {
|
|
306
|
+
if (!byParent.has(r.ppid)) byParent.set(r.ppid, []);
|
|
307
|
+
byParent.get(r.ppid).push(r.pid);
|
|
308
|
+
}
|
|
309
|
+
const doomed = new Set(roots);
|
|
310
|
+
const queue = [...roots];
|
|
311
|
+
while (queue.length) {
|
|
312
|
+
for (const child of byParent.get(queue.shift()) || []) {
|
|
313
|
+
if (!doomed.has(child)) { doomed.add(child); queue.push(child); }
|
|
302
314
|
}
|
|
303
|
-
}
|
|
315
|
+
}
|
|
316
|
+
for (const pid of doomed) {
|
|
317
|
+
if (pid !== process.pid.toString()) pids.push(pid);
|
|
318
|
+
}
|
|
304
319
|
} catch (e) {
|
|
305
320
|
// No processes found or error - continue
|
|
306
321
|
}
|
|
307
322
|
} else {
|
|
308
|
-
// macOS/Linux
|
|
323
|
+
// macOS/Linux. Identify our own processes by ancestry, never by name.
|
|
324
|
+
//
|
|
325
|
+
// Next renames its server process to a bare "next-server (v16.3.1)" -- no path,
|
|
326
|
+
// no project, nothing tying it to an app. Matching that string killed every
|
|
327
|
+
// Next server on the machine, so starting kRouter SIGKILLed a developer's
|
|
328
|
+
// unrelated dev server. The whitelist above it could not help: our own server
|
|
329
|
+
// matches by that string and nothing else, so the two are indistinguishable
|
|
330
|
+
// from the command line alone. Ancestry is the only thing that separates them.
|
|
309
331
|
try {
|
|
310
|
-
const output = execSync('ps
|
|
332
|
+
const output = execSync('ps -Ao pid,ppid,command 2>/dev/null', {
|
|
311
333
|
encoding: 'utf8',
|
|
312
334
|
timeout: 5000
|
|
313
335
|
});
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
336
|
+
const rows = output.split('\n').slice(1)
|
|
337
|
+
.map(l => l.trim().match(/^(\d+)\s+(\d+)\s+(.*)$/))
|
|
338
|
+
.filter(Boolean)
|
|
339
|
+
.map(m => ({ pid: m[1], ppid: m[2], cmd: m[3].toLowerCase() }));
|
|
340
|
+
|
|
341
|
+
// Roots: node processes whose *invoked script* is this CLI. Testing for
|
|
342
|
+
// "krouter" anywhere in the command line would promote any process that
|
|
343
|
+
// merely mentions the app -- a grep, an editor, a script taking the path as
|
|
344
|
+
// an argument -- into a root, and every descendant of a root is killed.
|
|
345
|
+
// Match the argv[1] path instead.
|
|
346
|
+
const isCliInvocation = (cmd) =>
|
|
347
|
+
/(^|[\s"'])[^\s"']*[\/\\]krouter[\/\\]cli\.js(\s|$|["'])/i.test(cmd) ||
|
|
348
|
+
/(^|[\s"'])[^\s"']*[\/\\]\.bin[\/\\]krouter(\s|$|["'])/i.test(cmd);
|
|
349
|
+
const roots = new Set(
|
|
350
|
+
rows.filter(r => r.cmd.includes("node") && isCliInvocation(r.cmd)).map(r => r.pid)
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
// Everything descended from a root, however deep. Next spawns its server as
|
|
354
|
+
// a child, so this reaches it without ever matching on "next-server".
|
|
355
|
+
const byParent = new Map();
|
|
356
|
+
for (const r of rows) {
|
|
357
|
+
if (!byParent.has(r.ppid)) byParent.set(r.ppid, []);
|
|
358
|
+
byParent.get(r.ppid).push(r.pid);
|
|
359
|
+
}
|
|
360
|
+
const doomed = new Set(roots);
|
|
361
|
+
const queue = [...roots];
|
|
362
|
+
while (queue.length) {
|
|
363
|
+
for (const child of byParent.get(queue.shift()) || []) {
|
|
364
|
+
if (!doomed.has(child)) { doomed.add(child); queue.push(child); }
|
|
331
365
|
}
|
|
332
|
-
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
for (const pid of doomed) {
|
|
369
|
+
if (pid !== process.pid.toString()) pids.push(pid);
|
|
370
|
+
}
|
|
333
371
|
} catch (e) {
|
|
334
372
|
// No processes found or error - continue
|
|
335
373
|
}
|
|
@@ -408,6 +446,42 @@ function killProxyByPidFile() {
|
|
|
408
446
|
} catch { }
|
|
409
447
|
}
|
|
410
448
|
|
|
449
|
+
// Is this PID one of our own server processes?
|
|
450
|
+
//
|
|
451
|
+
// killProcessOnPort used to kill-9 whatever `lsof -ti:PORT` returned, with no check on
|
|
452
|
+
// what it was. `krouter --port 3000` destroyed the user's own app on 3000 and
|
|
453
|
+
// `--port 5432` took out their Postgres, silently and before anything was printed.
|
|
454
|
+
//
|
|
455
|
+
// An orphaned kRouter server is the hard case: its parent CLI is gone, so ancestry
|
|
456
|
+
// cannot reach it, and Next has renamed it to a bare "next-server (vX)", so the command
|
|
457
|
+
// line says nothing either. spawnServer pins cwd to standaloneDir, and that survives
|
|
458
|
+
// both — it is the one durable marker of "this install's server".
|
|
459
|
+
function isOwnServerPid(pid) {
|
|
460
|
+
try {
|
|
461
|
+
const mine = fs.realpathSync(standaloneDir);
|
|
462
|
+
if (process.platform === "linux") {
|
|
463
|
+
return fs.realpathSync(`/proc/${pid}/cwd`) === mine;
|
|
464
|
+
}
|
|
465
|
+
if (process.platform === "darwin") {
|
|
466
|
+
const out = execSync(`lsof -a -p ${pid} -d cwd -Fn 2>/dev/null`, {
|
|
467
|
+
encoding: "utf8", timeout: 3000, stdio: ["pipe", "pipe", "ignore"],
|
|
468
|
+
});
|
|
469
|
+
const line = out.split("\n").find((l) => l.startsWith("n"));
|
|
470
|
+
return !!line && fs.realpathSync(line.slice(1).trim()) === mine;
|
|
471
|
+
}
|
|
472
|
+
if (process.platform === "win32") {
|
|
473
|
+
// No cheap cwd read on Windows. Fall back to the executable path, which for our
|
|
474
|
+
// server points inside the package directory.
|
|
475
|
+
const out = execSync(
|
|
476
|
+
`powershell -NonInteractive -WindowStyle Hidden -Command "(Get-Process -Id ${pid} -ErrorAction SilentlyContinue).Path"`,
|
|
477
|
+
{ encoding: "utf8", windowsHide: true, timeout: 4000 }
|
|
478
|
+
).trim();
|
|
479
|
+
return !!out && out.toLowerCase().includes("krouter");
|
|
480
|
+
}
|
|
481
|
+
} catch { /* process gone, or no permission to inspect it — treat as not ours */ }
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
|
|
411
485
|
// Kill ALL processes listening on the given port. Returns true if any were killed.
|
|
412
486
|
// Previous version: on Windows only killed the first PID from netstat, missing
|
|
413
487
|
// parent/child pairs (next-server has a watcher + worker). Now sweeps all PIDs.
|
|
@@ -417,6 +491,7 @@ function killProcessOnPort(port) {
|
|
|
417
491
|
try {
|
|
418
492
|
const platform = process.platform;
|
|
419
493
|
const pidsToKill = new Set();
|
|
494
|
+
const foreign = [];
|
|
420
495
|
|
|
421
496
|
if (platform === "win32") {
|
|
422
497
|
try {
|
|
@@ -428,7 +503,9 @@ function killProcessOnPort(port) {
|
|
|
428
503
|
}).trim();
|
|
429
504
|
output.split('\n').filter(l => l.includes('LISTENING')).forEach(line => {
|
|
430
505
|
const pid = line.trim().split(/\s+/).pop();
|
|
431
|
-
if (pid
|
|
506
|
+
if (!pid || !/^\d+$/.test(pid) || pid === String(process.pid)) return;
|
|
507
|
+
if (isOwnServerPid(pid)) pidsToKill.add(pid);
|
|
508
|
+
else foreign.push(pid);
|
|
432
509
|
});
|
|
433
510
|
for (const pid of pidsToKill) {
|
|
434
511
|
try {
|
|
@@ -447,7 +524,11 @@ function killProcessOnPort(port) {
|
|
|
447
524
|
stdio: ['pipe', 'pipe', 'ignore']
|
|
448
525
|
}).trim();
|
|
449
526
|
pidOutput.split('\n').filter(Boolean).forEach(pid => {
|
|
450
|
-
if (pid
|
|
527
|
+
if (pid === String(process.pid)) return;
|
|
528
|
+
// Only ever kill our own server. Anything else holding the port is the
|
|
529
|
+
// user's — say so and let them choose the port, rather than killing it.
|
|
530
|
+
if (isOwnServerPid(pid)) pidsToKill.add(pid);
|
|
531
|
+
else foreign.push(pid);
|
|
451
532
|
});
|
|
452
533
|
for (const pid of pidsToKill) {
|
|
453
534
|
try {
|
|
@@ -460,6 +541,26 @@ function killProcessOnPort(port) {
|
|
|
460
541
|
}
|
|
461
542
|
}
|
|
462
543
|
|
|
544
|
+
// Something that is not ours is holding the port. Say so and name it, instead
|
|
545
|
+
// of failing to start with no explanation -- the caller only learns "port busy".
|
|
546
|
+
if (foreign.length) {
|
|
547
|
+
const described = foreign.map((pid) => {
|
|
548
|
+
try {
|
|
549
|
+
const name = platform === "win32"
|
|
550
|
+
? execSync(`powershell -NonInteractive -WindowStyle Hidden -Command "(Get-Process -Id ${pid} -ErrorAction SilentlyContinue).ProcessName"`,
|
|
551
|
+
{ encoding: "utf8", windowsHide: true, timeout: 4000 }).trim()
|
|
552
|
+
: execSync(`ps -p ${pid} -o comm= 2>/dev/null`, { encoding: "utf8", timeout: 3000 }).trim();
|
|
553
|
+
return name ? `${name} (pid ${pid})` : `pid ${pid}`;
|
|
554
|
+
} catch { return `pid ${pid}`; }
|
|
555
|
+
});
|
|
556
|
+
console.error(`\n⚠️ Port ${port} is held by ${described.join(", ")} — not kRouter.`);
|
|
557
|
+
console.error(` Refusing to kill it. Start kRouter on another port, e.g. --port ${port + 1}.\n`);
|
|
558
|
+
// Exit rather than fall through: we deliberately did not free the port, so
|
|
559
|
+
// every subsequent bind attempt fails. The retry path treats EADDRINUSE as
|
|
560
|
+
// transient and would spin here forever.
|
|
561
|
+
process.exit(1);
|
|
562
|
+
}
|
|
563
|
+
|
|
463
564
|
// Wait for kernel to release the socket (Windows is slow here, give it 1s).
|
|
464
565
|
// Then verify the port is actually free — if not, surface the result so
|
|
465
566
|
// the caller can decide whether to retry or fail-fast.
|
|
@@ -648,6 +749,10 @@ function startServer(latestVersion) {
|
|
|
648
749
|
const lanIp = getLanIp();
|
|
649
750
|
if (lanIp) {
|
|
650
751
|
console.log(`\x1b[33m⚠ Network-exposed: reachable at http://${lanIp}:${port} (bound 0.0.0.0). Use --host 127.0.0.1 for local-only.\x1b[0m`);
|
|
752
|
+
// Remote callers already need an API key for /v1/* and a login for the
|
|
753
|
+
// dashboard, so the exposure is bounded. Say so, rather than leaving the
|
|
754
|
+
// reader to guess whether their provider quota is reachable.
|
|
755
|
+
console.log(`\x1b[33m Remote callers still need an API key for /v1/* and a login for the dashboard.\x1b[0m`);
|
|
651
756
|
}
|
|
652
757
|
}
|
|
653
758
|
|
package/package.json
CHANGED
package/src/cli/tray/tray.ps1
CHANGED
|
@@ -48,26 +48,50 @@ function Set-Tooltip($text) {
|
|
|
48
48
|
$script:notifyIcon.Text = $text
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
#
|
|
51
|
+
# stdin is polled from a System.Windows.Forms.Timer, whose Tick runs on the very
|
|
52
|
+
# thread Application::Run() pumps. The previous loop guarded on [Console]::In.Peek(),
|
|
53
|
+
# which does not return -1 on an open-but-idle pipe -- it blocks until the next byte
|
|
54
|
+
# arrives. So the first tick after the startup burst never returned, the message pump
|
|
55
|
+
# stopped, and the tray icon appeared but ignored every click: no menu, no Quit.
|
|
56
|
+
#
|
|
57
|
+
# [Console]::In is a SyncTextReader whose ReadLineAsync() is synchronous too, so it
|
|
58
|
+
# cannot be used either. Read the raw handle through our own StreamReader and poll a
|
|
59
|
+
# genuinely async task, so the Tick handler always returns immediately.
|
|
60
|
+
$script:stdin = New-Object System.IO.StreamReader([Console]::OpenStandardInput(), [System.Text.Encoding]::UTF8)
|
|
61
|
+
$script:pending = $null
|
|
62
|
+
|
|
52
63
|
$script:timer = New-Object System.Windows.Forms.Timer
|
|
53
64
|
$script:timer.Interval = 100
|
|
54
65
|
$script:timer.Add_Tick({
|
|
55
66
|
try {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
$
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
if ($null -eq $script:pending) { $script:pending = $script:stdin.ReadLineAsync() }
|
|
68
|
+
while ($script:pending.IsCompleted) {
|
|
69
|
+
$line = $script:pending.Result
|
|
70
|
+
$script:pending = $null
|
|
71
|
+
if ($null -eq $line) {
|
|
72
|
+
# EOF: the Node parent is gone. Exit instead of lingering as a dead icon the
|
|
73
|
+
# user can only clear through Task Manager.
|
|
74
|
+
$script:notifyIcon.Visible = $false
|
|
75
|
+
$script:notifyIcon.Dispose()
|
|
76
|
+
[System.Windows.Forms.Application]::Exit()
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
if (-not [string]::IsNullOrWhiteSpace($line)) {
|
|
80
|
+
$cmd = $line | ConvertFrom-Json
|
|
81
|
+
switch ($cmd.action) {
|
|
82
|
+
"add-item" { Add-MenuItem $cmd.index $cmd.title $cmd.enabled }
|
|
83
|
+
"update-item" { Update-MenuItem $cmd.index $cmd.title $cmd.enabled }
|
|
84
|
+
"set-tooltip" { Set-Tooltip $cmd.text }
|
|
85
|
+
"ready" { Write-Event @{ type = "ready" } }
|
|
86
|
+
"kill" {
|
|
87
|
+
$script:notifyIcon.Visible = $false
|
|
88
|
+
$script:notifyIcon.Dispose()
|
|
89
|
+
[System.Windows.Forms.Application]::Exit()
|
|
90
|
+
return
|
|
91
|
+
}
|
|
69
92
|
}
|
|
70
93
|
}
|
|
94
|
+
$script:pending = $script:stdin.ReadLineAsync()
|
|
71
95
|
}
|
|
72
96
|
} catch {
|
|
73
97
|
Write-Event @{ type = "error"; message = $_.Exception.Message }
|
package/src/cli/utils/input.js
CHANGED
|
@@ -157,7 +157,19 @@ async function selectMenu(title, items, defaultIndex = 0, subtitle = "", headerC
|
|
|
157
157
|
if (key.name === "down") return move(1);
|
|
158
158
|
if (key.name === "return") { cleanup(); resolve(selectedIndex); return; }
|
|
159
159
|
if (key.name === "escape") { cleanup(); resolve(-1); return; }
|
|
160
|
-
if (key.ctrl && key.name === "c") {
|
|
160
|
+
if (key.ctrl && key.name === "c") {
|
|
161
|
+
cleanup();
|
|
162
|
+
// Raw mode clears termios ISIG, so Ctrl-C arrives here as an ordinary
|
|
163
|
+
// keypress rather than as SIGINT. Exiting straight from here skipped
|
|
164
|
+
// cli.js's SIGINT handler -- the only thing that kills the detached server
|
|
165
|
+
// child, the privileged MITM process and any tunnel -- so quitting from the
|
|
166
|
+
// menu left all three running with no UI left to stop them. Restore cooked
|
|
167
|
+
// mode and re-raise the signal so that handler actually runs.
|
|
168
|
+
try { process.stdin.setRawMode(false); } catch {}
|
|
169
|
+
rawPrimed = false;
|
|
170
|
+
process.kill(process.pid, "SIGINT");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
161
173
|
};
|
|
162
174
|
|
|
163
175
|
process.stdin.on("keypress", onKeypress);
|