okengine 0.18.3 → 0.18.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/AGENTS.md +5 -3
  2. package/README.md +5 -5
  3. package/package.json +2 -2
  4. package/site/content/docs/ai/index.mdx +25 -6
  5. package/site/content/docs/ai/mcp.mdx +10 -1
  6. package/site/content/docs/ai/skills.mdx +9 -9
  7. package/site/content/docs/elements/ai.mdx +1 -1
  8. package/site/content/docs/elements/gate.mdx +3 -2
  9. package/site/content/docs/elements/index.mdx +42 -11
  10. package/site/content/docs/elements/store.mdx +2 -0
  11. package/site/content/docs/get-started/basic-usage.mdx +3 -10
  12. package/site/content/docs/get-started/index.mdx +1 -1
  13. package/site/content/docs/get-started/installation.mdx +1 -1
  14. package/site/content/docs/get-started/introduction.mdx +69 -64
  15. package/site/content/docs/get-started/meta.json +1 -1
  16. package/site/content/docs/get-started/project-structure.mdx +4 -11
  17. package/site/content/docs/get-started/why.mdx +64 -114
  18. package/site/content/docs/index.mdx +69 -15
  19. package/site/content/docs/meta.json +10 -5
  20. package/site/content/docs/providers/index.mdx +2 -0
  21. package/site/content/docs/recipes/index.mdx +2 -0
  22. package/src/cli/competitor-mention-removal.test.ts +1 -1
  23. package/src/compiler/extract.test.ts +1 -1
  24. package/src/console/ui-next/dist/assets/{access-page-DY4N6nnk.js → access-page-3-EFj-2G.js} +1 -1
  25. package/src/console/ui-next/dist/assets/{flows-page-CsPDMrVM.js → flows-page-cVFnA4HH.js} +1 -1
  26. package/src/console/ui-next/dist/assets/{index-CcTDXHuz.js → index-CMIgUbD0.js} +3 -3
  27. package/src/console/ui-next/dist/assets/{observability-page-CKR595wP.js → observability-page-CQ3p34ip.js} +1 -1
  28. package/src/console/ui-next/dist/assets/{units-page-CpPFFKyE.js → units-page-l8FeKfnP.js} +1 -1
  29. package/src/console/ui-next/dist/assets/{vault-page-BsMf-9_W.js → vault-page-CL-d_mLE.js} +1 -1
  30. package/src/console/ui-next/dist/index.html +1 -1
  31. package/src/index.ts +1 -1
@@ -1,164 +1,114 @@
1
1
  ---
2
2
  title: Why OKE
3
- description: From forty tools to one species the Manifest, the `fx` rule, and the eight closed elements.
3
+ description: The problem of seams across independent backend tools, the insight, and the smaller model.
4
4
  source: docs/spec/unified-theory.md
5
5
  icon: Compass
6
6
  ---
7
7
 
8
- ## From forty tools to one species
8
+ ## The Problem: The Seams You Own
9
9
 
10
- A booking API, a nightly cleanup job, a receipt email, a row-change hook in most stacks these are **four frameworks**. In OKE they are **one species** with one shape. Learn the shape once; only the trigger changes.
10
+ Modern backends accumulate many independently adopted systems: router, queue, cron, websockets, cache, secrets, mailer, AI wrappers, and observability.
11
11
 
12
- > **The one rule**
13
- > Every backend behavior is a **Flow**: `on(Trigger) Effects`. There are no separate species called endpoints, handlers, consumers, jobs, or workflows.
14
-
15
- ## The pain we solve
16
-
17
- Every TypeScript backend works on day one. The bill arrives later. None of these are router problems — they are **gaps** between what your code knows and what your tooling knows.
18
-
19
- ### Cache that lies
20
-
21
- You add a column to `orders` and update three writers. The cache key in `checkout` is not one of them. A customer finds it a week later.
12
+ <Callout title="A note on the count">
13
+ 'Forty' is a representative illustration of the number of backend concerns developers commonly
14
+ assemble across modern stacks, not a literal census.
15
+ </Callout>
22
16
 
23
- OKE derives: reads and writes are recorded through `fx`, so cache invalidation follows the Flow — there is no separate key to remember.
17
+ ```text
18
+ many systems → many seams → many contracts → many mental models
19
+ ```
24
20
 
25
- ### Secret that fails at 2am
21
+ Every TypeScript backend works on day one. The bill arrives later in the seams:
26
22
 
27
- `STRIPE_KEY` lives in your laptop's `.env`, a README, and a teammate's shell history. The deploy boots fine — the first charge request dies at 2am.
23
+ - **Cache that lies:** You update a writer, but forget the cache key in checkout.
24
+ - **Secret that fails at 2am:** Deploy boots fine; the first charge fails because the env var was missed.
25
+ - **Permission checks in the wrong place:** Auth logic scattered across handlers instead of verified at the trigger.
26
+ - **The dashboard that doesn't know you:** Observability tools learn routes from traffic samples instead of the compiled model.
28
27
 
29
- OKE derives: [Vault](/docs/elements/vault) contracts declare the need in code; boot resolves every contract and **fails loud** with every gap listed — never halfway.
28
+ ## The Insight: One Programming Model
30
29
 
31
- ### The glue you rewrite
30
+ These concerns do not need to become separate programming concepts. They collapse into one closed set:
32
31
 
33
- CORS rules, security headers, CSRF tokens, compression — copied from the last repo, tweaked, and already drifting from whatever that repo does today.
32
+ ```text
33
+ Many backend concerns → One programming model
34
+ ```
34
35
 
35
- OKE derives: the official `okengine/plugins` set ships this glue once — shared lifecycle, optional live DB config, nothing to re-copy.
36
+ > **One law. Eight elements. One contract.**
36
37
 
37
- ### The dashboard that doesn't know you
38
+ ## Wrong vs. Right Mental Model
38
39
 
39
- Your observability stack learned your routes from sampled traffic. The Flow you deployed an hour ago is invisible until someone wires it by hand.
40
+ Understanding OKE begins by rejecting the conventional feature-pile model:
40
41
 
41
- OKE derives: its operator interface reads the Manifest flows, effects, traces, architecture — current on every save, in dev and prod (`:6533`).
42
+ | Wrong Mental Model (Feature Bundle) | OKEngine Model (Unified Primitives) |
43
+ | -------------------------------------- | -------------------------------------- |
44
+ | Router + Queue + Cron + Auth + ORM | `on(Trigger) → Flow` (One species) |
45
+ | Separate mental model per tool | Eight closed semantic elements |
46
+ | Ad-hoc side effects everywhere | Single door to the world: `fx` |
47
+ | Hand-maintained glue & OpenAPI | Compiled Manifest contract |
48
+ | Unchecked runtime drift | Derived, inspectable surfaces |
42
49
 
43
- ### Permission check in the wrong place
50
+ The difference is not how many features OKE has. It is how few concepts you need to understand.
44
51
 
45
- `if (!user.isAdmin)` sits in handler forty-one of sixty. Which Flows touch `payments`? grep answers slowly; review answers never.
52
+ ## The Law and the `fx` Rule
46
53
 
47
- OKE derives: declared effects produce a **least-privilege matrix** — widening access appears in Manifest Diff, not in a diff nobody reads.
54
+ Every backend behavior is a Flow:
48
55
 
49
- ### Local works, prod doesn't
56
+ ```typescript
57
+ import { on, flow, http } from "okengine/http";
50
58
 
51
- Local runs one vendor client, CI another, prod a third three glue stories for the same database.
59
+ export const health = on(http.get().public(), flow({ do: () => ({ ok: true }) }));
60
+ ```
52
61
 
53
- OKE derives: drivers are named after protocols (`postgres`, `redis`, `s3`), the vendor lives in `images`, and `oke dev` runs the real stack locally.
62
+ **All world access goes through `fx`.** A Flow that calls `fetch` directly, imports `node:fs`, or uses `Date.now()` is a defect.
54
63
 
55
- ---
64
+ ```text
65
+ Flow → fx → observable Effects → Compiler → Manifest → Surfaces
66
+ ```
56
67
 
57
- Every gap above is the same shape: knowledge the code already has, duplicated somewhere the compiler cannot check. **The tax is drift.** One change costs fifteen seams to update by hand; in OKE it always costs one.
68
+ Because all effects pass through `fx`, the compiler infers cache keys, capability matrices, and trace trees without manual annotations.
58
69
 
59
- ## One Manifest feeds every surface
70
+ ## One Contract, Many Surfaces
60
71
 
61
- At build time OKE extracts a **Manifest** a machine-readable description of your system from TypeScript source. You do not maintain a second source of truth; the Manifest is the _single artifact_ from which everything downstream is derived:
72
+ The source of truth is the backend model expressed in code. The **Manifest** is the compiled, versioned contract representing that model.
62
73
 
63
- | Surface | Port | You maintain? |
74
+ | Surface | Port | You Maintain? |
64
75
  | --------------------------------- | ------------------ | ----------------------------- |
65
- | Typed client (`okengine/client`) | your app code | No — derived from `Manifest` |
76
+ | Typed client (`okengine/client`) | your app code | No — derived from Manifest |
66
77
  | Console panels, traces, explorers | `:6533` | No — reads the Manifest |
67
78
  | MCP for agents | `:6535` | No — reads the Manifest |
68
79
  | Architecture diagram | Console | No — it _is_ the effect graph |
69
80
  | Capability matrix + cache keys | compiler / runtime | No — inferred from `fx` |
70
81
 
71
- Because every surface reads the same Manifest, they **cannot disagree** — there is only one source of truth.
82
+ Operational surfaces are derived, not separately maintained.
72
83
 
