omnigateway 0.4.6 → 0.4.8

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.
Files changed (46) hide show
  1. package/README.md +53 -15
  2. package/bin/omni.js +17 -14
  3. package/gateway.js +16 -18
  4. package/package.json +1 -1
  5. package/public/assets/{CopyValue-BiiqC_Z2.js → CopyValue-CHZz2PLE.js} +1 -1
  6. package/public/assets/{Field-b0ohzqzR.js → Field-B79Yxdit.js} +1 -1
  7. package/public/assets/{Match-B2ZxNor3.js → Match-BWa6L0L1.js} +1 -1
  8. package/public/assets/Panel-CoulMx6R.js +25 -0
  9. package/public/assets/Rack-ziQuyb2l.js +314 -0
  10. package/public/assets/{Readout-VYnpaTMg.js → Readout-D1XEfywe.js} +1 -1
  11. package/public/assets/States-Shs8nZi1.js +54 -0
  12. package/public/assets/{Toggle-DMk46RX2.js → Toggle-CNnMgEU1.js} +1 -1
  13. package/public/assets/{TokenBreakdown-B9RanXin.js → TokenBreakdown-hkwYCWT3.js} +1 -1
  14. package/public/assets/_app-BD1K3SGD.js +1 -0
  15. package/public/assets/_app.accounts-BDBEn5vF.js +64 -0
  16. package/public/assets/{_app.console-eFiUh-OA.js → _app.console-BtLYkvSQ.js} +4 -4
  17. package/public/assets/_app.database-ByLAAKXX.js +24 -0
  18. package/public/assets/_app.index-3mAmJsCn.js +62 -0
  19. package/public/assets/_app.keys-Ce6Xd1RK.js +76 -0
  20. package/public/assets/{_app.logs-DV7O6ZUp.js → _app.logs-CmDNhsU4.js} +7 -7
  21. package/public/assets/_app.models-mqdU56d8.js +148 -0
  22. package/public/assets/_app.plugins._pluginId-C0VWWCD2.js +20 -0
  23. package/public/assets/{_app.settings-B8zjCira.js → _app.settings-BLJ-25xq.js} +3 -3
  24. package/public/assets/{_app.usage-C4GR06sI.js → _app.usage-BaB40kku.js} +4 -4
  25. package/public/assets/{index-B2twwe7y.js → index-C3Fp8XmZ.js} +3 -3
  26. package/public/assets/{login-CJz2YA-O.js → login-Bn1s6JI_.js} +2 -2
  27. package/public/assets/plus-Cdyfj4uP.js +1 -0
  28. package/public/assets/{queries-BOAAI06M.js → queries-CX9mStps.js} +5 -2
  29. package/public/assets/{shared-Rzhx6i7s.js → shared-DtfLcn24.js} +2 -2
  30. package/public/assets/{trash-2-C7-QrCg5.js → trash-2-B5fBDSkh.js} +1 -1
  31. package/public/index.html +4 -4
  32. package/public/shared/dashboard-sdk.js +1 -0
  33. package/public/assets/Confirm-BO1xS6uH.js +0 -4
  34. package/public/assets/Lamp-BDf7-dMa.js +0 -25
  35. package/public/assets/Modal-OALemCh6.js +0 -82
  36. package/public/assets/Rack-DhVnjAjC.js +0 -180
  37. package/public/assets/States-6G9NsYha.js +0 -54
  38. package/public/assets/_app-ChlUa_Ov.js +0 -1
  39. package/public/assets/_app.accounts-CJ6lFXIx.js +0 -64
  40. package/public/assets/_app.database-BHaMpXld.js +0 -39
  41. package/public/assets/_app.index-C1vtrxnM.js +0 -62
  42. package/public/assets/_app.keys-Bz6-VVJi.js +0 -76
  43. package/public/assets/_app.models-KIctkivt.js +0 -148
  44. package/public/assets/_app.plugins._pluginId-BbqXEJUB.js +0 -20
  45. package/public/assets/dist-9ps0Qd15.js +0 -1
  46. package/public/assets/plus-C7a0RuII.js +0 -1
package/README.md CHANGED
@@ -161,12 +161,27 @@ omni connect anthropic # or: openai, kimi, kilo, grok
161
161
  ```
162
162
 
163
163
  Every provider also takes a plain API key, if that is what you hold rather than
164
- a subscription. `custom` takes nothing else:
164
+ a subscription:
165
165
 
166
166
  ```bash
167
167
  omni credentials add-key anthropic # prompts for the key, or reads stdin
