cartethyia 2.5.4 → 2.5.7
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/.env.example +13 -4
- package/README.md +2 -2
- package/dist/dashboard/assets/{BannedPage-C2orBsI2.js → BannedPage-DE2607Tb.js} +1 -1
- package/dist/dashboard/assets/BannedPage-DE2607Tb.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-Duv6mfrl.js +1 -0
- package/dist/dashboard/assets/CliToolDetailPage-Duv6mfrl.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-BV6pxVQo.js → CliToolsPage-C2PNYWzk.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-C2PNYWzk.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-TXP9OfAM.js +1 -0
- package/dist/dashboard/assets/CombosPage-TXP9OfAM.js.gz +0 -0
- package/dist/dashboard/assets/{ConsoleLogPage-CW-wPmJ6.js → ConsoleLogPage-B-9xnAQN.js} +1 -1
- package/dist/dashboard/assets/ConsoleLogPage-B-9xnAQN.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-0p8uX7vB.js → CustomizationPage-xeax9nJt.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-xeax9nJt.js.gz +0 -0
- package/dist/dashboard/assets/{HealthEventsModal-BjqSMfko.js → HealthEventsModal-Df4jjaHJ.js} +1 -1
- package/dist/dashboard/assets/HealthEventsModal-Df4jjaHJ.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-BvzCx8Kr.js → LoginPage-Dyojsm84.js} +1 -1
- package/dist/dashboard/assets/LoginPage-Dyojsm84.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-C7pDb41R.js +1 -0
- package/dist/dashboard/assets/ModelPicker-C7pDb41R.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-BJfg4ow6.js +1 -0
- package/dist/dashboard/assets/OverviewPage-BJfg4ow6.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-ChCX1gmT.js +3 -0
- package/dist/dashboard/assets/ProviderDetailPage-ChCX1gmT.js.gz +0 -0
- package/dist/dashboard/assets/{ProvidersPage-Js9jUPSb.js → ProvidersPage-DeWSOEUO.js} +1 -1
- package/dist/dashboard/assets/ProvidersPage-DeWSOEUO.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-CkpWln2S.js +7 -0
- package/dist/dashboard/assets/ProxyPage-CkpWln2S.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-B3VOgQmt.js +1 -0
- package/dist/dashboard/assets/QuotaPage-B3VOgQmt.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-C_klIZom.js +1 -0
- package/dist/dashboard/assets/SettingsPage-C_klIZom.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-DDbMQsoo.js → SetupPage-BYph-InK.js} +1 -1
- package/dist/dashboard/assets/SetupPage-BYph-InK.js.gz +0 -0
- package/dist/dashboard/assets/{SortableList-CB3Z7VTf.js → SortableList-CvyQCYWJ.js} +1 -1
- package/dist/dashboard/assets/SortableList-CvyQCYWJ.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-D95UCPHI.js → StudioPage-Cm1JYilI.js} +3 -3
- package/dist/dashboard/assets/StudioPage-Cm1JYilI.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-DlFnc3_S.js +56 -0
- package/dist/dashboard/assets/UsagePage-DlFnc3_S.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-DQYLQxpW.js +1 -0
- package/dist/dashboard/assets/api-keys-DQYLQxpW.js.gz +0 -0
- package/dist/dashboard/assets/app-CX_Z8cMs.css +2 -0
- package/dist/dashboard/assets/app-CX_Z8cMs.css.gz +0 -0
- package/dist/dashboard/assets/{assert-Chi7pCnt.js → assert-C9FD_JwJ.js} +1 -1
- package/dist/dashboard/assets/assert-C9FD_JwJ.js.gz +0 -0
- package/dist/dashboard/assets/{badge-D4pQapKj.js → badge-CR72dasT.js} +1 -1
- package/dist/dashboard/assets/badge-CR72dasT.js.gz +0 -0
- package/dist/dashboard/assets/{banner-DH6cg-_B.js → banner-CI9_eSfO.js} +1 -1
- package/dist/dashboard/assets/banner-CI9_eSfO.js.gz +0 -0
- package/dist/dashboard/assets/{card-BKqlUOe4.js → card-DS7CQEsO.js} +1 -1
- package/dist/dashboard/assets/card-DS7CQEsO.js.gz +0 -0
- package/dist/dashboard/assets/{cli-tools-fTgljTGA.js → cli-tools-CNqzrfdb.js} +1 -1
- package/dist/dashboard/assets/cli-tools-CNqzrfdb.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-D5Ys_sM0.js → clipboard-button-611pSsaX.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-611pSsaX.js.gz +0 -0
- package/dist/dashboard/assets/{fingerprint-pattern-BWuHtbW4.js → concurrency-BDF0ok7y.js} +1 -1
- package/dist/dashboard/assets/concurrency-BDF0ok7y.js.gz +0 -0
- package/dist/dashboard/assets/dialog-k37exjNt.js +1 -0
- package/dist/dashboard/assets/dialog-k37exjNt.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CX7N8ucR.js +1 -0
- package/dist/dashboard/assets/drawer-CX7N8ucR.js.gz +0 -0
- package/dist/dashboard/assets/{entry-CQBr6U9c.js → entry-B9Xvtnfj.js} +1 -1
- package/dist/dashboard/assets/entry-B9Xvtnfj.js.gz +0 -0
- package/dist/dashboard/assets/entry-Bog0p925.js +4 -0
- package/dist/dashboard/assets/entry-Bog0p925.js.gz +0 -0
- package/dist/dashboard/assets/entry-CTP8AyiS.js +1 -0
- package/dist/dashboard/assets/entry-CTP8AyiS.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-BlptL8Uf.js → github-badge-sltk1qUi.js} +1 -1
- package/dist/dashboard/assets/github-badge-sltk1qUi.js.gz +0 -0
- package/dist/dashboard/assets/{index-js6TJvdr.js → index-CZQIrdoX.js} +2 -2
- package/dist/dashboard/assets/index-CZQIrdoX.js.gz +0 -0
- package/dist/dashboard/assets/{inline-DUWDSmDV.js → inline-BhY2sSnO.js} +1 -1
- package/dist/dashboard/assets/inline-BhY2sSnO.js.gz +0 -0
- package/dist/dashboard/assets/{input-LVjgZq4f.js → input-V1umFiBk.js} +1 -1
- package/dist/dashboard/assets/input-V1umFiBk.js.gz +0 -0
- package/dist/dashboard/assets/layout-BBOYycyS.js +1 -0
- package/dist/dashboard/assets/layout-BBOYycyS.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-DupvLfDx.js → list-row-1zzZYM0B.js} +1 -1
- package/dist/dashboard/assets/list-row-1zzZYM0B.js.gz +0 -0
- package/dist/dashboard/assets/{live-C4pEJUqI.js → live-BivGfuUs.js} +1 -1
- package/dist/dashboard/assets/live-BivGfuUs.js.gz +0 -0
- package/dist/dashboard/assets/{model-bans-BRiuufkB.js → model-bans-CmffjLuG.js} +1 -1
- package/dist/dashboard/assets/model-bans-CmffjLuG.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-B4ROwk8L.js → mutation-46P0oWMe.js} +1 -1
- package/dist/dashboard/assets/mutation-46P0oWMe.js.gz +0 -0
- package/dist/dashboard/assets/numbers-DkfMR5Qs.js +2 -0
- package/dist/dashboard/assets/numbers-DkfMR5Qs.js.gz +0 -0
- package/dist/dashboard/assets/{query-keys-gmjzC3RS.js → query-keys-BFhGpwR1.js} +1 -1
- package/dist/dashboard/assets/query-keys-BFhGpwR1.js.gz +0 -0
- package/dist/dashboard/assets/{routing-C7tBT5o-.js → routing-CAb4F37R.js} +1 -1
- package/dist/dashboard/assets/routing-CAb4F37R.js.gz +0 -0
- package/dist/dashboard/assets/{select-WUCXorXw.js → select-BPpSsBgL.js} +1 -1
- package/dist/dashboard/assets/select-BPpSsBgL.js.gz +0 -0
- package/dist/dashboard/assets/{settings-C_zKl1GS.js → settings-DNX9sydi.js} +1 -1
- package/dist/dashboard/assets/settings-DNX9sydi.js.gz +0 -0
- package/dist/dashboard/assets/{stack-_3O0F8Xn.js → stack-BHTfXdz_.js} +1 -1
- package/dist/dashboard/assets/stack-BHTfXdz_.js.gz +0 -0
- package/dist/dashboard/assets/{state-BgTxHcJS.js → state-mPDRlQkl.js} +1 -1
- package/dist/dashboard/assets/state-mPDRlQkl.js.gz +0 -0
- package/dist/dashboard/assets/{switch-DEjTtOWf.js → switch-DOmJxg7H.js} +1 -1
- package/dist/dashboard/assets/switch-DOmJxg7H.js.gz +0 -0
- package/dist/dashboard/assets/tokens-COzario9.js +1 -0
- package/dist/dashboard/assets/tokens-COzario9.js.gz +0 -0
- package/dist/dashboard/assets/use-modal-focus-By7oJoGd.js +1 -0
- package/dist/dashboard/assets/use-modal-focus-By7oJoGd.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-BWSC0UAS.js → useMutation-Dem0lXQj.js} +1 -1
- package/dist/dashboard/assets/useMutation-Dem0lXQj.js.gz +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/migrations/README.md +52 -52
- package/migrations/lite-sqlite3/0000_baseline.sql +2 -2
- package/package.json +95 -95
- package/scripts/cli/admin.ts +125 -0
- package/scripts/cli/{ui/background.ts → background.ts} +1 -1
- package/scripts/cli/{command/console-menu.ts → console-menu.ts} +275 -244
- package/scripts/cli/doctor.ts +37 -0
- package/scripts/cli/{support/env.ts → env.ts} +99 -99
- package/scripts/cli/{gateway/spawn.ts → gateway.ts} +112 -24
- package/scripts/cli/instance.ts +224 -0
- package/scripts/cli/main.ts +61 -18
- package/scripts/cli/{support/platform.ts → platform.ts} +64 -64
- package/scripts/cli/port.ts +100 -0
- package/scripts/cli/{support/services.ts → services.ts} +88 -88
- package/scripts/cli/{command/setup.ts → setup.ts} +35 -34
- package/scripts/cli/{command/start.ts → start.ts} +10 -5
- package/scripts/cli/{support/startup-signal.ts → startup-signal.ts} +23 -23
- package/scripts/cli/tray/index.ts +62 -12
- package/scripts/cli/{command/tray.ts → tray.ts} +208 -208
- package/scripts/cli/{command/update.ts → update.ts} +39 -39
- package/scripts/cli/version.ts +67 -0
- package/scripts/cli/{ui/wordmark.ts → wordmark.ts} +58 -58
- package/src/boot/app.ts +697 -693
- package/src/boot/dependencies.ts +647 -646
- package/src/boot/timeout.ts +2 -13
- package/src/config/cooldowns.ts +186 -138
- package/src/config/network.ts +8 -14
- package/src/config/providers.ts +7 -10
- package/src/config/runtime.ts +76 -76
- package/src/config/security.ts +15 -0
- package/src/config/spec.ts +20 -30
- package/src/config/telemetry.ts +0 -20
- package/src/config/timeouts.ts +0 -6
- package/src/console/admin/model-abuse/contracts.ts +28 -6
- package/src/console/admin/model-abuse/routes.ts +56 -3
- package/src/console/api-keys/contracts.ts +410 -414
- package/src/console/api-keys/routes.ts +881 -880
- package/src/console/auth/credentials.ts +3 -3
- package/src/console/auth/setup-service.ts +2 -2
- package/src/console/backup/export-endpoint.ts +6 -2
- package/src/console/backup/nine-router.ts +2 -5
- package/src/console/backup/service.ts +4 -0
- package/src/console/backup/store.ts +192 -29
- package/src/console/backup/validate.ts +3 -45
- package/src/console/cli-tools/fs-ops.ts +487 -487
- package/src/console/console-router-guards.ts +1 -1
- package/src/console/data-management/contracts.ts +13 -6
- package/src/console/data-management/operations.ts +23 -18
- package/src/console/data-management/routes.ts +0 -1
- package/src/console/domain-registration.ts +10 -5
- package/src/console/observability/live.ts +22 -0
- package/src/console/observability/store.ts +39 -16
- package/src/console/observability/usage-dimensions.ts +4 -4
- package/src/console/providers/catalog/catalog-projections.ts +6 -7
- package/src/console/providers/catalog/model-operations.ts +5 -2
- package/src/console/providers/catalog/provider-operations.ts +4 -4
- package/src/console/providers/catalog/public-model-store.ts +8 -11
- package/src/console/providers/catalog/store.ts +1553 -1553
- package/src/console/providers/oauth/routes.ts +8 -12
- package/src/console/quota/account-quota-tenant.ts +6 -6
- package/src/console/quota/quota-view.ts +1 -1
- package/src/console/remote-support/contracts.ts +61 -0
- package/src/console/remote-support/routes.ts +65 -0
- package/src/console/remote-support/service.ts +207 -0
- package/src/console/response-compression.ts +0 -3
- package/src/console/routing/pools/probe-result.ts +3 -2
- package/src/console/routing/pools/probe-verdict.ts +132 -132
- package/src/console/routing/pools/store.ts +8 -8
- package/src/console/settings/contracts.ts +58 -2
- package/src/console/settings/store.ts +30 -3
- package/src/console/shared/cursor.ts +8 -8
- package/src/console/shared/errors.ts +1 -3
- package/src/network/http2-bidi.ts +2 -4
- package/src/network/pool/agent.ts +478 -478
- package/src/network/pool/selector.ts +5 -4
- package/src/network/retry.ts +1 -2
- package/src/network/ssrf.ts +5 -4
- package/src/observability/event-compaction.ts +80 -78
- package/src/observability/event-day-index.ts +13 -15
- package/src/observability/event-log.ts +4 -4
- package/src/observability/logger.ts +6 -6
- package/src/observability/payload-capture.ts +151 -33
- package/src/observability/payload-store.ts +397 -440
- package/src/observability/redaction.ts +5 -6
- package/src/observability/request-notify.ts +43 -0
- package/src/observability/telemetry-status.ts +8 -9
- package/src/observability/token-speed.ts +5 -4
- package/src/persistence/db-mode.ts +7 -7
- package/src/persistence/readiness.ts +1 -1
- package/src/persistence/schema.ts +1406 -1402
- package/src/persistence/shared-cache.ts +1 -2
- package/src/persistence/stores/api-key-store.ts +18 -6
- package/src/persistence/stores/share-store.ts +4 -3
- package/src/persistence/stores/telemetry-store.ts +236 -237
- package/src/protocol/canonical-model.ts +11 -3
- package/src/protocol/codecs.ts +138 -4
- package/src/protocol/gateway-error.ts +6 -4
- package/src/protocol/request/chat.ts +21 -1
- package/src/protocol/request/codex.ts +10 -1
- package/src/protocol/request/messages.ts +4 -5
- package/src/protocol/request/responses.ts +9 -1
- package/src/protocol/response/chat.ts +34 -4
- package/src/protocol/response/codex.ts +7 -4
- package/src/protocol/response/dsml.ts +140 -28
- package/src/protocol/response/responses.ts +11 -5
- package/src/protocol/stream-error-frames.ts +4 -5
- package/src/providers/authentication/jwt-validator.ts +9 -10
- package/src/providers/authentication/oauth-refresh-service.ts +9 -11
- package/src/providers/configured-openai-providers.ts +134 -136
- package/src/providers/discovery/catalog/catalog-blob.ts +18 -18
- package/src/providers/discovery/catalog/catalog-format.ts +3 -6
- package/src/providers/discovery/models-dev-catalog.ts +354 -354
- package/src/providers/discovery/probe-phases.ts +4 -4
- package/src/providers/discovery/probe-wire.ts +6 -13
- package/src/providers/discovery/probing-service.ts +1117 -1045
- package/src/providers/integrations/alibabacp/alibabacp.ts +1 -1
- package/src/providers/integrations/antigravity/antigravity-quota.ts +5 -7
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +23 -2
- package/src/providers/integrations/buddy/buddy-checkin.ts +1 -4
- package/src/providers/integrations/buddy/buddy-cli-headers.ts +23 -6
- package/src/providers/integrations/buddy/buddy-conversation-headers.ts +0 -1
- package/src/providers/integrations/buddy/buddy-identity.ts +52 -0
- package/src/providers/integrations/buddy/buddy-media.ts +2 -2
- package/src/providers/integrations/buddy/buddy-usage-store.ts +3 -4
- package/src/providers/integrations/buddy/codebuddy/quota.ts +2 -13
- package/src/providers/integrations/buddy/codebuddy/shared.ts +118 -115
- package/src/providers/integrations/buddy/workbuddy/quota.ts +0 -11
- package/src/providers/integrations/buddy/workbuddy/shared.ts +5 -2
- package/src/providers/integrations/claude/claude.ts +608 -608
- package/src/providers/integrations/cline/cline-quota.ts +132 -132
- package/src/providers/integrations/cline/cline.ts +537 -539
- package/src/providers/integrations/codex/codex-oauth.ts +1 -1
- package/src/providers/integrations/commandcode/commandcode.ts +674 -675
- package/src/providers/integrations/commandcode/discovery.ts +117 -116
- package/src/providers/integrations/cursor/cursor-auth.ts +418 -418
- package/src/providers/integrations/cursor/cursor-quota.ts +309 -310
- package/src/providers/integrations/cursor/cursor.ts +11 -163
- package/src/providers/integrations/factory/factory-models.ts +3 -5
- package/src/providers/integrations/grok/grok-install-id.ts +2 -3
- package/src/providers/integrations/grok/grok.ts +6 -7
- package/src/providers/integrations/hermes.ts +14 -18
- package/src/providers/integrations/kiro/kiro-discovery.ts +1 -1
- package/src/providers/integrations/kiro/kiro.ts +1 -1
- package/src/providers/integrations/mistral.ts +6 -6
- package/src/providers/integrations/opencode/fingerprint.ts +3 -3
- package/src/providers/integrations/opencode/provider.ts +8 -8
- package/src/providers/integrations/qoder/qoder-catalog.ts +450 -450
- package/src/providers/integrations/qoder/qoder-oauth.ts +388 -310
- package/src/providers/integrations/qoder/qoder.ts +884 -865
- package/src/providers/integrations/shared/connect.ts +6 -6
- package/src/providers/integrations/trae/trae-catalog.ts +1 -2
- package/src/providers/integrations/trae/trae.ts +2 -2
- package/src/providers/integrations/zcode/oauth.ts +6 -1
- package/src/providers/operations/account-health-service.ts +1528 -1523
- package/src/providers/operations/account-reset-service.ts +1 -1
- package/src/providers/operations/client-versions.ts +6 -6
- package/src/providers/operations/custom-cli-headers.ts +3 -4
- package/src/providers/operations/provider-catalog-seeder.ts +95 -95
- package/src/providers/operations/provider-catalog-service.ts +3 -4
- package/src/providers/provider-metadata.ts +4 -8
- package/src/providers/provider-registry.ts +6 -7
- package/src/providers/provider-usage.ts +1 -1
- package/src/security/abuse.ts +15 -10
- package/src/security/access-control.ts +144 -146
- package/src/security/admission/contracts.ts +11 -0
- package/src/security/admission/in-memory-store.ts +4 -3
- package/src/security/admission/lease-sweep.ts +6 -6
- package/src/security/admission/reasons.ts +5 -1
- package/src/security/admission/redis-store.ts +211 -210
- package/src/security/admission/service.ts +4 -0
- package/src/security/api-key-auth.ts +504 -504
- package/src/security/ip-boundary.ts +155 -15
- package/src/security/model-abuse.ts +366 -94
- package/src/security/outbound-headers.ts +3 -4
- package/src/shared/sleep.ts +4 -0
- package/src/transport/dispatch/attempt-finalize.ts +47 -5
- package/src/transport/dispatch/attempt-loop.ts +531 -530
- package/src/transport/dispatch/stream-bridge.ts +1 -3
- package/src/transport/dispatch/streaming/finalize.ts +1 -1
- package/src/transport/dispatch/streaming/stream.ts +5 -6
- package/src/transport/failure-policy.ts +162 -8
- package/src/transport/guards/auth-guard.ts +7 -4
- package/src/transport/guards/concurrency-guard.ts +0 -5
- package/src/transport/guards/error-lifecycle.ts +13 -6
- package/src/transport/guards/pipeline.ts +15 -3
- package/src/transport/guards/request-context.ts +8 -2
- package/src/transport/request/inflight.ts +5 -6
- package/src/transport/request/preparer.ts +2 -2
- package/src/transport/request/state.ts +12 -8
- package/src/transport/routing/admission.ts +4 -0
- package/src/transport/routing/route-catalog.ts +8 -1
- package/src/transport/routing/route-model.ts +46 -14
- package/src/transport/routing/router.ts +21 -14
- package/src/transport/surface/completion.ts +2 -3
- package/src/transport/surface/dialects.ts +5 -6
- package/src/transport/surface/responses/encode.ts +38 -0
- package/src/transport/surface/responses/parse.ts +4 -0
- package/src/transport/translation/capabilities.ts +2 -3
- package/src/transport/translation/quirks.ts +3 -3
- package/src/workers/buddy-growth-tasks.ts +5 -10
- package/src/workers/daily-checkin.ts +17 -23
- package/src/workers/quota-refresh-sweep.ts +26 -26
- package/dist/dashboard/assets/BannedPage-C2orBsI2.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-DUcZ6pMB.js +0 -1
- package/dist/dashboard/assets/CliToolDetailPage-DUcZ6pMB.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-BV6pxVQo.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-Bsan4679.js +0 -1
- package/dist/dashboard/assets/CombosPage-Bsan4679.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-CW-wPmJ6.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-0p8uX7vB.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-BjqSMfko.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-BvzCx8Kr.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-BY1aKEkP.js +0 -1
- package/dist/dashboard/assets/ModelPicker-BY1aKEkP.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-DOQpy1y0.js +0 -1
- package/dist/dashboard/assets/OverviewPage-DOQpy1y0.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-ecxyUMzt.js +0 -3
- package/dist/dashboard/assets/ProviderDetailPage-ecxyUMzt.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-Js9jUPSb.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-J3TBi3Kx.js +0 -7
- package/dist/dashboard/assets/ProxyPage-J3TBi3Kx.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-C1gZS6xr.js +0 -1
- package/dist/dashboard/assets/QuotaPage-C1gZS6xr.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CS86ho5X.js +0 -1
- package/dist/dashboard/assets/SettingsPage-CS86ho5X.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-DDbMQsoo.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-CB3Z7VTf.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-D95UCPHI.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-Cnae9SWA.js +0 -56
- package/dist/dashboard/assets/UsagePage-Cnae9SWA.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-VY68Mhd1.js +0 -1
- package/dist/dashboard/assets/api-keys-VY68Mhd1.js.gz +0 -0
- package/dist/dashboard/assets/app-COlK95oi.css +0 -2
- package/dist/dashboard/assets/app-COlK95oi.css.gz +0 -0
- package/dist/dashboard/assets/assert-Chi7pCnt.js.gz +0 -0
- package/dist/dashboard/assets/badge-D4pQapKj.js.gz +0 -0
- package/dist/dashboard/assets/banner-DH6cg-_B.js.gz +0 -0
- package/dist/dashboard/assets/card-BKqlUOe4.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-fTgljTGA.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-D5Ys_sM0.js.gz +0 -0
- package/dist/dashboard/assets/dialog-BYj-8WuK.js +0 -1
- package/dist/dashboard/assets/dialog-BYj-8WuK.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CmXIZ6H1.js +0 -1
- package/dist/dashboard/assets/drawer-CmXIZ6H1.js.gz +0 -0
- package/dist/dashboard/assets/entry-CBg5zeu8.js +0 -1
- package/dist/dashboard/assets/entry-CBg5zeu8.js.gz +0 -0
- package/dist/dashboard/assets/entry-CQBr6U9c.js.gz +0 -0
- package/dist/dashboard/assets/entry-CgdSAzEV.js +0 -4
- package/dist/dashboard/assets/entry-CgdSAzEV.js.gz +0 -0
- package/dist/dashboard/assets/fingerprint-pattern-BWuHtbW4.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-BlptL8Uf.js.gz +0 -0
- package/dist/dashboard/assets/index-js6TJvdr.js.gz +0 -0
- package/dist/dashboard/assets/inline-DUWDSmDV.js.gz +0 -0
- package/dist/dashboard/assets/input-LVjgZq4f.js.gz +0 -0
- package/dist/dashboard/assets/layout-CPfxpsfy.js +0 -1
- package/dist/dashboard/assets/layout-CPfxpsfy.js.gz +0 -0
- package/dist/dashboard/assets/list-row-DupvLfDx.js.gz +0 -0
- package/dist/dashboard/assets/live-C4pEJUqI.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-BRiuufkB.js.gz +0 -0
- package/dist/dashboard/assets/mutation-B4ROwk8L.js.gz +0 -0
- package/dist/dashboard/assets/numbers-YNcHvRY7.js +0 -2
- package/dist/dashboard/assets/numbers-YNcHvRY7.js.gz +0 -0
- package/dist/dashboard/assets/query-keys-gmjzC3RS.js.gz +0 -0
- package/dist/dashboard/assets/routing-C7tBT5o-.js.gz +0 -0
- package/dist/dashboard/assets/select-WUCXorXw.js.gz +0 -0
- package/dist/dashboard/assets/settings-C_zKl1GS.js.gz +0 -0
- package/dist/dashboard/assets/stack-_3O0F8Xn.js.gz +0 -0
- package/dist/dashboard/assets/state-BgTxHcJS.js.gz +0 -0
- package/dist/dashboard/assets/switch-DEjTtOWf.js.gz +0 -0
- package/dist/dashboard/assets/tokens-DDxMbSRL.js +0 -1
- package/dist/dashboard/assets/tokens-DDxMbSRL.js.gz +0 -0
- package/dist/dashboard/assets/use-presence-BSZEBx7U.js +0 -1
- package/dist/dashboard/assets/use-presence-BSZEBx7U.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-BWSC0UAS.js.gz +0 -0
- package/scripts/cli/command/admin.ts +0 -65
- package/scripts/cli/command/doctor.ts +0 -257
- package/scripts/cli/gateway/drain-token.ts +0 -78
- package/scripts/cli/gateway/instance-lock.ts +0 -105
- package/scripts/cli/gateway/stop.ts +0 -51
- package/scripts/cli/support/bun.ts +0 -27
- package/scripts/cli/support/version.ts +0 -37
- /package/dist/dashboard/assets/{app-DCQZRmHY.js → app-BIt446yE.js} +0 -0
- /package/dist/dashboard/assets/{app-DCQZRmHY.js.gz → app-BIt446yE.js.gz} +0 -0
- /package/scripts/cli/{ui/prompt.ts → prompt.ts} +0 -0
package/migrations/README.md
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
# Database baselines
|
|
2
|
-
|
|
3
|
-
Cartethyia keeps one SQL baseline per database backend:
|
|
4
|
-
|
|
5
|
-
- `full-postgres/0000_baseline.sql` defines the foundational PostgreSQL schema
|
|
6
|
-
for a new database.
|
|
7
|
-
- `lite-sqlite3/0000_baseline.sql` is generated from the PostgreSQL baseline by
|
|
8
|
-
`scripts/generate
|
|
9
|
-
|
|
10
|
-
The startup runner applies the baseline and numbered forward migrations,
|
|
11
|
-
recording them in `cartethyia_schema_migrations` along with a hash marker for
|
|
12
|
-
the exact baseline contents. Released baselines are immutable so existing
|
|
13
|
-
installations keep matching their marker; numbered migrations bring that
|
|
14
|
-
foundational schema up to the current schema. Each backend's migrations must
|
|
15
|
-
have matching behavior. Startup fails with a recovery instruction for a
|
|
16
|
-
database with unsupported retired migration history instead of treating it as
|
|
17
|
-
current.
|
|
18
|
-
|
|
19
|
-
## Recovering an existing installation
|
|
20
|
-
|
|
21
|
-
1. Export a backup from the existing installation before switching it to a
|
|
22
|
-
release with unsupported migration history.
|
|
23
|
-
2. Create a fresh database and point the application at it.
|
|
24
|
-
3. Start the application so it creates the baseline schema.
|
|
25
|
-
4. Restore the backup through the console restore flow.
|
|
26
|
-
|
|
27
|
-
Restore normalizes legacy values that no longer satisfy current constraints,
|
|
28
|
-
including `bypass_proxy` → `skip_proxy`, `bridge` → `https`, the retired
|
|
29
|
-
provider User-Agent default, Cline's skip-proxy default, and `fusion` →
|
|
30
|
-
`fallback`. Unknown or retired columns are reported and skipped according to
|
|
31
|
-
the backup contract.
|
|
32
|
-
|
|
33
|
-
Do not point tests or recovery steps at development or production databases.
|
|
34
|
-
The startup path runs `ensureMigrated()` before provider/catalog seeding. Full
|
|
35
|
-
mode uses `src/persistence/db-pg.ts` and an advisory lock; Lite uses
|
|
36
|
-
`src/persistence/db-sqlite.ts`. Readiness compares the ledger to the available baseline and forward migration
|
|
37
|
-
files. A failed migration aborts startup and is not recorded.
|
|
38
|
-
|
|
39
|
-
Migrations are package assets, not resolved from the process working directory:
|
|
40
|
-
`src/config/package-paths.ts` resolves them from the package root. `package.json`
|
|
41
|
-
includes `migrations/` in the published files, and the Dockerfile copies the
|
|
42
|
-
migration directories into `/app/migrations`.
|
|
43
|
-
|
|
44
|
-
## Next schema change
|
|
45
|
-
|
|
46
|
-
1. Update `src/persistence/schema.ts` and add matching numbered migrations to
|
|
47
|
-
both backends. Preserve released baseline files so existing baseline markers
|
|
48
|
-
remain valid.
|
|
49
|
-
2. Update backup validation/mapping when old exported rows need normalization
|
|
50
|
-
or new required values.
|
|
51
|
-
3. Run focused migration, restore, and typecheck tests. Validate against an
|
|
52
|
-
isolated database only.
|
|
1
|
+
# Database baselines
|
|
2
|
+
|
|
3
|
+
Cartethyia keeps one SQL baseline per database backend:
|
|
4
|
+
|
|
5
|
+
- `full-postgres/0000_baseline.sql` defines the foundational PostgreSQL schema
|
|
6
|
+
for a new database.
|
|
7
|
+
- `lite-sqlite3/0000_baseline.sql` is generated from the PostgreSQL baseline by
|
|
8
|
+
`scripts/tools/generate-sqlite.ts`; do not edit it by hand.
|
|
9
|
+
|
|
10
|
+
The startup runner applies the baseline and numbered forward migrations,
|
|
11
|
+
recording them in `cartethyia_schema_migrations` along with a hash marker for
|
|
12
|
+
the exact baseline contents. Released baselines are immutable so existing
|
|
13
|
+
installations keep matching their marker; numbered migrations bring that
|
|
14
|
+
foundational schema up to the current schema. Each backend's migrations must
|
|
15
|
+
have matching behavior. Startup fails with a recovery instruction for a
|
|
16
|
+
database with unsupported retired migration history instead of treating it as
|
|
17
|
+
current.
|
|
18
|
+
|
|
19
|
+
## Recovering an existing installation
|
|
20
|
+
|
|
21
|
+
1. Export a backup from the existing installation before switching it to a
|
|
22
|
+
release with unsupported migration history.
|
|
23
|
+
2. Create a fresh database and point the application at it.
|
|
24
|
+
3. Start the application so it creates the baseline schema.
|
|
25
|
+
4. Restore the backup through the console restore flow.
|
|
26
|
+
|
|
27
|
+
Restore normalizes legacy values that no longer satisfy current constraints,
|
|
28
|
+
including `bypass_proxy` → `skip_proxy`, `bridge` → `https`, the retired
|
|
29
|
+
provider User-Agent default, Cline's skip-proxy default, and `fusion` →
|
|
30
|
+
`fallback`. Unknown or retired columns are reported and skipped according to
|
|
31
|
+
the backup contract.
|
|
32
|
+
|
|
33
|
+
Do not point tests or recovery steps at development or production databases.
|
|
34
|
+
The startup path runs `ensureMigrated()` before provider/catalog seeding. Full
|
|
35
|
+
mode uses `src/persistence/db-pg.ts` and an advisory lock; Lite uses
|
|
36
|
+
`src/persistence/db-sqlite.ts`. Readiness compares the ledger to the available baseline and forward migration
|
|
37
|
+
files. A failed migration aborts startup and is not recorded.
|
|
38
|
+
|
|
39
|
+
Migrations are package assets, not resolved from the process working directory:
|
|
40
|
+
`src/config/package-paths.ts` resolves them from the package root. `package.json`
|
|
41
|
+
includes `migrations/` in the published files, and the Dockerfile copies the
|
|
42
|
+
migration directories into `/app/migrations`.
|
|
43
|
+
|
|
44
|
+
## Next schema change
|
|
45
|
+
|
|
46
|
+
1. Update `src/persistence/schema.ts` and add matching numbered migrations to
|
|
47
|
+
both backends. Preserve released baseline files so existing baseline markers
|
|
48
|
+
remain valid.
|
|
49
|
+
2. Update backup validation/mapping when old exported rows need normalization
|
|
50
|
+
or new required values.
|
|
51
|
+
3. Run focused migration, restore, and typecheck tests. Validate against an
|
|
52
|
+
isolated database only.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
-- Generated by scripts/generate
|
|
1
|
+
-- Generated by scripts/tools/generate-sqlite.ts from migrations/full-postgres/0000_baseline.sql.
|
|
2
2
|
-- Do not edit by hand: change src/persistence/schema.ts, then re-run
|
|
3
|
-
-- `bun scripts/generate
|
|
3
|
+
-- `bun scripts/tools/generate-sqlite.ts`. The PostgreSQL baseline this is
|
|
4
4
|
-- derived from is hand-written and hash-pinned; add a numbered migration
|
|
5
5
|
-- for a schema change instead of editing it.
|
|
6
6
|
--> statement-breakpoint
|
package/package.json
CHANGED
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "cartethyia",
|
|
3
|
-
"version": "2.5.
|
|
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
|
|
5
|
-
"license": "GPL-3.0-only",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"packageManager": "bun@1.4.0",
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/risunCodex/Cartethyia.git"
|
|
11
|
-
},
|
|
12
|
-
"homepage": "https://github.com/risunCodex/Cartethyia#readme",
|
|
13
|
-
"bugs": {
|
|
14
|
-
"url": "https://github.com/risunCodex/Cartethyia/issues"
|
|
15
|
-
},
|
|
16
|
-
"keywords": [
|
|
17
|
-
"ai",
|
|
18
|
-
"gateway",
|
|
19
|
-
"llm",
|
|
20
|
-
"bun",
|
|
21
|
-
"self-hosted"
|
|
22
|
-
],
|
|
23
|
-
"bin": {
|
|
24
|
-
"cartethyia": "scripts/cli/bin/cartethyia.cjs",
|
|
25
|
-
"carte": "scripts/cli/bin/carte.cjs"
|
|
26
|
-
},
|
|
27
|
-
"files": [
|
|
28
|
-
"scripts/cli/",
|
|
29
|
-
"src/",
|
|
30
|
-
"migrations/",
|
|
31
|
-
"dist/dashboard/",
|
|
32
|
-
".env.example",
|
|
33
|
-
"README.md"
|
|
34
|
-
],
|
|
35
|
-
"workspaces": [
|
|
36
|
-
"dashboard"
|
|
37
|
-
],
|
|
38
|
-
"engines": {
|
|
39
|
-
"bun": ">=1.4.0"
|
|
40
|
-
},
|
|
41
|
-
"scripts": {
|
|
42
|
-
"dev": "bun run dev:stack",
|
|
43
|
-
"dev:watch": "bun run scripts/dev/supervisor.ts",
|
|
44
|
-
"test": "bun run scripts/
|
|
45
|
-
"build": "bun run scripts/
|
|
46
|
-
"prepack": "bun run dashboard:build",
|
|
47
|
-
"setup": "bun run scripts/cli/
|
|
48
|
-
"start": "bun run scripts/cli/main.ts start",
|
|
49
|
-
"doctor": "bun run scripts/cli/
|
|
50
|
-
"probe:egress": "bun run scripts/
|
|
51
|
-
"restart": "bun run scripts/
|
|
52
|
-
"build:aot": "bun run scripts/
|
|
53
|
-
"dev:stack": "concurrently -n BACKEND,DASHBOARD -c cyan,magenta --kill-others-on-fail \"bun run dev:backend\" \"bun run dashboard:dev\"",
|
|
54
|
-
"typecheck": "tsc --noEmit",
|
|
55
|
-
"test:watch": "bun run scripts/
|
|
56
|
-
"test-db:up": "docker compose -f docker-compose.test.yml up -d --wait postgres-test",
|
|
57
|
-
"dev:backend": "bun run --hot src/main.ts",
|
|
58
|
-
"dev:console-auth": "bun run scripts/
|
|
59
|
-
"dev:visual-baseline": "bun run scripts/
|
|
60
|
-
"build:binary": "bun run scripts/
|
|
61
|
-
"test:backend": "bun run scripts/
|
|
62
|
-
"test-db:down": "docker compose -f docker-compose.test.yml down",
|
|
63
|
-
"dashboard:dev": "bun run --cwd dashboard dev",
|
|
64
|
-
"test-db:check": "bun run scripts/
|
|
65
|
-
"dashboard:test": "bun run scripts/
|
|
66
|
-
"test-db:reset": "docker compose -f docker-compose.test.yml down -v && docker compose -f docker-compose.test.yml up -d --wait postgres-test",
|
|
67
|
-
"dashboard:build": "bun run --cwd dashboard build",
|
|
68
|
-
"dashboard:typecheck": "bun run --cwd dashboard typecheck",
|
|
69
|
-
"check:migrations": "bun run scripts/
|
|
70
|
-
},
|
|
71
|
-
"dependencies": {
|
|
72
|
-
"drizzle-orm": "0.45.2",
|
|
73
|
-
"elysia": "
|
|
74
|
-
"enquirer": "^2.4.1",
|
|
75
|
-
"ioredis": "6.0.0",
|
|
76
|
-
"jose": "^6.2.12",
|
|
77
|
-
"jsonrepair": "^3.15.0",
|
|
78
|
-
"pg": "8.23.0",
|
|
79
|
-
"pino": "^10.3.1",
|
|
80
|
-
"pino-pretty": "^13.1.3",
|
|
81
|
-
"protobufjs": "^7.6.5",
|
|
82
|
-
"socks-proxy-agent": "^10.1.0",
|
|
83
|
-
"systray2": "2.1.4",
|
|
84
|
-
"typebox": "1.3.27",
|
|
85
|
-
"ws": "8.22.0"
|
|
86
|
-
},
|
|
87
|
-
"devDependencies": {
|
|
88
|
-
"@types/pg": "8.11.10",
|
|
89
|
-
"@types/ws": "8.18.1",
|
|
90
|
-
"bun-types": "1.4.0",
|
|
91
|
-
"concurrently": "^10.0.5",
|
|
92
|
-
"drizzle-kit": "^0.31.11",
|
|
93
|
-
"typescript": "5.9.2"
|
|
94
|
-
}
|
|
95
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "cartethyia",
|
|
3
|
+
"version": "2.5.7",
|
|
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 \u2014 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
|
+
"license": "GPL-3.0-only",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"packageManager": "bun@1.4.0",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/risunCodex/Cartethyia.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/risunCodex/Cartethyia#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/risunCodex/Cartethyia/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"ai",
|
|
18
|
+
"gateway",
|
|
19
|
+
"llm",
|
|
20
|
+
"bun",
|
|
21
|
+
"self-hosted"
|
|
22
|
+
],
|
|
23
|
+
"bin": {
|
|
24
|
+
"cartethyia": "scripts/cli/bin/cartethyia.cjs",
|
|
25
|
+
"carte": "scripts/cli/bin/carte.cjs"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"scripts/cli/",
|
|
29
|
+
"src/",
|
|
30
|
+
"migrations/",
|
|
31
|
+
"dist/dashboard/",
|
|
32
|
+
".env.example",
|
|
33
|
+
"README.md"
|
|
34
|
+
],
|
|
35
|
+
"workspaces": [
|
|
36
|
+
"dashboard"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"bun": ">=1.4.0"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"dev": "bun run dev:stack",
|
|
43
|
+
"dev:watch": "bun run scripts/dev/supervisor.ts",
|
|
44
|
+
"test": "bun run scripts/test/run.ts",
|
|
45
|
+
"build": "bun run scripts/build/build.ts",
|
|
46
|
+
"prepack": "bun run dashboard:build",
|
|
47
|
+
"setup": "bun run scripts/cli/setup.ts",
|
|
48
|
+
"start": "bun run scripts/cli/main.ts start",
|
|
49
|
+
"doctor": "bun run scripts/cli/doctor.ts",
|
|
50
|
+
"probe:egress": "bun run scripts/tools/probe-egress.ts",
|
|
51
|
+
"restart": "bun run scripts/build/restart.ts",
|
|
52
|
+
"build:aot": "bun run scripts/build/aot.ts",
|
|
53
|
+
"dev:stack": "concurrently -n BACKEND,DASHBOARD -c cyan,magenta --kill-others-on-fail \"bun run dev:backend\" \"bun run dashboard:dev\"",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"test:watch": "bun run scripts/test/run.ts --watch",
|
|
56
|
+
"test-db:up": "docker compose -f docker-compose.test.yml up -d --wait postgres-test",
|
|
57
|
+
"dev:backend": "bun run --hot src/main.ts",
|
|
58
|
+
"dev:console-auth": "bun run scripts/test/console-session.ts",
|
|
59
|
+
"dev:visual-baseline": "bun run scripts/test/visual-baseline.ts",
|
|
60
|
+
"build:binary": "bun run scripts/build/compile.ts",
|
|
61
|
+
"test:backend": "bun run scripts/test/run.ts --scope backend",
|
|
62
|
+
"test-db:down": "docker compose -f docker-compose.test.yml down",
|
|
63
|
+
"dashboard:dev": "bun run --cwd dashboard dev",
|
|
64
|
+
"test-db:check": "bun run scripts/test/check-db.ts",
|
|
65
|
+
"dashboard:test": "bun run scripts/test/run.ts --scope dashboard",
|
|
66
|
+
"test-db:reset": "docker compose -f docker-compose.test.yml down -v && docker compose -f docker-compose.test.yml up -d --wait postgres-test",
|
|
67
|
+
"dashboard:build": "bun run --cwd dashboard build",
|
|
68
|
+
"dashboard:typecheck": "bun run --cwd dashboard typecheck",
|
|
69
|
+
"check:migrations": "bun run scripts/test/check-migrations.ts"
|
|
70
|
+
},
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"drizzle-orm": "0.45.2",
|
|
73
|
+
"elysia": "2.0.0-beta.16",
|
|
74
|
+
"enquirer": "^2.4.1",
|
|
75
|
+
"ioredis": "6.0.0",
|
|
76
|
+
"jose": "^6.2.12",
|
|
77
|
+
"jsonrepair": "^3.15.0",
|
|
78
|
+
"pg": "8.23.0",
|
|
79
|
+
"pino": "^10.3.1",
|
|
80
|
+
"pino-pretty": "^13.1.3",
|
|
81
|
+
"protobufjs": "^7.6.5",
|
|
82
|
+
"socks-proxy-agent": "^10.1.0",
|
|
83
|
+
"systray2": "2.1.4",
|
|
84
|
+
"typebox": "1.3.27",
|
|
85
|
+
"ws": "8.22.0"
|
|
86
|
+
},
|
|
87
|
+
"devDependencies": {
|
|
88
|
+
"@types/pg": "8.11.10",
|
|
89
|
+
"@types/ws": "8.18.1",
|
|
90
|
+
"bun-types": "1.4.0",
|
|
91
|
+
"concurrently": "^10.0.5",
|
|
92
|
+
"drizzle-kit": "^0.31.11",
|
|
93
|
+
"typescript": "5.9.2"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two admin actions the menu and the tray both offer.
|
|
3
|
+
*
|
|
4
|
+
* Both go through the running gateway rather than the database file: the
|
|
5
|
+
* gateway holds the connection and the schema is dialect-dependent, so reading
|
|
6
|
+
* or writing the tables from this process would need a second implementation
|
|
7
|
+
* of both.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { ENV_PATH, readEnvFile } from "./env";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Asks the gateway to write a gzipped config backup into the download
|
|
14
|
+
* directory. Returns the written path and counts, or null when it failed.
|
|
15
|
+
*/
|
|
16
|
+
export async function exportBackup(
|
|
17
|
+
port: number,
|
|
18
|
+
token: string,
|
|
19
|
+
): Promise<{ path: string; bytes: number; counts: Record<string, number> } | null> {
|
|
20
|
+
try {
|
|
21
|
+
const response = await fetch(`http://127.0.0.1:${port}/admin/export-backup`, {
|
|
22
|
+
method: "POST",
|
|
23
|
+
headers: { "content-type": "application/json", "x-drain-token": token },
|
|
24
|
+
body: JSON.stringify({}),
|
|
25
|
+
signal: AbortSignal.timeout(60_000),
|
|
26
|
+
});
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
const detail = await response.text().catch(() => "");
|
|
29
|
+
console.error(`The gateway refused the backup (HTTP ${response.status}). ${detail}`.trim());
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return (await response.json()) as {
|
|
33
|
+
path: string;
|
|
34
|
+
bytes: number;
|
|
35
|
+
counts: Record<string, number>;
|
|
36
|
+
};
|
|
37
|
+
} catch {
|
|
38
|
+
console.error("Could not reach the gateway. Is it still running?");
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Posts the console-account reset to the running gateway.
|
|
45
|
+
*
|
|
46
|
+
* Returns 0 on success and 1 on any failure so the caller can print one line
|
|
47
|
+
* either way.
|
|
48
|
+
*/
|
|
49
|
+
export async function resetConsoleAccount(port: number, token: string): Promise<number> {
|
|
50
|
+
try {
|
|
51
|
+
const response = await fetch(`http://127.0.0.1:${port}/admin/reset-console-account`, {
|
|
52
|
+
method: "POST",
|
|
53
|
+
headers: { "content-type": "application/json", "x-drain-token": token },
|
|
54
|
+
body: JSON.stringify({ confirm: "RESET" }),
|
|
55
|
+
signal: AbortSignal.timeout(10_000),
|
|
56
|
+
});
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
const detail = await response.text().catch(() => "");
|
|
59
|
+
console.error(`The gateway refused the reset (HTTP ${response.status}). ${detail}`.trim());
|
|
60
|
+
return 1;
|
|
61
|
+
}
|
|
62
|
+
return 0;
|
|
63
|
+
} catch {
|
|
64
|
+
console.error("Could not reach the gateway. Is it still running?");
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Operator escape hatch: clears the console login lockout bucket.
|
|
72
|
+
*
|
|
73
|
+
* The lockout is keyed by `<username>:<clientIp>` and lasts an hour, and there
|
|
74
|
+
* is no console surface to clear it — a locked-out operator has no way back in
|
|
75
|
+
* short of editing the database by hand. This is the documented reset.
|
|
76
|
+
*
|
|
77
|
+
* Usage:
|
|
78
|
+
* cartethyia admin reset-lockout <username> <clientIp>
|
|
79
|
+
* cartethyia admin reset-lockout --all
|
|
80
|
+
*/
|
|
81
|
+
export async function resetLockout(args: readonly string[]): Promise<void> {
|
|
82
|
+
const all = args.includes("--all");
|
|
83
|
+
const positional = args.filter((arg) => !arg.startsWith("--"));
|
|
84
|
+
if (!all && positional.length < 2) {
|
|
85
|
+
console.error("Usage: cartethyia admin reset-lockout <username> <clientIp>");
|
|
86
|
+
console.error(" cartethyia admin reset-lockout --all");
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const env = await readEnvFile(ENV_PATH);
|
|
91
|
+
const databaseUrl = env.DATABASE_URL ?? process.env.DATABASE_URL;
|
|
92
|
+
if (!databaseUrl) {
|
|
93
|
+
console.error("✗ DATABASE_URL is not set; cannot reach the lockout table.");
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
process.env.DATABASE_URL = databaseUrl;
|
|
97
|
+
|
|
98
|
+
const { getDb, closeDb } = await import("../../src/persistence/boot");
|
|
99
|
+
const { consoleLockouts } = await import("../../src/persistence/schema");
|
|
100
|
+
const { eq, or } = await import("drizzle-orm");
|
|
101
|
+
|
|
102
|
+
const db = getDb();
|
|
103
|
+
try {
|
|
104
|
+
if (all) {
|
|
105
|
+
const cleared = await db.delete(consoleLockouts).returning({ ip: consoleLockouts.ip });
|
|
106
|
+
console.log(`✓ Cleared ${cleared.length} lockout row(s).`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const username = positional[0]!.trim().toLowerCase();
|
|
110
|
+
const clientIp = positional[1]!;
|
|
111
|
+
// The bucket key is `<identifier>:<ip>`; match either exact spelling so
|
|
112
|
+
// an operator does not have to guess how the identifier was normalized.
|
|
113
|
+
const cleared = await db
|
|
114
|
+
.delete(consoleLockouts)
|
|
115
|
+
.where(or(eq(consoleLockouts.ip, `${username}:${clientIp}`), eq(consoleLockouts.ip, clientIp)))
|
|
116
|
+
.returning({ ip: consoleLockouts.ip });
|
|
117
|
+
if (cleared.length === 0) {
|
|
118
|
+
console.log(`• No lockout row for ${username}:${clientIp} (already clear).`);
|
|
119
|
+
} else {
|
|
120
|
+
console.log(`✓ Cleared lockout for ${cleared.map((row) => row.ip).join(", ")}.`);
|
|
121
|
+
}
|
|
122
|
+
} finally {
|
|
123
|
+
await closeDb();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { readFileSync, unlinkSync } from "node:fs";
|
|
3
|
-
import { PACKAGE_ROOT, resolvePackagePath } from "
|
|
3
|
+
import { PACKAGE_ROOT, resolvePackagePath } from "../../src/config/package-paths";
|
|
4
4
|
|
|
5
5
|
/** Opens a URL in the operator's default browser, ignoring a missing handler. */
|
|
6
6
|
export function openUrl(url: string): Promise<void> {
|