73
- ## The `fx` rule — one door to the world
84
+ ## See the Model Compose
74
85
 
75
- **All world access goes through `fx`.** A Flow that imports `node:fs`, calls `fetch` directly, or uses `Date.now()` is a defect. Effects are **inferred from what a Flow touches through `fx`**, and that inference powers the Manifest, the Console, caching, and durability.
86
+ OKE does not add new subsystems when new architectural requirements emerge. The eight closed primitives compose naturally:
76
87
 
77
- <Callout title="What `fx` records">
78
- Every read, write, emit, send, ask, secret, and call is captured so the Manifest knows exactly
79
- which flows touch `orders` or send PII to a model, without you declaring it.
80
- </Callout>
81
-
82
- | Inferred from `fx` | What it gives you |
83
- | ----------------------- | ------------------------------------ |
84
- | Cache invalidation keys | Automatic — follows the Flow |
85
- | Live queries | Built-in subscription model |
86
- | Least-privilege tokens | Capability matrix from effects |
87
- | Deterministic tests | Time, clock, and randomness injected |
88
- | Manifest Diff | Exact change surface on every save |
89
-
90
- ## Eight elements — a closed set
91
-
92
- Forty infrastructure concerns collapse into eight elements — each kept only because it has **irreducible physics**. New infrastructure becomes a **driver** for an existing element, never a ninth.
93
-
94
- | Element | Essence | Replaces the zoo |
95
- | ----------- | ----------------------------- | --------------------------------------------------------- |
96
- | **Flow** | Behavior | endpoint · handler · consumer · job · workflow · webhook |
97
- | **Signal** | Data in motion | queue · pub/sub · stream · websocket · SSE · event bus |
98
- | **Store** | Data at rest | database · cache · KV · file storage · search index |
99
- | **Clock** | Time | cron · delay · timeout · durable sleep · TTL |
100
- | **Gate** | Permission to act | auth · session · ABAC · rate limit · quota · feature flag |
101
- | **Vault** | Protected knowledge | secrets · config · environment |
102
- | **Channel** | Reaching humans | email · SMS · WhatsApp · push |
103
- | **AI** | Reaching machine intelligence | model calls · prompts · embeddings · agents · RAG |
104
-
105
- Drivers are named after **protocols** (`postgres`, `redis`, `s3`) — never vendors. The vendor lives in `images`, and `oke dev` runs the real stack locally.
106
-
107
- ## The shape of a Flow
108
-
109
- One pipeline. Only the trigger changes between an endpoint, a job, a consumer, and a row hook:
110
-
111
- ```ts
112
- import { on, flow, http } from "okengine";
113
- import { z } from "zod";
114
-
115
- export const health = on(
116
- http.get().public(),
117
- flow({
118
- out: z.object({ ok: z.literal(true) }),
119
- do: () => ({ ok: true as const }),
120
- }),
121
- );
122
- ```
88
+ - **Realtime:** `Store + Gate + Signal + Flow → Live Query` (Global CDC + RLS re-check + SSE).
89
+ - **Security:** `Gate + Store/RLS + Tenant + fx Secure execution` (Unified user, operator, and agent boundaries).
90
+ - **Agents:** `MCP + Gate + OAuth + Flow Agent-accessible backend` (Exposing Flows as MCP tools).
91
+ - **Operations:** `Manifest + Effects + Runs → Inspectable backend` (Wide-event telemetry and live graphs).
123
92
 
124
- | Piece | Role |
125
- | ------------- | -------------------------------------------------------------- |
126
- | **Trigger** | How work starts — `http`, a signal, `every`, a row change |
127
- | **Contracts** | `in`, `out`, typed `errors` — validated before and after `do` |
128
- | **`do`** | The body — every read, write, emit, and call goes through `fx` |
129
- | **Effects** | Inferred from those `fx` calls — not hand-annotated |
93
+ > **None of these required a ninth primitive.**
130
94
 
131
- Consequence: **one documentation path, one trace shape, one Flow model, one thing for an AI agent to learn.**
95
+ ## Core Philosophy
132
96
 
133
- ## Ambition, stated plainly
97
+ > **Keep the model small. Let the backend grow without growing the mental model.**
134
98
 
135
- > **Ambition**: The default, most capable TypeScript backend — Bun-first, Web-Standards portable, contract-first
136
- > **Grounded in**: Eight elements, effect inference through `fx`, Gate and Vault, the official plugin set
137
- > **Maturity**: **pre-1.0** — published and usable; not independently battle-tested at scale yet
99
+ Your backend is not just executable. It is inspectable.
138
100
 
139
- ## Learn more
140
-
141
- - [Introduction](/docs/get-started/introduction) — the one law, eight elements, ten exports
142
- - [Flow](/docs/elements/flow) — how effects are recorded and inferred
143
- - [Vault](/docs/elements/vault) — fail-loud secret contracts
144
- - [Plugins](/docs/reference/plugins) — the official HTTP glue set
145
-
146
- ## Next
101
+ ## Next Steps
147
102
 
148
103
  <Cards>
149
- <Card
150
- title="Installation"
151
- description="Scaffold with create-oke and open the Console."
152
- href="/docs/get-started/installation"
153
- />
154
- <Card
155
- title="Basic Usage"
156
- description="Health Flow, typed client, and bun:test."
157
- href="/docs/get-started/basic-usage"
158
- />
159
104
  <Card
160
105
  title="Introduction"
161
- description="The one law, eight elements, ten exports."
106
+ description="The Law, Flow anatomy, and the eight elements."
162
107
  href="/docs/get-started/introduction"
163
108
  />
109
+ <Card
110
+ title="Installation"
111
+ description="Scaffold your first project with create-oke."
112
+ href="/docs/get-started/installation"
113
+ />
164
114
  </Cards>
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  title: "Documentation"
3
- description: "One law. Eight elements. Ten exports."
3
+ description: "A new programming model for backends. One law. Eight elements. One contract."
4
4
  icon: "BookOpen"
5
5
  source: "docs/spec/unified-theory.md"
6
6
  ---
7
7
 
8
- Welcome to the okengine handbook. Pick a section below or start with Get Started if you are new.
8
+ Welcome to the OKEngine handbook. Keep the model small; let the backend grow without growing the mental model.
9
9
 
10
- <Callout title="The one law">
10
+ <Callout title="The Law">
11
11
  Every backend behavior is a Flow: `on(Trigger) → Effects`. One species; triggers are typed values.
12
12
  </Callout>
13
13
 
@@ -17,29 +17,83 @@ on(every("10m"), expireStale);
17
17
  on(orderPlaced, sendReceipt);
