okengine 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -2
- package/README.md +98 -71
- package/package.json +4 -4
- package/site/content/docs/console/clock.mdx +25 -5
- package/site/content/docs/console/signals.mdx +13 -4
- package/site/content/docs/elements/ai.mdx +29 -2
- package/site/content/docs/elements/channel.mdx +90 -20
- package/site/content/docs/elements/clock.mdx +56 -24
- package/site/content/docs/elements/flow.mdx +2 -0
- package/site/content/docs/elements/gate.mdx +8 -1
- package/site/content/docs/elements/signal.mdx +173 -29
- package/site/content/docs/elements/store.mdx +464 -73
- package/site/content/docs/elements/vault.mdx +15 -5
- package/site/content/docs/get-started/basic-usage.mdx +13 -6
- package/site/content/docs/get-started/installation.mdx +49 -13
- package/site/content/docs/get-started/introduction.mdx +1 -1
- package/site/content/docs/reference/cli.md +30 -2
- package/site/content/docs/reference/configuration.mdx +18 -17
- package/site/content/docs/reference/environment-variables.mdx +44 -18
- package/site/content/docs/reference/errors.mdx +12 -11
- package/site/content/docs/reference/fx.mdx +15 -13
- package/site/content/docs/reference/security.md +3 -1
- package/src/cli/ai-setup/ai-setup.test.ts +144 -0
- package/src/cli/ai-setup/apply.ts +214 -0
- package/src/cli/ai-setup/catalog.ts +263 -0
- package/src/cli/ai-setup/detect-ollama.ts +166 -0
- package/src/cli/ai-setup/index.ts +228 -0
- package/src/cli/ai-setup/prompts.ts +649 -0
- package/src/cli/ai-setup/recommend.test.ts +100 -0
- package/src/cli/ai-setup/recommend.ts +203 -0
- package/src/cli/ai.ts +38 -0
- package/src/cli/db-auto-push.test.ts +6 -1
- package/src/cli/db-auto-push.ts +8 -3
- package/src/cli/dev-db-push.test.ts +59 -0
- package/src/cli/dev.test.ts +40 -0
- package/src/cli/dev.ts +55 -1
- package/src/cli/docker-clean.test.ts +179 -0
- package/src/cli/docker-clean.ts +406 -0
- package/src/cli/docker.ts +16 -4
- package/src/cli/ensure-drizzle-config.ts +1 -1
- package/src/cli/hero-meta.test.ts +6 -5
- package/src/cli/hero-meta.ts +7 -1
- package/src/cli/index.ts +5 -0
- package/src/cli/load-config.ts +4 -4
- package/src/cli/openbao-bootstrap.test.ts +1 -0
- package/src/cli/openbao-bootstrap.ts +9 -2
- package/src/cli/openbao-restart.integration.test.ts +106 -97
- package/src/cli/registry.ts +79 -1
- package/src/client/live-gap.test.ts +35 -0
- package/src/client/transport.test.ts +21 -0
- package/src/client/transport.ts +27 -5
- package/src/compiler/fixtures/skyport/oke.config.ts +1 -1
- package/src/config/define-config.test.ts +6 -6
- package/src/config/index.ts +1 -1
- package/src/console/server/console.test.ts +45 -0
- package/src/console/server/flows.ts +39 -9
- package/src/console/server/i18n.ts +41 -0
- package/src/console/server/vault.ts +12 -38
- package/src/console/ui/dist/assets/index-ClX0ZCe5.js +10 -0
- package/src/console/ui/dist/assets/{panel-access-BGv45snf.js → panel-access-ri1X9Otj.js} +1 -1
- package/src/console/ui/dist/assets/{panel-ai-B2S7LEii.js → panel-ai-DLHjRoJk.js} +1 -1
- package/src/console/ui/dist/assets/{panel-architecture-D7UJh91v.js → panel-architecture-DI3bQF3J.js} +1 -1
- package/src/console/ui/dist/assets/{panel-channels-9T3ybqRu.js → panel-channels-BDYWX29p.js} +1 -1
- package/src/console/ui/dist/assets/{panel-clock-Cb1UXGRQ.js → panel-clock-i-JpTjVB.js} +1 -1
- package/src/console/ui/dist/assets/{panel-diff-DmYbKWmN.js → panel-diff-CFuWxiXy.js} +1 -1
- package/src/console/ui/dist/assets/{panel-flows-PiHwT55z.js → panel-flows-B8TRhcoe.js} +1 -1
- package/src/console/ui/dist/assets/{panel-gates-BQGYXvjT.js → panel-gates-CfkBgco7.js} +1 -1
- package/src/console/ui/dist/assets/{panel-overview-BBnRO18l.js → panel-overview-DONDzBd2.js} +1 -1
- package/src/console/ui/dist/assets/{panel-plugins-D0PsmVw2.js → panel-plugins-DDJwTehL.js} +1 -1
- package/src/console/ui/dist/assets/{panel-runs-CWuRDe0r.js → panel-runs-D5zf-D9c.js} +1 -1
- package/src/console/ui/dist/assets/{panel-signals-Bbg4ewpP.js → panel-signals-Dsxdu_AR.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-CPCbsDRa.js → panel-store-hy7O8HOs.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-DVAzuA_S.js → panel-traces-CBiAe5go.js} +1 -1
- package/src/console/ui/dist/assets/{panel-vault-D1_MvOmo.js → panel-vault-Za1GyJfM.js} +1 -1
- package/src/console/ui/dist/index.html +1 -1
- package/src/console/ui/shell/components/ui.tsx +5 -1
- package/src/console/ui/shell/setup/Wizard.tsx +26 -5
- package/src/docker/cleanup.test.ts +193 -0
- package/src/docker/cleanup.ts +355 -0
- package/src/docker/docker.test.ts +4 -0
- package/src/docker/dockerfile.integration.test.ts +126 -119
- package/src/docker/index.ts +19 -0
- package/src/docker/recipes/ollama.ts +10 -5
- package/src/docker/stack.integration.test.ts +118 -102
- package/src/drivers/ai-ollama-tools.integration.test.ts +8 -6
- package/src/drivers/ai-ollama.integration.test.ts +3 -19
- package/src/drivers/ai-ollama.ts +45 -2
- package/src/drivers/ai-providers.test.ts +31 -0
- package/src/drivers/channel-fcm.ts +49 -53
- package/src/drivers/channel-msegat.ts +61 -0
- package/src/drivers/channel-sently-map.ts +57 -0
- package/src/drivers/channel-sently.test.ts +99 -0
- package/src/drivers/channel-sndr.ts +28 -0
- package/src/drivers/channel-taqnyat.ts +57 -0
- package/src/drivers/channel-types.ts +79 -2
- package/src/drivers/channel-unifonic.ts +26 -43
- package/src/drivers/channel-wa-cloud.ts +33 -47
- package/src/drivers/channel-webpush.ts +39 -239
- package/src/drivers/index.ts +7 -0
- package/src/drivers/signal-engine.ts +98 -25
- package/src/drivers/signal-nats.ts +4 -4
- package/src/drivers/signal-postgres.ts +158 -64
- package/src/drivers/signal-redis.ts +4 -4
- package/src/drivers/signal-types.ts +61 -2
- package/src/drivers/vault-driver-removal.test.ts +5 -1
- package/src/elements/channel/costs.test.ts +2 -2
- package/src/elements/channel/costs.ts +14 -2
- package/src/elements/channel/mime.ts +11 -0
- package/src/elements/channel/runtime.ts +94 -0
- package/src/elements/channel/sndr-webhooks.test.ts +26 -0
- package/src/elements/channel.ts +10 -1
- package/src/elements/clock/chaos-child.ts +150 -0
- package/src/elements/clock/chaos.test.ts +204 -0
- package/src/elements/clock/reconcile.ts +110 -0
- package/src/elements/clock/runtime.ts +11 -0
- package/src/elements/clock.test.ts +164 -2
- package/src/elements/clock.ts +1 -0
- package/src/elements/gate/runtime.ts +6 -0
- package/src/elements/index.ts +9 -0
- package/src/elements/signal/chaos-child.ts +41 -4
- package/src/elements/signal/declare.ts +4 -1
- package/src/elements/signal/delivery-modes.test.ts +179 -0
- package/src/elements/signal/key-ordering.test.ts +306 -0
- package/src/elements/signal/lease-reclaim.test.ts +123 -0
- package/src/elements/signal/optional-emit.test.ts +76 -0
- package/src/elements/signal/order-lifecycle.test.ts +130 -0
- package/src/elements/signal/orphan-messages.test.ts +152 -0
- package/src/elements/signal/runtime.ts +11 -4
- package/src/elements/signal/schema-emit.test.ts +107 -0
- package/src/elements/signal.test.ts +89 -5
- package/src/elements/store/files-fx.ts +104 -0
- package/src/elements/store/files-image.test.ts +251 -0
- package/src/elements/store/files-image.ts +494 -0
- package/src/elements/store/runtime.ts +60 -0
- package/src/elements/store.ts +24 -0
- package/src/elements/vault/boot-chain.ts +150 -0
- package/src/elements/vault/runtime.ts +8 -0
- package/src/kernel/app.ts +3 -1
- package/src/kernel/boot-bind/channel.test.ts +68 -3
- package/src/kernel/boot-bind/channel.ts +93 -2
- package/src/kernel/boot-bind/clock.ts +52 -7
- package/src/kernel/boot-bind/gate.ts +71 -3
- package/src/kernel/boot-bind/honor-config.test.ts +247 -0
- package/src/kernel/boot-bind/signal.ts +64 -7
- package/src/kernel/boot-bind/vault.ts +27 -8
- package/src/kernel/boot.ts +10 -2
- package/src/kernel/errors.ts +8 -2
- package/src/kernel/fx.test.ts +13 -0
- package/src/kernel/fx.ts +27 -4
- package/src/plugins/auth-delivery.mailpit.integration.test.ts +10 -4
- package/src/release/exports.test.ts +26 -0
- package/src/release/exports.ts +64 -5
- package/src/release/index.ts +5 -0
- package/src/release/measure.exports.test.ts +13 -1
- package/src/release/measure.ts +76 -13
- package/src/release/official-plugins.ts +46 -0
- package/src/release/readme.test.ts +30 -2
- package/src/runtime/dev-request-log.test.ts +20 -1
- package/src/runtime/dev-request-log.ts +38 -0
- package/src/term.test.ts +15 -0
- package/src/term.ts +8 -3
- package/src/console/ui/dist/assets/index-CjxwRGVv.js +0 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,r as t}from"./rolldown-runtime-B0Z9INg1.js";import{C as n,Q as r,Z as i,a,b as o,d as s,et as c,g as l,nt as u,o as d,r as f,tt as p,u as m,w as h,y as g}from"./panel-access-BGv45snf.js";import{r as _}from"./panel-runs-CWuRDe0r.js";import{n as v}from"./panel-channels-9T3ybqRu.js";var y=g({q:o().optional(),ref:o().optional(),child:o().optional(),tenant:o().optional(),view:l([`browse`,`cache`,`sql`,`probe`]).optional(),prefix:o().optional()});function b(e){let t=y.safeParse(e);return t.success?t.data:{}}function x(e){let t={};return e.q&&(t.q=e.q),e.ref&&(t.ref=e.ref),e.child&&(t.child=e.child),e.tenant&&(t.tenant=e.tenant),e.view&&e.view!==`browse`&&(t.view=e.view),e.prefix&&(t.prefix=e.prefix),t}function S(e,t){return{...e,ref:t,child:void 0,view:`browse`}}function C(e,t){return{...e,child:t,view:`browse`}}var w=[`sql`,`kv`,`files`,`index`],T={sql:`SQL`,kv:`KV`,files:`Files`,index:`Index`};function E(e,t=``){let n=t.trim().toLowerCase(),r=n?e.filter(e=>e.name.toLowerCase().includes(n)||e.ref.toLowerCase().includes(n)||e.children.some(e=>e.name.toLowerCase().includes(n))):e;return w.map(e=>({facet:e,label:T[e],stores:r.filter(t=>t.facet===e)})).filter(e=>e.stores.length>0)}function D(e={production:!0}){return e.production?{kind:`typed`,phrase:`EDIT`,requireReason:!0}:{kind:`undo`,windowMs:f}}function O(e={production:!0}){return e.production?{kind:`typed`,phrase:`DELETE`,requireReason:!0}:{kind:`undo`,windowMs:f}}function k(e={production:!0}){return e.production?{kind:`typed`,phrase:`PURGE`,requireReason:!0}:{kind:`undo`,windowMs:f}}function A(e){let t=[];for(let n of e.signals)t.push(`Signal \`${n}\` will not be emitted`);for(let n of e.channels)t.push(`Channel \`${n}\` will not fire`);return e.writerFlowIds.length>0&&t.push(`Owning flow(s): ${e.writerFlowIds.map(e=>`\`${e}\``).join(`, `)} — not executed`),{headline:`Direct edit is not a flow execution — the following will NOT happen:`,lines:t,empty:t.length===0}}function j(e){return e.facet===`index`?{ok:!1,reason:`Index facet has no bulk-update preview — similarity probe is read-only.`}:{ok:!0}}function ee(e){let t=e.cache,n=t.invalidatedByWrites,r=t.invalidatingFlowIds,i=n.length===0?`Read key \`${t.producedByRead}\` — no write invalidators declared.`:`Read key \`${t.producedByRead}\` — invalidated by writes to ${n.map(e=>`\`${e}\``).join(`, `)}.`;return{producedByRead:t.producedByRead,invalidatedBy:n,invalidatingFlows:r,summary:i}}var M=e(u(),1),N=p();function P(){let e=h({from:`/store`}),t=n({from:`/store`}),o=c(),[l,u]=(0,M.useState)(``),[d,f]=(0,M.useState)(``),[p,g]=(0,M.useState)(`{}`),[_,y]=(0,M.useState)(`SELECT * FROM "bookings" LIMIT 50`),[b,C]=(0,M.useState)(`0.1,0.2,0.3`),[w,T]=(0,M.useState)(null),P=e=>{t({search:x(e),replace:!0})},I=r({queryKey:[`console.store.list`],queryFn:async()=>{let e=await s.storeList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:1e4}),L=I.data?.tenancyDeclared??!1,te=I.data?.tenants??[],R=I.data?.stores??[],ne=(0,M.useMemo)(()=>E(R,e.q??``),[R,e.q]),z=R.find(t=>t.ref===e.ref),B=z?.children.find(t=>t.name===e.child)??z?.children[0],V=e.view??`browse`,H=D({production:!0}),U=O({production:!0}),W=k({production:!0}),G=z?j(z):null,re=B?A(B.willNotFire):null,ie=B?ee(B):null,K=r({queryKey:[`console.store.query`,e.ref,B?.name,e.tenant,e.prefix,V,b],enabled:!!z&&!!B&&V===`browse`&&(!L||!!e.tenant),queryFn:async()=>{if(!z||!B)return null;let t=z.facet===`index`?b.split(`,`).map(e=>Number(e.trim())).filter(e=>!Number.isNaN(e)):void 0,n=await s.storeQuery({ref:z.ref,child:B.name,tenant:e.tenant,prefix:e.prefix,vector:t,topK:5});if(n.error)throw Error(n.error.code);return n.data}});(0,M.useEffect)(()=>{u(``),f(``),T(null)},[z?.ref,B?.name]);let q=()=>{o.invalidateQueries({queryKey:[`console.store.list`]}),o.invalidateQueries({queryKey:[`console.store.query`]})},J=i({mutationFn:async()=>{if(!z||!B)return;if(G&&!G.ok)throw Error(G.reason);let t={};try{t=JSON.parse(p)}catch{throw Error(`Patch must be valid JSON`)}let n=await s.storePreview({ref:z.ref,child:B.name,tenant:e.tenant,id:String(t.id??`preview`),key:typeof t.key==`string`?t.key:void 0,patch:t});if(n.error)throw Error(n.error.code);let r=n.data;return T(A(r.willNotFire).lines),r}}),Y=i({mutationFn:async()=>{if(!z||!B)return;if(H.kind===`typed`){let e=a({typed:l,reason:d,phrase:H.phrase});if(e)throw Error(e.typed??e.reason)}let t={};try{t=JSON.parse(p)}catch{throw Error(`Patch must be valid JSON`)}let n=await s.storeEdit({ref:z.ref,child:B.name,tenant:e.tenant,id:String(t.id??``),key:typeof t.key==`string`?t.key:void 0,patch:t,confirmation:l,reason:d,commit:!0});if(n.error)throw Error(n.error.code);return n.data},onSuccess:q}),X=i({mutationFn:async t=>{if(!z||!B)return;if(U.kind===`typed`){let e=a({typed:l,reason:d,phrase:U.phrase});if(e)throw Error(e.typed??e.reason)}let n=await s.storeDelete({ref:z.ref,child:B.name,tenant:e.tenant,ids:z.facet===`sql`||z.facet===`index`?t:void 0,keys:z.facet===`kv`||z.facet===`files`?t:void 0,confirmation:l,reason:d});if(n.error)throw Error(n.error.code);return n.data},onSuccess:q}),Z=i({mutationFn:async()=>{if(!B)return;if(W.kind===`typed`){let e=a({typed:l,reason:d,phrase:W.phrase});if(e)throw Error(e.typed??e.reason)}let e=await s.storePurgeCache({resource:B.effectRef,confirmation:l,reason:d});if(e.error)throw Error(e.error.code);return e.data},onSuccess:q}),Q=i({mutationFn:async()=>{if(!z||z.facet!==`sql`)return;let t=await s.storeSql({ref:z.ref,sql:_,tenant:e.tenant,allowWrite:!1});if(t.error)throw Error(t.error.code);return t.data}}),$=i({mutationFn:async t=>{if(!z||!B)return;let n=await s.storeReveal({ref:z.ref,child:B.name,tenant:e.tenant,id:t.id,column:t.column});if(n.error)throw Error(n.error.code);return n.data}});return(0,N.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,N.jsxs)(`header`,{className:`flex shrink-0 flex-wrap items-end gap-3 border-b border-[var(--oke-line)] px-4 py-3`,children:[(0,N.jsxs)(`div`,{className:`mr-auto`,children:[(0,N.jsx)(`h1`,{className:`text-lg font-medium`,children:`Store`}),(0,N.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`One list, grouped by facet — direct edits are not flow executions`})]}),L?(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,N.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Tenant`}),(0,N.jsxs)(`select`,{"aria-label":`Tenant`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2`,value:e.tenant??``,onChange:t=>P({...e,tenant:t.target.value||void 0}),children:[(0,N.jsx)(`option`,{value:``,children:`Select tenant…`}),te.map(e=>(0,N.jsx)(`option`,{value:e,children:e},e))]})]}):null,(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,N.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Filter`}),(0,N.jsx)(`input`,{"aria-label":`Filter stores`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2`,value:e.q??``,onChange:t=>P({...e,q:t.target.value||void 0})})]})]}),(0,N.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,N.jsxs)(`section`,{"aria-label":`Store list`,className:`w-72 shrink-0 overflow-y-auto border-r border-[var(--oke-line)]`,children:[I.isLoading?(0,N.jsx)(`p`,{className:`p-3 text-sm text-[var(--oke-muted)]`,children:`Loading…`}):null,ne.map(t=>(0,N.jsxs)(`div`,{className:`border-b border-[var(--oke-line)]`,children:[(0,N.jsx)(`h2`,{className:`px-3 py-2 text-xs tracking-wide text-[var(--oke-muted)]`,children:t.label}),(0,N.jsx)(`ul`,{children:t.stores.map(t=>(0,N.jsx)(`li`,{children:(0,N.jsxs)(`button`,{type:`button`,"aria-pressed":t.ref===e.ref,className:m(`flex min-h-8 w-full flex-col items-start px-3 py-2 text-left text-sm`,t.ref===e.ref?`bg-[var(--oke-line)]/40`:`hover:bg-[var(--oke-line)]/20`),onClick:()=>P(S(e,t.ref)),children:[(0,N.jsx)(`span`,{children:v(t.name,t.description)}),t.description?(0,N.jsx)(`span`,{className:`font-mono text-xs text-[var(--oke-muted)]`,children:t.name}):null,(0,N.jsxs)(`span`,{className:`text-xs text-[var(--oke-muted)]`,children:[t.children.length,` resource(s)`,t.replicaLagMs==null?``:` · lag ${t.replicaLagMs}ms`,t.migrationDrift?.drifted?` · drift`:``,t.warnings.length>0?` · ${t.warnings.length} warn`:``]})]})},t.ref))})]},t.facet))]}),(0,N.jsx)(`section`,{"aria-label":`Store detail`,className:`min-w-0 flex-1 overflow-y-auto p-4`,"aria-live":`polite`,children:z?L&&!e.tenant?(0,N.jsx)(`p`,{role:`status`,className:`text-sm`,children:`Select a tenant in the header before browsing — compliance boundary, not a display filter.`}):(0,N.jsx)(F,{open:z,childName:B?.name,view:V,search:e,setSearch:P,browse:K.data,browseLoading:K.isLoading,cache:ie,willNot:re,willNotPreview:w,patchJson:p,setPatchJson:g,typed:l,setTyped:u,reason:d,setReason:f,sqlText:_,setSqlText:y,probeVector:b,setProbeVector:C,onPreview:()=>J.mutate(),onCommit:()=>Y.mutate(),onDelete:e=>X.mutate(e),onPurge:()=>Z.mutate(),onSql:()=>Q.mutate(),sqlResult:Q.data,onReveal:(e,t)=>$.mutate({id:e,column:t}),revealValue:$.data?.value,error:J.error?.message??Y.error?.message??X.error?.message??Z.error?.message??Q.error?.message??$.error?.message}):(0,N.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Select a store. Tenant selector appears only when tenancy is declared on the Manifest.`})})]})]})}function F(e){let{open:t,childName:n,view:r,search:i,setSearch:a,browse:o,browseLoading:s,cache:c,willNot:l,willNotPreview:u,patchJson:f,setPatchJson:p,typed:h,setTyped:g,reason:y,setReason:b,sqlText:x,setSqlText:S,probeVector:w,setProbeVector:T,onPreview:E,onCommit:D,onDelete:O,onPurge:k,onSql:A,sqlResult:j,onReveal:ee,revealValue:M,error:P}=e,F=t.children.find(e=>e.name===n);return(0,N.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-2`,children:[(0,N.jsx)(`h2`,{className:`text-base font-medium`,children:v(t.name,t.description)}),(0,N.jsxs)(`span`,{className:`text-sm text-[var(--oke-muted)]`,children:[t.description?`${t.name} · `:``,t.ref]}),t.contentAddressed?(0,N.jsx)(`span`,{role:`status`,className:`text-xs text-[var(--oke-muted)]`,children:`content-addressed keys`}):null]}),(0,N.jsx)(`div`,{className:`flex flex-wrap gap-2`,role:`tablist`,"aria-label":`Views`,children:[[`browse`,`Browse`],[`cache`,`Cache`],...t.facet===`sql`?[[`sql`,`SQL`]]:[],...t.facet===`index`?[[`probe`,`Probe`]]:[]].map(([e,t])=>(0,N.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":r===e,className:m(`min-h-8 px-2 text-sm`,r===e?`text-[var(--oke-fg)] underline`:`text-[var(--oke-muted)]`),onClick:()=>a({...i,view:e}),children:t},e))}),(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,N.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Resource`}),(0,N.jsx)(`select`,{"aria-label":`Store resource`,className:`min-h-8 max-w-xs border border-[var(--oke-line)] bg-transparent px-2`,value:n??``,onChange:e=>a(C(i,e.target.value)),children:t.children.map(e=>(0,N.jsx)(`option`,{value:e.name,children:e.name},e.name))})]}),F?(0,N.jsxs)(`p`,{className:`text-sm`,role:`status`,children:[`Writers:`,` `,F.writers.map(e=>(0,N.jsx)(_,{to:`/flows`,search:{flow:e},className:`mr-2 underline`,children:e},e)),F.writers.length===0?`none`:null,` · `,`Readers: `,F.readers.join(`, `)||`none`,F.piiColumns.length>0?` · PII columns: ${F.piiColumns.join(`, `)}`:``]}):null,t.migrationDrift?(0,N.jsxs)(`p`,{className:`text-sm`,role:`status`,children:[`Migration: declared `,t.migrationDrift.declared.slice(0,12),`…`,t.migrationDrift.applied?` / applied ${t.migrationDrift.applied.slice(0,12)}…`:` / applied (none)`,t.migrationDrift.drifted?` — drifted`:` — in sync`]}):null,t.warnings.length>0?(0,N.jsx)(`ul`,{"aria-label":`Operational warnings`,className:`text-sm`,children:t.warnings.map(e=>(0,N.jsxs)(`li`,{role:`status`,children:[e.key,`: `,e.message]},`${e.key}:${e.code}`))}):null,r===`cache`&&c?(0,N.jsxs)(`section`,{"aria-label":`Cache`,children:[(0,N.jsx)(`h3`,{className:`text-sm font-medium`,children:`Cache`}),(0,N.jsx)(`p`,{className:`text-sm`,role:`status`,children:c.summary}),(0,N.jsxs)(`p`,{className:`text-xs text-[var(--oke-muted)]`,children:[`Invalidating flows: `,c.invalidatingFlows.join(`, `)||`none`]}),(0,N.jsx)(d,{type:`button`,onClick:k,children:`Purge cache namespace`})]}):null,r===`sql`&&t.facet===`sql`?(0,N.jsxs)(`section`,{"aria-label":`SQL console`,className:`flex flex-col gap-2`,children:[(0,N.jsx)(`h3`,{className:`text-sm font-medium`,children:`SQL console (read-only)`}),(0,N.jsx)(`textarea`,{"aria-label":`SQL console`,className:`min-h-24 border border-[var(--oke-line)] bg-transparent p-2 font-mono text-sm`,value:x,onChange:e=>S(e.target.value)}),(0,N.jsx)(d,{type:`button`,onClick:A,children:`Run`}),j?(0,N.jsxs)(`p`,{className:`text-xs text-[var(--oke-muted)]`,children:[j.rows.length,` row(s) · routed `,j.routedRole,j.masked?` · PII masked`:``]}):null]}):null,(r===`browse`||r===`probe`)&&(0,N.jsxs)(`section`,{"aria-label":`Browse`,children:[t.facet===`index`?(0,N.jsxs)(`label`,{className:`mb-2 flex flex-col gap-1 text-sm`,children:[(0,N.jsx)(`span`,{children:`Probe vector`}),(0,N.jsx)(`input`,{"aria-label":`Probe vector`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2 font-mono`,value:w,onChange:e=>T(e.target.value)})]}):null,s?(0,N.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Loading…`}):null,o?.rows?(0,N.jsxs)(`table`,{className:`w-full text-left text-sm`,children:[(0,N.jsx)(`thead`,{children:(0,N.jsxs)(`tr`,{children:[Object.keys(o.rows[0]??{id:1}).map(e=>(0,N.jsx)(`th`,{scope:`col`,className:`border-b px-2 py-1`,children:v(e,F?.columnDescriptions[e])},e)),(0,N.jsx)(`th`,{scope:`col`,className:`border-b px-2 py-1`,children:`Actions`})]})}),(0,N.jsx)(`tbody`,{children:o.rows.map((e,t)=>(0,N.jsxs)(`tr`,{children:[Object.entries(e).map(([t,n])=>(0,N.jsxs)(`td`,{className:`border-b px-2 py-1 font-mono`,children:[String(n),F?.piiColumns.includes(t)?(0,N.jsx)(`button`,{type:`button`,className:`ml-2 underline`,style:{minHeight:32},onClick:()=>ee(String(e.id??``),t),children:`Reveal`}):null]},t)),(0,N.jsx)(`td`,{className:`border-b px-2 py-1`,children:(0,N.jsx)(d,{type:`button`,onClick:()=>O([String(e.id??``)]),children:`Delete`})})]},t))})]}):null,o?.keys?(0,N.jsx)(`ul`,{"aria-label":`Keys`,className:`text-sm`,children:o.keys.map(e=>(0,N.jsxs)(`li`,{className:`flex min-h-8 items-center gap-2`,children:[(0,N.jsx)(`span`,{className:`font-mono`,children:e.key}),e.value===void 0?null:(0,N.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:JSON.stringify(e.value)}),e.warnings?.map(e=>(0,N.jsx)(`span`,{role:`status`,className:`text-xs`,children:e.message},e.code)),(0,N.jsx)(d,{type:`button`,onClick:()=>O([e.key]),children:`Delete`})]},e.key))}):null,o?.hits?(0,N.jsx)(`ul`,{"aria-label":`Similarity hits`,className:`text-sm`,children:o.hits.map(e=>(0,N.jsxs)(`li`,{children:[e.id,` · score `,e.score.toFixed(3)]},e.id))}):null,M===void 0?null:(0,N.jsxs)(`p`,{role:`status`,className:`text-sm`,children:[`Revealed: `,String(M)]})]}),(0,N.jsxs)(`section`,{"aria-label":`Direct edit`,className:`flex flex-col gap-2 border-t border-[var(--oke-line)] pt-4`,children:[(0,N.jsx)(`h3`,{className:`text-sm font-medium`,children:`Direct edit`}),(0,N.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Not a flow execution. Before saving, preview names what will not fire.`}),l&&!l.empty?(0,N.jsx)(`ul`,{className:`text-sm`,children:(u??l.lines).map(e=>(0,N.jsx)(`li`,{children:e},e))}):(0,N.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`No owning-flow emissions declared for this resource.`}),(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[`Patch (JSON)`,(0,N.jsx)(`textarea`,{"aria-label":`Edit patch JSON`,className:`min-h-20 border border-[var(--oke-line)] bg-transparent p-2 font-mono text-sm`,value:f,onChange:e=>p(e.target.value)})]}),(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[`Type EDIT / DELETE / PURGE`,(0,N.jsx)(`input`,{"aria-label":`Confirmation phrase`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2`,value:h,onChange:e=>g(e.target.value)})]}),(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[`Reason`,(0,N.jsx)(`input`,{"aria-label":`Confirmation reason`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2`,value:y,onChange:e=>b(e.target.value)})]}),(0,N.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,N.jsx)(d,{type:`button`,onClick:E,children:`Preview`}),(0,N.jsx)(d,{type:`button`,onClick:D,children:`Save edit`})]}),P?(0,N.jsx)(`p`,{role:`alert`,className:`text-sm text-red-600`,children:P}):null]})]})}var I=t({default:()=>P});export{b as n,I as t};
|
|
1
|
+
import{a as e,r as t}from"./rolldown-runtime-B0Z9INg1.js";import{C as n,Q as r,Z as i,a,b as o,d as s,et as c,g as l,nt as u,o as d,r as f,tt as p,u as m,w as h,y as g}from"./panel-access-ri1X9Otj.js";import{r as _}from"./panel-runs-D5zf-D9c.js";import{n as v}from"./panel-channels-BDYWX29p.js";var y=g({q:o().optional(),ref:o().optional(),child:o().optional(),tenant:o().optional(),view:l([`browse`,`cache`,`sql`,`probe`]).optional(),prefix:o().optional()});function b(e){let t=y.safeParse(e);return t.success?t.data:{}}function x(e){let t={};return e.q&&(t.q=e.q),e.ref&&(t.ref=e.ref),e.child&&(t.child=e.child),e.tenant&&(t.tenant=e.tenant),e.view&&e.view!==`browse`&&(t.view=e.view),e.prefix&&(t.prefix=e.prefix),t}function S(e,t){return{...e,ref:t,child:void 0,view:`browse`}}function C(e,t){return{...e,child:t,view:`browse`}}var w=[`sql`,`kv`,`files`,`index`],T={sql:`SQL`,kv:`KV`,files:`Files`,index:`Index`};function E(e,t=``){let n=t.trim().toLowerCase(),r=n?e.filter(e=>e.name.toLowerCase().includes(n)||e.ref.toLowerCase().includes(n)||e.children.some(e=>e.name.toLowerCase().includes(n))):e;return w.map(e=>({facet:e,label:T[e],stores:r.filter(t=>t.facet===e)})).filter(e=>e.stores.length>0)}function D(e={production:!0}){return e.production?{kind:`typed`,phrase:`EDIT`,requireReason:!0}:{kind:`undo`,windowMs:f}}function O(e={production:!0}){return e.production?{kind:`typed`,phrase:`DELETE`,requireReason:!0}:{kind:`undo`,windowMs:f}}function k(e={production:!0}){return e.production?{kind:`typed`,phrase:`PURGE`,requireReason:!0}:{kind:`undo`,windowMs:f}}function A(e){let t=[];for(let n of e.signals)t.push(`Signal \`${n}\` will not be emitted`);for(let n of e.channels)t.push(`Channel \`${n}\` will not fire`);return e.writerFlowIds.length>0&&t.push(`Owning flow(s): ${e.writerFlowIds.map(e=>`\`${e}\``).join(`, `)} — not executed`),{headline:`Direct edit is not a flow execution — the following will NOT happen:`,lines:t,empty:t.length===0}}function j(e){return e.facet===`index`?{ok:!1,reason:`Index facet has no bulk-update preview — similarity probe is read-only.`}:{ok:!0}}function ee(e){let t=e.cache,n=t.invalidatedByWrites,r=t.invalidatingFlowIds,i=n.length===0?`Read key \`${t.producedByRead}\` — no write invalidators declared.`:`Read key \`${t.producedByRead}\` — invalidated by writes to ${n.map(e=>`\`${e}\``).join(`, `)}.`;return{producedByRead:t.producedByRead,invalidatedBy:n,invalidatingFlows:r,summary:i}}var M=e(u(),1),N=p();function P(){let e=h({from:`/store`}),t=n({from:`/store`}),o=c(),[l,u]=(0,M.useState)(``),[d,f]=(0,M.useState)(``),[p,g]=(0,M.useState)(`{}`),[_,y]=(0,M.useState)(`SELECT * FROM "bookings" LIMIT 50`),[b,C]=(0,M.useState)(`0.1,0.2,0.3`),[w,T]=(0,M.useState)(null),P=e=>{t({search:x(e),replace:!0})},I=r({queryKey:[`console.store.list`],queryFn:async()=>{let e=await s.storeList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:1e4}),L=I.data?.tenancyDeclared??!1,te=I.data?.tenants??[],R=I.data?.stores??[],ne=(0,M.useMemo)(()=>E(R,e.q??``),[R,e.q]),z=R.find(t=>t.ref===e.ref),B=z?.children.find(t=>t.name===e.child)??z?.children[0],V=e.view??`browse`,H=D({production:!0}),U=O({production:!0}),W=k({production:!0}),G=z?j(z):null,re=B?A(B.willNotFire):null,ie=B?ee(B):null,K=r({queryKey:[`console.store.query`,e.ref,B?.name,e.tenant,e.prefix,V,b],enabled:!!z&&!!B&&V===`browse`&&(!L||!!e.tenant),queryFn:async()=>{if(!z||!B)return null;let t=z.facet===`index`?b.split(`,`).map(e=>Number(e.trim())).filter(e=>!Number.isNaN(e)):void 0,n=await s.storeQuery({ref:z.ref,child:B.name,tenant:e.tenant,prefix:e.prefix,vector:t,topK:5});if(n.error)throw Error(n.error.code);return n.data}});(0,M.useEffect)(()=>{u(``),f(``),T(null)},[z?.ref,B?.name]);let q=()=>{o.invalidateQueries({queryKey:[`console.store.list`]}),o.invalidateQueries({queryKey:[`console.store.query`]})},J=i({mutationFn:async()=>{if(!z||!B)return;if(G&&!G.ok)throw Error(G.reason);let t={};try{t=JSON.parse(p)}catch{throw Error(`Patch must be valid JSON`)}let n=await s.storePreview({ref:z.ref,child:B.name,tenant:e.tenant,id:String(t.id??`preview`),key:typeof t.key==`string`?t.key:void 0,patch:t});if(n.error)throw Error(n.error.code);let r=n.data;return T(A(r.willNotFire).lines),r}}),Y=i({mutationFn:async()=>{if(!z||!B)return;if(H.kind===`typed`){let e=a({typed:l,reason:d,phrase:H.phrase});if(e)throw Error(e.typed??e.reason)}let t={};try{t=JSON.parse(p)}catch{throw Error(`Patch must be valid JSON`)}let n=await s.storeEdit({ref:z.ref,child:B.name,tenant:e.tenant,id:String(t.id??``),key:typeof t.key==`string`?t.key:void 0,patch:t,confirmation:l,reason:d,commit:!0});if(n.error)throw Error(n.error.code);return n.data},onSuccess:q}),X=i({mutationFn:async t=>{if(!z||!B)return;if(U.kind===`typed`){let e=a({typed:l,reason:d,phrase:U.phrase});if(e)throw Error(e.typed??e.reason)}let n=await s.storeDelete({ref:z.ref,child:B.name,tenant:e.tenant,ids:z.facet===`sql`||z.facet===`index`?t:void 0,keys:z.facet===`kv`||z.facet===`files`?t:void 0,confirmation:l,reason:d});if(n.error)throw Error(n.error.code);return n.data},onSuccess:q}),Z=i({mutationFn:async()=>{if(!B)return;if(W.kind===`typed`){let e=a({typed:l,reason:d,phrase:W.phrase});if(e)throw Error(e.typed??e.reason)}let e=await s.storePurgeCache({resource:B.effectRef,confirmation:l,reason:d});if(e.error)throw Error(e.error.code);return e.data},onSuccess:q}),Q=i({mutationFn:async()=>{if(!z||z.facet!==`sql`)return;let t=await s.storeSql({ref:z.ref,sql:_,tenant:e.tenant,allowWrite:!1});if(t.error)throw Error(t.error.code);return t.data}}),$=i({mutationFn:async t=>{if(!z||!B)return;let n=await s.storeReveal({ref:z.ref,child:B.name,tenant:e.tenant,id:t.id,column:t.column});if(n.error)throw Error(n.error.code);return n.data}});return(0,N.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,N.jsxs)(`header`,{className:`flex shrink-0 flex-wrap items-end gap-3 border-b border-[var(--oke-line)] px-4 py-3`,children:[(0,N.jsxs)(`div`,{className:`mr-auto`,children:[(0,N.jsx)(`h1`,{className:`text-lg font-medium`,children:`Store`}),(0,N.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`One list, grouped by facet — direct edits are not flow executions`})]}),L?(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,N.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Tenant`}),(0,N.jsxs)(`select`,{"aria-label":`Tenant`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2`,value:e.tenant??``,onChange:t=>P({...e,tenant:t.target.value||void 0}),children:[(0,N.jsx)(`option`,{value:``,children:`Select tenant…`}),te.map(e=>(0,N.jsx)(`option`,{value:e,children:e},e))]})]}):null,(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,N.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Filter`}),(0,N.jsx)(`input`,{"aria-label":`Filter stores`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2`,value:e.q??``,onChange:t=>P({...e,q:t.target.value||void 0})})]})]}),(0,N.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,N.jsxs)(`section`,{"aria-label":`Store list`,className:`w-72 shrink-0 overflow-y-auto border-r border-[var(--oke-line)]`,children:[I.isLoading?(0,N.jsx)(`p`,{className:`p-3 text-sm text-[var(--oke-muted)]`,children:`Loading…`}):null,ne.map(t=>(0,N.jsxs)(`div`,{className:`border-b border-[var(--oke-line)]`,children:[(0,N.jsx)(`h2`,{className:`px-3 py-2 text-xs tracking-wide text-[var(--oke-muted)]`,children:t.label}),(0,N.jsx)(`ul`,{children:t.stores.map(t=>(0,N.jsx)(`li`,{children:(0,N.jsxs)(`button`,{type:`button`,"aria-pressed":t.ref===e.ref,className:m(`flex min-h-8 w-full flex-col items-start px-3 py-2 text-left text-sm`,t.ref===e.ref?`bg-[var(--oke-line)]/40`:`hover:bg-[var(--oke-line)]/20`),onClick:()=>P(S(e,t.ref)),children:[(0,N.jsx)(`span`,{children:v(t.name,t.description)}),t.description?(0,N.jsx)(`span`,{className:`font-mono text-xs text-[var(--oke-muted)]`,children:t.name}):null,(0,N.jsxs)(`span`,{className:`text-xs text-[var(--oke-muted)]`,children:[t.children.length,` resource(s)`,t.replicaLagMs==null?``:` · lag ${t.replicaLagMs}ms`,t.migrationDrift?.drifted?` · drift`:``,t.warnings.length>0?` · ${t.warnings.length} warn`:``]})]})},t.ref))})]},t.facet))]}),(0,N.jsx)(`section`,{"aria-label":`Store detail`,className:`min-w-0 flex-1 overflow-y-auto p-4`,"aria-live":`polite`,children:z?L&&!e.tenant?(0,N.jsx)(`p`,{role:`status`,className:`text-sm`,children:`Select a tenant in the header before browsing — compliance boundary, not a display filter.`}):(0,N.jsx)(F,{open:z,childName:B?.name,view:V,search:e,setSearch:P,browse:K.data,browseLoading:K.isLoading,cache:ie,willNot:re,willNotPreview:w,patchJson:p,setPatchJson:g,typed:l,setTyped:u,reason:d,setReason:f,sqlText:_,setSqlText:y,probeVector:b,setProbeVector:C,onPreview:()=>J.mutate(),onCommit:()=>Y.mutate(),onDelete:e=>X.mutate(e),onPurge:()=>Z.mutate(),onSql:()=>Q.mutate(),sqlResult:Q.data,onReveal:(e,t)=>$.mutate({id:e,column:t}),revealValue:$.data?.value,error:J.error?.message??Y.error?.message??X.error?.message??Z.error?.message??Q.error?.message??$.error?.message}):(0,N.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Select a store. Tenant selector appears only when tenancy is declared on the Manifest.`})})]})]})}function F(e){let{open:t,childName:n,view:r,search:i,setSearch:a,browse:o,browseLoading:s,cache:c,willNot:l,willNotPreview:u,patchJson:f,setPatchJson:p,typed:h,setTyped:g,reason:y,setReason:b,sqlText:x,setSqlText:S,probeVector:w,setProbeVector:T,onPreview:E,onCommit:D,onDelete:O,onPurge:k,onSql:A,sqlResult:j,onReveal:ee,revealValue:M,error:P}=e,F=t.children.find(e=>e.name===n);return(0,N.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-2`,children:[(0,N.jsx)(`h2`,{className:`text-base font-medium`,children:v(t.name,t.description)}),(0,N.jsxs)(`span`,{className:`text-sm text-[var(--oke-muted)]`,children:[t.description?`${t.name} · `:``,t.ref]}),t.contentAddressed?(0,N.jsx)(`span`,{role:`status`,className:`text-xs text-[var(--oke-muted)]`,children:`content-addressed keys`}):null]}),(0,N.jsx)(`div`,{className:`flex flex-wrap gap-2`,role:`tablist`,"aria-label":`Views`,children:[[`browse`,`Browse`],[`cache`,`Cache`],...t.facet===`sql`?[[`sql`,`SQL`]]:[],...t.facet===`index`?[[`probe`,`Probe`]]:[]].map(([e,t])=>(0,N.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":r===e,className:m(`min-h-8 px-2 text-sm`,r===e?`text-[var(--oke-fg)] underline`:`text-[var(--oke-muted)]`),onClick:()=>a({...i,view:e}),children:t},e))}),(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,N.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Resource`}),(0,N.jsx)(`select`,{"aria-label":`Store resource`,className:`min-h-8 max-w-xs border border-[var(--oke-line)] bg-transparent px-2`,value:n??``,onChange:e=>a(C(i,e.target.value)),children:t.children.map(e=>(0,N.jsx)(`option`,{value:e.name,children:e.name},e.name))})]}),F?(0,N.jsxs)(`p`,{className:`text-sm`,role:`status`,children:[`Writers:`,` `,F.writers.map(e=>(0,N.jsx)(_,{to:`/flows`,search:{flow:e},className:`mr-2 underline`,children:e},e)),F.writers.length===0?`none`:null,` · `,`Readers: `,F.readers.join(`, `)||`none`,F.piiColumns.length>0?` · PII columns: ${F.piiColumns.join(`, `)}`:``]}):null,t.migrationDrift?(0,N.jsxs)(`p`,{className:`text-sm`,role:`status`,children:[`Migration: declared `,t.migrationDrift.declared.slice(0,12),`…`,t.migrationDrift.applied?` / applied ${t.migrationDrift.applied.slice(0,12)}…`:` / applied (none)`,t.migrationDrift.drifted?` — drifted`:` — in sync`]}):null,t.warnings.length>0?(0,N.jsx)(`ul`,{"aria-label":`Operational warnings`,className:`text-sm`,children:t.warnings.map(e=>(0,N.jsxs)(`li`,{role:`status`,children:[e.key,`: `,e.message]},`${e.key}:${e.code}`))}):null,r===`cache`&&c?(0,N.jsxs)(`section`,{"aria-label":`Cache`,children:[(0,N.jsx)(`h3`,{className:`text-sm font-medium`,children:`Cache`}),(0,N.jsx)(`p`,{className:`text-sm`,role:`status`,children:c.summary}),(0,N.jsxs)(`p`,{className:`text-xs text-[var(--oke-muted)]`,children:[`Invalidating flows: `,c.invalidatingFlows.join(`, `)||`none`]}),(0,N.jsx)(d,{type:`button`,onClick:k,children:`Purge cache namespace`})]}):null,r===`sql`&&t.facet===`sql`?(0,N.jsxs)(`section`,{"aria-label":`SQL console`,className:`flex flex-col gap-2`,children:[(0,N.jsx)(`h3`,{className:`text-sm font-medium`,children:`SQL console (read-only)`}),(0,N.jsx)(`textarea`,{"aria-label":`SQL console`,className:`min-h-24 border border-[var(--oke-line)] bg-transparent p-2 font-mono text-sm`,value:x,onChange:e=>S(e.target.value)}),(0,N.jsx)(d,{type:`button`,onClick:A,children:`Run`}),j?(0,N.jsxs)(`p`,{className:`text-xs text-[var(--oke-muted)]`,children:[j.rows.length,` row(s) · routed `,j.routedRole,j.masked?` · PII masked`:``]}):null]}):null,(r===`browse`||r===`probe`)&&(0,N.jsxs)(`section`,{"aria-label":`Browse`,children:[t.facet===`index`?(0,N.jsxs)(`label`,{className:`mb-2 flex flex-col gap-1 text-sm`,children:[(0,N.jsx)(`span`,{children:`Probe vector`}),(0,N.jsx)(`input`,{"aria-label":`Probe vector`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2 font-mono`,value:w,onChange:e=>T(e.target.value)})]}):null,s?(0,N.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Loading…`}):null,o?.rows?(0,N.jsxs)(`table`,{className:`w-full text-left text-sm`,children:[(0,N.jsx)(`thead`,{children:(0,N.jsxs)(`tr`,{children:[Object.keys(o.rows[0]??{id:1}).map(e=>(0,N.jsx)(`th`,{scope:`col`,className:`border-b px-2 py-1`,children:v(e,F?.columnDescriptions[e])},e)),(0,N.jsx)(`th`,{scope:`col`,className:`border-b px-2 py-1`,children:`Actions`})]})}),(0,N.jsx)(`tbody`,{children:o.rows.map((e,t)=>(0,N.jsxs)(`tr`,{children:[Object.entries(e).map(([t,n])=>(0,N.jsxs)(`td`,{className:`border-b px-2 py-1 font-mono`,children:[String(n),F?.piiColumns.includes(t)?(0,N.jsx)(`button`,{type:`button`,className:`ml-2 underline`,style:{minHeight:32},onClick:()=>ee(String(e.id??``),t),children:`Reveal`}):null]},t)),(0,N.jsx)(`td`,{className:`border-b px-2 py-1`,children:(0,N.jsx)(d,{type:`button`,onClick:()=>O([String(e.id??``)]),children:`Delete`})})]},t))})]}):null,o?.keys?(0,N.jsx)(`ul`,{"aria-label":`Keys`,className:`text-sm`,children:o.keys.map(e=>(0,N.jsxs)(`li`,{className:`flex min-h-8 items-center gap-2`,children:[(0,N.jsx)(`span`,{className:`font-mono`,children:e.key}),e.value===void 0?null:(0,N.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:JSON.stringify(e.value)}),e.warnings?.map(e=>(0,N.jsx)(`span`,{role:`status`,className:`text-xs`,children:e.message},e.code)),(0,N.jsx)(d,{type:`button`,onClick:()=>O([e.key]),children:`Delete`})]},e.key))}):null,o?.hits?(0,N.jsx)(`ul`,{"aria-label":`Similarity hits`,className:`text-sm`,children:o.hits.map(e=>(0,N.jsxs)(`li`,{children:[e.id,` · score `,e.score.toFixed(3)]},e.id))}):null,M===void 0?null:(0,N.jsxs)(`p`,{role:`status`,className:`text-sm`,children:[`Revealed: `,String(M)]})]}),(0,N.jsxs)(`section`,{"aria-label":`Direct edit`,className:`flex flex-col gap-2 border-t border-[var(--oke-line)] pt-4`,children:[(0,N.jsx)(`h3`,{className:`text-sm font-medium`,children:`Direct edit`}),(0,N.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Not a flow execution. Before saving, preview names what will not fire.`}),l&&!l.empty?(0,N.jsx)(`ul`,{className:`text-sm`,children:(u??l.lines).map(e=>(0,N.jsx)(`li`,{children:e},e))}):(0,N.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`No owning-flow emissions declared for this resource.`}),(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[`Patch (JSON)`,(0,N.jsx)(`textarea`,{"aria-label":`Edit patch JSON`,className:`min-h-20 border border-[var(--oke-line)] bg-transparent p-2 font-mono text-sm`,value:f,onChange:e=>p(e.target.value)})]}),(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[`Type EDIT / DELETE / PURGE`,(0,N.jsx)(`input`,{"aria-label":`Confirmation phrase`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2`,value:h,onChange:e=>g(e.target.value)})]}),(0,N.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[`Reason`,(0,N.jsx)(`input`,{"aria-label":`Confirmation reason`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2`,value:y,onChange:e=>b(e.target.value)})]}),(0,N.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,N.jsx)(d,{type:`button`,onClick:E,children:`Preview`}),(0,N.jsx)(d,{type:`button`,onClick:D,children:`Save edit`})]}),P?(0,N.jsx)(`p`,{role:`alert`,className:`text-sm text-red-600`,children:P}):null]})]})}var I=t({default:()=>P});export{b as n,I as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,r as t}from"./rolldown-runtime-B0Z9INg1.js";import{C as n,Q as r,Z as i,b as a,d as o,et as s,l as c,nt as l,o as u,tt as d,u as f,w as p,y as m}from"./panel-access-BGv45snf.js";import{r as h}from"./panel-runs-CWuRDe0r.js";import{n as g,t as _}from"./panel-flows-PiHwT55z.js";var v=e(l(),1);function y(e,t){if(!t)return!0;switch(t.kind){case`wrote`:return e.effects.some(e=>e.kind===`write`&&e.resource===t.resource);case`asked`:return e.effects.some(e=>e.kind===`ask`);case`sent`:return e.effects.some(e=>e.kind===`send`&&(t.resource===void 0||e.resource===t.resource));case`secret`:return e.effects.some(e=>e.kind===`secret`&&(t.resource===void 0||e.resource===t.resource));case`cost`:return(e.cost??0)>t.min}}function b(e,t){return!t||e.some(e=>y(e,t))}function x(e){if(!e?.trim())return null;let t=e.trim();if(t===`asked`)return{kind:`asked`};if(t===`sent`)return{kind:`sent`};if(t.startsWith(`wrote:`))return{kind:`wrote`,resource:t.slice(6)};if(t.startsWith(`sent:`))return{kind:`sent`,resource:t.slice(5)};if(t.startsWith(`secret:`))return{kind:`secret`,resource:t.slice(7)};if(t===`secret`)return{kind:`secret`};if(t.startsWith(`cost:`)){let e=Number(t.slice(5));return Number.isFinite(e)?{kind:`cost`,min:e}:null}return null}function S(e){if(e)switch(e.kind){case`wrote`:return`wrote:${e.resource}`;case`asked`:return`asked`;case`sent`:return e.resource?`sent:${e.resource}`:`sent`;case`secret`:return e.resource?`secret:${e.resource}`:`secret`;case`cost`:return`cost:${e.min}`}}var C=m({trace:a().optional(),span:a().optional(),effect:a().optional(),q:a().optional(),folds:a().optional(),boost:a().optional()});function w(e){let t=C.safeParse(e??{});return t.success?t.data:C.parse({})}function T(e){let t={};return e.trace&&(t.trace=e.trace),e.span&&(t.span=e.span),e.effect&&(t.effect=e.effect),e.q&&(t.q=e.q),e.folds&&(t.folds=e.folds),e.boost&&(t.boost=e.boost),t}function E(e){return e.folds?new Set(e.folds.split(`,`).map(e=>e.trim()).filter(Boolean)):new Set}function D(e,t,n){return{...e,trace:t,span:n}}function ee(e){return{...e,trace:void 0,span:void 0,folds:void 0}}function te(e,t){let n=E(e);n.has(t)?n.delete(t):n.add(t);let r=[...n].join(`,`);return{...e,folds:r||void 0}}function O(e,t){return{...e,effect:S(t)}}function k(e){let t=new Map,n=new Map;for(let n of e)t.set(n.id,n);for(let t of e){if(!t.parentId)continue;let e=n.get(t.parentId)??[];e.push(t),n.set(t.parentId,e)}for(let[,e]of n)e.sort((e,t)=>e.startedAt-t.startedAt);return{byId:t,childrenOf:n}}function A(e,t){let{byId:n,childrenOf:r}=k(e),i=n.get(t);if(!i)return null;let a=[],o=i,s=new Set;for(;o?.parentId&&!s.has(o.parentId);){s.add(o.parentId);let e=n.get(o.parentId);if(!e)break;a.unshift(e),o=e}return{parents:a,current:i,children:r.get(i.id)??[],connected:N((a[0]??i).id,n,r)}}function j(e){let{byId:t,childrenOf:n}=k(e),r=e.filter(e=>!e.parentId||!t.has(e.parentId));return r.sort((e,t)=>t.startedAt-e.startedAt),r.map(e=>({rootId:e.id,root:e,spans:N(e.id,t,n)}))}function M(e,t){if(t&&e.some(e=>e.id===t))return t;let n=e.find(e=>e.errorCode!=null&&e.errorCode!==``);return n?n.id:e.find(t=>!t.parentId||!e.some(e=>e.id===t.parentId))?.id??e[0]?.id}function N(e,t,n){let r=[],i=e=>{let a=t.get(e);if(a){r.push(a);for(let t of n.get(e)??[])i(t.id)}};return i(e),r.sort((e,t)=>e.startedAt-t.startedAt),r}function P(e){if(e.length===0)return new Set;let{byId:t,childrenOf:n}=k(e),r=e.filter(e=>!e.parentId||!t.has(e.parentId)),i=[],a=-1,o=(e,r,s)=>{let c=n.get(e)??[],l=t.get(e);if(!l)return;let u=s+F(l),d=[...r,e];if(c.length===0){u>a&&(a=u,i=d);return}for(let e of c)o(e.id,d,u)};for(let e of r)o(e.id,[],0);return new Set(i)}function F(e){return e.effects.length===0?Math.max(0,e.durationMs):e.effects.reduce((e,t)=>e+Math.max(0,t.duration),0)}function I(e){switch(e){case`read`:return`reads`;case`write`:return`writes`;case`emit`:return`emits`;case`send`:case`ask`:return`external`;case`secret`:return`capabilities`;case`call`:return`reads`}}function L(e){let t=`none`;for(let n of e){let e=I(n.kind);z(e)>z(t)&&(t=e)}return t}function R(e){return e.some(e=>L(e.effects)===`external`)}function z(e){switch(e){case`external`:return 5;case`capabilities`:return 4;case`emits`:return 3;case`writes`:return 2;case`reads`:return 1;case`none`:return 0}}function B(e){let t=Math.max(0,Math.round(e));if(t<1e3)return`${t}ms idle`;let n=t/1e3;if(n<60)return`${U(n)}s idle`;let r=n/60;if(r<60)return`${U(r)}m idle`;let i=r/60;return i<48?`${U(i)}h idle`:`${U(i/24)}d idle`}function V(e,t={},n=new Set){let r=t.foldThresholdMs??50,i=t.expandedFolds??new Set,a=[...e].sort((e,t)=>e.startMs-t.startMs);if(a.length===0)return{segments:[],displayDurationMs:0,wallDurationMs:0};let o=a[0],s=a[a.length-1];if(!o||!s)return{segments:[],displayDurationMs:0,wallDurationMs:0};let c=o.startMs,l=Math.max(...a.map(e=>e.endMs)),u=[],d=c;for(let e of a){let t=e.startMs-d;if(t>=r){let n=`fold:${d}:${e.startMs}`,r=i.has(n),a=t;u.push({kind:`fold`,id:n,startMs:d,endMs:e.startMs,durationMs:a,label:B(a),expanded:r,displayMs:r?a:40})}let a=Math.max(0,e.endMs-e.startMs);u.push({kind:`work`,id:e.id,label:e.label,startMs:e.startMs,endMs:e.endMs,durationMs:a,tier:e.tier,spanId:e.spanId,critical:n.has(e.spanId),failed:e.failed===!0,displayMs:Math.max(1,a)}),d=Math.max(d,e.endMs)}let f=u.reduce((e,t)=>e+t.displayMs,0);return{segments:u,displayDurationMs:Math.max(1,f),wallDurationMs:l-c}}function H(e){let t=[];for(let n of e)if(n.effects.length>0)for(let e of n.effects)t.push({id:`${n.id}:${e.kind}:${e.resource}:${e.timestamp}`,label:`${e.kind} ${e.resource}`,startMs:e.timestamp,endMs:e.timestamp+Math.max(1,e.duration),tier:I(e.kind),spanId:n.id,failed:n.errorCode!=null&&e===n.effects[n.effects.length-1]});else t.push({id:n.id,label:n.flow,startMs:n.startedAt,endMs:n.endedAt,tier:`none`,spanId:n.id,failed:n.errorCode!=null});return t}function U(e){let t=Math.round(e*10)/10;return Number.isInteger(t)?String(t):t.toFixed(1)}function W(e){if(e.length===0)return[];let t=Math.min(...e.map(e=>e.startedAt)),n=Math.max(...e.map(e=>e.endedAt)),r=Math.max(1,n-t);if(e.every(e=>e.effects.length===0))return e.map(e=>({start:(e.startedAt-t)/r,width:Math.max(.02,e.durationMs/r),tier:L(e.effects),failed:e.errorCode!=null}));let i=[];for(let n of e){if(n.effects.length===0){i.push({start:(n.startedAt-t)/r,width:Math.max(.02,n.durationMs/r),tier:`none`,failed:n.errorCode!=null});continue}for(let e=0;e<n.effects.length;e++){let a=n.effects[e];a&&i.push({start:(a.timestamp-t)/r,width:Math.max(.02,a.duration/r),tier:I(a.kind),failed:n.errorCode!=null&&e===n.effects.length-1})}}return i}function G(e){for(let t of e)if(t.errorCode)return t.errorCode;return null}function K(e){return R(e)?{mode:`dry-run`,reason:`This trace contains an external effect. Replay runs as a dry run with external effects stubbed.`}:{mode:`replay`}}var q=`10% + all errors`,J=6e5;function Y(e,t=Date.now()){let n=e.filter(e=>e.until>t);return n.length===0?q:`${q} · full: ${n.map(e=>e.flow).join(`, `)}`}function X(e,t,n=Date.now()){let r=n+J;return[...e.filter(e=>e.flow!==t&&e.until>n),{flow:t,until:r}]}function ne(e,t=Date.now()){return e.filter(e=>e.until>t)}var Z=d();function Q(){let e=p({from:`/traces`}),t=n({from:`/traces`}),a=s(),[l,d]=(0,v.useState)([]),[m]=(0,v.useState)(()=>_()),[y,S]=(0,v.useState)(0),[,C]=(0,v.useState)(0),w=e=>{t({search:T(e),replace:!0})},k=r({queryKey:[`console.runs.list`],queryFn:async()=>{let e=await o.runsList();if(e.error)throw Error(e.error.code);return e.data.runs},refetchInterval:5e3}),N=(0,v.useMemo)(()=>(k.data??[]).map(re),[k.data]);(0,v.useEffect)(()=>{if(N.length===0)return;if(m.visible.length===0){for(let e of N)m.offer({id:e.id,value:e,arrivedAt:e.startedAt});m.flush(),S(0),C(e=>e+1);return}let e=new Set(m.visible.map(e=>e.id));for(let t of m.pending)e.add(t.id);for(let t of N)e.has(t.id)?m.updateInPlace(t.id,t):m.offer({id:t.id,value:t,arrivedAt:Date.now()});S(m.pendingCount),C(e=>e+1)},[N,m]);let F=m.visible.map(e=>e.value),I=x(e.effect),R=(0,v.useMemo)(()=>j(F).filter(t=>{let n=g([t.root.flow,t.root.id,G(t.spans)??``],e.q),r=b(t.spans,I);return n&&r}),[F,e.q,I]),z=R.find(t=>t.rootId===e.trace)??(e.trace?j(F).find(t=>t.rootId===e.trace):void 0),B=z?M(z.spans,e.span):void 0,U=B?A(F,B):null,q=U?P(U.connected):new Set,J=U?V(H(U.connected),{expandedFolds:E(e)},q):null,Q=U?K(U.connected):null,$=i({mutationFn:async()=>{if(!U||!Q)return;let e=await o.tracesReplay({rootId:U.connected[0]?.id??U.current.id,dryRun:Q.mode===`dry-run`});if(e.error)throw Error(e.error.code);return e.data},onSuccess:()=>{a.invalidateQueries({queryKey:[`console.runs.list`]})}}),ae=ne(l);return(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,Z.jsxs)(`header`,{className:`flex shrink-0 flex-wrap items-end gap-4 border-b border-[var(--oke-line)] px-6 py-4`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,Z.jsx)(`p`,{className:`text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]`,children:`Traces`}),(0,Z.jsx)(`h1`,{className:`text-xl font-semibold tracking-tight`,children:`Causal chain`}),(0,Z.jsxs)(`p`,{className:`text-xs text-[var(--oke-muted)]`,children:[`Sampling: `,Y(ae)]})]}),(0,Z.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,Z.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Filter by effect`}),(0,Z.jsxs)(`select`,{"aria-label":`Filter by effect`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2 text-sm`,value:e.effect??``,onChange:t=>{let n=t.target.value;w(O(e,n?x(n):null))},children:[(0,Z.jsx)(`option`,{value:``,children:`All effects`}),(0,Z.jsx)(`option`,{value:`wrote:sql:bookings`,children:`Wrote sql:bookings`}),(0,Z.jsx)(`option`,{value:`sent`,children:`Sent (channel)`}),(0,Z.jsx)(`option`,{value:`asked`,children:`Asked a model`}),(0,Z.jsx)(`option`,{value:`secret`,children:`Read a secret`}),(0,Z.jsx)(`option`,{value:`cost:0.05`,children:`Cost > $0.05`})]})]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Z.jsx)(u,{type:`button`,variant:`ghost`,onClick:()=>{let e=z?.root.flow??R[0]?.root.flow??`bookings.create`;d(t=>X(t,e))},children:`Trace flow fully for 10 minutes`}),(0,Z.jsx)(c,{count:y,onFlush:()=>{m.flush(),S(0),C(e=>e+1)}})]})]}),(0,Z.jsxs)(`div`,{className:`grid min-h-0 flex-1 grid-cols-1 md:grid-cols-[minmax(0,1fr)_minmax(0,1.4fr)]`,children:[(0,Z.jsx)(`section`,{"aria-label":`Trace list`,className:`min-h-0 overflow-auto border-r border-[var(--oke-line)]`,children:k.isLoading?(0,Z.jsx)(`p`,{className:`px-6 py-8 text-sm text-[var(--oke-muted)]`,children:`Loading traces…`}):R.length===0?(0,Z.jsx)(`p`,{className:`px-6 py-8 text-sm text-[var(--oke-muted)]`,children:`No traces yet. Invoke a flow or wait for traffic.`}):(0,Z.jsx)(`ul`,{className:`divide-y divide-[var(--oke-line)]`,children:R.map(t=>{let n=G(t.spans),r=W(t.spans),i=t.rootId===e.trace;return(0,Z.jsx)(`li`,{children:(0,Z.jsxs)(`button`,{type:`button`,"aria-pressed":i,className:f(`flex w-full min-h-10 flex-col gap-1 px-4 py-3 text-left text-sm`,i?`bg-[color-mix(in_oklab,var(--oke-fg)_6%,transparent)]`:`hover:bg-[color-mix(in_oklab,var(--oke-fg)_3%,transparent)]`),onClick:()=>{let n=M(t.spans);w(D(e,t.rootId,n))},children:[(0,Z.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,Z.jsx)(`span`,{className:`font-medium`,children:t.root.flow}),n?(0,Z.jsx)(`span`,{role:`status`,className:`font-mono text-xs text-[var(--oke-danger)]`,children:n}):(0,Z.jsxs)(`span`,{className:`font-mono text-xs text-[var(--oke-muted)]`,children:[t.root.durationMs,`ms`]})]}),(0,Z.jsx)(ie,{bars:r})]})},t.rootId)})})}),(0,Z.jsx)(`section`,{"aria-label":`Trace detail`,className:`min-h-0 overflow-auto px-6 py-6`,"aria-live":`polite`,children:!U||!J?(0,Z.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Select a trace to see the causal chain and folded-time waterfall.`}):(0,Z.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`h2`,{className:`text-lg font-semibold`,children:U.current.flow}),(0,Z.jsxs)(`p`,{className:`text-xs text-[var(--oke-muted)]`,children:[U.connected.length,` span`,U.connected.length===1?``:`s`,` · wall `,J.wallDurationMs,`ms · display scale `,Math.round(J.displayDurationMs),`ms`]})]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,Z.jsx)(h,{to:`/runs`,search:{run:U.current.id},className:`inline-flex min-h-8 items-center border border-[var(--oke-line)] px-3 text-sm`,children:`Open in Runs`}),(0,Z.jsx)(u,{type:`button`,variant:Q?.mode===`dry-run`?`external`:`primary`,disabled:$.isPending,title:Q?.mode===`dry-run`?Q.reason:`Replay from the journal`,onClick:()=>$.mutate(),children:Q?.mode===`dry-run`?`Dry-run replay`:`Replay`}),(0,Z.jsx)(u,{type:`button`,variant:`ghost`,onClick:()=>w(ee(e)),children:`Close`})]})]}),Q?.mode===`dry-run`?(0,Z.jsx)(`p`,{role:`note`,className:`text-sm text-[var(--oke-external)]`,children:Q.reason}):null,(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Causal chain`}),(0,Z.jsxs)(`ol`,{className:`flex flex-col gap-1 border-l border-[var(--oke-line)] pl-4`,children:[U.parents.map(t=>(0,Z.jsx)(`li`,{children:(0,Z.jsx)(`button`,{type:`button`,className:`min-h-8 text-sm text-[var(--oke-muted)]`,onClick:()=>w({...e,span:t.id}),children:t.flow})},t.id)),(0,Z.jsxs)(`li`,{"aria-current":`true`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium`,children:U.current.flow}),U.current.errorCode?(0,Z.jsx)(`span`,{role:`status`,className:`ml-2 font-mono text-xs text-[var(--oke-danger)]`,children:U.current.errorCode}):null,L(U.current.effects)===`external`?(0,Z.jsx)(`span`,{"aria-label":`external effect`,children:` ↗`}):null]}),U.children.map(t=>(0,Z.jsx)(`li`,{children:(0,Z.jsxs)(`button`,{type:`button`,className:`min-h-8 text-sm text-[var(--oke-muted)]`,onClick:()=>w({...e,span:t.id}),children:[t.flow,L(t.effects)===`external`?(0,Z.jsx)(`span`,{"aria-label":`external effect`,children:` ↗`}):null]})},t.id))]})]}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`h3`,{id:`waterfall-heading`,className:`mb-2 text-sm font-medium`,children:`Waterfall`}),(0,Z.jsx)(`ul`,{"aria-labelledby":`waterfall-heading`,className:`flex min-h-10 list-none items-stretch gap-0.5 p-0`,children:J.segments.map(t=>t.kind===`fold`?(0,Z.jsx)(`li`,{style:{flex:`${t.displayMs} 1 0`,minWidth:24},children:(0,Z.jsx)(`button`,{type:`button`,"aria-expanded":t.expanded,className:`h-full min-h-10 w-full border border-dashed border-[var(--oke-line)] px-1 font-mono text-[10px] text-[var(--oke-muted)]`,onClick:()=>w(te(e,t.id)),children:t.label})},t.id):(0,Z.jsx)(`li`,{title:t.label,className:f(`min-h-10 px-1 text-[10px] leading-10`,t.tier===`external`?`bg-[var(--oke-external)] text-black`:`bg-[color-mix(in_oklab,var(--oke-accent)_55%,transparent)]`,t.failed&&`outline outline-2 outline-[var(--oke-danger)]`),style:{flex:`${t.displayMs} 1 0`,opacity:t.critical?1:.38,minWidth:4},children:(0,Z.jsxs)(`span`,{className:`sr-only`,children:[t.label,t.critical?` (critical path)`:``,t.failed?` (failed)`:``]})},t.id))}),(0,Z.jsx)(`p`,{className:`mt-2 text-xs text-[var(--oke-muted)]`,children:`Critical path at full opacity · dead time folded into expandable bars`})]})]})})]})]})}function re(e){return{id:e.id,...e.parentId?{parentId:e.parentId}:{},flow:e.flow,...e.unit?{unit:e.unit}:{},trigger:e.trigger,startedAt:e.startedAt,endedAt:e.endedAt,durationMs:e.durationMs,errorCode:e.error,cost:e.cost??void 0,sampled:e.sampled??(e.error?`error`:`sample`),effects:e.effects??[]}}function ie({bars:e}){return(0,Z.jsx)(`div`,{"aria-hidden":`true`,className:`relative h-2 w-full overflow-hidden bg-[color-mix(in_oklab,var(--oke-fg)_6%,transparent)]`,children:e.map((e,t)=>(0,Z.jsx)(`span`,{className:f(`absolute inset-y-0`,e.tier===`external`?`bg-[var(--oke-external)]`:e.failed?`bg-[var(--oke-danger)]`:`bg-[var(--oke-accent)]`),style:{left:`${e.start*100}%`,width:`${Math.max(2,e.width*100)}%`}},t))})}var $=t({default:()=>Q});export{w as n,$ as t};
|
|
1
|
+
import{a as e,r as t}from"./rolldown-runtime-B0Z9INg1.js";import{C as n,Q as r,Z as i,b as a,d as o,et as s,l as c,nt as l,o as u,tt as d,u as f,w as p,y as m}from"./panel-access-ri1X9Otj.js";import{r as h}from"./panel-runs-D5zf-D9c.js";import{n as g,t as _}from"./panel-flows-B8TRhcoe.js";var v=e(l(),1);function y(e,t){if(!t)return!0;switch(t.kind){case`wrote`:return e.effects.some(e=>e.kind===`write`&&e.resource===t.resource);case`asked`:return e.effects.some(e=>e.kind===`ask`);case`sent`:return e.effects.some(e=>e.kind===`send`&&(t.resource===void 0||e.resource===t.resource));case`secret`:return e.effects.some(e=>e.kind===`secret`&&(t.resource===void 0||e.resource===t.resource));case`cost`:return(e.cost??0)>t.min}}function b(e,t){return!t||e.some(e=>y(e,t))}function x(e){if(!e?.trim())return null;let t=e.trim();if(t===`asked`)return{kind:`asked`};if(t===`sent`)return{kind:`sent`};if(t.startsWith(`wrote:`))return{kind:`wrote`,resource:t.slice(6)};if(t.startsWith(`sent:`))return{kind:`sent`,resource:t.slice(5)};if(t.startsWith(`secret:`))return{kind:`secret`,resource:t.slice(7)};if(t===`secret`)return{kind:`secret`};if(t.startsWith(`cost:`)){let e=Number(t.slice(5));return Number.isFinite(e)?{kind:`cost`,min:e}:null}return null}function S(e){if(e)switch(e.kind){case`wrote`:return`wrote:${e.resource}`;case`asked`:return`asked`;case`sent`:return e.resource?`sent:${e.resource}`:`sent`;case`secret`:return e.resource?`secret:${e.resource}`:`secret`;case`cost`:return`cost:${e.min}`}}var C=m({trace:a().optional(),span:a().optional(),effect:a().optional(),q:a().optional(),folds:a().optional(),boost:a().optional()});function w(e){let t=C.safeParse(e??{});return t.success?t.data:C.parse({})}function T(e){let t={};return e.trace&&(t.trace=e.trace),e.span&&(t.span=e.span),e.effect&&(t.effect=e.effect),e.q&&(t.q=e.q),e.folds&&(t.folds=e.folds),e.boost&&(t.boost=e.boost),t}function E(e){return e.folds?new Set(e.folds.split(`,`).map(e=>e.trim()).filter(Boolean)):new Set}function D(e,t,n){return{...e,trace:t,span:n}}function ee(e){return{...e,trace:void 0,span:void 0,folds:void 0}}function te(e,t){let n=E(e);n.has(t)?n.delete(t):n.add(t);let r=[...n].join(`,`);return{...e,folds:r||void 0}}function O(e,t){return{...e,effect:S(t)}}function k(e){let t=new Map,n=new Map;for(let n of e)t.set(n.id,n);for(let t of e){if(!t.parentId)continue;let e=n.get(t.parentId)??[];e.push(t),n.set(t.parentId,e)}for(let[,e]of n)e.sort((e,t)=>e.startedAt-t.startedAt);return{byId:t,childrenOf:n}}function A(e,t){let{byId:n,childrenOf:r}=k(e),i=n.get(t);if(!i)return null;let a=[],o=i,s=new Set;for(;o?.parentId&&!s.has(o.parentId);){s.add(o.parentId);let e=n.get(o.parentId);if(!e)break;a.unshift(e),o=e}return{parents:a,current:i,children:r.get(i.id)??[],connected:N((a[0]??i).id,n,r)}}function j(e){let{byId:t,childrenOf:n}=k(e),r=e.filter(e=>!e.parentId||!t.has(e.parentId));return r.sort((e,t)=>t.startedAt-e.startedAt),r.map(e=>({rootId:e.id,root:e,spans:N(e.id,t,n)}))}function M(e,t){if(t&&e.some(e=>e.id===t))return t;let n=e.find(e=>e.errorCode!=null&&e.errorCode!==``);return n?n.id:e.find(t=>!t.parentId||!e.some(e=>e.id===t.parentId))?.id??e[0]?.id}function N(e,t,n){let r=[],i=e=>{let a=t.get(e);if(a){r.push(a);for(let t of n.get(e)??[])i(t.id)}};return i(e),r.sort((e,t)=>e.startedAt-t.startedAt),r}function P(e){if(e.length===0)return new Set;let{byId:t,childrenOf:n}=k(e),r=e.filter(e=>!e.parentId||!t.has(e.parentId)),i=[],a=-1,o=(e,r,s)=>{let c=n.get(e)??[],l=t.get(e);if(!l)return;let u=s+F(l),d=[...r,e];if(c.length===0){u>a&&(a=u,i=d);return}for(let e of c)o(e.id,d,u)};for(let e of r)o(e.id,[],0);return new Set(i)}function F(e){return e.effects.length===0?Math.max(0,e.durationMs):e.effects.reduce((e,t)=>e+Math.max(0,t.duration),0)}function I(e){switch(e){case`read`:return`reads`;case`write`:return`writes`;case`emit`:return`emits`;case`send`:case`ask`:return`external`;case`secret`:return`capabilities`;case`call`:return`reads`}}function L(e){let t=`none`;for(let n of e){let e=I(n.kind);z(e)>z(t)&&(t=e)}return t}function R(e){return e.some(e=>L(e.effects)===`external`)}function z(e){switch(e){case`external`:return 5;case`capabilities`:return 4;case`emits`:return 3;case`writes`:return 2;case`reads`:return 1;case`none`:return 0}}function B(e){let t=Math.max(0,Math.round(e));if(t<1e3)return`${t}ms idle`;let n=t/1e3;if(n<60)return`${U(n)}s idle`;let r=n/60;if(r<60)return`${U(r)}m idle`;let i=r/60;return i<48?`${U(i)}h idle`:`${U(i/24)}d idle`}function V(e,t={},n=new Set){let r=t.foldThresholdMs??50,i=t.expandedFolds??new Set,a=[...e].sort((e,t)=>e.startMs-t.startMs);if(a.length===0)return{segments:[],displayDurationMs:0,wallDurationMs:0};let o=a[0],s=a[a.length-1];if(!o||!s)return{segments:[],displayDurationMs:0,wallDurationMs:0};let c=o.startMs,l=Math.max(...a.map(e=>e.endMs)),u=[],d=c;for(let e of a){let t=e.startMs-d;if(t>=r){let n=`fold:${d}:${e.startMs}`,r=i.has(n),a=t;u.push({kind:`fold`,id:n,startMs:d,endMs:e.startMs,durationMs:a,label:B(a),expanded:r,displayMs:r?a:40})}let a=Math.max(0,e.endMs-e.startMs);u.push({kind:`work`,id:e.id,label:e.label,startMs:e.startMs,endMs:e.endMs,durationMs:a,tier:e.tier,spanId:e.spanId,critical:n.has(e.spanId),failed:e.failed===!0,displayMs:Math.max(1,a)}),d=Math.max(d,e.endMs)}let f=u.reduce((e,t)=>e+t.displayMs,0);return{segments:u,displayDurationMs:Math.max(1,f),wallDurationMs:l-c}}function H(e){let t=[];for(let n of e)if(n.effects.length>0)for(let e of n.effects)t.push({id:`${n.id}:${e.kind}:${e.resource}:${e.timestamp}`,label:`${e.kind} ${e.resource}`,startMs:e.timestamp,endMs:e.timestamp+Math.max(1,e.duration),tier:I(e.kind),spanId:n.id,failed:n.errorCode!=null&&e===n.effects[n.effects.length-1]});else t.push({id:n.id,label:n.flow,startMs:n.startedAt,endMs:n.endedAt,tier:`none`,spanId:n.id,failed:n.errorCode!=null});return t}function U(e){let t=Math.round(e*10)/10;return Number.isInteger(t)?String(t):t.toFixed(1)}function W(e){if(e.length===0)return[];let t=Math.min(...e.map(e=>e.startedAt)),n=Math.max(...e.map(e=>e.endedAt)),r=Math.max(1,n-t);if(e.every(e=>e.effects.length===0))return e.map(e=>({start:(e.startedAt-t)/r,width:Math.max(.02,e.durationMs/r),tier:L(e.effects),failed:e.errorCode!=null}));let i=[];for(let n of e){if(n.effects.length===0){i.push({start:(n.startedAt-t)/r,width:Math.max(.02,n.durationMs/r),tier:`none`,failed:n.errorCode!=null});continue}for(let e=0;e<n.effects.length;e++){let a=n.effects[e];a&&i.push({start:(a.timestamp-t)/r,width:Math.max(.02,a.duration/r),tier:I(a.kind),failed:n.errorCode!=null&&e===n.effects.length-1})}}return i}function G(e){for(let t of e)if(t.errorCode)return t.errorCode;return null}function K(e){return R(e)?{mode:`dry-run`,reason:`This trace contains an external effect. Replay runs as a dry run with external effects stubbed.`}:{mode:`replay`}}var q=`10% + all errors`,J=6e5;function Y(e,t=Date.now()){let n=e.filter(e=>e.until>t);return n.length===0?q:`${q} · full: ${n.map(e=>e.flow).join(`, `)}`}function X(e,t,n=Date.now()){let r=n+J;return[...e.filter(e=>e.flow!==t&&e.until>n),{flow:t,until:r}]}function ne(e,t=Date.now()){return e.filter(e=>e.until>t)}var Z=d();function Q(){let e=p({from:`/traces`}),t=n({from:`/traces`}),a=s(),[l,d]=(0,v.useState)([]),[m]=(0,v.useState)(()=>_()),[y,S]=(0,v.useState)(0),[,C]=(0,v.useState)(0),w=e=>{t({search:T(e),replace:!0})},k=r({queryKey:[`console.runs.list`],queryFn:async()=>{let e=await o.runsList();if(e.error)throw Error(e.error.code);return e.data.runs},refetchInterval:5e3}),N=(0,v.useMemo)(()=>(k.data??[]).map(re),[k.data]);(0,v.useEffect)(()=>{if(N.length===0)return;if(m.visible.length===0){for(let e of N)m.offer({id:e.id,value:e,arrivedAt:e.startedAt});m.flush(),S(0),C(e=>e+1);return}let e=new Set(m.visible.map(e=>e.id));for(let t of m.pending)e.add(t.id);for(let t of N)e.has(t.id)?m.updateInPlace(t.id,t):m.offer({id:t.id,value:t,arrivedAt:Date.now()});S(m.pendingCount),C(e=>e+1)},[N,m]);let F=m.visible.map(e=>e.value),I=x(e.effect),R=(0,v.useMemo)(()=>j(F).filter(t=>{let n=g([t.root.flow,t.root.id,G(t.spans)??``],e.q),r=b(t.spans,I);return n&&r}),[F,e.q,I]),z=R.find(t=>t.rootId===e.trace)??(e.trace?j(F).find(t=>t.rootId===e.trace):void 0),B=z?M(z.spans,e.span):void 0,U=B?A(F,B):null,q=U?P(U.connected):new Set,J=U?V(H(U.connected),{expandedFolds:E(e)},q):null,Q=U?K(U.connected):null,$=i({mutationFn:async()=>{if(!U||!Q)return;let e=await o.tracesReplay({rootId:U.connected[0]?.id??U.current.id,dryRun:Q.mode===`dry-run`});if(e.error)throw Error(e.error.code);return e.data},onSuccess:()=>{a.invalidateQueries({queryKey:[`console.runs.list`]})}}),ae=ne(l);return(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,Z.jsxs)(`header`,{className:`flex shrink-0 flex-wrap items-end gap-4 border-b border-[var(--oke-line)] px-6 py-4`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,Z.jsx)(`p`,{className:`text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]`,children:`Traces`}),(0,Z.jsx)(`h1`,{className:`text-xl font-semibold tracking-tight`,children:`Causal chain`}),(0,Z.jsxs)(`p`,{className:`text-xs text-[var(--oke-muted)]`,children:[`Sampling: `,Y(ae)]})]}),(0,Z.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,Z.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Filter by effect`}),(0,Z.jsxs)(`select`,{"aria-label":`Filter by effect`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2 text-sm`,value:e.effect??``,onChange:t=>{let n=t.target.value;w(O(e,n?x(n):null))},children:[(0,Z.jsx)(`option`,{value:``,children:`All effects`}),(0,Z.jsx)(`option`,{value:`wrote:sql:bookings`,children:`Wrote sql:bookings`}),(0,Z.jsx)(`option`,{value:`sent`,children:`Sent (channel)`}),(0,Z.jsx)(`option`,{value:`asked`,children:`Asked a model`}),(0,Z.jsx)(`option`,{value:`secret`,children:`Read a secret`}),(0,Z.jsx)(`option`,{value:`cost:0.05`,children:`Cost > $0.05`})]})]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Z.jsx)(u,{type:`button`,variant:`ghost`,onClick:()=>{let e=z?.root.flow??R[0]?.root.flow??`bookings.create`;d(t=>X(t,e))},children:`Trace flow fully for 10 minutes`}),(0,Z.jsx)(c,{count:y,onFlush:()=>{m.flush(),S(0),C(e=>e+1)}})]})]}),(0,Z.jsxs)(`div`,{className:`grid min-h-0 flex-1 grid-cols-1 md:grid-cols-[minmax(0,1fr)_minmax(0,1.4fr)]`,children:[(0,Z.jsx)(`section`,{"aria-label":`Trace list`,className:`min-h-0 overflow-auto border-r border-[var(--oke-line)]`,children:k.isLoading?(0,Z.jsx)(`p`,{className:`px-6 py-8 text-sm text-[var(--oke-muted)]`,children:`Loading traces…`}):R.length===0?(0,Z.jsx)(`p`,{className:`px-6 py-8 text-sm text-[var(--oke-muted)]`,children:`No traces yet. Invoke a flow or wait for traffic.`}):(0,Z.jsx)(`ul`,{className:`divide-y divide-[var(--oke-line)]`,children:R.map(t=>{let n=G(t.spans),r=W(t.spans),i=t.rootId===e.trace;return(0,Z.jsx)(`li`,{children:(0,Z.jsxs)(`button`,{type:`button`,"aria-pressed":i,className:f(`flex w-full min-h-10 flex-col gap-1 px-4 py-3 text-left text-sm`,i?`bg-[color-mix(in_oklab,var(--oke-fg)_6%,transparent)]`:`hover:bg-[color-mix(in_oklab,var(--oke-fg)_3%,transparent)]`),onClick:()=>{let n=M(t.spans);w(D(e,t.rootId,n))},children:[(0,Z.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,Z.jsx)(`span`,{className:`font-medium`,children:t.root.flow}),n?(0,Z.jsx)(`span`,{role:`status`,className:`font-mono text-xs text-[var(--oke-danger)]`,children:n}):(0,Z.jsxs)(`span`,{className:`font-mono text-xs text-[var(--oke-muted)]`,children:[t.root.durationMs,`ms`]})]}),(0,Z.jsx)(ie,{bars:r})]})},t.rootId)})})}),(0,Z.jsx)(`section`,{"aria-label":`Trace detail`,className:`min-h-0 overflow-auto px-6 py-6`,"aria-live":`polite`,children:!U||!J?(0,Z.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Select a trace to see the causal chain and folded-time waterfall.`}):(0,Z.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`h2`,{className:`text-lg font-semibold`,children:U.current.flow}),(0,Z.jsxs)(`p`,{className:`text-xs text-[var(--oke-muted)]`,children:[U.connected.length,` span`,U.connected.length===1?``:`s`,` · wall `,J.wallDurationMs,`ms · display scale `,Math.round(J.displayDurationMs),`ms`]})]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,Z.jsx)(h,{to:`/runs`,search:{run:U.current.id},className:`inline-flex min-h-8 items-center border border-[var(--oke-line)] px-3 text-sm`,children:`Open in Runs`}),(0,Z.jsx)(u,{type:`button`,variant:Q?.mode===`dry-run`?`external`:`primary`,disabled:$.isPending,title:Q?.mode===`dry-run`?Q.reason:`Replay from the journal`,onClick:()=>$.mutate(),children:Q?.mode===`dry-run`?`Dry-run replay`:`Replay`}),(0,Z.jsx)(u,{type:`button`,variant:`ghost`,onClick:()=>w(ee(e)),children:`Close`})]})]}),Q?.mode===`dry-run`?(0,Z.jsx)(`p`,{role:`note`,className:`text-sm text-[var(--oke-external)]`,children:Q.reason}):null,(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Causal chain`}),(0,Z.jsxs)(`ol`,{className:`flex flex-col gap-1 border-l border-[var(--oke-line)] pl-4`,children:[U.parents.map(t=>(0,Z.jsx)(`li`,{children:(0,Z.jsx)(`button`,{type:`button`,className:`min-h-8 text-sm text-[var(--oke-muted)]`,onClick:()=>w({...e,span:t.id}),children:t.flow})},t.id)),(0,Z.jsxs)(`li`,{"aria-current":`true`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium`,children:U.current.flow}),U.current.errorCode?(0,Z.jsx)(`span`,{role:`status`,className:`ml-2 font-mono text-xs text-[var(--oke-danger)]`,children:U.current.errorCode}):null,L(U.current.effects)===`external`?(0,Z.jsx)(`span`,{"aria-label":`external effect`,children:` ↗`}):null]}),U.children.map(t=>(0,Z.jsx)(`li`,{children:(0,Z.jsxs)(`button`,{type:`button`,className:`min-h-8 text-sm text-[var(--oke-muted)]`,onClick:()=>w({...e,span:t.id}),children:[t.flow,L(t.effects)===`external`?(0,Z.jsx)(`span`,{"aria-label":`external effect`,children:` ↗`}):null]})},t.id))]})]}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`h3`,{id:`waterfall-heading`,className:`mb-2 text-sm font-medium`,children:`Waterfall`}),(0,Z.jsx)(`ul`,{"aria-labelledby":`waterfall-heading`,className:`flex min-h-10 list-none items-stretch gap-0.5 p-0`,children:J.segments.map(t=>t.kind===`fold`?(0,Z.jsx)(`li`,{style:{flex:`${t.displayMs} 1 0`,minWidth:24},children:(0,Z.jsx)(`button`,{type:`button`,"aria-expanded":t.expanded,className:`h-full min-h-10 w-full border border-dashed border-[var(--oke-line)] px-1 font-mono text-[10px] text-[var(--oke-muted)]`,onClick:()=>w(te(e,t.id)),children:t.label})},t.id):(0,Z.jsx)(`li`,{title:t.label,className:f(`min-h-10 px-1 text-[10px] leading-10`,t.tier===`external`?`bg-[var(--oke-external)] text-black`:`bg-[color-mix(in_oklab,var(--oke-accent)_55%,transparent)]`,t.failed&&`outline outline-2 outline-[var(--oke-danger)]`),style:{flex:`${t.displayMs} 1 0`,opacity:t.critical?1:.38,minWidth:4},children:(0,Z.jsxs)(`span`,{className:`sr-only`,children:[t.label,t.critical?` (critical path)`:``,t.failed?` (failed)`:``]})},t.id))}),(0,Z.jsx)(`p`,{className:`mt-2 text-xs text-[var(--oke-muted)]`,children:`Critical path at full opacity · dead time folded into expandable bars`})]})]})})]})]})}function re(e){return{id:e.id,...e.parentId?{parentId:e.parentId}:{},flow:e.flow,...e.unit?{unit:e.unit}:{},trigger:e.trigger,startedAt:e.startedAt,endedAt:e.endedAt,durationMs:e.durationMs,errorCode:e.error,cost:e.cost??void 0,sampled:e.sampled??(e.error?`error`:`sample`),effects:e.effects??[]}}function ie({bars:e}){return(0,Z.jsx)(`div`,{"aria-hidden":`true`,className:`relative h-2 w-full overflow-hidden bg-[color-mix(in_oklab,var(--oke-fg)_6%,transparent)]`,children:e.map((e,t)=>(0,Z.jsx)(`span`,{className:f(`absolute inset-y-0`,e.tier===`external`?`bg-[var(--oke-external)]`:e.failed?`bg-[var(--oke-danger)]`:`bg-[var(--oke-accent)]`),style:{left:`${e.start*100}%`,width:`${Math.max(2,e.width*100)}%`}},t))})}var $=t({default:()=>Q});export{w as n,$ as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,r as t}from"./rolldown-runtime-B0Z9INg1.js";import{C as n,Q as r,Z as i,a,b as o,c as s,d as c,et as l,g as u,nt as d,o as f,tt as p,u as m,w as h,y as g}from"./panel-access-BGv45snf.js";import{n as _}from"./panel-channels-9T3ybqRu.js";var v=g({q:o().optional(),name:o().optional(),action:u([`set`,`rotate`]).optional()});function y(e){let t=v.safeParse(e);return t.success?t.data:{}}function b(e){let t={};return e.q&&(t.q=e.q),e.name&&(t.name=e.name),e.action&&(t.action=e.action),t}function x(e,t){return{...e,name:t,action:void 0}}function S(e,t=``){let n=t.trim().toLowerCase(),r=n?e.filter(e=>e.name.toLowerCase().includes(n)||(e.description?.toLowerCase().includes(n)??!1)):e,i=[`secret`,`config`],a={secret:`Secrets`,config:`Config`};return i.map(e=>({kind:e,label:a[e],secrets:r.filter(t=>t.kind===e)})).filter(e=>e.secrets.length>0)}function C(e={production:!0}){return e.production?{kind:`typed`,phrase:`SET`,requireReason:!0}:{kind:`undo`,windowMs:15e3}}function w(e={production:!0}){return{kind:`typed`,phrase:`ROTATE`,requireReason:!0}}function T(e){if(e.count===0)return{summary:`No in-flight durable runs hold this secret`,detail:null,warn:!1};let t=e.longestOutstandingMs==null?null:E(e.longestOutstandingMs);return{summary:`${e.count} in-flight durable run(s) will wake holding a new key`,detail:t?`Longest outstanding wake in ${t}`:e.longestWakeAt==null?null:`Longest wake at ${new Date(e.longestWakeAt).toISOString()}`,warn:!0}}function E(e){if(e<1e3)return`${e}ms`;let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);if(n<60)return`${n}m`;let r=Math.floor(n/60);return r<48?`${r}h`:`${Math.floor(r/24)}d`}function D(e){return{name:e.name,kind:e.kind,sensitive:e.sensitive,description:e.description??null,rotate:e.rotate??null,fingerprints:{...e.fingerprints},fingerprint:e.fingerprint,cleartext:e.sensitive?null:e.cleartext,winner:e.winner,resolution:e.resolution.map(e=>({...e})),readers:[...e.readers],blastRadius:{count:e.blastRadius.count,longestWakeAt:e.blastRadius.longestWakeAt,longestOutstandingMs:e.blastRadius.longestOutstandingMs,runIds:[...e.blastRadius.runIds]},lastReadAt:e.lastReadAt,sharedFingerprintEnvs:[...e.sharedFingerprintEnvs]}}function O(e){return JSON.stringify(e.map(e=>D(e)),null,2)}var k=e(d(),1),A=p();function j(){let e=h({from:`/vault`}),t=n({from:`/vault`}),o=l(),[u,d]=(0,k.useState)(``),[p,g]=(0,k.useState)(``),[v,y]=(0,k.useState)(``),[E,D]=(0,k.useState)(null),j=e=>{t({search:b(e),replace:!0})},M=r({queryKey:[`console.vault.list`],queryFn:async()=>{let e=await c.vaultList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:1e4}),N=M.data?.secrets??[],P=M.data?.env??`local`,F=(0,k.useMemo)(()=>S(N,e.q??``),[N,e.q]),I=N.find(t=>t.name===e.name),L=I?T(I.blastRadius):null,R=C({production:!0}),z=w({production:!0}),B=e.action;(0,k.useEffect)(()=>{d(``),g(``),y(``),D(null)},[I?.name,B]);let V=i({mutationFn:async()=>{if(!I)throw Error(`no secret`);if(R.kind===`typed`){let e=a({typed:u,reason:p,phrase:R.phrase});if(e)throw Error(e.typed??e.reason??`confirm`)}let e=await c.vaultSet({name:I.name,value:v,confirmation:R.kind===`typed`?u:void 0,reason:p||void 0});if(e.error)throw Error(e.error.code);return e.data},onSuccess:async()=>{y(``),d(``),g(``),j({...e,action:void 0}),await o.invalidateQueries({queryKey:[`console.vault.list`]})}}),H=i({mutationFn:async()=>{if(!I)throw Error(`no secret`);let e=a({typed:u,reason:p,phrase:z.kind===`typed`?z.phrase:`ROTATE`});if(e)throw Error(e.typed??e.reason??`confirm`);let t=await c.vaultRotate({name:I.name,value:v,confirmation:u,reason:p});if(t.error)throw Error(t.error.code);return t.data},onSuccess:async()=>{y(``),d(``),g(``),j({...e,action:void 0}),await o.invalidateQueries({queryKey:[`console.vault.list`]})}});return(0,A.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,A.jsxs)(`header`,{className:`flex shrink-0 flex-wrap items-end gap-3 border-b border-[var(--oke-line)] px-4 py-3`,children:[(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`h1`,{className:`text-lg font-medium text-[var(--oke-fg)]`,children:`Vault`}),(0,A.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Fingerprints only — secrets are write-only`})]}),(0,A.jsxs)(`p`,{className:`text-sm text-[var(--oke-muted)]`,role:`status`,children:[`Environment `,P]}),(0,A.jsxs)(`label`,{className:`ml-auto flex min-w-[12rem] flex-col gap-1 text-sm`,children:[(0,A.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Filter vault`}),(0,A.jsx)(s,{"aria-label":`Filter vault`,value:e.q??``,onChange:t=>j({...e,q:t.currentTarget.value||void 0})})]}),(0,A.jsx)(f,{type:`button`,variant:`ghost`,onClick:()=>{let e=O(N);navigator.clipboard?.writeText(e),D(`Exported fingerprints only (no secret values)`)},children:`Export`})]}),E?(0,A.jsx)(`p`,{className:`px-4 py-2 text-sm text-[var(--oke-muted)]`,role:`status`,children:E}):null,(0,A.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,A.jsxs)(`section`,{"aria-label":`Vault list`,className:`w-80 shrink-0 overflow-y-auto border-r border-[var(--oke-line)]`,children:[(0,A.jsx)(`h2`,{className:`sr-only`,children:`Contracts`}),M.isLoading?(0,A.jsx)(`p`,{className:`p-4 text-sm text-[var(--oke-muted)]`,children:`Loading…`}):null,F.map(t=>(0,A.jsxs)(`section`,{"aria-label":t.label,className:`py-2`,children:[(0,A.jsx)(`h3`,{className:`px-4 py-1 text-xs uppercase tracking-wide text-[var(--oke-muted)]`,children:t.label}),(0,A.jsx)(`ul`,{children:t.secrets.map(t=>(0,A.jsx)(`li`,{children:(0,A.jsxs)(`button`,{type:`button`,"aria-pressed":t.name===I?.name,className:m(`flex min-h-10 w-full flex-col items-start px-4 py-2 text-left text-sm`,t.name===I?.name?`bg-[var(--oke-line)] text-[var(--oke-fg)]`:`text-[var(--oke-muted)] hover:text-[var(--oke-fg)]`),onClick:()=>j(x(e,t.name)),children:[(0,A.jsx)(`span`,{children:_(t.name,t.description)}),t.description?(0,A.jsx)(`span`,{className:`font-mono text-xs text-[var(--oke-muted)]`,children:t.name}):null,(0,A.jsx)(`span`,{className:`truncate text-xs`,children:t.sensitive?t.fingerprint??`unset`:t.cleartext??`unset`}),t.blastRadius.count>0?(0,A.jsxs)(`span`,{role:`status`,className:`text-xs text-[var(--oke-danger)]`,children:[`blast `,t.blastRadius.count]}):null,t.sharedFingerprintEnvs.length>0?(0,A.jsx)(`span`,{role:`status`,className:`text-xs`,children:`shared fingerprint`}):null]})},t.name))})]},t.kind))]}),(0,A.jsx)(`section`,{"aria-label":`Vault detail`,"aria-live":`polite`,className:`min-w-0 flex-1 overflow-y-auto p-4`,children:I?(0,A.jsxs)(`div`,{className:`flex max-w-2xl flex-col gap-6`,children:[(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`h2`,{className:`text-lg text-[var(--oke-fg)]`,children:_(I.name,I.description)}),I.description?(0,A.jsx)(`p`,{className:`font-mono text-sm text-[var(--oke-muted)]`,children:I.name}):null,I.rotate?(0,A.jsxs)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:[`Rotate hint: `,I.rotate]}):null]}),(0,A.jsxs)(`section`,{"aria-label":`Fingerprints by environment`,children:[(0,A.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Fingerprints`}),I.sensitive?(0,A.jsxs)(`ul`,{className:`space-y-1 font-mono text-sm`,children:[Object.entries(I.fingerprints).map(([e,t])=>(0,A.jsxs)(`li`,{children:[(0,A.jsxs)(`span`,{className:`text-[var(--oke-muted)]`,children:[e,`:`]}),` `,t,I.sharedFingerprintEnvs.includes(e)?(0,A.jsxs)(`span`,{role:`status`,className:`ml-2 text-[var(--oke-warn,var(--oke-muted))]`,children:[`(matches `,P,` — warning, may be deliberate)`]}):null]},e)),Object.keys(I.fingerprints).length===0?(0,A.jsx)(`li`,{className:`text-[var(--oke-muted)]`,children:`Unset`}):null]}):(0,A.jsx)(`p`,{className:`font-mono text-sm`,role:`status`,children:I.cleartext??`unset`})]}),(0,A.jsxs)(`section`,{"aria-label":`Resolution chain`,children:[(0,A.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Resolution chain`}),(0,A.jsx)(`ol`,{className:`list-decimal space-y-1 pl-5 text-sm`,children:I.resolution.map(e=>(0,A.jsxs)(`li`,{className:e.won?`text-[var(--oke-fg)]`:`text-[var(--oke-muted)]`,children:[(0,A.jsx)(`span`,{className:`font-mono`,children:e.source}),e.won?` — won`:e.present?` — present (lost)`:` — absent`]},e.source))}),(0,A.jsxs)(`p`,{className:`mt-2 text-sm`,role:`status`,children:[`Winner: `,(0,A.jsx)(`span`,{className:`font-mono`,children:I.winner??`none`})]})]}),(0,A.jsxs)(`section`,{"aria-label":`Readers`,children:[(0,A.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Readers`}),(0,A.jsxs)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:[`Flows that declare `,(0,A.jsxs)(`code`,{className:`font-mono`,children:[`fx.vault(`,I.name,`)`]})]}),(0,A.jsx)(`ul`,{className:`mt-1 list-disc pl-5 font-mono text-sm`,children:I.readers.length===0?(0,A.jsx)(`li`,{className:`text-[var(--oke-muted)]`,children:`none`}):I.readers.map(e=>(0,A.jsx)(`li`,{children:e},e))})]}),(0,A.jsxs)(`section`,{"aria-label":`Rotation blast radius`,children:[(0,A.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Rotation blast radius`}),L?(0,A.jsxs)(A.Fragment,{children:[(0,A.jsx)(`p`,{className:`text-sm`,role:L.warn?`alert`:`status`,children:L.summary}),L.detail?(0,A.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:L.detail}):null,I.blastRadius.runIds.length>0?(0,A.jsx)(`p`,{className:`mt-1 font-mono text-xs text-[var(--oke-muted)]`,children:I.blastRadius.runIds.join(`, `)}):null]}):null]}),(0,A.jsxs)(`section`,{"aria-label":`Last read`,children:[(0,A.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Last read`}),(0,A.jsx)(`p`,{className:`text-sm`,role:`status`,children:I.lastReadAt==null?`Never read — possible dead secret`:new Date(I.lastReadAt).toISOString()})]}),(0,A.jsxs)(`section`,{"aria-label":`Set or rotate`,className:`space-y-3`,children:[(0,A.jsx)(`h3`,{className:`text-sm font-medium`,children:`Set / rotate`}),(0,A.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Write-only. Values are never revealed after submit. No preview.`}),(0,A.jsxs)(`div`,{className:`flex gap-2`,children:[(0,A.jsx)(f,{type:`button`,variant:B===`set`?`primary`:`ghost`,"aria-pressed":B===`set`,onClick:()=>j({...e,action:`set`}),children:`Set`}),(0,A.jsx)(f,{type:`button`,variant:B===`rotate`?`danger`:`ghost`,"aria-pressed":B===`rotate`,onClick:()=>j({...e,action:`rotate`}),children:`Rotate`})]}),B?(0,A.jsxs)(`div`,{className:`space-y-3 border border-[var(--oke-line)] p-3`,children:[(0,A.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,A.jsx)(`span`,{children:`New value`}),(0,A.jsx)(s,{"aria-label":`New vault value`,type:`password`,autoComplete:`off`,value:v,onChange:e=>y(e.currentTarget.value)})]}),(B===`rotate`||R.kind===`typed`)&&(0,A.jsxs)(A.Fragment,{children:[(0,A.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,A.jsxs)(`span`,{children:[`Type`,` `,B===`rotate`?z.kind===`typed`?z.phrase:`ROTATE`:R.kind===`typed`?R.phrase:`SET`,` `,`to confirm`]}),(0,A.jsx)(s,{"aria-label":`Confirmation phrase`,value:u,onChange:e=>d(e.currentTarget.value)})]}),(0,A.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,A.jsx)(`span`,{children:`Reason`}),(0,A.jsx)(s,{"aria-label":`Reason for vault write`,value:p,onChange:e=>g(e.currentTarget.value)})]})]}),(0,A.jsx)(f,{type:`button`,variant:B===`rotate`?`danger`:`primary`,disabled:!v||(B===`set`?V.isPending:H.isPending),onClick:()=>{B===`set`?V.mutate():H.mutate()},children:B===`set`?`Commit set`:`Commit rotate`}),(V.isError||H.isError)&&(0,A.jsx)(`p`,{role:`alert`,className:`text-sm text-[var(--oke-danger)]`,children:(V.error??H.error)?.message??`Failed`})]}):null]})]}):(0,A.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Select a contract to inspect fingerprints, resolution, and readers.`})})]})]})}var M=t({default:()=>j});export{y as n,M as t};
|
|
1
|
+
import{a as e,r as t}from"./rolldown-runtime-B0Z9INg1.js";import{C as n,Q as r,Z as i,a,b as o,c as s,d as c,et as l,g as u,nt as d,o as f,tt as p,u as m,w as h,y as g}from"./panel-access-ri1X9Otj.js";import{n as _}from"./panel-channels-BDYWX29p.js";var v=g({q:o().optional(),name:o().optional(),action:u([`set`,`rotate`]).optional()});function y(e){let t=v.safeParse(e);return t.success?t.data:{}}function b(e){let t={};return e.q&&(t.q=e.q),e.name&&(t.name=e.name),e.action&&(t.action=e.action),t}function x(e,t){return{...e,name:t,action:void 0}}function S(e,t=``){let n=t.trim().toLowerCase(),r=n?e.filter(e=>e.name.toLowerCase().includes(n)||(e.description?.toLowerCase().includes(n)??!1)):e,i=[`secret`,`config`],a={secret:`Secrets`,config:`Config`};return i.map(e=>({kind:e,label:a[e],secrets:r.filter(t=>t.kind===e)})).filter(e=>e.secrets.length>0)}function C(e={production:!0}){return e.production?{kind:`typed`,phrase:`SET`,requireReason:!0}:{kind:`undo`,windowMs:15e3}}function w(e={production:!0}){return{kind:`typed`,phrase:`ROTATE`,requireReason:!0}}function T(e){if(e.count===0)return{summary:`No in-flight durable runs hold this secret`,detail:null,warn:!1};let t=e.longestOutstandingMs==null?null:E(e.longestOutstandingMs);return{summary:`${e.count} in-flight durable run(s) will wake holding a new key`,detail:t?`Longest outstanding wake in ${t}`:e.longestWakeAt==null?null:`Longest wake at ${new Date(e.longestWakeAt).toISOString()}`,warn:!0}}function E(e){if(e<1e3)return`${e}ms`;let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);if(n<60)return`${n}m`;let r=Math.floor(n/60);return r<48?`${r}h`:`${Math.floor(r/24)}d`}function D(e){return{name:e.name,kind:e.kind,sensitive:e.sensitive,description:e.description??null,rotate:e.rotate??null,fingerprints:{...e.fingerprints},fingerprint:e.fingerprint,cleartext:e.sensitive?null:e.cleartext,winner:e.winner,resolution:e.resolution.map(e=>({...e})),readers:[...e.readers],blastRadius:{count:e.blastRadius.count,longestWakeAt:e.blastRadius.longestWakeAt,longestOutstandingMs:e.blastRadius.longestOutstandingMs,runIds:[...e.blastRadius.runIds]},lastReadAt:e.lastReadAt,sharedFingerprintEnvs:[...e.sharedFingerprintEnvs]}}function O(e){return JSON.stringify(e.map(e=>D(e)),null,2)}var k=e(d(),1),A=p();function j(){let e=h({from:`/vault`}),t=n({from:`/vault`}),o=l(),[u,d]=(0,k.useState)(``),[p,g]=(0,k.useState)(``),[v,y]=(0,k.useState)(``),[E,D]=(0,k.useState)(null),j=e=>{t({search:b(e),replace:!0})},M=r({queryKey:[`console.vault.list`],queryFn:async()=>{let e=await c.vaultList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:1e4}),N=M.data?.secrets??[],P=M.data?.env??`local`,F=(0,k.useMemo)(()=>S(N,e.q??``),[N,e.q]),I=N.find(t=>t.name===e.name),L=I?T(I.blastRadius):null,R=C({production:!0}),z=w({production:!0}),B=e.action;(0,k.useEffect)(()=>{d(``),g(``),y(``),D(null)},[I?.name,B]);let V=i({mutationFn:async()=>{if(!I)throw Error(`no secret`);if(R.kind===`typed`){let e=a({typed:u,reason:p,phrase:R.phrase});if(e)throw Error(e.typed??e.reason??`confirm`)}let e=await c.vaultSet({name:I.name,value:v,confirmation:R.kind===`typed`?u:void 0,reason:p||void 0});if(e.error)throw Error(e.error.code);return e.data},onSuccess:async()=>{y(``),d(``),g(``),j({...e,action:void 0}),await o.invalidateQueries({queryKey:[`console.vault.list`]})}}),H=i({mutationFn:async()=>{if(!I)throw Error(`no secret`);let e=a({typed:u,reason:p,phrase:z.kind===`typed`?z.phrase:`ROTATE`});if(e)throw Error(e.typed??e.reason??`confirm`);let t=await c.vaultRotate({name:I.name,value:v,confirmation:u,reason:p});if(t.error)throw Error(t.error.code);return t.data},onSuccess:async()=>{y(``),d(``),g(``),j({...e,action:void 0}),await o.invalidateQueries({queryKey:[`console.vault.list`]})}});return(0,A.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,A.jsxs)(`header`,{className:`flex shrink-0 flex-wrap items-end gap-3 border-b border-[var(--oke-line)] px-4 py-3`,children:[(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`h1`,{className:`text-lg font-medium text-[var(--oke-fg)]`,children:`Vault`}),(0,A.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Fingerprints only — secrets are write-only`})]}),(0,A.jsxs)(`p`,{className:`text-sm text-[var(--oke-muted)]`,role:`status`,children:[`Environment `,P]}),(0,A.jsxs)(`label`,{className:`ml-auto flex min-w-[12rem] flex-col gap-1 text-sm`,children:[(0,A.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Filter vault`}),(0,A.jsx)(s,{"aria-label":`Filter vault`,value:e.q??``,onChange:t=>j({...e,q:t.currentTarget.value||void 0})})]}),(0,A.jsx)(f,{type:`button`,variant:`ghost`,onClick:()=>{let e=O(N);navigator.clipboard?.writeText(e),D(`Exported fingerprints only (no secret values)`)},children:`Export`})]}),E?(0,A.jsx)(`p`,{className:`px-4 py-2 text-sm text-[var(--oke-muted)]`,role:`status`,children:E}):null,(0,A.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,A.jsxs)(`section`,{"aria-label":`Vault list`,className:`w-80 shrink-0 overflow-y-auto border-r border-[var(--oke-line)]`,children:[(0,A.jsx)(`h2`,{className:`sr-only`,children:`Contracts`}),M.isLoading?(0,A.jsx)(`p`,{className:`p-4 text-sm text-[var(--oke-muted)]`,children:`Loading…`}):null,F.map(t=>(0,A.jsxs)(`section`,{"aria-label":t.label,className:`py-2`,children:[(0,A.jsx)(`h3`,{className:`px-4 py-1 text-xs uppercase tracking-wide text-[var(--oke-muted)]`,children:t.label}),(0,A.jsx)(`ul`,{children:t.secrets.map(t=>(0,A.jsx)(`li`,{children:(0,A.jsxs)(`button`,{type:`button`,"aria-pressed":t.name===I?.name,className:m(`flex min-h-10 w-full flex-col items-start px-4 py-2 text-left text-sm`,t.name===I?.name?`bg-[var(--oke-line)] text-[var(--oke-fg)]`:`text-[var(--oke-muted)] hover:text-[var(--oke-fg)]`),onClick:()=>j(x(e,t.name)),children:[(0,A.jsx)(`span`,{children:_(t.name,t.description)}),t.description?(0,A.jsx)(`span`,{className:`font-mono text-xs text-[var(--oke-muted)]`,children:t.name}):null,(0,A.jsx)(`span`,{className:`truncate text-xs`,children:t.sensitive?t.fingerprint??`unset`:t.cleartext??`unset`}),t.blastRadius.count>0?(0,A.jsxs)(`span`,{role:`status`,className:`text-xs text-[var(--oke-danger)]`,children:[`blast `,t.blastRadius.count]}):null,t.sharedFingerprintEnvs.length>0?(0,A.jsx)(`span`,{role:`status`,className:`text-xs`,children:`shared fingerprint`}):null]})},t.name))})]},t.kind))]}),(0,A.jsx)(`section`,{"aria-label":`Vault detail`,"aria-live":`polite`,className:`min-w-0 flex-1 overflow-y-auto p-4`,children:I?(0,A.jsxs)(`div`,{className:`flex max-w-2xl flex-col gap-6`,children:[(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`h2`,{className:`text-lg text-[var(--oke-fg)]`,children:_(I.name,I.description)}),I.description?(0,A.jsx)(`p`,{className:`font-mono text-sm text-[var(--oke-muted)]`,children:I.name}):null,I.rotate?(0,A.jsxs)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:[`Rotate hint: `,I.rotate]}):null]}),(0,A.jsxs)(`section`,{"aria-label":`Fingerprints by environment`,children:[(0,A.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Fingerprints`}),I.sensitive?(0,A.jsxs)(`ul`,{className:`space-y-1 font-mono text-sm`,children:[Object.entries(I.fingerprints).map(([e,t])=>(0,A.jsxs)(`li`,{children:[(0,A.jsxs)(`span`,{className:`text-[var(--oke-muted)]`,children:[e,`:`]}),` `,t,I.sharedFingerprintEnvs.includes(e)?(0,A.jsxs)(`span`,{role:`status`,className:`ml-2 text-[var(--oke-warn,var(--oke-muted))]`,children:[`(matches `,P,` — warning, may be deliberate)`]}):null]},e)),Object.keys(I.fingerprints).length===0?(0,A.jsx)(`li`,{className:`text-[var(--oke-muted)]`,children:`Unset`}):null]}):(0,A.jsx)(`p`,{className:`font-mono text-sm`,role:`status`,children:I.cleartext??`unset`})]}),(0,A.jsxs)(`section`,{"aria-label":`Resolution chain`,children:[(0,A.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Resolution chain`}),(0,A.jsx)(`ol`,{className:`list-decimal space-y-1 pl-5 text-sm`,children:I.resolution.map(e=>(0,A.jsxs)(`li`,{className:e.won?`text-[var(--oke-fg)]`:`text-[var(--oke-muted)]`,children:[(0,A.jsx)(`span`,{className:`font-mono`,children:e.source}),e.won?` — won`:e.present?` — present (lost)`:` — absent`]},e.source))}),(0,A.jsxs)(`p`,{className:`mt-2 text-sm`,role:`status`,children:[`Winner: `,(0,A.jsx)(`span`,{className:`font-mono`,children:I.winner??`none`})]})]}),(0,A.jsxs)(`section`,{"aria-label":`Readers`,children:[(0,A.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Readers`}),(0,A.jsxs)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:[`Flows that declare `,(0,A.jsxs)(`code`,{className:`font-mono`,children:[`fx.vault(`,I.name,`)`]})]}),(0,A.jsx)(`ul`,{className:`mt-1 list-disc pl-5 font-mono text-sm`,children:I.readers.length===0?(0,A.jsx)(`li`,{className:`text-[var(--oke-muted)]`,children:`none`}):I.readers.map(e=>(0,A.jsx)(`li`,{children:e},e))})]}),(0,A.jsxs)(`section`,{"aria-label":`Rotation blast radius`,children:[(0,A.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Rotation blast radius`}),L?(0,A.jsxs)(A.Fragment,{children:[(0,A.jsx)(`p`,{className:`text-sm`,role:L.warn?`alert`:`status`,children:L.summary}),L.detail?(0,A.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:L.detail}):null,I.blastRadius.runIds.length>0?(0,A.jsx)(`p`,{className:`mt-1 font-mono text-xs text-[var(--oke-muted)]`,children:I.blastRadius.runIds.join(`, `)}):null]}):null]}),(0,A.jsxs)(`section`,{"aria-label":`Last read`,children:[(0,A.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Last read`}),(0,A.jsx)(`p`,{className:`text-sm`,role:`status`,children:I.lastReadAt==null?`Never read — possible dead secret`:new Date(I.lastReadAt).toISOString()})]}),(0,A.jsxs)(`section`,{"aria-label":`Set or rotate`,className:`space-y-3`,children:[(0,A.jsx)(`h3`,{className:`text-sm font-medium`,children:`Set / rotate`}),(0,A.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Write-only. Values are never revealed after submit. No preview.`}),(0,A.jsxs)(`div`,{className:`flex gap-2`,children:[(0,A.jsx)(f,{type:`button`,variant:B===`set`?`primary`:`ghost`,"aria-pressed":B===`set`,onClick:()=>j({...e,action:`set`}),children:`Set`}),(0,A.jsx)(f,{type:`button`,variant:B===`rotate`?`danger`:`ghost`,"aria-pressed":B===`rotate`,onClick:()=>j({...e,action:`rotate`}),children:`Rotate`})]}),B?(0,A.jsxs)(`div`,{className:`space-y-3 border border-[var(--oke-line)] p-3`,children:[(0,A.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,A.jsx)(`span`,{children:`New value`}),(0,A.jsx)(s,{"aria-label":`New vault value`,type:`password`,autoComplete:`off`,value:v,onChange:e=>y(e.currentTarget.value)})]}),(B===`rotate`||R.kind===`typed`)&&(0,A.jsxs)(A.Fragment,{children:[(0,A.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,A.jsxs)(`span`,{children:[`Type`,` `,B===`rotate`?z.kind===`typed`?z.phrase:`ROTATE`:R.kind===`typed`?R.phrase:`SET`,` `,`to confirm`]}),(0,A.jsx)(s,{"aria-label":`Confirmation phrase`,value:u,onChange:e=>d(e.currentTarget.value)})]}),(0,A.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,A.jsx)(`span`,{children:`Reason`}),(0,A.jsx)(s,{"aria-label":`Reason for vault write`,value:p,onChange:e=>g(e.currentTarget.value)})]})]}),(0,A.jsx)(f,{type:`button`,variant:B===`rotate`?`danger`:`primary`,disabled:!v||(B===`set`?V.isPending:H.isPending),onClick:()=>{B===`set`?V.mutate():H.mutate()},children:B===`set`?`Commit set`:`Commit rotate`}),(V.isError||H.isError)&&(0,A.jsx)(`p`,{role:`alert`,className:`text-sm text-[var(--oke-danger)]`,children:(V.error??H.error)?.message??`Failed`})]}):null]})]}):(0,A.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Select a contract to inspect fingerprints, resolution, and readers.`})})]})]})}var M=t({default:()=>j});export{y as n,M as t};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
7
7
|
<title>oke Console</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-ClX0ZCe5.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-B0Z9INg1.js">
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/style-C8MxEWPd.css">
|
|
11
11
|
</head>
|
|
@@ -58,14 +58,16 @@ export function Input({ className, ...props }: ComponentProps<typeof BaseInput>)
|
|
|
58
58
|
/**
|
|
59
59
|
* Field label + control.
|
|
60
60
|
*
|
|
61
|
-
* @param props - Label text, optional error, children
|
|
61
|
+
* @param props - Label text, optional hint/error, children
|
|
62
62
|
*/
|
|
63
63
|
export function Field({
|
|
64
64
|
label,
|
|
65
|
+
hint,
|
|
65
66
|
error,
|
|
66
67
|
children,
|
|
67
68
|
}: {
|
|
68
69
|
readonly label: string;
|
|
70
|
+
readonly hint?: string;
|
|
69
71
|
readonly error?: string;
|
|
70
72
|
readonly children: ReactNode;
|
|
71
73
|
}) {
|
|
@@ -77,6 +79,8 @@ export function Field({
|
|
|
77
79
|
<span role="alert" className="text-xs text-[var(--oke-danger)]">
|
|
78
80
|
{error}
|
|
79
81
|
</span>
|
|
82
|
+
) : hint ? (
|
|
83
|
+
<span className="text-xs text-[var(--oke-muted)]">{hint}</span>
|
|
80
84
|
) : null}
|
|
81
85
|
</label>
|
|
82
86
|
);
|
|
@@ -9,6 +9,27 @@ import { consoleCalls, setAccessToken } from "../client.ts";
|
|
|
9
9
|
import { OkeLogo } from "../components/oke-logo.tsx";
|
|
10
10
|
import { Button, Field, Input } from "../components/ui.tsx";
|
|
11
11
|
|
|
12
|
+
/** Prefer human message / reason over a bare error code. */
|
|
13
|
+
function clientErrorText(error: {
|
|
14
|
+
readonly code: string;
|
|
15
|
+
readonly message?: string;
|
|
16
|
+
readonly data?: unknown;
|
|
17
|
+
}): string {
|
|
18
|
+
if (typeof error.message === "string" && error.message.trim().length > 0) {
|
|
19
|
+
return error.message;
|
|
20
|
+
}
|
|
21
|
+
if (error.data !== null && typeof error.data === "object") {
|
|
22
|
+
const data = error.data as { message?: unknown; reason?: unknown };
|
|
23
|
+
if (typeof data.message === "string" && data.message.trim().length > 0) {
|
|
24
|
+
return data.message;
|
|
25
|
+
}
|
|
26
|
+
if (error.code === "TransportError" && typeof data.message === "string") {
|
|
27
|
+
return data.message;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return error.code;
|
|
31
|
+
}
|
|
32
|
+
|
|
12
33
|
/**
|
|
13
34
|
* Setup wizard page.
|
|
14
35
|
*/
|
|
@@ -18,7 +39,7 @@ export function SetupWizard() {
|
|
|
18
39
|
queryKey: ["console.setup.status"],
|
|
19
40
|
queryFn: async () => {
|
|
20
41
|
const res = await consoleCalls.setupStatus();
|
|
21
|
-
if (res.error) throw new Error(res.error
|
|
42
|
+
if (res.error) throw new Error(clientErrorText(res.error));
|
|
22
43
|
return res.data as { setupClosed: boolean; claimRequired: boolean };
|
|
23
44
|
},
|
|
24
45
|
});
|
|
@@ -37,7 +58,7 @@ export function SetupWizard() {
|
|
|
37
58
|
name,
|
|
38
59
|
password,
|
|
39
60
|
});
|
|
40
|
-
if (res.error) throw new Error(res.error
|
|
61
|
+
if (res.error) throw new Error(clientErrorText(res.error));
|
|
41
62
|
return res.data as { accessToken: string };
|
|
42
63
|
},
|
|
43
64
|
onSuccess: (data) => {
|
|
@@ -110,13 +131,13 @@ export function SetupWizard() {
|
|
|
110
131
|
required
|
|
111
132
|
/>
|
|
112
133
|
</Field>
|
|
113
|
-
<Field label="Password">
|
|
134
|
+
<Field label="Password" hint="At least 12 characters, with a letter and a number.">
|
|
114
135
|
<Input
|
|
115
136
|
name="password"
|
|
116
137
|
type="password"
|
|
117
138
|
value={password}
|
|
118
139
|
onValueChange={(v) => setPassword(String(v ?? ""))}
|
|
119
|
-
minLength={
|
|
140
|
+
minLength={12}
|
|
120
141
|
autoComplete="new-password"
|
|
121
142
|
required
|
|
122
143
|
/>
|
|
@@ -142,7 +163,7 @@ function LoginForm() {
|
|
|
142
163
|
const login = useMutation({
|
|
143
164
|
mutationFn: async () => {
|
|
144
165
|
const res = await consoleCalls.sessionLogin({ email, password });
|
|
145
|
-
if (res.error) throw new Error(res.error
|
|
166
|
+
if (res.error) throw new Error(clientErrorText(res.error));
|
|
146
167
|
return res.data as { accessToken: string };
|
|
147
168
|
},
|
|
148
169
|
onSuccess: (data) => {
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OKE docker stack discovery / selection helpers.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, expect, test } from "bun:test";
|
|
6
|
+
import { mkdtemp } from "node:fs/promises";
|
|
7
|
+
import { tmpdir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import {
|
|
10
|
+
composeProjectName,
|
|
11
|
+
downStack,
|
|
12
|
+
isOkeDevProject,
|
|
13
|
+
isOkeProjectRoot,
|
|
14
|
+
listOkeComposeProjects,
|
|
15
|
+
parseJsonRecords,
|
|
16
|
+
projectFromResourceName,
|
|
17
|
+
projectsFromContainerSelection,
|
|
18
|
+
resolveSelection,
|
|
19
|
+
selectionKey,
|
|
20
|
+
type DockerRunner,
|
|
21
|
+
type OkeContainer,
|
|
22
|
+
} from "./cleanup.ts";
|
|
23
|
+
import { stackAppSlug } from "./stack-id.ts";
|
|
24
|
+
|
|
25
|
+
describe("oke docker cleanup helpers", () => {
|
|
26
|
+
test("composeProjectName matches oke-${stackAppSlug}", async () => {
|
|
27
|
+
const dir = await mkdtemp(join(tmpdir(), "oke-clean-id-"));
|
|
28
|
+
expect(composeProjectName(dir)).toBe(`oke-${stackAppSlug(dir)}`);
|
|
29
|
+
expect(isOkeDevProject(composeProjectName(dir))).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("isOkeDevProject accepts only oke-dev-<6hex>", () => {
|
|
33
|
+
expect(isOkeDevProject("oke-dev-a3f791")).toBe(true);
|
|
34
|
+
expect(isOkeDevProject("oke-app")).toBe(false);
|
|
35
|
+
expect(isOkeDevProject("oke-dev-ABCDEF")).toBe(false);
|
|
36
|
+
expect(isOkeDevProject("other-dev-a3f791")).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("projectFromResourceName strips volume/network suffixes", () => {
|
|
40
|
+
expect(projectFromResourceName("oke-dev-a3f791_oke")).toBe("oke-dev-a3f791");
|
|
41
|
+
expect(projectFromResourceName("oke-dev-a3f791_store-sql-data")).toBe("oke-dev-a3f791");
|
|
42
|
+
expect(projectFromResourceName("oke-dev-a3f791")).toBe("oke-dev-a3f791");
|
|
43
|
+
expect(projectFromResourceName("bridge")).toBeNull();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("isOkeProjectRoot detects oke.config.ts", async () => {
|
|
47
|
+
const dir = await mkdtemp(join(tmpdir(), "oke-clean-root-"));
|
|
48
|
+
expect(await isOkeProjectRoot(dir)).toBe(false);
|
|
49
|
+
await Bun.write(join(dir, "oke.config.ts"), "export default {};\n");
|
|
50
|
+
expect(await isOkeProjectRoot(dir)).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("parseJsonRecords handles array and NDJSON", () => {
|
|
54
|
+
expect(parseJsonRecords('[{"Name":"a"},{"Name":"b"}]')).toEqual([{ Name: "a" }, { Name: "b" }]);
|
|
55
|
+
expect(parseJsonRecords('{"Name":"a"}\n{"Name":"b"}\n')).toEqual([
|
|
56
|
+
{ Name: "a" },
|
|
57
|
+
{ Name: "b" },
|
|
58
|
+
]);
|
|
59
|
+
expect(parseJsonRecords("")).toEqual([]);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("projectsFromContainerSelection dedupes", () => {
|
|
63
|
+
const containers: OkeContainer[] = [
|
|
64
|
+
{
|
|
65
|
+
id: "1",
|
|
66
|
+
name: "oke-dev-a3f791-store-sql-1",
|
|
67
|
+
service: "store-sql",
|
|
68
|
+
state: "running",
|
|
69
|
+
project: "oke-dev-a3f791",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: "2",
|
|
73
|
+
name: "oke-dev-a3f791-store-kv-1",
|
|
74
|
+
service: "store-kv",
|
|
75
|
+
state: "exited",
|
|
76
|
+
project: "oke-dev-a3f791",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "3",
|
|
80
|
+
name: "oke-dev-b0b0b0-store-sql-1",
|
|
81
|
+
service: "store-sql",
|
|
82
|
+
state: "running",
|
|
83
|
+
project: "oke-dev-b0b0b0",
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
expect(projectsFromContainerSelection(containers)).toEqual([
|
|
87
|
+
"oke-dev-a3f791",
|
|
88
|
+
"oke-dev-b0b0b0",
|
|
89
|
+
]);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("resolveSelection maps keys to projects", () => {
|
|
93
|
+
const stacks = [
|
|
94
|
+
{
|
|
95
|
+
project: "oke-dev-a3f791",
|
|
96
|
+
containers: [
|
|
97
|
+
{
|
|
98
|
+
id: "1",
|
|
99
|
+
name: "c1",
|
|
100
|
+
service: "store-sql",
|
|
101
|
+
state: "running",
|
|
102
|
+
project: "oke-dev-a3f791",
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
{ project: "oke-dev-b0b0b0", containers: [] },
|
|
107
|
+
];
|
|
108
|
+
const { projects, containers } = resolveSelection(
|
|
109
|
+
[selectionKey("oke-dev-a3f791", "c1"), selectionKey("oke-dev-b0b0b0")],
|
|
110
|
+
stacks,
|
|
111
|
+
);
|
|
112
|
+
expect(projects).toEqual(["oke-dev-a3f791", "oke-dev-b0b0b0"]);
|
|
113
|
+
expect(containers).toHaveLength(1);
|
|
114
|
+
expect(containers[0]!.name).toBe("c1");
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("listOkeComposeProjects merges compose ls + containers + volumes", async () => {
|
|
118
|
+
const run: DockerRunner = async (args) => {
|
|
119
|
+
const key = args.join(" ");
|
|
120
|
+
if (key.startsWith("compose ls")) {
|
|
121
|
+
return {
|
|
122
|
+
exitCode: 0,
|
|
123
|
+
stdout: JSON.stringify([{ Name: "oke-dev-aaaaaa", Status: "exited(1)" }]),
|
|
124
|
+
stderr: "",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
if (key.includes("label=com.docker.compose.project=") && key.startsWith("ps")) {
|
|
128
|
+
const filter = args[args.indexOf("--filter")! + 1]!;
|
|
129
|
+
const project = filter.replace(/^label=com\.docker\.compose\.project=/, "");
|
|
130
|
+
if (project === "oke-dev-bbbbbb") {
|
|
131
|
+
return {
|
|
132
|
+
exitCode: 0,
|
|
133
|
+
stdout: JSON.stringify({
|
|
134
|
+
ID: "x",
|
|
135
|
+
Names: "oke-dev-bbbbbb-store-sql-1",
|
|
136
|
+
State: "exited",
|
|
137
|
+
Labels:
|
|
138
|
+
"com.docker.compose.project=oke-dev-bbbbbb,com.docker.compose.service=store-sql",
|
|
139
|
+
}),
|
|
140
|
+
stderr: "",
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return { exitCode: 0, stdout: "", stderr: "" };
|
|
144
|
+
}
|
|
145
|
+
if (key.startsWith("ps -a --filter label=com.docker.compose.project --format")) {
|
|
146
|
+
return {
|
|
147
|
+
exitCode: 0,
|
|
148
|
+
stdout: JSON.stringify({
|
|
149
|
+
ID: "x",
|
|
150
|
+
Names: "oke-dev-bbbbbb-store-sql-1",
|
|
151
|
+
State: "exited",
|
|
152
|
+
Labels:
|
|
153
|
+
"com.docker.compose.project=oke-dev-bbbbbb,com.docker.compose.service=store-sql",
|
|
154
|
+
}),
|
|
155
|
+
stderr: "",
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (key.startsWith("volume ls")) {
|
|
159
|
+
return {
|
|
160
|
+
exitCode: 0,
|
|
161
|
+
stdout: JSON.stringify({ Name: "oke-dev-cccccc_store-files-data" }),
|
|
162
|
+
stderr: "",
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
if (key.startsWith("network ls")) {
|
|
166
|
+
return { exitCode: 0, stdout: "", stderr: "" };
|
|
167
|
+
}
|
|
168
|
+
return { exitCode: 1, stdout: "", stderr: `unexpected: ${key}` };
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const stacks = await listOkeComposeProjects(run);
|
|
172
|
+
expect(stacks.map((s) => s.project)).toEqual([
|
|
173
|
+
"oke-dev-aaaaaa",
|
|
174
|
+
"oke-dev-bbbbbb",
|
|
175
|
+
"oke-dev-cccccc",
|
|
176
|
+
]);
|
|
177
|
+
expect(stacks.find((s) => s.project === "oke-dev-bbbbbb")!.containers).toHaveLength(1);
|
|
178
|
+
expect(stacks.find((s) => s.project === "oke-dev-cccccc")!.containers).toHaveLength(0);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test("downStack refuses non-OKE names and runs down -v", async () => {
|
|
182
|
+
await expect(
|
|
183
|
+
downStack("evil", async () => ({ exitCode: 0, stdout: "", stderr: "" })),
|
|
184
|
+
).rejects.toThrow(/refusing/);
|
|
185
|
+
|
|
186
|
+
const calls: string[][] = [];
|
|
187
|
+
await downStack("oke-dev-a3f791", async (args) => {
|
|
188
|
+
calls.push([...args]);
|
|
189
|
+
return { exitCode: 0, stdout: "", stderr: "" };
|
|
190
|
+
});
|
|
191
|
+
expect(calls).toEqual([["compose", "-p", "oke-dev-a3f791", "down", "-v", "--remove-orphans"]]);
|
|
192
|
+
});
|
|
193
|
+
});
|