168
168
  ```
169
169
 
170
+ There is a sixth provider, `custom`, which points an existing wire codec at an
171
+ origin you supply — an endpoint you host or pay for that is not one of the five.
172
+ It has no subscription to authorize, so there is no `omni connect custom`; it is
173
+ an API key plus the endpoint to spend it against:
174
+
175
+ ```bash
176
+ omni credentials add-key custom \
177
+ --endpoint-id my-endpoint --endpoint-label 'My endpoint' \
178
+ --origin https://api.example.com --protocol chat-completions
179
+ ```
180
+
181
+ `--protocol` is `chat-completions` or `responses`, naming which codec to reuse.
182
+ `--origin` is a bare origin — scheme and host, no path, query, or credentials in
183
+ the URL.
184
+
170
185
  The console offers the same choice per provider on the Connect dialog.
171
186
 
172
187
  Define a virtual model your clients will ask for, seeding its pricing and
@@ -353,10 +368,12 @@ Use `--db <path>` to point one command somewhere else.
353
368
  | `omni usage` | spend and tokens, by provider, model, key, or day |
354
369
  | `omni quota` | provider quota per window: use, burn rate, and when it runs out |
355
370
  | `omni connect <provider>` | authorize an account from the terminal |
356
- | `omni credentials …` | list, show, enable, disable, retier, refresh, remove |
357
- | `omni models …` | list, show, put, remove, `dry-run`, `catalog` |
358
- | `omni keys …` | list, create, revoke |
371
+ | `omni credentials …` | list, show, enable, disable, `set`, `rm`, refresh, `add-key`, health |
372
+ | `omni models …` | list, show, put, `rm`, `dry-run`, `catalog` |
373
+ | `omni keys …` | list, create, `limits`, revoke |
359
374
  | `omni plugin …` | list, verify, install, remove; see [Plugins](#plugins) |
375
+ | `omni service install` / `uninstall` | write or remove a systemd unit for this installation |
376
+ | `omni setup claude` / `opencode` | point a client's config at this gateway |
360
377
  | `omni settings get` / `set` | routing weights, retention, deadlines, and the runtime switches |
361
378
  | `omni admin set-password` | change the console password |
362
379
  | `omni db migrate` | create or upgrade the database |
@@ -390,9 +407,11 @@ start` supervises the process itself with a pidfile under
390
407
 
391
408
  ### Restarting and stopping from the console
392
409
 
393
- The console's Database screen can restart and shut down the gateway. A restart
394
- only restarts if something would start the process again, so what the control
395
- does and whether it is offered at all depends on how this installation runs:
410
+ The console can restart and shut down the gateway, from the foot of its sidebar
411
+ reachable from every screen, because a gateway you need to restart is rarely
412
+ one you were looking at the Database screen of. A restart only restarts if
413
+ something would start the process again, so what the control does — and whether
414
+ it is offered at all — depends on how this installation runs:
396
415
 
397
416
  - **Under systemd**, it works. The gateway asks the manager rather than
