cartethyia 2.5.3 → 2.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard/assets/{BannedPage-hfCzi-Ux.js → BannedPage-C2orBsI2.js} +1 -1
- package/dist/dashboard/assets/BannedPage-C2orBsI2.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-DUcZ6pMB.js +1 -0
- package/dist/dashboard/assets/CliToolDetailPage-DUcZ6pMB.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-DEDyKBlC.js → CliToolsPage-BV6pxVQo.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-BV6pxVQo.js.gz +0 -0
- package/dist/dashboard/assets/{CombosPage-CfuYiQ8Z.js → CombosPage-Bsan4679.js} +1 -1
- package/dist/dashboard/assets/CombosPage-Bsan4679.js.gz +0 -0
- package/dist/dashboard/assets/{ConsoleLogPage-bsLuZmYH.js → ConsoleLogPage-CW-wPmJ6.js} +1 -1
- package/dist/dashboard/assets/ConsoleLogPage-CW-wPmJ6.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-_UWhwziJ.js → CustomizationPage-0p8uX7vB.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-0p8uX7vB.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-BjqSMfko.js +1 -0
- package/dist/dashboard/assets/HealthEventsModal-BjqSMfko.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-DDVIfZGW.js → LoginPage-BvzCx8Kr.js} +1 -1
- package/dist/dashboard/assets/LoginPage-BvzCx8Kr.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-CWkTUtpX.js → ModelPicker-BY1aKEkP.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-BY1aKEkP.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-DOQpy1y0.js +1 -0
- package/dist/dashboard/assets/OverviewPage-DOQpy1y0.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-ecxyUMzt.js +3 -0
- package/dist/dashboard/assets/ProviderDetailPage-ecxyUMzt.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-Js9jUPSb.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-Js9jUPSb.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-J3TBi3Kx.js +7 -0
- package/dist/dashboard/assets/ProxyPage-J3TBi3Kx.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-C1gZS6xr.js +1 -0
- package/dist/dashboard/assets/QuotaPage-C1gZS6xr.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CS86ho5X.js +1 -0
- package/dist/dashboard/assets/SettingsPage-CS86ho5X.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-D6pmQ86L.js → SetupPage-DDbMQsoo.js} +1 -1
- package/dist/dashboard/assets/SetupPage-DDbMQsoo.js.gz +0 -0
- package/dist/dashboard/assets/{SortableList-DWvKiuSl.js → SortableList-CB3Z7VTf.js} +1 -1
- package/dist/dashboard/assets/SortableList-CB3Z7VTf.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-CmkUrgdj.js → StudioPage-D95UCPHI.js} +3 -3
- package/dist/dashboard/assets/StudioPage-D95UCPHI.js.gz +0 -0
- package/dist/dashboard/assets/{UsagePage-B47uOydr.js → UsagePage-Cnae9SWA.js} +13 -13
- package/dist/dashboard/assets/UsagePage-Cnae9SWA.js.gz +0 -0
- package/dist/dashboard/assets/{api-keys-uNywYlfv.js → api-keys-VY68Mhd1.js} +1 -1
- package/dist/dashboard/assets/api-keys-VY68Mhd1.js.gz +0 -0
- package/dist/dashboard/assets/app-COlK95oi.css +2 -0
- package/dist/dashboard/assets/app-COlK95oi.css.gz +0 -0
- package/dist/dashboard/assets/{assert-NHwYq95t.js → assert-Chi7pCnt.js} +1 -1
- package/dist/dashboard/assets/assert-Chi7pCnt.js.gz +0 -0
- package/dist/dashboard/assets/{badge-6uzDDvqs.js → badge-D4pQapKj.js} +1 -1
- package/dist/dashboard/assets/badge-D4pQapKj.js.gz +0 -0
- package/dist/dashboard/assets/{banner-4_WNg2WZ.js → banner-DH6cg-_B.js} +1 -1
- package/dist/dashboard/assets/banner-DH6cg-_B.js.gz +0 -0
- package/dist/dashboard/assets/{card--AtFedAq.js → card-BKqlUOe4.js} +1 -1
- package/dist/dashboard/assets/card-BKqlUOe4.js.gz +0 -0
- package/dist/dashboard/assets/{cli-tools-B3e7dx3N.js → cli-tools-fTgljTGA.js} +1 -1
- package/dist/dashboard/assets/cli-tools-fTgljTGA.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-NreUx6c8.js → clipboard-button-D5Ys_sM0.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-D5Ys_sM0.js.gz +0 -0
- package/dist/dashboard/assets/database-Dz9N3zGd.js +1 -0
- package/dist/dashboard/assets/database-Dz9N3zGd.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-BtpsJU98.js → dialog-BYj-8WuK.js} +1 -1
- package/dist/dashboard/assets/dialog-BYj-8WuK.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-WwwtzihF.js → drawer-CmXIZ6H1.js} +1 -1
- package/dist/dashboard/assets/drawer-CmXIZ6H1.js.gz +0 -0
- package/dist/dashboard/assets/entry-CBg5zeu8.js +1 -0
- package/dist/dashboard/assets/entry-CBg5zeu8.js.gz +0 -0
- package/dist/dashboard/assets/entry-CQBr6U9c.js +1 -0
- package/dist/dashboard/assets/entry-CQBr6U9c.js.gz +0 -0
- package/dist/dashboard/assets/entry-CgdSAzEV.js +4 -0
- package/dist/dashboard/assets/entry-CgdSAzEV.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-D_eM3IgG.js → github-badge-BlptL8Uf.js} +1 -1
- package/dist/dashboard/assets/github-badge-BlptL8Uf.js.gz +0 -0
- package/dist/dashboard/assets/{index-BydyKaDz.js → index-js6TJvdr.js} +2 -2
- package/dist/dashboard/assets/index-js6TJvdr.js.gz +0 -0
- package/dist/dashboard/assets/{inline-BcNGF8Gr.js → inline-DUWDSmDV.js} +1 -1
- package/dist/dashboard/assets/inline-DUWDSmDV.js.gz +0 -0
- package/dist/dashboard/assets/{input-BG41et9G.js → input-LVjgZq4f.js} +1 -1
- package/dist/dashboard/assets/input-LVjgZq4f.js.gz +0 -0
- package/dist/dashboard/assets/{layout-C8mer_Ak.js → layout-CPfxpsfy.js} +1 -1
- package/dist/dashboard/assets/layout-CPfxpsfy.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-Gh_W4OR_.js → list-row-DupvLfDx.js} +1 -1
- package/dist/dashboard/assets/list-row-DupvLfDx.js.gz +0 -0
- package/dist/dashboard/assets/{live-BJGYRBnR.js → live-C4pEJUqI.js} +1 -1
- package/dist/dashboard/assets/live-C4pEJUqI.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-BRiuufkB.js +1 -0
- package/dist/dashboard/assets/model-bans-BRiuufkB.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-BkoLM5Ba.js → mutation-B4ROwk8L.js} +1 -1
- package/dist/dashboard/assets/mutation-B4ROwk8L.js.gz +0 -0
- package/dist/dashboard/assets/numbers-YNcHvRY7.js +2 -0
- package/dist/dashboard/assets/numbers-YNcHvRY7.js.gz +0 -0
- package/dist/dashboard/assets/{query-keys-D7wX2vM5.js → query-keys-gmjzC3RS.js} +1 -1
- package/dist/dashboard/assets/{query-keys-D7wX2vM5.js.gz → query-keys-gmjzC3RS.js.gz} +0 -0
- package/dist/dashboard/assets/{routing-CcusqXA7.js → routing-C7tBT5o-.js} +1 -1
- package/dist/dashboard/assets/routing-C7tBT5o-.js.gz +0 -0
- package/dist/dashboard/assets/{select-BO6h8yNv.js → select-WUCXorXw.js} +2 -2
- package/dist/dashboard/assets/select-WUCXorXw.js.gz +0 -0
- package/dist/dashboard/assets/{settings-mpmXTgUa.js → settings-C_zKl1GS.js} +1 -1
- package/dist/dashboard/assets/settings-C_zKl1GS.js.gz +0 -0
- package/dist/dashboard/assets/{stack-DwLmjUFK.js → stack-_3O0F8Xn.js} +1 -1
- package/dist/dashboard/assets/stack-_3O0F8Xn.js.gz +0 -0
- package/dist/dashboard/assets/{state-DYdQmdAl.js → state-BgTxHcJS.js} +1 -1
- package/dist/dashboard/assets/state-BgTxHcJS.js.gz +0 -0
- package/dist/dashboard/assets/switch-DEjTtOWf.js +1 -0
- package/dist/dashboard/assets/switch-DEjTtOWf.js.gz +0 -0
- package/dist/dashboard/assets/terminal-0_IjPWTk.js +1 -0
- package/dist/dashboard/assets/terminal-0_IjPWTk.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-w4u4CVue.js → useMutation-BWSC0UAS.js} +1 -1
- package/dist/dashboard/assets/useMutation-BWSC0UAS.js.gz +0 -0
- package/dist/dashboard/assets/zap-C4EeVW4q.js +1 -0
- package/dist/dashboard/assets/zap-C4EeVW4q.js.gz +0 -0
- package/dist/dashboard/donation/qris-risun-marke.png +0 -0
- package/dist/dashboard/index.html +1 -1
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +54 -54
- package/package.json +1 -1
- package/scripts/cli/autostart.ts +237 -0
- package/scripts/cli/command/console-menu.ts +4 -8
- package/scripts/cli/command/update.ts +27 -10
- package/scripts/cli/main.ts +28 -1
- package/src/boot/app.ts +693 -693
- package/src/boot/dependencies.ts +646 -616
- package/src/config/spec.ts +55 -0
- package/src/config/telemetry.ts +46 -0
- package/src/console/api-keys/bucket-spend.ts +15 -4
- package/src/console/backup/contracts.ts +15 -2
- package/src/console/console-router.ts +8 -0
- package/src/console/data-management/contracts.ts +93 -0
- package/src/console/data-management/operations.ts +229 -0
- package/src/console/data-management/routes.ts +104 -0
- package/src/console/domain-registration.ts +39 -0
- package/src/console/observability/contracts.ts +524 -485
- package/src/console/observability/store.ts +1115 -1018
- package/src/console/providers/catalog/contracts.ts +6 -0
- package/src/console/providers/catalog/provider-operations.ts +20 -0
- package/src/console/providers/catalog/routes.ts +7 -0
- package/src/console/providers/catalog/store.ts +22 -1
- package/src/console/quota/account-quota-shared.ts +52 -39
- package/src/console/quota/refresh.ts +441 -429
- package/src/console/routing/pools/import-parse.ts +206 -0
- package/src/console/routing/pools/operations.ts +543 -501
- package/src/console/routing/pools/routes.ts +181 -164
- package/src/console/settings/contracts.ts +37 -0
- package/src/console/settings/store.ts +51 -0
- package/src/console/updates/routes.ts +16 -0
- package/src/main.ts +10 -0
- package/src/observability/event-compaction.ts +315 -0
- package/src/observability/event-day-index.ts +442 -0
- package/src/observability/event-log.ts +152 -3
- package/src/observability/payload-capture.ts +8 -1
- package/src/observability/payload-store.ts +440 -376
- package/src/persistence/health-event-flush.ts +36 -0
- package/src/persistence/schema.ts +1402 -1360
- package/src/persistence/stores/telemetry-store.ts +237 -214
- package/src/protocol/codecs.ts +1 -2
- package/src/protocol/image-clamp.ts +19 -1
- package/src/protocol/registry.ts +8 -0
- package/src/protocol/request/gemini.ts +9 -2
- package/src/protocol/request/messages.ts +14 -2
- package/src/providers/adapters/compatible-adapter.ts +3 -0
- package/src/providers/bundled-discovery-providers.ts +122 -119
- package/src/providers/configured-openai-providers.ts +136 -134
- package/src/providers/default-registry.ts +5 -4
- package/src/providers/discovery/openai-model-discovery.ts +5 -0
- package/src/providers/discovery/openrouter-free-roster.ts +15 -17
- package/src/providers/integrations/cline/cline-quota.ts +132 -125
- package/src/providers/integrations/codex/codex-headers.ts +25 -39
- package/src/providers/integrations/codex/codex.ts +2 -29
- package/src/providers/integrations/cursor/cursor-quota.ts +310 -0
- package/src/providers/integrations/cursor/cursor-request.ts +616 -471
- package/src/providers/integrations/cursor/cursor-session-manager.ts +319 -281
- package/src/providers/integrations/cursor/cursor.ts +1485 -960
- package/src/providers/integrations/cursor/protocol/messages.ts +25 -0
- package/src/providers/integrations/factory/factory.ts +8 -1
- package/src/providers/integrations/gemini.ts +6 -1
- package/src/providers/integrations/grok/grok-quota.ts +279 -177
- package/src/providers/integrations/grok/grok-ratelimit-store.ts +73 -0
- package/src/providers/integrations/grok/grok-ratelimit.ts +218 -0
- package/src/providers/integrations/opencode/provider.ts +12 -13
- package/src/providers/integrations/qoder/qoder-quota.ts +192 -0
- package/src/providers/integrations/trae/trae-quota.ts +384 -0
- package/src/providers/operations/account-health-service.ts +1523 -1480
- package/src/providers/provider-contracts.ts +7 -0
- package/src/providers/provider-metadata.ts +6 -0
- package/src/providers/quota/quota-support.ts +8 -0
- package/src/security/api-key-auth.ts +504 -494
- package/src/transport/dispatch/generation.ts +6 -0
- package/src/transport/dispatch/proxy-request.ts +24 -1
- package/src/transport/dispatch/ratelimit-capture.ts +37 -0
- package/src/transport/dispatch/streaming/stream.ts +14 -0
- package/src/transport/dispatch/upstream.ts +9 -0
- package/src/transport/request/preparer.ts +7 -6
- package/src/transport/request/state.ts +9 -0
- package/src/transport/request/tenant-preferences.ts +60 -0
- package/src/transport/routing/route-catalog.ts +58 -10
- package/dist/dashboard/assets/BannedPage-hfCzi-Ux.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-DLGqYEwI.js +0 -1
- package/dist/dashboard/assets/CliToolDetailPage-DLGqYEwI.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-DEDyKBlC.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-CfuYiQ8Z.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-bsLuZmYH.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-_UWhwziJ.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-Cjfc5WFS.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-Cjfc5WFS.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-DDVIfZGW.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-CWkTUtpX.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-B53YYMng.js +0 -1
- package/dist/dashboard/assets/OverviewPage-B53YYMng.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-B0KaAQf0.js +0 -3
- package/dist/dashboard/assets/ProviderDetailPage-B0KaAQf0.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-Dx31DgIO.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-Dx31DgIO.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-BpnR4kXT.js +0 -7
- package/dist/dashboard/assets/ProxyPage-BpnR4kXT.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-BpOQCnun.js +0 -1
- package/dist/dashboard/assets/QuotaPage-BpOQCnun.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-DV1eo2J_.js +0 -1
- package/dist/dashboard/assets/SettingsPage-DV1eo2J_.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-D6pmQ86L.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-DWvKiuSl.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-CmkUrgdj.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-B47uOydr.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-uNywYlfv.js.gz +0 -0
- package/dist/dashboard/assets/app-DxivpfYG.css +0 -2
- package/dist/dashboard/assets/app-DxivpfYG.css.gz +0 -0
- package/dist/dashboard/assets/assert-NHwYq95t.js.gz +0 -0
- package/dist/dashboard/assets/badge-6uzDDvqs.js.gz +0 -0
- package/dist/dashboard/assets/banner-4_WNg2WZ.js.gz +0 -0
- package/dist/dashboard/assets/card--AtFedAq.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-B3e7dx3N.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-NreUx6c8.js.gz +0 -0
- package/dist/dashboard/assets/dialog-BtpsJU98.js.gz +0 -0
- package/dist/dashboard/assets/download-A0SW9OCW.js +0 -1
- package/dist/dashboard/assets/download-A0SW9OCW.js.gz +0 -0
- package/dist/dashboard/assets/drawer-WwwtzihF.js.gz +0 -0
- package/dist/dashboard/assets/entry-CkryrIea.js +0 -4
- package/dist/dashboard/assets/entry-CkryrIea.js.gz +0 -0
- package/dist/dashboard/assets/entry-TJIye_jT.js +0 -1
- package/dist/dashboard/assets/entry-TJIye_jT.js.gz +0 -0
- package/dist/dashboard/assets/entry-jy9_4-Ke.js +0 -1
- package/dist/dashboard/assets/entry-jy9_4-Ke.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-D_eM3IgG.js.gz +0 -0
- package/dist/dashboard/assets/index-BydyKaDz.js.gz +0 -0
- package/dist/dashboard/assets/inline-BcNGF8Gr.js.gz +0 -0
- package/dist/dashboard/assets/input-BG41et9G.js.gz +0 -0
- package/dist/dashboard/assets/layout-C8mer_Ak.js.gz +0 -0
- package/dist/dashboard/assets/list-row-Gh_W4OR_.js.gz +0 -0
- package/dist/dashboard/assets/live-BJGYRBnR.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-DeVLDA7I.js +0 -1
- package/dist/dashboard/assets/model-bans-DeVLDA7I.js.gz +0 -0
- package/dist/dashboard/assets/mutation-BkoLM5Ba.js.gz +0 -0
- package/dist/dashboard/assets/numbers-Bs4LOOuf.js +0 -2
- package/dist/dashboard/assets/numbers-Bs4LOOuf.js.gz +0 -0
- package/dist/dashboard/assets/routing-CcusqXA7.js.gz +0 -0
- package/dist/dashboard/assets/select-BO6h8yNv.js.gz +0 -0
- package/dist/dashboard/assets/settings-mpmXTgUa.js.gz +0 -0
- package/dist/dashboard/assets/sparkles-BRaRUxAU.js +0 -1
- package/dist/dashboard/assets/sparkles-BRaRUxAU.js.gz +0 -0
- package/dist/dashboard/assets/stack-DwLmjUFK.js.gz +0 -0
- package/dist/dashboard/assets/state-DYdQmdAl.js.gz +0 -0
- package/dist/dashboard/assets/switch-CidSfbG7.js +0 -1
- package/dist/dashboard/assets/switch-CidSfbG7.js.gz +0 -0
- package/dist/dashboard/assets/terminal-Bd4ee8TA.js +0 -1
- package/dist/dashboard/assets/terminal-Bd4ee8TA.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-w4u4CVue.js.gz +0 -0
- /package/dist/dashboard/assets/{app-CafWtVXA.js → app-DCQZRmHY.js} +0 -0
- /package/dist/dashboard/assets/{app-CafWtVXA.js.gz → app-DCQZRmHY.js.gz} +0 -0
|
@@ -2,72 +2,72 @@
|
|
|
2
2
|
"count": 114,
|
|
3
3
|
"assets": [
|
|
4
4
|
"assets\\AccountCooldown-Bjo92Qat.js",
|
|
5
|
-
"assets\\BannedPage-
|
|
6
|
-
"assets\\CliToolDetailPage-
|
|
7
|
-
"assets\\CliToolsPage-
|
|
8
|
-
"assets\\CombosPage-
|
|
9
|
-
"assets\\ConsoleLogPage-
|
|
10
|
-
"assets\\CustomizationPage-
|
|
11
|
-
"assets\\HealthEventsModal-
|
|
12
|
-
"assets\\LoginPage-
|
|
13
|
-
"assets\\ModelPicker-
|
|
14
|
-
"assets\\OverviewPage-
|
|
15
|
-
"assets\\ProviderDetailPage-
|
|
5
|
+
"assets\\BannedPage-C2orBsI2.js",
|
|
6
|
+
"assets\\CliToolDetailPage-DUcZ6pMB.js",
|
|
7
|
+
"assets\\CliToolsPage-BV6pxVQo.js",
|
|
8
|
+
"assets\\CombosPage-Bsan4679.js",
|
|
9
|
+
"assets\\ConsoleLogPage-CW-wPmJ6.js",
|
|
10
|
+
"assets\\CustomizationPage-0p8uX7vB.js",
|
|
11
|
+
"assets\\HealthEventsModal-BjqSMfko.js",
|
|
12
|
+
"assets\\LoginPage-BvzCx8Kr.js",
|
|
13
|
+
"assets\\ModelPicker-BY1aKEkP.js",
|
|
14
|
+
"assets\\OverviewPage-DOQpy1y0.js",
|
|
15
|
+
"assets\\ProviderDetailPage-ecxyUMzt.js",
|
|
16
16
|
"assets\\ProviderIcon-CmfzxpVM.js",
|
|
17
|
-
"assets\\ProvidersPage-
|
|
18
|
-
"assets\\ProxyPage-
|
|
19
|
-
"assets\\QuotaPage-
|
|
20
|
-
"assets\\SettingsPage-
|
|
21
|
-
"assets\\SetupPage-
|
|
22
|
-
"assets\\SortableList-
|
|
23
|
-
"assets\\StudioPage-
|
|
17
|
+
"assets\\ProvidersPage-Js9jUPSb.js",
|
|
18
|
+
"assets\\ProxyPage-J3TBi3Kx.js",
|
|
19
|
+
"assets\\QuotaPage-C1gZS6xr.js",
|
|
20
|
+
"assets\\SettingsPage-CS86ho5X.js",
|
|
21
|
+
"assets\\SetupPage-DDbMQsoo.js",
|
|
22
|
+
"assets\\SortableList-CB3Z7VTf.js",
|
|
23
|
+
"assets\\StudioPage-D95UCPHI.js",
|
|
24
24
|
"assets\\ToolIcon-K1ckcDKg.js",
|
|
25
|
-
"assets\\UsagePage-
|
|
26
|
-
"assets\\api-keys-
|
|
27
|
-
"assets\\app-
|
|
28
|
-
"assets\\app-
|
|
25
|
+
"assets\\UsagePage-Cnae9SWA.js",
|
|
26
|
+
"assets\\api-keys-VY68Mhd1.js",
|
|
27
|
+
"assets\\app-COlK95oi.css",
|
|
28
|
+
"assets\\app-DCQZRmHY.js",
|
|
29
29
|
"assets\\arrow-left-CpBxkoxI.js",
|
|
30
30
|
"assets\\arrow-right-Dl5yKnp8.js",
|
|
31
|
-
"assets\\assert-
|
|
31
|
+
"assets\\assert-Chi7pCnt.js",
|
|
32
32
|
"assets\\backup-file-gdKIlg8U.js",
|
|
33
|
-
"assets\\badge-
|
|
34
|
-
"assets\\banner-
|
|
33
|
+
"assets\\badge-D4pQapKj.js",
|
|
34
|
+
"assets\\banner-DH6cg-_B.js",
|
|
35
35
|
"assets\\brain-Cwed_72z.js",
|
|
36
|
-
"assets\\card
|
|
36
|
+
"assets\\card-BKqlUOe4.js",
|
|
37
37
|
"assets\\chevron-right-BXIy5l3h.js",
|
|
38
38
|
"assets\\circle-alert-CntYHV5v.js",
|
|
39
39
|
"assets\\circle-check-BU3v_mFW.js",
|
|
40
|
-
"assets\\cli-tools-
|
|
41
|
-
"assets\\clipboard-button-
|
|
40
|
+
"assets\\cli-tools-fTgljTGA.js",
|
|
41
|
+
"assets\\clipboard-button-D5Ys_sM0.js",
|
|
42
42
|
"assets\\cog-CdWhsajs.js",
|
|
43
|
-
"assets\\
|
|
43
|
+
"assets\\database-Dz9N3zGd.js",
|
|
44
|
+
"assets\\dialog-BYj-8WuK.js",
|
|
44
45
|
"assets\\dialog-actions-B1axpEg7.js",
|
|
45
|
-
"assets\\download-A0SW9OCW.js",
|
|
46
46
|
"assets\\download-dRFo5_Wu.js",
|
|
47
|
-
"assets\\drawer-
|
|
48
|
-
"assets\\entry-
|
|
49
|
-
"assets\\entry-
|
|
50
|
-
"assets\\entry-
|
|
47
|
+
"assets\\drawer-CmXIZ6H1.js",
|
|
48
|
+
"assets\\entry-CBg5zeu8.js",
|
|
49
|
+
"assets\\entry-CQBr6U9c.js",
|
|
50
|
+
"assets\\entry-CgdSAzEV.js",
|
|
51
51
|
"assets\\eye-C_hawfH4.js",
|
|
52
52
|
"assets\\eye-off-Bk5g2luF.js",
|
|
53
53
|
"assets\\fingerprint-pattern-BWuHtbW4.js",
|
|
54
54
|
"assets\\gauge-BbIMy7MB.js",
|
|
55
|
-
"assets\\github-badge-
|
|
55
|
+
"assets\\github-badge-BlptL8Uf.js",
|
|
56
56
|
"assets\\image-BPaouViG.js",
|
|
57
|
-
"assets\\index-
|
|
58
|
-
"assets\\inline-
|
|
59
|
-
"assets\\input-
|
|
57
|
+
"assets\\index-js6TJvdr.js",
|
|
58
|
+
"assets\\inline-DUWDSmDV.js",
|
|
59
|
+
"assets\\input-LVjgZq4f.js",
|
|
60
60
|
"assets\\jsx-runtime-CXUMngI_.js",
|
|
61
61
|
"assets\\key-round-UkavsGxp.js",
|
|
62
62
|
"assets\\layers-2-glBbjl.js",
|
|
63
|
-
"assets\\layout-
|
|
64
|
-
"assets\\list-row-
|
|
65
|
-
"assets\\live-
|
|
63
|
+
"assets\\layout-CPfxpsfy.js",
|
|
64
|
+
"assets\\list-row-DupvLfDx.js",
|
|
65
|
+
"assets\\live-C4pEJUqI.js",
|
|
66
66
|
"assets\\log-in-BmRjy60c.js",
|
|
67
67
|
"assets\\message-circle-CCxGwRvv.js",
|
|
68
|
-
"assets\\model-bans-
|
|
69
|
-
"assets\\mutation-
|
|
70
|
-
"assets\\numbers-
|
|
68
|
+
"assets\\model-bans-BRiuufkB.js",
|
|
69
|
+
"assets\\mutation-B4ROwk8L.js",
|
|
70
|
+
"assets\\numbers-YNcHvRY7.js",
|
|
71
71
|
"assets\\pencil-768ysRAr.js",
|
|
72
72
|
"assets\\plus-DIdX_g-x.js",
|
|
73
73
|
"assets\\power-off-Yjw9GMJh.js",
|
|
@@ -89,31 +89,31 @@
|
|
|
89
89
|
"assets\\providers\\parallel.svg",
|
|
90
90
|
"assets\\providers\\tokenharbor.svg",
|
|
91
91
|
"assets\\providers\\zai-coding-plan.svg",
|
|
92
|
-
"assets\\query-keys-
|
|
92
|
+
"assets\\query-keys-gmjzC3RS.js",
|
|
93
93
|
"assets\\quota-DZGyp0N5.js",
|
|
94
94
|
"assets\\refresh-cw-BqJFk4sU.js",
|
|
95
95
|
"assets\\rotate-ccw-CufcqITi.js",
|
|
96
96
|
"assets\\route-CNSNj9Zm.js",
|
|
97
|
-
"assets\\routing-
|
|
97
|
+
"assets\\routing-C7tBT5o-.js",
|
|
98
98
|
"assets\\scaling-nWE4Cx8f.js",
|
|
99
99
|
"assets\\search-JOKus9rb.js",
|
|
100
|
-
"assets\\select-
|
|
101
|
-
"assets\\settings-
|
|
100
|
+
"assets\\select-WUCXorXw.js",
|
|
101
|
+
"assets\\settings-C_zKl1GS.js",
|
|
102
102
|
"assets\\shield-check-DVS0Foqh.js",
|
|
103
|
-
"assets\\
|
|
104
|
-
"assets\\
|
|
105
|
-
"assets\\state-DYdQmdAl.js",
|
|
103
|
+
"assets\\stack-_3O0F8Xn.js",
|
|
104
|
+
"assets\\state-BgTxHcJS.js",
|
|
106
105
|
"assets\\stream-retry-5QnVuSSo.js",
|
|
107
|
-
"assets\\switch-
|
|
108
|
-
"assets\\terminal-
|
|
106
|
+
"assets\\switch-DEjTtOWf.js",
|
|
107
|
+
"assets\\terminal-0_IjPWTk.js",
|
|
109
108
|
"assets\\tokens-DDxMbSRL.js",
|
|
110
109
|
"assets\\trash-Cppn5c3R.js",
|
|
111
110
|
"assets\\use-clipboard-B0Sy03fE.js",
|
|
112
111
|
"assets\\use-presence-BSZEBx7U.js",
|
|
113
112
|
"assets\\use-reduced-motion-C4B0R6Sz.js",
|
|
114
113
|
"assets\\use-timeout-BwcBBRrT.js",
|
|
115
|
-
"assets\\useMutation-
|
|
114
|
+
"assets\\useMutation-BWSC0UAS.js",
|
|
116
115
|
"assets\\wrench-B6E1oEuY.js",
|
|
116
|
+
"assets\\zap-C4EeVW4q.js",
|
|
117
117
|
"index.html"
|
|
118
118
|
]
|
|
119
119
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cartethyia",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.4",
|
|
4
4
|
"description": "A powerful, self-hosted reverse proxy for OpenAI- and Anthropic-compatible AI clients, powered by native Bun and Elysia. It serves both protocols from a single server, routes every model across any configured provider, and translates requests and responses in real time — streaming and prompt caching included. Underneath it runs a full delivery engine: per-account health tracking, quota and cooldown enforcement, automatic failover across pools and providers, usage accounting, and telemetry. Point OpenCode, Cline, Claude Code, Codex, or any compatible client at Cartethyia and it keeps its native protocol while the gateway absorbs every provider-specific difference behind it. Runs on embedded SQLite or external PostgreSQL with optional Redis coordination, ships as a global CLI with a system-tray console, and needs only Bun 1.4+ alongside Node.js/npm.",
|
|
5
5
|
"license": "GPL-3.0-only",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// Registers the tray with the OS login/startup facility.
|
|
2
|
+
//
|
|
3
|
+
// The tray only runs while someone starts it, so a gateway that is meant to be
|
|
4
|
+
// always-on needs the OS to start it. Each platform has its own place for that,
|
|
5
|
+
// and they differ in what "disable" means:
|
|
6
|
+
//
|
|
7
|
+
// - **Windows** — a value under `HKCU\\Software\\Microsoft\\Windows\\
|
|
8
|
+
// CurrentVersion\\Run`. Task Manager's Startup tab lists it, so an operator
|
|
9
|
+
// can disable it there without touching the registry by hand.
|
|
10
|
+
// - **macOS** — a launch agent plist in `~/Library/LaunchAgents`.
|
|
11
|
+
// - **Linux** — a `.desktop` file in `~/.config/autostart` (the freedesktop
|
|
12
|
+
// spec, honoured by every mainstream desktop).
|
|
13
|
+
//
|
|
14
|
+
// This only ever writes the *user's* own startup location, never a system one,
|
|
15
|
+
// so nothing here needs elevation and nothing here is forced on: removing the
|
|
16
|
+
// entry is the documented way to turn it off, and the tray itself keeps working
|
|
17
|
+
// when started by hand.
|
|
18
|
+
|
|
19
|
+
import { existsSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
20
|
+
import { homedir, platform } from "node:os";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
|
|
23
|
+
/** The launch label, used as the registry value name, plist label and file name. */
|
|
24
|
+
const APP_ID = "cartethyia-tray";
|
|
25
|
+
|
|
26
|
+
export interface AutostartState {
|
|
27
|
+
readonly platform: string;
|
|
28
|
+
readonly enabled: boolean;
|
|
29
|
+
/** Where the entry lives, for the operator who wants to remove it by hand. */
|
|
30
|
+
readonly location: string;
|
|
31
|
+
/** Why it is not supported here, when it is not. */
|
|
32
|
+
readonly reason?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The command the OS should run.
|
|
37
|
+
*
|
|
38
|
+
* Quoted once here rather than at each call site: the Windows registry value,
|
|
39
|
+
* the plist arguments and the desktop `Exec` line each parse spaces
|
|
40
|
+
* differently, and a path under `C:\\Users\\First Last\\...` silently becomes
|
|
41
|
+
* two arguments otherwise.
|
|
42
|
+
*/
|
|
43
|
+
function commandFor(executable: string, args: readonly string[]): string {
|
|
44
|
+
const quoted = /\s/.test(executable) ? `"${executable}"` : executable;
|
|
45
|
+
return [quoted, ...args.map((arg) => (/\s/.test(arg) ? `"${arg}"` : arg))].join(" ");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function windowsCommand(command: string): string[] {
|
|
49
|
+
return [
|
|
50
|
+
"reg",
|
|
51
|
+
"add",
|
|
52
|
+
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
53
|
+
"/v",
|
|
54
|
+
APP_ID,
|
|
55
|
+
"/t",
|
|
56
|
+
"REG_SZ",
|
|
57
|
+
"/d",
|
|
58
|
+
command,
|
|
59
|
+
"/f",
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function launchAgentsPath(): string {
|
|
64
|
+
return join(homedir(), "Library", "LaunchAgents", `${APP_ID}.plist`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Escapes the five entities XML defines, so a path cannot break the plist. */
|
|
68
|
+
function xmlEscape(value: string): string {
|
|
69
|
+
return value
|
|
70
|
+
.replaceAll("&", "&")
|
|
71
|
+
.replaceAll("<", "<")
|
|
72
|
+
.replaceAll(">", ">")
|
|
73
|
+
.replaceAll('"', """)
|
|
74
|
+
.replaceAll("'", "'");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function plistFor(executable: string, args: readonly string[]): string {
|
|
78
|
+
const programArgs = [executable, ...args]
|
|
79
|
+
.map((part) => ` <string>${xmlEscape(part)}</string>`)
|
|
80
|
+
.join("\n");
|
|
81
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
82
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
83
|
+
<plist version="1.0">
|
|
84
|
+
<dict>
|
|
85
|
+
<key>Label</key>
|
|
86
|
+
<string>${APP_ID}</string>
|
|
87
|
+
<key>ProgramArguments</key>
|
|
88
|
+
<array>
|
|
89
|
+
${programArgs}
|
|
90
|
+
</array>
|
|
91
|
+
<key>RunAtLoad</key>
|
|
92
|
+
<true/>
|
|
93
|
+
<!-- Restart only if it exits on its own; a crash loop is not a reason to
|
|
94
|
+
respawn forever, and a stopped tray should stay stopped. -->
|
|
95
|
+
<key>KeepAlive</key>
|
|
96
|
+
<false/>
|
|
97
|
+
</dict>
|
|
98
|
+
</plist>
|
|
99
|
+
`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function desktopEntryFor(command: string): string {
|
|
103
|
+
return `[Desktop Entry]
|
|
104
|
+
Type=Application
|
|
105
|
+
Name=Cartethyia Tray
|
|
106
|
+
Exec=${command}
|
|
107
|
+
Hidden=false
|
|
108
|
+
NoDisplay=false
|
|
109
|
+
X-GNOME-Autostart-enabled=true
|
|
110
|
+
`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Enables autostart for the tray.
|
|
115
|
+
*
|
|
116
|
+
* Returns the resulting state rather than throwing, because a failure here must
|
|
117
|
+
* not abort startup: the tray is still perfectly usable when launched by hand,
|
|
118
|
+
* and an operator who cannot write to their own startup folder has a reason we
|
|
119
|
+
* should report, not crash on.
|
|
120
|
+
*/
|
|
121
|
+
export async function enableAutostart(
|
|
122
|
+
executable: string,
|
|
123
|
+
args: readonly string[],
|
|
124
|
+
): Promise<AutostartState> {
|
|
125
|
+
const os = platform();
|
|
126
|
+
const command = commandFor(executable, args);
|
|
127
|
+
|
|
128
|
+
if (os === "win32") {
|
|
129
|
+
const proc = Bun.spawn(windowsCommand(command), { stdout: "pipe", stderr: "pipe" });
|
|
130
|
+
const code = await proc.exited;
|
|
131
|
+
return {
|
|
132
|
+
platform: os,
|
|
133
|
+
enabled: code === 0,
|
|
134
|
+
location: "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
135
|
+
...(code === 0
|
|
136
|
+
? {}
|
|
137
|
+
: { reason: "reg add failed; the entry can be added by hand or via Task Manager" }),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (os === "darwin") {
|
|
142
|
+
const path = launchAgentsPath();
|
|
143
|
+
try {
|
|
144
|
+
mkdirSync(join(homedir(), "Library", "LaunchAgents"), { recursive: true });
|
|
145
|
+
writeFileSync(path, plistFor(executable, args), "utf8");
|
|
146
|
+
return { platform: os, enabled: true, location: path };
|
|
147
|
+
} catch (error) {
|
|
148
|
+
return {
|
|
149
|
+
platform: os,
|
|
150
|
+
enabled: false,
|
|
151
|
+
location: path,
|
|
152
|
+
reason: error instanceof Error ? error.message : "could not write the launch agent",
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (os === "linux") {
|
|
158
|
+
const dir = join(homedir(), ".config", "autostart");
|
|
159
|
+
const path = join(dir, `${APP_ID}.desktop`);
|
|
160
|
+
try {
|
|
161
|
+
mkdirSync(dir, { recursive: true });
|
|
162
|
+
writeFileSync(path, desktopEntryFor(command), "utf8");
|
|
163
|
+
return { platform: os, enabled: true, location: path };
|
|
164
|
+
} catch (error) {
|
|
165
|
+
return {
|
|
166
|
+
platform: os,
|
|
167
|
+
enabled: false,
|
|
168
|
+
location: path,
|
|
169
|
+
reason: error instanceof Error ? error.message : "could not write the desktop entry",
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
platform: os,
|
|
176
|
+
enabled: false,
|
|
177
|
+
location: "",
|
|
178
|
+
reason: `no supported autostart location on ${os}`,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** Removes the entry, so the tray stops starting with the session. */
|
|
183
|
+
export async function disableAutostart(): Promise<AutostartState> {
|
|
184
|
+
const os = platform();
|
|
185
|
+
|
|
186
|
+
if (os === "win32") {
|
|
187
|
+
const proc = Bun.spawn(
|
|
188
|
+
[
|
|
189
|
+
"reg",
|
|
190
|
+
"delete",
|
|
191
|
+
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
192
|
+
"/v",
|
|
193
|
+
APP_ID,
|
|
194
|
+
"/f",
|
|
195
|
+
],
|
|
196
|
+
{ stdout: "pipe", stderr: "pipe" },
|
|
197
|
+
);
|
|
198
|
+
// `reg delete` exits non-zero when the value was already absent, which is
|
|
199
|
+
// the state the caller wanted anyway, so the code is not read.
|
|
200
|
+
await proc.exited;
|
|
201
|
+
return {
|
|
202
|
+
platform: os,
|
|
203
|
+
enabled: false,
|
|
204
|
+
location: "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const path = os === "darwin" ? launchAgentsPath() : join(homedir(), ".config", "autostart", `${APP_ID}.desktop`);
|
|
209
|
+
try {
|
|
210
|
+
if (existsSync(path)) rmSync(path);
|
|
211
|
+
return { platform: os, enabled: false, location: path };
|
|
212
|
+
} catch (error) {
|
|
213
|
+
return {
|
|
214
|
+
platform: os,
|
|
215
|
+
enabled: false,
|
|
216
|
+
location: path,
|
|
217
|
+
reason: error instanceof Error ? error.message : "could not remove the entry",
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Whether an entry is currently registered. */
|
|
223
|
+
export function autostartStatus(): AutostartState {
|
|
224
|
+
const os = platform();
|
|
225
|
+
if (os === "win32") {
|
|
226
|
+
// Reading the registry needs a process, so this is reported as unknown
|
|
227
|
+
// rather than guessed; `disableAutostart` is idempotent either way.
|
|
228
|
+
return {
|
|
229
|
+
platform: os,
|
|
230
|
+
enabled: false,
|
|
231
|
+
location: "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
232
|
+
reason: "status is not readable synchronously; enable or disable to set it",
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
const path = os === "darwin" ? launchAgentsPath() : join(homedir(), ".config", "autostart", `${APP_ID}.desktop`);
|
|
236
|
+
return { platform: os, enabled: existsSync(path), location: path };
|
|
237
|
+
}
|
|
@@ -14,7 +14,7 @@ import { launchBackgroundWithStatus, openUrl } from "../ui/background";
|
|
|
14
14
|
import { chooseFromMenu, confirmByTyping, confirmStep } from "../ui/prompt";
|
|
15
15
|
import { renderWordmark } from "../ui/wordmark";
|
|
16
16
|
import { exportBackup, resetConsoleAccount } from "./admin";
|
|
17
|
-
import {
|
|
17
|
+
import { runDetachedUpdate } from "./update";
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* The default `carte` experience: start the gateway, then offer an arrow-key
|
|
@@ -176,17 +176,13 @@ export async function startMenu(): Promise<void> {
|
|
|
176
176
|
// from that directory, so an in-process install can never succeed.
|
|
177
177
|
// Print the command and exit, the way 9router does.
|
|
178
178
|
await shutDown();
|
|
179
|
+
runDetachedUpdate();
|
|
179
180
|
console.log("");
|
|
180
181
|
console.log(`Update available: ${currentVersion} \u2192 ${latestVersion}`);
|
|
182
|
+
console.log("Detached update started; this process will exit now.");
|
|
183
|
+
console.log("Re-run `carte` after it finishes.");
|
|
181
184
|
console.log("");
|
|
182
|
-
console.log("Run this now that Cartethyia has stopped:");
|
|
183
|
-
console.log("");
|
|
184
|
-
console.log(` ${updateCommand()}`);
|
|
185
|
-
console.log("");
|
|
186
|
-
console.log("This terminal will stay open for 180s so you can copy the command, then exit.");
|
|
187
185
|
running = false;
|
|
188
|
-
await new Promise<void>((resolve) => setTimeout(resolve, 180_000));
|
|
189
|
-
console.log("Session ended. Run the command above to update.");
|
|
190
186
|
process.exit(0);
|
|
191
187
|
},
|
|
192
188
|
async () => {
|
|
@@ -1,23 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The update path
|
|
2
|
+
* The update path.
|
|
3
3
|
*
|
|
4
4
|
* npm cannot replace this package's directory while a process is executing out
|
|
5
|
-
* of it
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* the
|
|
5
|
+
* of it (EBUSY on Windows). So we spawn the installer as a detached process,
|
|
6
|
+
* print a short notice, and exit — the installer runs after this process is gone.
|
|
7
|
+
* After install, it attempts to restart the gateway (systemd if available, else
|
|
8
|
+
* `cartethyia start`), so the new version comes up automatically.
|
|
9
|
+
* Cross-OS: uses npm.cmd on Windows.
|
|
9
10
|
*/
|
|
11
|
+
import { spawn } from "node:child_process";
|
|
12
|
+
|
|
10
13
|
export function updateCommand(): string {
|
|
11
14
|
return "npm install -g cartethyia@latest --prefer-online";
|
|
12
15
|
}
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
export function runDetachedUpdate(): void {
|
|
18
|
+
const isWin = process.platform === "win32";
|
|
19
|
+
const shell = isWin ? "cmd.exe" : "/bin/sh";
|
|
20
|
+
const install = "npm install -g cartethyia@latest --prefer-online";
|
|
21
|
+
const restart = isWin
|
|
22
|
+
? "cartethyia start"
|
|
23
|
+
: "systemctl restart cartethyia 2>/dev/null || cartethyia start";
|
|
24
|
+
const script = `${install} && ${restart}`;
|
|
25
|
+
const args = isWin ? ["/c", script] : ["-c", script];
|
|
26
|
+
const child = spawn(shell, args, {
|
|
27
|
+
detached: true,
|
|
28
|
+
stdio: "ignore",
|
|
29
|
+
});
|
|
30
|
+
child.unref();
|
|
31
|
+
}
|
|
32
|
+
|
|
15
33
|
export function printUpdateInstructions(from: string, to: string | null): void {
|
|
16
34
|
console.log("");
|
|
17
35
|
console.log(`Update available: ${from} \u2192 ${to ?? "latest"}`);
|
|
18
36
|
console.log("");
|
|
19
|
-
console.log("
|
|
37
|
+
console.log("Starting detached update; this process will exit now.");
|
|
38
|
+
console.log("The gateway will restart automatically after the install.");
|
|
20
39
|
console.log("");
|
|
21
|
-
|
|
22
|
-
console.log("");
|
|
23
|
-
}
|
|
40
|
+
}
|
package/scripts/cli/main.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { mkdirSync } from "node:fs";
|
|
|
2
2
|
import { resolveUserConfigDir } from "../../src/config/package-paths";
|
|
3
3
|
import { ENV_PATH, readEnvFile } from "./support/env";
|
|
4
4
|
import { MINIMUM_BUN_VERSION, assertBunVersion } from "./support/bun";
|
|
5
|
-
import { printUpdateInstructions } from "./command/update";
|
|
5
|
+
import { printUpdateInstructions, runDetachedUpdate } from "./command/update";
|
|
6
6
|
import { reportTrayStartup } from "./support/startup-signal";
|
|
7
7
|
|
|
8
8
|
process.env.CARTETHYIA_CONFIG_DIR ??= resolveUserConfigDir();
|
|
@@ -67,12 +67,39 @@ async function main(): Promise<void> {
|
|
|
67
67
|
await startTray();
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
|
+
case "autostart": {
|
|
71
|
+
const { enableAutostart, disableAutostart, autostartStatus } = await import("./autostart");
|
|
72
|
+
const arg = Bun.argv[3]?.trim();
|
|
73
|
+
if (arg === "off" || arg === "disable") {
|
|
74
|
+
const state = await disableAutostart();
|
|
75
|
+
console.log(`Autostart disabled (${state.location || state.platform}).`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (arg === "status") {
|
|
79
|
+
const state = autostartStatus();
|
|
80
|
+
console.log(
|
|
81
|
+
`Autostart: ${state.enabled ? "enabled" : "not enabled"} — ${state.location || state.platform}` +
|
|
82
|
+
(state.reason ? ` (${state.reason})` : ""),
|
|
83
|
+
);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// The tray is what autostart launches: a gateway alone has no session to
|
|
87
|
+
// attach to and no icon to show.
|
|
88
|
+
const state = await enableAutostart(process.execPath, [Bun.argv[1] ?? "carte", "tray"]);
|
|
89
|
+
console.log(
|
|
90
|
+
state.enabled
|
|
91
|
+
? `Autostart enabled — ${state.location}`
|
|
92
|
+
: `Autostart not enabled: ${state.reason ?? "unknown reason"}`,
|
|
93
|
+
);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
70
96
|
case "doctor": {
|
|
71
97
|
const { doctor } = await import("./command/doctor");
|
|
72
98
|
await doctor();
|
|
73
99
|
return;
|
|
74
100
|
}
|
|
75
101
|
case "update":
|
|
102
|
+
runDetachedUpdate();
|
|
76
103
|
printUpdateInstructions("this install", null);
|
|
77
104
|
return;
|
|
78
105
|
case "--help":
|