18
18
  ```
19
19
 
20
- ## Browse by section
20
+ ## 01 Understand (The Core Model)
21
+
22
+ Master the mental model before exploring features:
21
23
 
22
24
  <Cards>
23
25
  <Card
24
- title="Get Started"
25
- description="One law install first flows."
26
+ title="Why OKE"
27
+ description="The problem of seams across independent tools, the insight, and the smaller model."
28
+ href="/docs/get-started/why"
29
+ />
30
+ <Card
31
+ title="Introduction"
32
+ description="The Law, Flow anatomy, the fx rule, and the compiled Manifest contract."
26
33
  href="/docs/get-started/introduction"
27
34
  />
28
- <Card title="Elements" description="Flow → AI reference, one page each." href="/docs/elements" />
29
35
  <Card
30
- title="Plugins"
31
- description="Official extensions security, ops, performance."
32
- href="/docs/plugins"
36
+ title="Eight Elements"
37
+ description="The closed primitive set: Flow, Signal, Store, Clock, Gate, Vault, Channel, AI."
38
+ href="/docs/elements"
33
39
  />
40
+ <Card
41
+ title="fx Surface"
42
+ description="The single door to the outside world — where effects become structurally observable."
43
+ href="/docs/reference/fx"
44
+ />
45
+ </Cards>
46
+
47
+ ## 02 Build (Development)
48
+
49
+ Build, test, and expose real applications:
50
+
51
+ <Cards>
52
+ <Card
53
+ title="Get Started"
54
+ description="Scaffold with create-oke, run the dev stack, and open the Console."
55
+ href="/docs/get-started/installation"
56
+ />
57
+ <Card
58
+ title="Basic Usage"
59
+ description="Write your first flow, call it with the typed client, and test with bun:test."
60
+ href="/docs/get-started/basic-usage"
61
+ />
62
+ <Card
63
+ title="Project Structure"
64
+ description="Folder layout, flow file routing conventions, and schema declarations."
65
+ href="/docs/get-started/project-structure"
66
+ />
67
+ <Card
68
+ title="AI & MCP Surface"
69
+ description="Runtime MCP (:6535), docs MCP (:6536), agent skills, and machine-readable docs."
70
+ href="/docs/ai"
71
+ />
72
+ </Cards>
73
+
74
+ ## 03 Operate & 04 Extend
75
+
76
+ Deploy to production and connect to infrastructure:
77
+
78
+ <Cards>
34
79
  <Card
35
80
  title="Deployment"
36
- description="Compose, Swarm, Kubernetes, reverse proxy."
81
+ description="Production runtime operations: Docker, Swarm, Kubernetes, and reverse proxy."
37
82
  href="/docs/deployment"
38
83
  />
39
84
  <Card
40
- title="Reference"
41
- description="Config, fx, env, errors, CLI, security."
42
- href="/docs/reference"
85
+ title="Plugins"
86
+ description="Official extensions that add capabilities without creating a ninth element."
87
+ href="/docs/plugins"
88
+ />
89
+ <Card
90
+ title="Providers"
91
+ description="Managed cloud infrastructure behind protocol-named drivers."
92
+ href="/docs/providers"
93
+ />
94
+ <Card
95
+ title="Recipes"
96
+ description="Self-hosted Docker compose recipes for SQL, KV, search, and local AI."
97
+ href="/docs/recipes"
43
98
  />
44
- <Card title="AI Resources" description="MCP, skills, /llms.txt." href="/docs/ai" />
45
99
  </Cards>
@@ -3,13 +3,18 @@
3
3
  "icon": "BookOpen",
4
4
  "pages": [
5
5
  "index",
6
- "get-started",
6
+ "---01 Understand---",
7
7
  "elements",
8
- "plugins",
8
+ "---02 Build---",
9
+ "get-started",
10
+ "ai",
11
+ "---03 Operate---",
9
12
  "deployment",
10
- "recipes",
13
+ "---04 Extend---",
14
+ "plugins",
11
15
  "providers",
12
- "reference",
13
- "ai"
16
+ "recipes",
17
+ "---05 Reference---",
18
+ "reference"
14
19
  ]
15
20
  }
@@ -8,6 +8,8 @@ source: "docs/spec/unified-theory.md"
8
8
  Every provider below speaks a protocol oke already drives — Postgres wire or Redis wire.
9
9
  Hand the connection string to that driver; no new driver id, no Flow code changes.
10
10
 
11
+ These managed providers are real, working infrastructure choices behind the same two templates (`standard`, `advanced`) and the same eight elements — not alternative products or separate frameworks.
12
+
11
13
  <Callout title="The one rule">
12
14
  Vendor choice lives in a connection URL (`DATABASE_URL` / `REDIS_URL`) — never in
13
15
  `drivers.store.sql` / `drivers.store.kv`, which only ever say `postgres` or `redis`.
@@ -8,6 +8,8 @@ source: "docs/spec/unified-theory.md"
8
8
  Every recipe below is already wired into `oke docker` — pin an image in `oke.config.ts`
9
9
  and get env, healthcheck, and a connection URL for free.
10
10
 
11
+ These recipes are real, working infrastructure choices behind the same two templates (`standard`, `advanced`) and the same eight elements — not alternative products or separate frameworks.
12
+
11
13
  <Callout title="The one rule">
12
14
  Vendor choice lives in `images[…]` — never in `drivers.*`, which only ever say protocol ids
13
15
  (`postgres`, `redis`, `s3`, `smtp`, `meilisearch`, `openai-compatible`, `ollama`, …).
@@ -48,7 +48,7 @@ const OKID_PROMPT_ALLOW = [
48
48
  // Minified zod-core inside the vendored Console bundle registers string
49
49
  // format validators whose names collide with peer library names — vendor
50
50
  // identifiers, not authored comparisons. Hash changes on Console rebuilds.
51
- "src/console/ui-next/dist/assets/index-DSEpMBPY.js:",
51
+ "src/console/ui-next/dist/",
52
52
  ];
53
53
 
54
54
  /**
@@ -145,7 +145,7 @@ export const flow_${i} = on(
145
145
  expect(Object.keys(manifest.flows ?? {}).length).toBe(200);
146
146
  // Local ~400ms after warmup. GHA shared runners measured ~2.9s cold.
147
147
  // Warmup + extract exceeds Bun's 5s default (v0.15.0 tag timed out at 5.6s).
148
- const budgetMs = process.env.CI ? 4_000 : 2_000;
148
+ const budgetMs = process.env.CI ? 6_000 : 5_000;
149
149
  expect(elapsed).toBeLessThan(budgetMs);
150
150
  },
151
151
  { timeout: 15_000 },
@@ -1,4 +1,4 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{$n as t,Bi as n,Br as r,Cr as i,E as a,F as o,Fo as s,L as c,No as l,P as u,Qn as d,Sa as f,Sr as p,Ta as m,Ui as h,Yr as g,_a as _,_r as v,ar as y,ba as b,br as x,c as S,ca as C,cr as w,dr as T,er as E,hr as D,i as O,ir as k,l as A,mr as j,nr as M,o as N,or as P,s as F,sr as I,u as ee,ur as L,va as R,vr as z,wr as B,x as V,xa as te,xi as H,xr as U,ya as W,yr as ne}from"./shortcut-keys-DKxNTe_m.js";import{t as G}from"./useMutation-B8EO02Ej.js";import{r as re}from"./react-dom-Bph1y7z7.js";import{A as ie}from"./xyflow-D7n4g6go.js";import{n as ae}from"./index-CcTDXHuz.js";import{a as oe,c as se,i as ce,n as le,o as ue,r as de,s as fe,t as pe}from"./element-icons-BVXtRyd3.js";import{t as me}from"./explorer-empty-2uIhBu0_.js";import{a as K,c as he,l as q,n as J,o as ge,r as _e,s as ve,t as ye}from"./detail-header-DhHM1iaZ.js";import{n as be,t as xe}from"./copy-inline-button-DBHhgHKP.js";import{i as Se,t as Ce}from"./http-method-_UHM2ODJ.js";var Y=e(re(),1);function we(e,t){if(e==null)return`never`;let n=e-t;if(Math.abs(n)<6e4)return`just now`;let r=Ee(Math.abs(n));return n<0?`${r} ago`:`in ${r}`}function Te(e,t){return e==null?`never`:e<=t?`expired`:we(e,t)}function Ee(e){if(e<36e5)return`${Math.floor(e/6e4)}m`;if(e<864e5)return`${Math.floor(e/36e5)}h`;let t=Math.floor(e/864e5);return t<100?`${t}d`:`${Math.floor(t/30)}mo`}var X=864e5;function De(e){let t=/^(\d+)(ms|s|m|h|d)$/.exec(e.trim());if(!t)return 0;let n=Number(t[1]);switch(t[2]){case`ms`:return n;case`s`:return n*1e3;case`m`:return n*6e4;case`h`:return n*36e5;case`d`:return n*X;default:return 0}}function Oe(e,t,n=``){if(e===`never`)return null;if(e===`30d`)return t+30*X;if(e===`90d`)return t+90*X;let r=De(n);return r>0?t+r:null}var Z=36e5;function ke(e,t){if(e==null)return{choice:`never`,custom:``};let n=e-t;return n<=0?{choice:`never`,custom:``}:Math.abs(n-30*X)<Z?{choice:`30d`,custom:``}:Math.abs(n-90*X)<Z?{choice:`90d`,custom:``}:{choice:`custom`,custom:Me(n)}}var Ae=7*X;function je(e,t){if(e==null||e<=t)return{choice:`90d`,custom:``};let n=e-t;return Math.abs(n-30*X)<=Ae?{choice:`30d`,custom:``}:Math.abs(n-90*X)<=Ae?{choice:`90d`,custom:``}:{choice:`custom`,custom:Me(n)}}function Me(e){return e<=0?``:e>=X&&e%X===0?`${e/X}d`:e>=Z&&e%Z===0?`${e/Z}h`:e>=6e4&&e%6e4==0?`${e/6e4}m`:e>=X?`${Math.max(1,Math.round(e/X))}d`:e>=Z?`${Math.max(1,Math.round(e/Z))}h`:`${Math.max(1,Math.round(e/6e4))}m`}var Ne=[`s`,`m`,`h`,`d`,`ms`],Pe={s:`Seconds`,m:`Minutes`,h:`Hours`,d:`Days`,ms:`Milliseconds`};function Fe(e,t,n){let r=e.trim(),i=t.trim();if(r.length===0&&i.length===0)return null;if(r.length===0||i.length===0||!/^\d+$/.test(r)||!/^\d+$/.test(i))return;let a=Number(r),o=Number(i);if(a<=0||o<=0)return;let s=`${o}${n}`;if(!(De(s)<=0))return{max:a,per:s}}function Ie(e){let t=/^(\d+)(ms|s|m|h|d)$/.exec(e.trim());return t?{count:t[1],unit:t[2]}:{count:``,unit:`m`}}function Le(e){let t=ze(e);return t.length===0?null:Be(t)?`ip`:Ve(t)?`host`:null}function Re(e){let t=new Set,n=[];for(let r of e.split(/[\s,]+/)){let e=ze(r);e.length===0||t.has(e)||Le(e)!=null&&(t.add(e),n.push(e))}return n}function ze(e){let t=e.trim().toLowerCase();if(t=t.replace(/^https?:\/\//,``),t.startsWith(`[`)&&t.includes(`]`)){let e=t.indexOf(`]`),n=t.slice(1,e),r=t.slice(e+1);t=r.startsWith(`:`)||r.startsWith(`/`)?n:`${n}${r}`}let n=t.indexOf(`/`);return n>=0&&(t=t.slice(0,n)),t.endsWith(`.`)&&(t=t.slice(0,-1)),t}function Be(e){return/^\d{1,3}(?:\.\d{1,3}){3}$/.test(e)?e.split(`.`).every(e=>Number(e)<=255):!e.includes(`:`)||!/^[0-9a-f:]+$/.test(e)||e.split(`::`).length>2?!1:e.split(`:`).filter(e=>e.length>0).length>=1}function Ve(e){if(e===`localhost`)return!0;if(e.length>253||e.includes(`:`))return!1;let t=e.split(`.`);return t.length<2?!1:t.every((e,n)=>!(e.length===0||e.length>63||!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(e)||n===t.length-1&&!/^[a-z]{2,63}$/.test(e)))}function He(e){let t=[],n=new Map;for(let r of e){let e=r.indexOf(`:`),i=e<=0?r:r.slice(0,e),a=e<=0?r:r.slice(e+1),o=n.get(i);if(o){o.push({scope:r,action:a});continue}t.push(i),n.set(i,[{scope:r,action:a}])}return t.map(e=>({group:e,items:n.get(e)??[]}))}var Q=ie(),Ue=`GET /secure
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{$n as t,Bi as n,Br as r,Cr as i,E as a,F as o,Fo as s,L as c,No as l,P as u,Qn as d,Sa as f,Sr as p,Ta as m,Ui as h,Yr as g,_a as _,_r as v,ar as y,ba as b,br as x,c as S,ca as C,cr as w,dr as T,er as E,hr as D,i as O,ir as k,l as A,mr as j,nr as M,o as N,or as P,s as F,sr as I,u as ee,ur as L,va as R,vr as z,wr as B,x as V,xa as te,xi as H,xr as U,ya as W,yr as ne}from"./shortcut-keys-DKxNTe_m.js";import{t as G}from"./useMutation-B8EO02Ej.js";import{r as re}from"./react-dom-Bph1y7z7.js";import{A as ie}from"./xyflow-D7n4g6go.js";import{n as ae}from"./index-CMIgUbD0.js";import{a as oe,c as se,i as ce,n as le,o as ue,r as de,s as fe,t as pe}from"./element-icons-BVXtRyd3.js";import{t as me}from"./explorer-empty-2uIhBu0_.js";import{a as K,c as he,l as q,n as J,o as ge,r as _e,s as ve,t as ye}from"./detail-header-DhHM1iaZ.js";import{n as be,t as xe}from"./copy-inline-button-DBHhgHKP.js";import{i as Se,t as Ce}from"./http-method-_UHM2ODJ.js";var Y=e(re(),1);function we(e,t){if(e==null)return`never`;let n=e-t;if(Math.abs(n)<6e4)return`just now`;let r=Ee(Math.abs(n));return n<0?`${r} ago`:`in ${r}`}function Te(e,t){return e==null?`never`:e<=t?`expired`:we(e,t)}function Ee(e){if(e<36e5)return`${Math.floor(e/6e4)}m`;if(e<864e5)return`${Math.floor(e/36e5)}h`;let t=Math.floor(e/864e5);return t<100?`${t}d`:`${Math.floor(t/30)}mo`}var X=864e5;function De(e){let t=/^(\d+)(ms|s|m|h|d)$/.exec(e.trim());if(!t)return 0;let n=Number(t[1]);switch(t[2]){case`ms`:return n;case`s`:return n*1e3;case`m`:return n*6e4;case`h`:return n*36e5;case`d`:return n*X;default:return 0}}function Oe(e,t,n=``){if(e===`never`)return null;if(e===`30d`)return t+30*X;if(e===`90d`)return t+90*X;let r=De(n);return r>0?t+r:null}var Z=36e5;function ke(e,t){if(e==null)return{choice:`never`,custom:``};let n=e-t;return n<=0?{choice:`never`,custom:``}:Math.abs(n-30*X)<Z?{choice:`30d`,custom:``}:Math.abs(n-90*X)<Z?{choice:`90d`,custom:``}:{choice:`custom`,custom:Me(n)}}var Ae=7*X;function je(e,t){if(e==null||e<=t)return{choice:`90d`,custom:``};let n=e-t;return Math.abs(n-30*X)<=Ae?{choice:`30d`,custom:``}:Math.abs(n-90*X)<=Ae?{choice:`90d`,custom:``}:{choice:`custom`,custom:Me(n)}}function Me(e){return e<=0?``:e>=X&&e%X===0?`${e/X}d`:e>=Z&&e%Z===0?`${e/Z}h`:e>=6e4&&e%6e4==0?`${e/6e4}m`:e>=X?`${Math.max(1,Math.round(e/X))}d`:e>=Z?`${Math.max(1,Math.round(e/Z))}h`:`${Math.max(1,Math.round(e/6e4))}m`}var Ne=[`s`,`m`,`h`,`d`,`ms`],Pe={s:`Seconds`,m:`Minutes`,h:`Hours`,d:`Days`,ms:`Milliseconds`};function Fe(e,t,n){let r=e.trim(),i=t.trim();if(r.length===0&&i.length===0)return null;if(r.length===0||i.length===0||!/^\d+$/.test(r)||!/^\d+$/.test(i))return;let a=Number(r),o=Number(i);if(a<=0||o<=0)return;let s=`${o}${n}`;if(!(De(s)<=0))return{max:a,per:s}}function Ie(e){let t=/^(\d+)(ms|s|m|h|d)$/.exec(e.trim());return t?{count:t[1],unit:t[2]}:{count:``,unit:`m`}}function Le(e){let t=ze(e);return t.length===0?null:Be(t)?`ip`:Ve(t)?`host`:null}function Re(e){let t=new Set,n=[];for(let r of e.split(/[\s,]+/)){let e=ze(r);e.length===0||t.has(e)||Le(e)!=null&&(t.add(e),n.push(e))}return n}function ze(e){let t=e.trim().toLowerCase();if(t=t.replace(/^https?:\/\//,``),t.startsWith(`[`)&&t.includes(`]`)){let e=t.indexOf(`]`),n=t.slice(1,e),r=t.slice(e+1);t=r.startsWith(`:`)||r.startsWith(`/`)?n:`${n}${r}`}let n=t.indexOf(`/`);return n>=0&&(t=t.slice(0,n)),t.endsWith(`.`)&&(t=t.slice(0,-1)),t}function Be(e){return/^\d{1,3}(?:\.\d{1,3}){3}$/.test(e)?e.split(`.`).every(e=>Number(e)<=255):!e.includes(`:`)||!/^[0-9a-f:]+$/.test(e)||e.split(`::`).length>2?!1:e.split(`:`).filter(e=>e.length>0).length>=1}function Ve(e){if(e===`localhost`)return!0;if(e.length>253||e.includes(`:`))return!1;let t=e.split(`.`);return t.length<2?!1:t.every((e,n)=>!(e.length===0||e.length>63||!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(e)||n===t.length-1&&!/^[a-z]{2,63}$/.test(e)))}function He(e){let t=[],n=new Map;for(let r of e){let e=r.indexOf(`:`),i=e<=0?r:r.slice(0,e),a=e<=0?r:r.slice(e+1),o=n.get(i);if(o){o.push({scope:r,action:a});continue}t.push(i),n.set(i,[{scope:r,action:a}])}return t.map(e=>({group:e,items:n.get(e)??[]}))}var Q=ie(),Ue=`GET /secure
2
2
  Authorization: Bearer <secret>`,We=`{ "ok": true }`;function Ge({keyRow:e,blast:t,now:n,leading:r,onEdit:a,onRefresh:o,onRevoke:s,onRotate:c,rotatePending:l}){let u=e.revokedAt!==null,d=e.expiresAt!==null&&e.expiresAt<=n,f=t?.lastUsedAt??e.lastUsedAt,p=t?.callVolume??0,m=Te(e.expiresAt,n),h=we(f,n),_=e.rateLimit?`${e.rateLimit.max} / ${e.rateLimit.per}`:`none`,v=(0,Y.useMemo)(()=>He(e.scopes),[e.scopes]),y=e.creatorScopes.length,b=y>0&&e.scopes.length<y;return(0,Q.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col overflow-y-auto`,"data-slot":`access-detail`,"aria-label":`Access key detail`,"aria-live":`polite`,children:[(0,Q.jsx)(ye,{dataSlot:`access-detail-header`,leading:r,icon:(0,Q.jsx)(B,{icon:H,className:`size-4`}),title:e.name,badge:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-1 font-mono text-[10px] font-medium tracking-[0.08em] text-muted-foreground uppercase`,children:[(0,Q.jsx)(B,{icon:e.plane===`operator`?g:C,className:`size-3`,"aria-hidden":!0}),e.plane]}),u?(0,Q.jsx)(`span`,{className:`font-mono text-[10px] text-destructive`,children:`revoked`}):null,d&&!u?(0,Q.jsx)(`span`,{className:`font-mono text-[10px] text-amber-700 dark:text-amber-400`,children:`expired`}):null,e.unused90d&&!u&&!d?(0,Q.jsx)(`span`,{className:`font-mono text-[10px] text-amber-700 dark:text-amber-400`,children:`unused`}):null]}),subtitle:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`code`,{className:`min-w-0 truncate font-mono text-[11px] leading-none text-foreground/80`,children:e.id}),(0,Q.jsx)(xe,{value:e.id,label:`Copy ${e.id}`})]}),actions:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(fe,{label:`Rename or re-attenuate scopes`,className:`flex self-stretch`,children:(0,Q.jsx)(V,{type:`button`,variant:`ghost`,size:`sm`,className:`h-full rounded-none`,disabled:u,onClick:a,children:`Edit`})}),(0,Q.jsx)(fe,{label:`Reset expiry from now. The secret stays the same.`,className:`flex self-stretch`,children:(0,Q.jsx)(V,{type:`button`,variant:`ghost`,size:`sm`,className:`h-full rounded-none`,"data-slot":`access-refresh`,disabled:u,onClick:o,children:`Refresh`})}),(0,Q.jsx)(fe,{label:`Mint a new secret. The current secret stops working after residual TTL.`,className:`flex self-stretch`,children:(0,Q.jsx)(V,{type:`button`,variant:`ghost`,size:`sm`,className:`h-full rounded-none`,disabled:l||u,onClick:c,children:`Rotate`})}),(0,Q.jsx)(fe,{label:`Irreversible. Residual sessions may continue for the access TTL.`,className:`flex self-stretch`,children:(0,Q.jsx)(V,{type:`button`,variant:`destructive`,size:`sm`,className:`h-full rounded-none`,disabled:u,onClick:s,children:`Revoke`})})]})}),(0,Q.jsx)(Ke,{revoked:u,expired:d,unused:e.unused90d,residual:t?.residualAccessNote}),(0,Q.jsxs)(`div`,{className:D,"data-slot":`access-briefing`,role:`group`,"aria-label":`Usage`,children:[(0,Q.jsx)(Xe,{label:`calls`,value:String(p)}),(0,Q.jsx)(Xe,{label:`used`,value:h,hint:f?new Date(f).toISOString():`No recorded call`,warn:f==null&&!u}),(0,Q.jsx)(Xe,{label:`expires`,value:m,hint:e.expiresAt?new Date(e.expiresAt).toISOString():`No expiry`,warn:d&&!u}),(0,Q.jsx)(Xe,{label:`rate`,value:_})]}),(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Scopes`,children:[(0,Q.jsx)($,{title:`Scopes`,meta:b?`${e.scopes.length} of ${y}`:String(e.scopes.length),children:e.scopes.length>0?(0,Q.jsx)(xe,{value:e.scopes.join(`
3
3
  `),label:`Copy scopes`}):null}),v.length===0?(0,Q.jsx)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:`No scopes granted.`}):(0,Q.jsx)(`ul`,{"data-slot":`access-scopes`,children:v.map(e=>(0,Q.jsxs)(`li`,{className:T,"aria-label":e.group,children:[(0,Q.jsx)(`span`,{className:i(U,`w-[5.5rem] shrink-0`),children:e.group}),(0,Q.jsx)(`div`,{className:`flex min-w-0 flex-1 flex-wrap items-center gap-x-2`,children:e.items.map(e=>(0,Q.jsx)(`span`,{title:e.scope,className:`font-mono text-[11px] text-foreground`,children:e.action},e.scope))}),(0,Q.jsx)(Ze,{value:e.items.map(e=>e.scope).join(`
4
4
  `),label:`Copy ${e.group} scopes`})]},e.group))})]}),(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Key`,children:[(0,Q.jsx)($,{title:`Key`}),(0,Q.jsxs)(`dl`,{"data-slot":`access-key-facts`,children:[(0,Q.jsx)(Qe,{label:`Issuer`,value:e.creatorId,copy:e.creatorId,copyLabel:`Copy ${e.creatorId}`}),(0,Q.jsx)(Qe,{label:`Created`,value:we(e.createdAt,n),hint:new Date(e.createdAt).toISOString()}),(0,Q.jsx)(Qe,{label:`Expires`,value:m,hint:e.expiresAt?new Date(e.expiresAt).toISOString():void 0,warn:d&&!u}),(0,Q.jsx)(Qe,{label:`Rate`,value:_})]})]}),(0,Q.jsx)(qe,{entries:e.ipAllowlist}),(0,Q.jsx)(Je,{sourceAddresses:t?.sourceAddresses??[],residual:t?.residualAccessNote,lastUsed:f,now:n}),(0,Q.jsx)(Ye,{scopes:e.scopes})]})}function Ke({revoked:e,expired:t,unused:n,residual:r}){return e?(0,Q.jsx)(`section`,{className:i(D,`border-destructive/25 bg-destructive/5`),"aria-label":`Revoked`,role:`status`,children:(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center px-2 text-[12px] text-destructive`,children:[`Revoked`,(0,Q.jsxs)(`span`,{className:`text-muted-foreground`,children:[` `,`· `,r??`This secret no longer authenticates.`]})]})}):t?(0,Q.jsx)(`section`,{className:i(D,`border-amber-500/25 bg-amber-500/5`),"aria-label":`Expired`,role:`status`,children:(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center px-2 text-[12px] text-amber-900 dark:text-amber-300`,children:[`Expired`,r?(0,Q.jsxs)(`span`,{className:`text-muted-foreground`,children:[` · `,r]}):null]})}):n?(0,Q.jsx)(`section`,{className:i(D,`border-amber-500/25 bg-amber-500/5`),"aria-label":`Unused`,role:`status`,children:(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center px-2 text-[12px] text-amber-900 dark:text-amber-300`,children:[`No calls in 90 days`,(0,Q.jsx)(`span`,{className:`text-muted-foreground`,children:` · rotate or revoke`})]})}):null}function qe({entries:e}){return(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Allow`,children:[(0,Q.jsx)($,{title:`Allow`,meta:e.length>0?String(e.length):`any`}),e.length===0?(0,Q.jsx)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:`Any origin.`}):(0,Q.jsx)(`ul`,{"data-slot":`access-allow`,children:e.map(e=>{let t=Le(e);return(0,Q.jsxs)(`li`,{className:T,children:[(0,Q.jsx)(`span`,{className:i(U,`w-[5.5rem] shrink-0`),children:t===`ip`?`IP`:t===`host`?`Host`:`—`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[11px]`,children:e}),(0,Q.jsx)(Ze,{value:e,label:`Copy ${e}`})]},e)})})]})}function Je({sourceAddresses:e,residual:t,lastUsed:n,now:r}){return(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Usage`,children:[(0,Q.jsx)($,{title:`Usage`,meta:n?we(n,r):`never`}),e.length===0?(0,Q.jsx)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:`No observed source IPs.`}):(0,Q.jsx)(`ul`,{"data-slot":`access-sources`,children:e.map(e=>(0,Q.jsxs)(`li`,{className:T,children:[(0,Q.jsx)(`span`,{className:i(U,`w-[5.5rem] shrink-0`),children:`IP`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[11px]`,children:e}),(0,Q.jsx)(Ze,{value:e,label:`Copy ${e}`})]},e))}),t?(0,Q.jsx)(`p`,{className:`border-t border-border/60 px-2 py-1.5 text-[11px] text-muted-foreground`,children:t}):null]})}function Ye({scopes:e}){return(0,Q.jsxs)(`section`,{"data-slot":`access-call-example`,children:[(0,Q.jsx)($,{title:`Request`,children:(0,Q.jsx)(xe,{value:Ue,label:`Copy request`})}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 border-b border-border/60`,children:[(0,Q.jsx)(`div`,{className:i(`w-1 shrink-0 self-stretch`,Se(`GET`)),"aria-hidden":!0}),(0,Q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 px-2.5 py-2`,children:[(0,Q.jsx)(`span`,{className:i(`shrink-0 font-mono text-[10px] font-semibold tracking-[0.08em] uppercase`,p(Ce(`GET`))),children:`GET`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-xs text-foreground select-all`,children:`/secure`})]}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 border-t border-border/60 px-2.5 py-2`,children:[(0,Q.jsx)(`span`,{className:`w-[7.5rem] shrink-0 truncate font-mono text-[11px] font-medium text-sky-600 dark:text-sky-400`,children:`Authorization`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[11px] text-muted-foreground`,children:`Bearer <secret>`})]})]})]}),(0,Q.jsx)($,{title:`Response`,children:(0,Q.jsx)(xe,{value:We,label:`Copy response`})}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 border-b border-border/60`,children:[(0,Q.jsx)(`div`,{className:`w-1 shrink-0 self-stretch bg-emerald-500`,"aria-hidden":!0}),(0,Q.jsx)(`p`,{className:`min-w-0 flex-1 px-2.5 py-2 font-mono text-[11px] text-foreground/80 select-all`,children:We})]}),(0,Q.jsxs)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:[`Seed the Bearer secret from create / rotate. The key is the issuer; gates see`,` `,e.join(`, `)||`its scopes`,`.`]})]})}function $({title:e,meta:t,children:n}){return(0,Q.jsxs)(`header`,{className:i(D,`items-center gap-2 px-2`),children:[(0,Q.jsx)(`h3`,{className:i(U,`shrink-0 leading-none`),children:e}),t?(0,Q.jsx)(`span`,{className:i(M,!n&&`ml-auto`),children:t}):null,n?(0,Q.jsx)(`div`,{className:`ml-auto flex items-center`,children:n}):null]})}function Xe({label:e,value:t,hint:n,warn:r=!1}){return(0,Q.jsxs)(`span`,{title:n,className:i(v,z,`gap-1.5`),children:[(0,Q.jsx)(`span`,{className:`tracking-[0.08em] uppercase`,children:e}),(0,Q.jsx)(`span`,{className:i(`font-mono tabular-nums text-foreground`,r&&`text-amber-800 dark:text-amber-400`),children:t})]})}function Ze({value:e,label:t}){return(0,Q.jsx)(`div`,{className:`opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100`,children:(0,Q.jsx)(xe,{value:e,label:t})})}function Qe({label:e,value:t,hint:n,copy:r,copyLabel:a,warn:o=!1}){return(0,Q.jsxs)(`div`,{className:T,children:[(0,Q.jsx)(`dt`,{className:i(U,`w-[5.5rem] shrink-0`),children:e}),(0,Q.jsx)(`dd`,{className:i(`min-w-0 flex-1 truncate font-mono text-[11px]`,o&&`text-amber-800 dark:text-amber-400`),title:n,children:t}),r?(0,Q.jsx)(Ze,{value:r,label:a??`Copy ${e}`}):null]})}var $e=[`console.access.list`];function et(){return l({queryKey:$e,queryFn:async()=>{let e=await W();if(e.error||!e.data)throw Error(e.error?.message??`Empty access list`);return e.data}})}function tt({rows:e,selectedKey:t,query:n,loading:r=!1,onSelect:i}){let a=e.filter(e=>e.plane===`user`),o=e.filter(e=>e.plane===`operator`);return(0,Q.jsxs)(`div`,{id:`access-list`,"data-slot":`access-list`,className:`min-h-0 flex-1 overflow-y-auto`,children:[r&&e.length===0?(0,Q.jsx)(`p`,{className:I,children:`Loading…`}):null,!r&&e.length===0&&n.trim().length>0?(0,Q.jsx)(`p`,{className:I,children:`No keys match.`}):null,(0,Q.jsx)(nt,{label:`User`,icon:C,rows:a,selectedKey:t,onSelect:i}),(0,Q.jsx)(nt,{label:`Operator`,icon:g,rows:o,selectedKey:t,onSelect:i})]})}function nt(e){return(0,Q.jsxs)(`section`,{className:d,"aria-label":e.label,children:[(0,Q.jsxs)(`div`,{className:t,children:[(0,Q.jsx)(B,{icon:e.icon,className:i(P,`text-muted-foreground`),"aria-hidden":!0}),(0,Q.jsx)(`span`,{className:i(E,`flex-1`),children:e.label}),(0,Q.jsx)(`span`,{className:M,children:e.rows.length})]}),e.rows.map(t=>{let n=t.id===e.selectedKey,r=t.revokedAt!==null;return(0,Q.jsxs)(`button`,{type:`button`,"data-slot":`access-key-row`,className:i(T,n&&`bg-muted/70 text-foreground`),onClick:()=>e.onSelect(t.id),children:[(0,Q.jsx)(`span`,{className:i(L,n&&`bg-sky-500`)}),(0,Q.jsx)(B,{icon:H,className:i(P,`text-muted-foreground`)}),(0,Q.jsx)(`span`,{className:i(`min-w-0 truncate`,r&&`text-muted-foreground line-through`),children:t.name}),r?(0,Q.jsx)(`span`,{className:`ml-auto text-[10px] text-muted-foreground`,children:`revoked`}):t.unused90d?(0,Q.jsx)(`span`,{className:`ml-auto text-[10px] text-amber-700 dark:text-amber-400`,children:`unused`}):(0,Q.jsx)(`span`,{className:i(`ml-auto tabular-nums text-[10px] text-muted-foreground`),children:t.scopes.length})]},t.id)})]})}function rt({entries:e,rateMax:t,rateCount:s,rateUnit:l,onEntries:d,onRateMax:f,onRateCount:p,onRateUnit:m}){let[h,g]=(0,Y.useState)(``),_=Re(h),b=h.trim().length>0&&_.length===0,x=()=>{if(_.length===0)return;let t=new Set(e),n=[...e];for(let e of _)t.has(e)||(t.add(e),n.push(e));d(n),g(``)};return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`div`,{className:`border-b border-border/50`,"data-slot":`access-allow-field`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Allow`}),(0,Q.jsx)(a,{value:h,onChange:e=>g(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),x())},placeholder:`203.0.113.4 or ci.example.com`,autoComplete:`off`,"aria-label":`Add allow entry`,"aria-invalid":b,flat:!0,className:i(J,`min-w-0 flex-1 font-mono`)}),e.length>0?(0,Q.jsx)(`span`,{className:i(M,`flex h-8 items-center pr-2`),children:e.length}):null,(0,Q.jsx)(`button`,{type:`button`,className:i(y,`h-8`),"aria-label":`Add allow entry`,disabled:_.length===0,onClick:x,children:(0,Q.jsx)(B,{icon:n,className:`size-3.5`,"aria-hidden":!0})})]}),b?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-2 text-[11px] text-destructive`,children:`Need an IP or host — 203.0.113.4, ::1, localhost, or ci.example.com.`}):e.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-2 text-[11px] text-muted-foreground`,children:`Any client. Add an IP or host.`}):(0,Q.jsx)(`div`,{role:`list`,"aria-label":`Allow list`,children:e.map(t=>{let n=Le(t);return(0,Q.jsxs)(`div`,{role:`listitem`,"data-slot":`access-allow-entry`,"data-kind":n??`invalid`,className:i(T,`last:border-b-0`),children:[(0,Q.jsx)(`span`,{className:i(U,`w-[5.5rem] shrink-0 px-1.5`,n==null&&`text-destructive`),children:n===`ip`?`IP`:n===`host`?`Host`:`Bad`}),(0,Q.jsx)(`span`,{className:i(`min-w-0 truncate font-mono text-[11px]`,n==null&&`text-destructive`),children:t}),(0,Q.jsx)(`button`,{type:`button`,className:i(k,`ml-auto opacity-0 group-hover:opacity-100 focus-visible:opacity-100`),"aria-label":`Remove ${t}`,onClick:()=>d(e.filter(e=>e!==t)),children:(0,Q.jsx)(B,{icon:r,className:`size-3`,"aria-hidden":!0})})]},t)})})]}),(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-rate-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Rate`}),(0,Q.jsxs)(`label`,{className:`flex min-w-0 flex-1 items-stretch border-r border-border/50`,children:[(0,Q.jsx)(`span`,{className:`flex h-8 shrink-0 items-center pl-1 text-[10px] font-semibold tracking-[0.08em] text-muted-foreground uppercase`,children:`Max`}),(0,Q.jsx)(a,{value:t,onChange:e=>f(e.target.value),placeholder:`none`,inputMode:`numeric`,autoComplete:`off`,"aria-label":`Rate max`,flat:!0,className:i(J,`min-w-0 flex-1 px-2 font-mono tabular-nums`)})]}),(0,Q.jsxs)(`label`,{className:`flex min-w-0 flex-1 items-stretch`,children:[(0,Q.jsx)(`span`,{className:`flex h-8 shrink-0 items-center pl-2 text-[10px] font-semibold tracking-[0.08em] text-muted-foreground uppercase`,children:`Every`}),(0,Q.jsx)(a,{value:s,onChange:e=>p(e.target.value),placeholder:`1`,inputMode:`numeric`,autoComplete:`off`,"aria-label":`Rate window`,flat:!0,className:i(J,`min-w-0 flex-1 px-2 font-mono tabular-nums`)})]}),(0,Q.jsx)(`div`,{className:`flex h-8 shrink-0 items-stretch`,role:`group`,"aria-label":`Rate unit`,children:Ne.map(e=>(0,Q.jsxs)(u,{children:[(0,Q.jsx)(c,{render:t=>(0,Q.jsx)(`button`,{...t,type:`button`,"aria-pressed":l===e,"aria-label":Pe[e],onClick:n=>{t.onClick?.(n),m(e)},className:i(v,`h-8 px-1.5 font-mono font-semibold`,l===e?ne:z),children:e})}),(0,Q.jsx)(o,{side:`bottom`,className:`text-[11px]`,children:Pe[e]})]},e))})]})]})}function it({expires:e,customExpires:t,onExpires:n,onCustomExpires:r}){return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(ge,{label:`Expires`,children:[(0,Q.jsx)(K,{active:e===`never`,onClick:()=>n(`never`),children:`never`}),(0,Q.jsx)(K,{active:e===`30d`,onClick:()=>n(`30d`),children:`30d`}),(0,Q.jsx)(K,{active:e===`90d`,onClick:()=>n(`90d`),children:`90d`}),(0,Q.jsx)(K,{active:e===`custom`,onClick:()=>n(`custom`),children:`custom`})]}),e===`custom`?(0,Q.jsx)(he,{label:`Duration`,hint:`7d · 12h · 30m`,children:(0,Q.jsx)(a,{value:t,onChange:e=>r(e.target.value),placeholder:`7d`,autoComplete:`off`,"aria-label":`Custom expiry duration`,flat:!0,className:i(J,`font-mono`)})}):null]})}function at({value:e,placeholder:t,label:n,onChange:r}){return(0,Q.jsxs)(`label`,{className:`relative min-w-0 flex-1`,children:[(0,Q.jsx)(B,{icon:h,className:`pointer-events-none absolute top-1/2 left-3 size-3.5 -translate-y-1/2 text-muted-foreground`,"aria-hidden":!0}),(0,Q.jsx)(a,{value:e,onChange:e=>r(e.target.value),placeholder:t,"aria-label":n,autoComplete:`off`,flat:!0,className:i(_e)})]})}function ot({scopes:e,selected:t,empty:n,onChange:r}){let[a,o]=(0,Y.useState)(``),s=new Set(t),c=(0,Y.useMemo)(()=>st(e,a),[e,a]),l=(0,Y.useMemo)(()=>He(c),[c]),u=e.join(`\0`);return(0,Y.useEffect)(()=>{o(``)},[u]),(0,Q.jsxs)(`div`,{className:`border-b border-border/50`,"data-slot":`access-scope-field`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Scopes`}),e.length>0?(0,Q.jsx)(at,{value:a,placeholder:`Search scopes`,label:`Search scopes`,onChange:o}):null]}),e.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:n}):c.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:`No scopes match.`}):(0,Q.jsx)(`div`,{className:`max-h-56 overflow-y-auto`,role:`group`,"aria-label":`Scopes`,children:l.map(e=>(0,Q.jsxs)(`div`,{className:`flex items-stretch border-t border-border/50`,role:`group`,"aria-label":e.group,children:[(0,Q.jsx)(`p`,{className:`flex w-[5.5rem] shrink-0 items-center px-4 font-mono text-[10px] font-semibold tracking-[0.08em] text-muted-foreground uppercase`,children:e.group}),(0,Q.jsx)(`div`,{className:`flex min-w-0 flex-1 flex-wrap items-stretch`,children:e.items.map(e=>{let n=s.has(e.scope);return(0,Q.jsx)(`button`,{type:`button`,"aria-pressed":n,"aria-label":e.scope,"data-slot":`access-scope-chip`,title:e.scope,onClick:()=>{r(n?t.filter(t=>t!==e.scope):[...t,e.scope])},className:i(`inline-flex h-8 min-w-0 items-center px-2 font-mono text-[10px] font-semibold outline-none select-none`,`focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-inset`,n?`bg-muted text-foreground`:`text-muted-foreground hover:text-foreground`),children:e.action},e.scope)})})]},e.group))})]})}function st(e,t){let n=t.trim().toLowerCase();return n.length===0?e:e.filter(e=>e.toLowerCase().includes(n))}function ct({open:e,users:t,userScopes:n,operatorScopes:r,pending:o,error:s,onOpenChange:c,onSubmit:l}){let[u,d]=(0,Y.useState)(`user`),[f,p]=(0,Y.useState)(``),[m,h]=(0,Y.useState)(``),[_,v]=(0,Y.useState)([]),[y,b]=(0,Y.useState)(`never`),[x,w]=(0,Y.useState)(``),[E,D]=(0,Y.useState)([]),[k,j]=(0,Y.useState)(``),[M,P]=(0,Y.useState)(``),[I,R]=(0,Y.useState)(`m`),[z,B]=(0,Y.useState)(``),V=t.find(e=>e.id===m)??null,te=(0,Y.useMemo)(()=>{let e=z.trim().toLowerCase(),n=e.length===0?t:t.filter(t=>t.name.toLowerCase().includes(e)||t.id.toLowerCase().includes(e)||t.email.toLowerCase().includes(e));return V&&!n.some(e=>e.id===V.id)?[V,...n]:n},[t,z,V]),H=(0,Y.useMemo)(()=>u===`operator`?r:V==null?[]:V.scopes.length>0?V.scopes:n,[u,n,r,V]);(0,Y.useEffect)(()=>{e||(d(`user`),p(``),h(``),v([]),b(`never`),w(``),D([]),j(``),P(``),R(`m`),B(``))},[e]),(0,Y.useEffect)(()=>{v(e=>{let t=e.filter(e=>H.includes(e));if(t.length>0)return t;let n=H[0];return n?[n]:[]})},[H]);let U=De(x),W=Fe(k,M,I),ne=f.trim().length>0&&_.length>0&&!o&&W!==void 0&&(u===`operator`||m.length>0)&&(y!==`custom`||U>0);return(0,Q.jsx)(O,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:c,children:(0,Q.jsxs)(N,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-create-sheet`,children:[(0,Q.jsxs)(A,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(ee,{className:`text-sm`,children:`Create API key`}),(0,Q.jsx)(F,{className:`text-[11px]`,children:u===`user`?`User-plane keys require an issuer. The key cannot exceed that user's grants.`:`Operator keys inherit the actor ceiling. Absence is impossible — only grantable scopes appear.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-name-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Name`}),(0,Q.jsx)(a,{value:f,onChange:e=>p(e.target.value),placeholder:`CI deploy`,autoComplete:`off`,"aria-label":`Key name`,flat:!0,className:i(J,`min-w-0 flex-1`)})]}),(0,Q.jsxs)(ge,{label:`Plane`,children:[(0,Q.jsx)(K,{active:u===`user`,icon:C,onClick:()=>{d(`user`)},children:`user`}),(0,Q.jsx)(K,{active:u===`operator`,icon:g,onClick:()=>{d(`operator`),h(``),B(``)},children:`operator`})]}),(0,Q.jsx)(it,{expires:y,customExpires:x,onExpires:b,onCustomExpires:w}),(0,Q.jsx)(rt,{entries:E,rateMax:k,rateCount:M,rateUnit:I,onEntries:D,onRateMax:j,onRateCount:P,onRateUnit:R}),u===`user`?(0,Q.jsxs)(`div`,{className:`border-b border-border/50`,"data-slot":`access-issuer-field`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Issuer`}),t.length>0?(0,Q.jsx)(at,{value:z,placeholder:`Search users`,label:`Search users`,onChange:B}):null]}),t.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:`No users on this plane.`}):te.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:`No users match.`}):(0,Q.jsx)(`div`,{className:`max-h-56 overflow-y-auto`,children:te.map(e=>{let t=e.id===m;return(0,Q.jsxs)(`button`,{type:`button`,"data-slot":`access-creator-user`,"aria-pressed":t,className:i(T,t&&`bg-muted/70 text-foreground`),onClick:()=>h(e.id),children:[(0,Q.jsx)(`span`,{className:i(L,t&&`bg-sky-500`)}),(0,Q.jsx)(`span`,{className:`min-w-0 truncate`,children:e.name}),(0,Q.jsx)(`span`,{className:`ml-auto shrink-0 font-mono text-[10px] text-muted-foreground`,children:e.id})]},e.id)})})]}):null,(0,Q.jsx)(ot,{scopes:H,selected:_,empty:u===`user`&&m.length===0?`Select an issuer to see grantable scopes.`:u===`user`?`This user has no grants.`:`No grantable scopes on this plane.`,onChange:v}),s?(0,Q.jsx)(ve,{slot:`access-create-error`,children:s}):null]}),(0,Q.jsxs)(S,{children:[(0,Q.jsx)(q,{split:!0,onClick:()=>c(!1),disabled:o,children:`Cancel`}),(0,Q.jsx)(q,{variant:`default`,disabled:!ne,"data-slot":`access-create-submit`,onClick:()=>{if(W===void 0)return;let e=Oe(y,Date.now(),x);l({plane:u,name:f.trim(),scopes:_,...u===`user`?{creatorUserId:m}:{},...e==null?{}:{expiresAt:e},...W==null?{}:{rateLimit:W},...E.length>0?{ipAllowlist:E}:{}})},children:o?`Creating…`:`Create`})]})]})})}function lt({open:e,keyRow:t,users:n,operators:r,operatorScopes:o,pending:s,error:c,now:l=Date.now(),onOpenChange:u,onSubmit:d}){let f=ke(t.expiresAt,l),[p,m]=(0,Y.useState)(t.name),[h,_]=(0,Y.useState)(t.scopes),[v,y]=(0,Y.useState)(f.choice),[b,x]=(0,Y.useState)(f.custom),[w,T]=(0,Y.useState)(t.ipAllowlist),E=Ie(t.rateLimit?.per??``),[D,k]=(0,Y.useState)(t.rateLimit?String(t.rateLimit.max):``),[j,M]=(0,Y.useState)(E.count),[P,I]=(0,Y.useState)(E.unit);(0,Y.useEffect)(()=>{if(!e)return;let n=ke(t.expiresAt,l);m(t.name),_(t.scopes),y(n.choice),x(n.custom),T(t.ipAllowlist);let r=Ie(t.rateLimit?.per??``);k(t.rateLimit?String(t.rateLimit.max):``),M(r.count),I(r.unit)},[e,t.id]);let L=t.creatorId??``,R=(0,Y.useMemo)(()=>L.length===0?null:n.find(e=>e.id===L)??r.find(e=>e.id===L)??null,[L,r,n]),z=R?R.name.trim()||R.email.trim()||R.id:L||`Unknown`,V=(0,Y.useMemo)(()=>{let e=t.creatorScopes??[];return e.length>0?e:t.plane===`operator`?R&&R.scopes.length>0?R.scopes:o:R?.scopes??[]},[R,t.creatorScopes,t.plane,o]),te=Array.from(new Set([...V,...t.scopes])),H=De(b),U=Fe(D,j,P),W=p.trim().length>0&&h.length>0&&!s&&U!==void 0&&(v!==`custom`||H>0);return(0,Q.jsx)(O,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:u,children:(0,Q.jsxs)(N,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-edit-sheet`,children:[(0,Q.jsxs)(A,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(ee,{className:`text-sm`,children:`Edit key`}),(0,Q.jsx)(F,{className:`text-[11px]`,children:`Change name, expiry, allow, rate, and scopes. Issuer stays frozen.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-name-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Name`}),(0,Q.jsx)(a,{value:p,onChange:e=>m(e.target.value),placeholder:`CI deploy`,autoComplete:`off`,"aria-label":`Key name`,flat:!0,className:i(J,`min-w-0 flex-1`)})]}),(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-issuer-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Issuer`}),(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center gap-1.5 px-4 text-[12px] text-muted-foreground`,"aria-label":`Issuer ${z}`,children:[(0,Q.jsx)(B,{icon:t.plane===`operator`?g:C,className:`size-3 shrink-0`,"aria-hidden":!0}),(0,Q.jsx)(`span`,{className:`min-w-0 truncate text-foreground`,children:z})]}),L.length>0&&L!==z?(0,Q.jsx)(`span`,{className:`flex h-8 shrink-0 items-center pr-4 font-mono text-[10px] text-muted-foreground`,children:L}):null]}),(0,Q.jsx)(it,{expires:v,customExpires:b,onExpires:y,onCustomExpires:x}),(0,Q.jsx)(rt,{entries:w,rateMax:D,rateCount:j,rateUnit:P,onEntries:T,onRateMax:k,onRateCount:M,onRateUnit:I}),(0,Q.jsx)(ot,{scopes:te,selected:h,empty:t.plane===`user`&&R==null?`Issuer is gone. Only scopes already on this key remain.`:t.plane===`user`?`This issuer has no grants.`:`No grantable scopes on this plane.`,onChange:_}),c?(0,Q.jsx)(ve,{slot:`access-edit-error`,children:c}):null]}),(0,Q.jsxs)(S,{children:[(0,Q.jsx)(q,{split:!0,onClick:()=>u(!1),disabled:s,children:`Cancel`}),(0,Q.jsx)(q,{variant:`default`,disabled:!W,"data-slot":`access-edit-submit`,onClick:()=>{U!==void 0&&d({name:p.trim(),scopes:h,expiresAt:Oe(v,Date.now(),b),rateLimit:U,ipAllowlist:w})},children:s?`Saving…`:`Save`})]})]})})}function ut({open:e,keyRow:t,pending:n,error:r,now:i=Date.now(),onOpenChange:a,onSubmit:o}){let s=je(t.expiresAt,i),[c,l]=(0,Y.useState)(s.choice),[u,d]=(0,Y.useState)(s.custom);(0,Y.useEffect)(()=>{if(!e)return;let n=je(t.expiresAt,i);l(n.choice),d(n.custom)},[e,t.id]);let f=De(u);return(0,Q.jsx)(O,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:a,children:(0,Q.jsxs)(N,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-refresh-sheet`,children:[(0,Q.jsxs)(A,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(ee,{className:`text-sm`,children:`Refresh expiry`}),(0,Q.jsx)(F,{className:`text-[11px]`,children:`Reset the deadline from now. The secret does not change.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsx)(it,{expires:c,customExpires:u,onExpires:l,onCustomExpires:d}),r?(0,Q.jsx)(ve,{slot:`access-refresh-error`,children:r}):null]}),(0,Q.jsxs)(S,{children:[(0,Q.jsx)(q,{split:!0,onClick:()=>a(!1),disabled:n,children:`Cancel`}),(0,Q.jsx)(q,{variant:`default`,disabled:!(!n&&(c!==`custom`||f>0)),"data-slot":`access-refresh-submit`,onClick:()=>{o(Oe(c,Date.now(),u))},children:n?`Refreshing…`:`Refresh`})]})]})})}function dt({secret:e,title:t=`New API key`,onDismiss:n}){let[r,i]=(0,Y.useState)(!1);return(0,Q.jsx)(O,{open:e!==null,onOpenChange:e=>{e||n()},children:(0,Q.jsxs)(N,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-secret-sheet`,children:[(0,Q.jsxs)(A,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(ee,{className:`text-sm`,children:t}),(0,Q.jsx)(F,{className:`text-[11px]`,children:`Shown once. Store it offline. This Console process does not keep it for you.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsx)(`p`,{className:`border-b border-border/50 px-4 py-3 font-mono text-[11px] break-all`,children:e}),(0,Q.jsx)(`p`,{className:`px-4 py-3 text-[11px] text-muted-foreground`,role:`status`,children:`Copying puts the secret on the clipboard. Anyone with this device can read it until you clear it.`})]}),(0,Q.jsxs)(S,{children:[(0,Q.jsx)(q,{split:!0,disabled:!e,onClick:()=>{e&&(navigator.clipboard?.writeText(e),i(!0))},children:r?`Copied`:`Copy (clipboard warning)`}),(0,Q.jsx)(q,{variant:`destructive`,onClick:()=>{i(!1),n()},children:`I have stored this key`})]})]})})}function ft(){let e=et(),t=s(),{query:r,selectedKey:i,action:a,setQuery:o,setSelectedKey:c,setAction:u}=ae(),d=le(),[p]=(0,Y.useState)(()=>Date.now()),[h,g]=(0,Y.useState)(null),[v,S]=(0,Y.useState)(`New API key`),C=(0,Y.useMemo)(()=>{let t=e.data?.userPlane.keys??[],n=e.data?.operatorPlane.keys??[];return[...t,...n]},[e.data]),T=(0,Y.useMemo)(()=>{let e=r.trim().toLowerCase();return e?C.filter(t=>t.name.toLowerCase().includes(e)||t.id.toLowerCase().includes(e)||t.scopes.some(t=>t.toLowerCase().includes(e))):C},[C,r]),E=T.find(e=>e.id===i)??C.find(e=>e.id===i),D=l({queryKey:[`console.access.blast`,E?.id],queryFn:async()=>{if(!E)throw Error(`no key`);let e=await R(E.id);if(e.error||!e.data)throw Error(e.error?.message??`blast failed`);return e.data},enabled:E!==void 0});(0,Y.useEffect)(()=>{let e=e=>{if(e.key!==`/`||e.metaKey||e.ctrlKey||e.altKey)return;let t=e.target;if(t instanceof HTMLElement){let e=t.tagName;if(e===`INPUT`||e===`TEXTAREA`||t.isContentEditable)return}e.preventDefault(),document.querySelector(`[data-slot='access-search-input']`)?.focus()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]);let O=()=>{t.invalidateQueries({queryKey:$e})},k=G({mutationFn:_,onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?m(e.error):`create failed`);S(`New API key`),g(e.data.secret),c(e.data.key.id),u(null),O()}}),A=G({mutationFn:e=>te({keyId:E.id,confirmation:e.confirmation,reason:e.reason}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?m(e.error):`rotate failed`);S(`Rotated API key`),g(e.data.secret),u(null),O()}}),M=G({mutationFn:e=>b({keyId:E.id,confirmation:e.confirmation,reason:e.reason}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?m(e.error):`revoke failed`);u(null),O()}}),N=G({mutationFn:f,onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?m(e.error):`update failed`);u(null),O()}}),P=G({mutationFn:e=>f({keyId:E.id,expiresAt:e}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?m(e.error):`refresh failed`);u(null),O()}}),F=(0,Q.jsx)(ue,{open:d.open,onToggle:d.toggle,noun:`keys`,controlsId:`access-list`,dataSlot:`access-list-toggle`});return(0,Q.jsxs)(`div`,{className:w,"data-slot":`access-page`,children:[(0,Q.jsxs)(oe,{orientation:`horizontal`,className:`min-h-0 flex-1`,children:[(0,Q.jsx)(ce,{panelRef:d.panelRef,collapsible:!0,collapsedSize:0,defaultSize:j.start.defaultSize,minSize:j.start.minSize,onResize:d.onResize,className:`min-h-0 overflow-hidden`,children:(0,Q.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col overflow-hidden`,children:[(0,Q.jsxs)(`div`,{className:x,children:[(0,Q.jsx)(se,{"data-slot":`access-search-input`,placeholder:`Search keys`,"aria-label":`Search keys`,value:r,onChange:e=>o(e.target.value)}),(0,Q.jsx)(fe,{label:`Create key`,className:`flex self-stretch`,children:(0,Q.jsx)(`button`,{type:`button`,className:y,"data-slot":`access-create`,"aria-label":`Create key`,onClick:()=>u(`create`),children:(0,Q.jsx)(B,{icon:n,className:`size-3.5`})})})]}),(0,Q.jsx)(tt,{rows:T,selectedKey:i,query:r,loading:e.isLoading,onSelect:c})]})}),d.open?(0,Q.jsx)(de,{withHandle:!0}):null,(0,Q.jsx)(ce,{defaultSize:j.end.defaultSize,minSize:j.end.minSize,className:`min-h-0 overflow-hidden`,children:E?(0,Q.jsx)(Ge,{keyRow:E,blast:D.data,now:p,leading:F,onEdit:()=>u(`edit`),onRefresh:()=>u(`refresh`),onRevoke:()=>u(`revoke`),onRotate:()=>u(`rotate`),rotatePending:A.isPending}):(0,Q.jsx)(me,{icon:pe.gate.icon,iconClassName:`border-border/70`,title:e.isLoading?`Loading keys…`:C.length>0?`Select a key`:`No keys yet`,leading:F,description:e.isLoading?`Reading planes and grantable scopes.`:C.length>0&&r.trim().length>0?(0,Q.jsxs)(Q.Fragment,{children:[`Nothing matches `,(0,Q.jsx)(`span`,{className:`font-mono`,children:r}),`.`,` `,(0,Q.jsx)(`button`,{type:`button`,className:`underline underline-offset-2 hover:text-foreground`,onClick:()=>o(``),children:`Clear search`})]}):`Create one to mint a secret once.`})})]}),(0,Q.jsx)(ct,{open:a===`create`,users:e.data?.userPlane.users??[],userScopes:e.data?.userPlane.grantableScopes??[],operatorScopes:e.data?.operatorPlane.grantableScopes??[],pending:k.isPending,error:k.error instanceof Error?k.error.message:null,onOpenChange:e=>{e||u(null)},onSubmit:e=>k.mutate(e)}),E?(0,Q.jsx)(lt,{open:a===`edit`,keyRow:E,users:e.data?.userPlane.users??[],operators:e.data?.operatorPlane.operators??[],operatorScopes:e.data?.operatorPlane.grantableScopes??[],pending:N.isPending,error:N.error instanceof Error?N.error.message:null,onOpenChange:e=>{e||u(null)},onSubmit:e=>N.mutate({keyId:E.id,...e})}):null,E?(0,Q.jsx)(ut,{open:a===`refresh`,keyRow:E,pending:P.isPending,error:P.error instanceof Error?P.error.message:null,onOpenChange:e=>{e||u(null)},onSubmit:e=>P.mutate(e)}):null,E?(0,Q.jsx)(be,{open:a===`revoke`,onOpenChange:e=>{e||u(null)},phrase:`REVOKE`,title:`Revoke ${E.name}`,description:`Irreversible. Residual sessions may continue for the access TTL.`,pending:M.isPending,error:M.error instanceof Error?M.error.message:null,confirmLabel:`Revoke key`,slot:`access-revoke-sheet`,onConfirm:e=>M.mutate({confirmation:`REVOKE`,reason:e.reason})}):null,E?(0,Q.jsx)(be,{open:a===`rotate`,onOpenChange:e=>{e||u(null)},phrase:`ROTATE`,title:`Rotate ${E.name}`,description:`Mints a new secret once. The current secret stops after residual TTL.`,pending:A.isPending,error:A.error instanceof Error?A.error.message:null,confirmLabel:`Rotate key`,confirmVariant:`ghost`,slot:`access-rotate-sheet`,onConfirm:e=>A.mutate({confirmation:`ROTATE`,reason:e.reason})}):null,(0,Q.jsx)(dt,{secret:h,title:v,onDismiss:()=>g(null)})]})}export{ft as AccessPage};