398
417
  signalling itself — `systemctl [--user] --no-block restart
@@ -404,8 +423,9 @@ does — and whether it is offered at all — depends on how this installation r
404
423
  of promising a restart it has no way to verify. Run with
405
424
  `--restart unless-stopped` if you want the control to mean what it says.
406
425
  - **With no supervisor** — `omni start` with no unit installed — the control is
407
- disabled and shows the reason. Nothing is watching the process, so an exit is
408
- simply the end of it. Use `omni restart` from a terminal on the machine.
426
+ disabled, and the section names the supervisor it found. Nothing is watching
427
+ the process, so an exit is simply the end of it. Use `omni restart` from a
428
+ terminal on the machine.
409
429
 
410
430
  Shutdown is offered in every shape, because stopping is the point of it. In a
411
431
  container it is a one-way door: stopping the only process takes the console that
@@ -426,6 +446,20 @@ Configuration is environment variables, read from the installation's `.env`:
426
446
  | `OMNI_LOG_LEVEL` | No | `info` | Stdout threshold: `debug`, `info`, `warn`, or `error` |
427
447
  | `OMNI_LOG_FILE` | No | the systemd journal, when there is one | Where stdout was already redirected, so the Console screen can read it back. Names a file; does not create one |
428
448
  | `OMNI_BODY_LOGGING_ALLOWED` | No | unset | Permits request/response body capture on this installation. Read at boot. Capture also needs the runtime setting; see [Recording bodies](#recording-bodies) |
449
+ | `OMNI_EXPOSE_CLAUDE_CODE_ALIASES` | No | off | Advertises the reserved `claude/*` aliases on `/v1/models`. Read at boot |
450
+ | `OMNI_ROOT` | No | the installation in the current directory, else `~/.config/omnigateway` | Which installation the CLI acts on, when `--root` is not passed |
451
+ | `OMNI_PLUGIN_REGISTRY` | No | the public npm registry | Registry `omni plugin install <name>` resolves through; must be `https://` |
452
+
453
+ `OMNI_ROOT` is the one variable read from your shell and never from a root's `.env`, for the
454
+ reason it has to be: a variable that selects the installation cannot live inside the installation
455
+ it selects. A `--root` flag additionally suppresses an ambient `OMNI_DB_PATH`, and says so on
456
+ stderr, so pointing the CLI at one installation from inside an unrelated checkout cannot pick up
457
+ that checkout's database.
458
+
459
+ The provider client-identity overrides — `OMNI_UA_*`, `OMNI_ORDER_*`, and the per-provider CLI
460
+ version pins — are deliberately left out of this table and documented in `.env.example`. They
461
+ change how the gateway identifies itself to a provider, which is not configuration in the sense
462
+ the rest of this table is.
429
463
 
430
464
  Gateway events are written to stdout as one greppable line each: process lifecycle, OAuth
431
465
  refreshes, quota probes, failover, and errors.
@@ -441,12 +475,16 @@ bun apps/gateway/src/index.ts >> /var/log/omni.log 2>&1
441
475
  `omni start` does both for the gateway it supervises, and under systemd the journal needs no
442
476
  setup.
443
477
 
444
- Routing behaviour weights, retry limits, request deadline, log retention,
445
- how often provider quota is polled lives in the database, not the
446
- environment. Edit it with `omni settings set` or in the console.
447
-
448
- `.env.example` in the repository documents the optional provider
449
- client-identity overrides.
478
+ Everything else lives in the database rather than the environment, so it can be
479
+ changed without a restart: the six routing weights, `maxAttempts`,
480
+ `requestDeadlineMs`, the circuit breaker's `breakerThreshold` and
481
+ `breakerCooldownMs`, `logRetentionDays`, `quotaPollIntervalMs`, `rtkEnabled`,
482
+ and the two body-capture switches. Edit them with `omni settings set` or in the
483
+ console. `quotaPollIntervalMs` is the one exception: the poller reads it once at
484
+ boot, so a change to it takes a restart. Snapshot retention —
485
+ `snapshotKeepLatest` and `snapshotMaxAgeDays` — is stored alongside them but
486
+ deliberately edited on the Database screen instead; see
487
+ [Snapshots and restore](#snapshots-and-restore) for why.
450
488
 
451
489
  ## Recording bodies
452
490
 
package/bin/omni.js CHANGED
@@ -2879,6 +2879,7 @@ var grokAdapter = {
2879
2879
  import { request as httpRequest } from "http";
2880
2880
  import { request as httpsRequest } from "https";
2881
2881
  import { Readable } from "stream";
2882
+ var CONNECT_ATTEMPT_TIMEOUT_MS = 3000;
2882
2883
  function nodeHttpClient(options = {}) {
2883
2884
  const logger2 = options.logger ?? noopLogger;
2884
2885
  const now = options.now ?? (() => Date.now());
@@ -2907,15 +2908,17 @@ function nodeHttpClient(options = {}) {
2907
2908
  if (req.body.length > 0 && !hasHeader(req, "content-length")) {
2908
2909
  headers["Content-Length"] = bodyBytes.byteLength;
2909
2910
  }
2910
- const outgoing = send({
2911
+ const requestOptions = {
2911
2912
  protocol: url.protocol,
2912
2913
  hostname: url.hostname,
2913
2914
  port: url.port || (url.protocol === "https:" ? 443 : 80),
2914
2915
  path: `${url.pathname}${url.search}`,
2915
2916
  method: req.method,
2916
2917
  headers,
2917
- setHost: !hasHeader(req, "host")
2918
- }, (incoming) => {
2918
+ setHost: !hasHeader(req, "host"),
2919
+ autoSelectFamilyAttemptTimeout: CONNECT_ATTEMPT_TIMEOUT_MS
2920
+ };
2921
+ const outgoing = send(requestOptions, (incoming) => {
2919
2922
  const chunks = [];
2920
2923
  let buffered = null;
2921
2924
  const responseHeaders = new Headers;
@@ -3526,14 +3529,13 @@ function createConnectFlows(deps) {
3526
3529
  return {
3527
3530
  async start(providerInput, labelInput) {
3528
3531
  flows.sweep();
3529
- if (!isProviderId(providerInput)) {
3530
- throw new GatewayError("BAD_REQUEST", "provider must be one of anthropic, openai, kimi, kilo, grok");
3531
- }
3532
- const label = typeof labelInput === "string" && labelInput.trim().length > 0 ? labelInput.trim() : providerInput;
3532
+ const unconnectable = () => new GatewayError("BAD_REQUEST", `provider must be one of ${Object.keys(deps.providers).join(", ")}`);
3533
+ if (!isProviderId(providerInput))
3534
+ throw unconnectable();
3533
3535
  const provider = deps.providers[providerInput];
3534
- if (provider === undefined) {
3535
- throw new GatewayError("BAD_REQUEST", "provider does not support OAuth");
3536
- }
3536
+ if (provider === undefined)
3537
+ throw unconnectable();
3538
+ const label = typeof labelInput === "string" && labelInput.trim().length > 0 ? labelInput.trim() : providerInput;
3537
3539
  const redirectUri = callbackUri(providerInput);
3538
3540
  const oauthDeps = { http: deps.http, now: deps.now };
3539
3541
  const initial = await provider.start({ redirectUri }, oauthDeps);
@@ -21308,7 +21310,7 @@ import { basename as basename2, join as join3, resolve as resolve2, sep as sep2
21308
21310
 
21309
21311
  // packages/plugin-api/src/version.ts
21310
21312
  var PLUGIN_API_VERSION = 1;
21311
- var DASHBOARD_SDK_VERSION = "0.1.0";
21313
+ var DASHBOARD_SDK_VERSION = "0.1.1";
21312
21314
  // packages/plugin-api/src/manifest.ts
21313
21315
  var CAPABILITIES = [
21314
21316
  "storage",
@@ -22885,6 +22887,7 @@ var OAUTH_PROVIDERS = {
22885
22887
  kilo: kiloOAuth,
22886
22888
  grok: grokOAuth
22887
22889
  };
22890
+ var OAUTH_PROVIDER_IDS = Object.keys(OAUTH_PROVIDERS);
22888
22891
  // packages/control/src/oauth/refresh.ts
22889
22892
  function createRefresher(deps) {
22890
22893
  const logger2 = deps.logger ?? noopLogger;
@@ -23498,8 +23501,8 @@ var connect = {
23498
23501
  options: { label: { type: "string" } },
23499
23502
  async run(args, { ctx, writer, prompt, connect: connectFlows }) {
23500
23503
  const providerId = requirePositional(args, 0, "provider");
23501
- if (!isProviderId(providerId)) {
23502
- throw new UsageError("provider must be one of anthropic, openai, kimi, kilo, grok");
23504
+ if (!OAUTH_PROVIDER_IDS.includes(providerId)) {
23505
+ throw new UsageError(`provider must be one of ${OAUTH_PROVIDER_IDS.join(", ")}`);
23503
23506
  }
23504
23507
  const flows = connectFlows(await ctx.store());
23505
23508
  const start = await flows.start(providerId, stringFlag(args.values, "label"));
@@ -23975,7 +23978,7 @@ var credentialsAddKey = {
23975
23978
  async run(args, { ctx, writer, prompt }) {
23976
23979
  const providerId = requirePositional(args, 0, "provider");
23977
23980
  if (!isProviderId(providerId)) {
23978
- throw new UsageError("provider must be one of anthropic, openai, kimi, kilo, grok, custom");
23981
+ throw new UsageError(`provider must be one of ${PROVIDER_IDS.join(", ")}`);
23979
23982
  }
23980
23983
  const protocolFlag = stringFlag(args.values, "protocol");
23981
23984
  const protocol = protocolFlag === "chat-completions" ? "chat_completions" : protocolFlag === "responses" ? "responses" : protocolFlag;
package/gateway.js CHANGED
@@ -8239,6 +8239,7 @@ var grokAdapter = {
8239
8239
  import { request as httpRequest } from "http";
8240
8240
  import { request as httpsRequest } from "https";
8241
8241
  import { Readable } from "stream";
8242
+ var CONNECT_ATTEMPT_TIMEOUT_MS = 3000;
8242
8243
  function nodeHttpClient(options = {}) {
8243
8244
  const logger2 = options.logger ?? noopLogger;
8244
8245
  const now = options.now ?? (() => Date.now());
@@ -8267,15 +8268,17 @@ function nodeHttpClient(options = {}) {
8267
8268
  if (req.body.length > 0 && !hasHeader(req, "content-length")) {
8268
8269
  headers["Content-Length"] = bodyBytes.byteLength;
8269
8270
  }
8270
- const outgoing = send({
8271
+ const requestOptions = {
8271
8272
  protocol: url.protocol,
8272
8273
  hostname: url.hostname,
8273
8274
  port: url.port || (url.protocol === "https:" ? 443 : 80),
8274
8275
  path: `${url.pathname}${url.search}`,
8275
8276
  method: req.method,
8276
8277
  headers,
8277
- setHost: !hasHeader(req, "host")
8278
- }, (incoming) => {
8278
+ setHost: !hasHeader(req, "host"),
8279
+ autoSelectFamilyAttemptTimeout: CONNECT_ATTEMPT_TIMEOUT_MS
8280
+ };
8281
+ const outgoing = send(requestOptions, (incoming) => {
8279
8282
  const chunks = [];
8280
8283
  let buffered = null;
8281
8284
  const responseHeaders = new Headers;
@@ -8895,14 +8898,13 @@ function createConnectFlows(deps) {
8895
8898
  return {
8896
8899
  async start(providerInput, labelInput) {
8897
8900
  flows.sweep();
8898
- if (!isProviderId(providerInput)) {
8899
- throw new GatewayError("BAD_REQUEST", "provider must be one of anthropic, openai, kimi, kilo, grok");
8900
- }
8901
- const label = typeof labelInput === "string" && labelInput.trim().length > 0 ? labelInput.trim() : providerInput;
8901
+ const unconnectable = () => new GatewayError("BAD_REQUEST", `provider must be one of ${Object.keys(deps.providers).join(", ")}`);
8902
+ if (!isProviderId(providerInput))
8903
+ throw unconnectable();
8902
8904
  const provider = deps.providers[providerInput];
8903
- if (provider === undefined) {
8904
- throw new GatewayError("BAD_REQUEST", "provider does not support OAuth");
8905
- }
8905
+ if (provider === undefined)
8906
+ throw unconnectable();
8907
+ const label = typeof labelInput === "string" && labelInput.trim().length > 0 ? labelInput.trim() : providerInput;
8906
8908
  const redirectUri = callbackUri(providerInput);
8907
8909
  const oauthDeps = { http: deps.http, now: deps.now };
8908
8910
  const initial = await provider.start({ redirectUri }, oauthDeps);
@@ -26692,12 +26694,7 @@ function describeLifecycle(env2, fileExists) {
26692
26694
  note: "restart exits the container and relies on its restart policy, which cannot be read from inside it"
26693
26695
  };
26694
26696
  }
26695
- return {
26696
- supervisor: "none",
26697
- canRestart: false,
26698
- canShutdown: true,
26699
- note: "no supervisor is watching this process, so nothing would start it again"
26700
- };
26697
+ return { supervisor: "none", canRestart: false, canShutdown: true };
26701
26698
  }
26702
26699
  function systemdScope(env2) {
26703
26700
  return env2.MANAGERPID === undefined ? "system" : "user";
@@ -26860,7 +26857,7 @@ import { join as join3 } from "path";
26860
26857
 
26861
26858
  // packages/plugin-api/src/version.ts
26862
26859
  var PLUGIN_API_VERSION = 1;
26863
- var DASHBOARD_SDK_VERSION = "0.1.0";
26860
+ var DASHBOARD_SDK_VERSION = "0.1.1";
26864
26861
  // packages/plugin-api/src/manifest.ts
26865
26862
  var CAPABILITIES = [
26866
26863
  "storage",
@@ -27846,6 +27843,7 @@ var OAUTH_PROVIDERS = {
27846
27843
  kilo: kiloOAuth,
27847
27844
  grok: grokOAuth
27848
27845
  };
27846
+ var OAUTH_PROVIDER_IDS = Object.keys(OAUTH_PROVIDERS);
27849
27847
  // packages/control/src/oauth/lead.ts
27850
27848
  var DISPATCH_REFRESH_LEAD_MS = 120000;
27851
27849
  var SCHEDULER_REFRESH_LEAD_MS = 300000;
@@ -48083,7 +48081,7 @@ function createApp(deps) {
48083
48081
  } catch {
48084
48082
  return error51();
48085
48083
  }
48086
- const protectedPrefix = ["/api", "/v1", "/oauth"].some((prefix2) => decodedPath === prefix2 || decodedPath.startsWith(`${prefix2}/`));
48084
+ const protectedPrefix = ["/api", "/v1"].some((prefix2) => decodedPath === prefix2 || decodedPath.startsWith(`${prefix2}/`));
48087
48085
  if (protectedPrefix)
48088
48086
  return error51();
48089
48087
  const requestedPath = decodedPath === "/" ? "/index.html" : decodedPath;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnigateway",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "description": "Self-hosted AI gateway with Anthropic- and OpenAI-compatible APIs, an admin console, and a CLI",
5
5
  "license": "MIT",
6
6
  "author": "Harismawan <mail@harismawan.com>",
@@ -1,4 +1,4 @@
1
- import{at as e,ut as t}from"./queries-BOAAI06M.js";import{c as n}from"./Rack-DhVnjAjC.js";import{useCallback as r,useEffect as i,useRef as a,useState as o}from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";import l from"styled-components";var u=n(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]),d=n(`chevron-down`,[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]),f=n(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),p=n(`copy`,[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]);function m(e){if(e===null||typeof getSelection!=`function`)return!1;let t=getSelection();if(t===null)return!1;try{let n=document.createRange();return n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n),!0}catch{return!1}}async function h(e,t){if(typeof navigator<`u`&&navigator.clipboard!==void 0)try{return await navigator.clipboard.writeText(e),`copied`}catch{}let n=m(t??null);if(n&&typeof document.execCommand==`function`)try{if(document.execCommand(`copy`))return`copied`}catch{}return n?`selected`:`failed`}var g=l.div`
1
+ import{at as e,ut as t}from"./queries-CX9mStps.js";import{g as n}from"./Rack-ziQuyb2l.js";import{useCallback as r,useEffect as i,useRef as a,useState as o}from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";import l from"styled-components";var u=n(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]),d=n(`chevron-down`,[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]),f=n(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),p=n(`copy`,[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]);function m(e){if(e===null||typeof getSelection!=`function`)return!1;let t=getSelection();if(t===null)return!1;try{let n=document.createRange();return n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n),!0}catch{return!1}}async function h(e,t){if(typeof navigator<`u`&&navigator.clipboard!==void 0)try{return await navigator.clipboard.writeText(e),`copied`}catch{}let n=m(t??null);if(n&&typeof document.execCommand==`function`)try{if(document.execCommand(`copy`))return`copied`}catch{}return n?`selected`:`failed`}var g=l.div`
2
2
  display: flex;
3
3
  align-items: stretch;
4
4
  gap: 0;
@@ -1,4 +1,4 @@
1
- import{$ as e}from"./queries-BOAAI06M.js";import{useId as t}from"react";import{jsx as n,jsxs as r}from"react/jsx-runtime";import i from"styled-components";var a=`
1
+ import{$ as e}from"./queries-CX9mStps.js";import{useId as t}from"react";import{jsx as n,jsxs as r}from"react/jsx-runtime";import i from"styled-components";var a=`
2
2
  width: 100%;
3
3
  border-radius: 3px;
4
4
  transition: border-color 120ms ease;
@@ -1 +1 @@
1
- import{_t as e,ht as t,pt as n}from"./queries-BOAAI06M.js";import{n as r}from"./matchContext-BOenO3J2.js";import*as i from"react";import{Fragment as a,jsx as o,jsxs as s}from"react/jsx-runtime";function c(e){return e?.isNotFound===!0}function l(e){return o(u,{...e})}var u=class extends i.Component{constructor(...e){super(...e),this.state={error:null},this.reset=()=>{this.setState({error:null})}}static getDerivedStateFromProps(e,t){let n=e.getResetKey();return t.error&&t.resetKey!==n?{resetKey:n,error:null}:{resetKey:n}}static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){this.props.onCatch?.(e,t)}render(){let e=this.state.error;return e?i.createElement(this.props.errorComponent??d,{error:e,reset:this.reset}):this.props.children}};function d({error:e}){let[t,n]=i.useState(!1);return s(`div`,{style:{padding:`.5rem`,maxWidth:`100%`},children:[s(`div`,{style:{display:`flex`,alignItems:`center`,gap:`.5rem`},children:[o(`strong`,{style:{fontSize:`1rem`},children:`Something went wrong!`}),o(`button`,{style:{appearance:`none`,fontSize:`.6em`,border:`1px solid currentColor`,padding:`.1rem .2rem`,fontWeight:`bold`,borderRadius:`.25rem`},onClick:()=>n(e=>!e),children:t?`Hide Error`:`Show Error`})]}),o(`div`,{style:{height:`.25rem`}}),t?o(`div`,{children:o(`pre`,{style:{fontSize:`.7em`,border:`1px solid red`,borderRadius:`.25rem`,padding:`.3rem`,color:`red`,overflow:`auto`},children:e.message?o(`code`,{children:e.message}):null})}):null]})}function f(e){let r=t(),i=`not-found-${n(r.stores.location,e=>e.pathname)}-${n(r.stores.status,e=>e)}`;return o(l,{getResetKey:()=>i,onCatch:(t,n)=>{if(c(t))e.onCatch?.(t,n);else throw t},errorComponent:({error:t})=>{if(c(t))return e.fallback?.(t);throw t},children:e.children})}function p(){return o(`p`,{children:`Not Found`})}function m(e){return o(a,{children:e.children})}function h(e,t,n){return t.options.notFoundComponent?o(t.options.notFoundComponent,{...n}):e.options.defaultNotFoundComponent?o(e.options.defaultNotFoundComponent,{...n}):o(p,{})}function g(e,t){let n=t?.options.pendingComponent??e.options.defaultPendingComponent;return n?o(n,{}):null}var _=(e,t)=>e[0]===t[0]&&e[1]===t[1],v=i.memo(function({routeId:e}){let r=t();return o(y,{router:r,match:n(r.stores.getMatchStore(e),e=>e)})});function y({router:t,match:n}){let a=t.routesById[n.routeId],u=g(t,a),d=a.options.errorComponent??t.options.defaultErrorComponent,p=a.options.onCatch??t.options.defaultOnCatch,h=a.isRoot?a.options.notFoundComponent??t.options.notFoundRoute?.options.component:a.options.notFoundComponent,_=n.ssr===!1||n.ssr===`data-only`,v=a.options.wrapInSuspense??u??(a.options.errorComponent?.preload||_)?i.Suspense:m,y=d?l:m,x=h?f:m;return s(a.isRoot?a.options.shellComponent??m:m,{children:[o(r.Provider,{value:n.routeId,children:o(v,{fallback:u,children:o(y,{getResetKey:()=>n,errorComponent:d,onCatch:(e,t)=>{if(c(e))throw e.routeId??=n.routeId,e;p?.(e,t)},children:o(x,{fallback:e=>{if(e.routeId??=n.routeId,e.routeId!==n.routeId)throw e;return i.createElement(h,e)},children:_?o(e,{fallback:u,children:o(b,{match:n})}):o(b,{match:n})})})})}),null]})}var b=i.memo(function({match:e}){let n=t(),r=e.routeId,a=n.routesById[r],s=i.useMemo(()=>{let t=(a.options.remountDeps??n.options.defaultRemountDeps)?.({routeId:r,loaderDeps:e.loaderDeps,params:e._strictParams,search:e._strictSearch});return t?JSON.stringify(t):void 0},[r,e.loaderDeps,e._strictParams,e._strictSearch,a.options.remountDeps,n.options.defaultRemountDeps]),c=i.useMemo(()=>{let e=a.options.component??n.options.defaultComponent;return e?o(e,{},s):o(x,{})},[s,a.options.component,n.options.defaultComponent]);if(e.status===`pending`){if(n._tx)throw n._tx[5];return g(n,a)}if(e.status===`notFound`)return h(n,a,e.error);if(e.status===`error`)throw e.error;return c}),x=i.memo(function(){let e=t(),a=i.useContext(r),s,c,l;{let t=e.stores.getMatchStore(a);[s,c]=n(t,e=>[!!e._notFound,e.error],_),l=n(e.stores.ids,e=>e[e.indexOf(a)+1])}if(s)return h(e,e.routesById[a],c);if(!l)return null;let u=o(v,{routeId:l});return a===`__root__`?o(i.Suspense,{fallback:g(e),children:u}):u});export{l as a,m as i,x as n,c as o,g as r,v as t};
1
+ import{_t as e,ht as t,pt as n}from"./queries-CX9mStps.js";import{n as r}from"./matchContext-BOenO3J2.js";import*as i from"react";import{Fragment as a,jsx as o,jsxs as s}from"react/jsx-runtime";function c(e){return e?.isNotFound===!0}function l(e){return o(u,{...e})}var u=class extends i.Component{constructor(...e){super(...e),this.state={error:null},this.reset=()=>{this.setState({error:null})}}static getDerivedStateFromProps(e,t){let n=e.getResetKey();return t.error&&t.resetKey!==n?{resetKey:n,error:null}:{resetKey:n}}static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){this.props.onCatch?.(e,t)}render(){let e=this.state.error;return e?i.createElement(this.props.errorComponent??d,{error:e,reset:this.reset}):this.props.children}};function d({error:e}){let[t,n]=i.useState(!1);return s(`div`,{style:{padding:`.5rem`,maxWidth:`100%`},children:[s(`div`,{style:{display:`flex`,alignItems:`center`,gap:`.5rem`},children:[o(`strong`,{style:{fontSize:`1rem`},children:`Something went wrong!`}),o(`button`,{style:{appearance:`none`,fontSize:`.6em`,border:`1px solid currentColor`,padding:`.1rem .2rem`,fontWeight:`bold`,borderRadius:`.25rem`},onClick:()=>n(e=>!e),children:t?`Hide Error`:`Show Error`})]}),o(`div`,{style:{height:`.25rem`}}),t?o(`div`,{children:o(`pre`,{style:{fontSize:`.7em`,border:`1px solid red`,borderRadius:`.25rem`,padding:`.3rem`,color:`red`,overflow:`auto`},children:e.message?o(`code`,{children:e.message}):null})}):null]})}function f(e){let r=t(),i=`not-found-${n(r.stores.location,e=>e.pathname)}-${n(r.stores.status,e=>e)}`;return o(l,{getResetKey:()=>i,onCatch:(t,n)=>{if(c(t))e.onCatch?.(t,n);else throw t},errorComponent:({error:t})=>{if(c(t))return e.fallback?.(t);throw t},children:e.children})}function p(){return o(`p`,{children:`Not Found`})}function m(e){return o(a,{children:e.children})}function h(e,t,n){return t.options.notFoundComponent?o(t.options.notFoundComponent,{...n}):e.options.defaultNotFoundComponent?o(e.options.defaultNotFoundComponent,{...n}):o(p,{})}function g(e,t){let n=t?.options.pendingComponent??e.options.defaultPendingComponent;return n?o(n,{}):null}var _=(e,t)=>e[0]===t[0]&&e[1]===t[1],v=i.memo(function({routeId:e}){let r=t();return o(y,{router:r,match:n(r.stores.getMatchStore(e),e=>e)})});function y({router:t,match:n}){let a=t.routesById[n.routeId],u=g(t,a),d=a.options.errorComponent??t.options.defaultErrorComponent,p=a.options.onCatch??t.options.defaultOnCatch,h=a.isRoot?a.options.notFoundComponent??t.options.notFoundRoute?.options.component:a.options.notFoundComponent,_=n.ssr===!1||n.ssr===`data-only`,v=a.options.wrapInSuspense??u??(a.options.errorComponent?.preload||_)?i.Suspense:m,y=d?l:m,x=h?f:m;return s(a.isRoot?a.options.shellComponent??m:m,{children:[o(r.Provider,{value:n.routeId,children:o(v,{fallback:u,children:o(y,{getResetKey:()=>n,errorComponent:d,onCatch:(e,t)=>{if(c(e))throw e.routeId??=n.routeId,e;p?.(e,t)},children:o(x,{fallback:e=>{if(e.routeId??=n.routeId,e.routeId!==n.routeId)throw e;return i.createElement(h,e)},children:_?o(e,{fallback:u,children:o(b,{match:n})}):o(b,{match:n})})})})}),null]})}var b=i.memo(function({match:e}){let n=t(),r=e.routeId,a=n.routesById[r],s=i.useMemo(()=>{let t=(a.options.remountDeps??n.options.defaultRemountDeps)?.({routeId:r,loaderDeps:e.loaderDeps,params:e._strictParams,search:e._strictSearch});return t?JSON.stringify(t):void 0},[r,e.loaderDeps,e._strictParams,e._strictSearch,a.options.remountDeps,n.options.defaultRemountDeps]),c=i.useMemo(()=>{let e=a.options.component??n.options.defaultComponent;return e?o(e,{},s):o(x,{})},[s,a.options.component,n.options.defaultComponent]);if(e.status===`pending`){if(n._tx)throw n._tx[5];return g(n,a)}if(e.status===`notFound`)return h(n,a,e.error);if(e.status===`error`)throw e.error;return c}),x=i.memo(function(){let e=t(),a=i.useContext(r),s,c,l;{let t=e.stores.getMatchStore(a);[s,c]=n(t,e=>[!!e._notFound,e.error],_),l=n(e.stores.ids,e=>e[e.indexOf(a)+1])}if(s)return h(e,e.routesById[a],c);if(!l)return null;let u=o(v,{routeId:l});return a===`__root__`?o(i.Suspense,{fallback:g(e),children:u}):u});export{l as a,m as i,x as n,c as o,g as r,v as t};
@@ -0,0 +1,25 @@
1
+ import{$ as e,it as t,nt as n}from"./queries-CX9mStps.js";import{jsx as r,jsxs as i}from"react/jsx-runtime";import a from"styled-components";var o=a.section`
2
+ background: ${({theme:e})=>e.color.panel};
3
+ border: 1px solid ${({theme:e})=>e.color.rule};
4
+ border-radius: ${({theme:e})=>e.radius.panel};
5
+ box-shadow: ${({theme:e})=>e.color.shadow};
6
+ overflow: hidden;
7
+ display: flex;
8
+ flex-direction: column;
9
+ min-width: 0;
10
+ `,s=a.header`
11
+ display: flex;
12
+ align-items: center;
13
+ gap: ${({theme:e})=>e.space(2)};
14
+ padding: ${({theme:e})=>`${e.space(2)} ${e.space(3)}`};
15
+ border-bottom: 1px solid ${({theme:e})=>e.color.rule};
16
+ background: ${({theme:e})=>e.color.panelSunk};
17
+ min-height: 34px;
18
+ `,c=a.div`
19
+ padding: ${({theme:e,$flush:t})=>t===!0?`0`:e.space(3)};
20
+ min-width: 0;
21
+ `,l=a.footer`
22
+ padding: ${({theme:e})=>`${e.space(2)} ${e.space(3)}`};
23
+ border-top: 1px solid ${({theme:e})=>e.color.rule};
24
+ background: ${({theme:e})=>e.color.panelSunk};
25
+ `;function u({legend:a,meta:u,actions:d,footer:f,flush:p,className:m,children:h}){return i(o,{className:m,children:[i(s,{children:[r(e,{children:a}),u===void 0?null:r(e,{as:`span`,children:u}),r(t,{}),d===void 0?null:r(n,{$gap:1,children:d})]}),r(c,{...p===!0?{$flush:!0}:{},children:h}),f===void 0?null:r(l,{children:f})]})}export{o as n,u as t};