@sigmashake/ssg 0.24.3 → 0.24.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +14 -12
- package/public/assets/app.js +2 -2
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sigmashake/ssg",
|
|
3
|
-
"version": "0.24.
|
|
4
|
-
"description": "AI Agent Governance CLI
|
|
3
|
+
"version": "0.24.5",
|
|
4
|
+
"description": "AI Agent Governance CLI \u2014 evaluate tool calls against rules, block dangerous operations, and surface blocked commands",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"ssg": "bin/ssg.cjs"
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
"README.md"
|
|
14
14
|
],
|
|
15
15
|
"optionalDependencies": {
|
|
16
|
-
"@sigmashake/ssg-linux-x64": "0.24.
|
|
17
|
-
"@sigmashake/ssg-linux-arm64": "0.24.
|
|
18
|
-
"@sigmashake/ssg-darwin-arm64": "0.24.
|
|
19
|
-
"@sigmashake/ssg-darwin-x64": "0.24.
|
|
20
|
-
"@sigmashake/ssg-win32-x64": "0.24.
|
|
16
|
+
"@sigmashake/ssg-linux-x64": "0.24.5",
|
|
17
|
+
"@sigmashake/ssg-linux-arm64": "0.24.5",
|
|
18
|
+
"@sigmashake/ssg-darwin-arm64": "0.24.5",
|
|
19
|
+
"@sigmashake/ssg-darwin-x64": "0.24.5",
|
|
20
|
+
"@sigmashake/ssg-win32-x64": "0.24.5"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"postinstall": "node ./bin/cleanup-globals.cjs",
|
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
"typecheck:client": "tsc --noEmit -p tsconfig.client.json",
|
|
40
40
|
"test": "bun test",
|
|
41
41
|
"test:e2e": "SSG_E2E=1 bun test test/dashboard-e2e.test.ts",
|
|
42
|
+
"test:e2e:agents": "bun run scripts/e2e-agents.ts",
|
|
43
|
+
"test:e2e:session-record": "bun run scripts/record-agent-session.ts",
|
|
42
44
|
"lint": "bun run src/cli.ts lint",
|
|
43
45
|
"sast:check": "npx gts check src/shared/daemon-metrics.ts src/engine/config.ts src/server/store.ts src/server/handlers/core.ts src/engine/config.ts",
|
|
44
46
|
"gts-lint": "gts lint",
|
|
@@ -67,11 +69,11 @@
|
|
|
67
69
|
"build:rust": "cd native/rust && cargo build --release",
|
|
68
70
|
"test:rust": "cd native/rust && cargo test",
|
|
69
71
|
"build:native": "bun run build:rust && cd native && zig build -Doptimize=ReleaseFast",
|
|
70
|
-
"build:native:linux-x64": "cd native/rust && cargo build --release --target x86_64-unknown-linux-gnu && cd .. && zig build -Doptimize=ReleaseFast -Dtarget=x86_64-linux-gnu -Drust-target=x86_64-unknown-linux-gnu && mkdir -p zig-out/lib/linux-x64 && cp zig-out/lib/libssg_eval.so zig-out/lib/linux-x64/ && cp zig-out/bin/ssg-hook-fast zig-out/lib/linux-x64/ && cd rust-sidecar && cargo zigbuild --release --bin ssg-eval-server --target x86_64-unknown-linux-gnu && cd .. && cp rust-sidecar/target/x86_64-unknown-linux-gnu/release/ssg-eval-server zig-out/lib/linux-x64/",
|
|
71
|
-
"build:native:linux-arm64": "cd native/rust && cargo build --release --target aarch64-unknown-linux-gnu && cd .. && zig build -Doptimize=ReleaseFast -Dtarget=aarch64-linux-gnu -Drust-target=aarch64-unknown-linux-gnu && mkdir -p zig-out/lib/linux-arm64 && cp zig-out/lib/libssg_eval.so zig-out/lib/linux-arm64/ && cp zig-out/bin/ssg-hook-fast zig-out/lib/linux-arm64/ && cd rust-sidecar && cargo zigbuild --release --bin ssg-eval-server --target aarch64-unknown-linux-gnu && cd .. && cp rust-sidecar/target/aarch64-unknown-linux-gnu/release/ssg-eval-server zig-out/lib/linux-arm64/",
|
|
72
|
-
"build:native:darwin-arm64": "cd native/rust && cargo build --release --target aarch64-apple-darwin && cd .. && zig build -Doptimize=ReleaseFast -Dtarget=aarch64-macos -Drust-target=aarch64-apple-darwin && mkdir -p zig-out/lib/darwin-arm64 && cp zig-out/lib/libssg_eval.dylib zig-out/lib/darwin-arm64/ && cp zig-out/bin/ssg-hook-fast zig-out/lib/darwin-arm64/ && cd rust-sidecar && cargo zigbuild --release --bin ssg-eval-server --target aarch64-apple-darwin && cd .. && cp rust-sidecar/target/aarch64-apple-darwin/release/ssg-eval-server zig-out/lib/darwin-arm64/",
|
|
73
|
-
"build:native:darwin-x64": "cd native/rust && cargo build --release --target x86_64-apple-darwin && cd .. && zig build -Doptimize=ReleaseFast -Dtarget=x86_64-macos -Drust-target=x86_64-apple-darwin && mkdir -p zig-out/lib/darwin-x64 && cp zig-out/lib/libssg_eval.dylib zig-out/lib/darwin-x64/ && cp zig-out/bin/ssg-hook-fast zig-out/lib/darwin-x64/ && cd rust-sidecar && cargo zigbuild --release --bin ssg-eval-server --target x86_64-apple-darwin && cd .. && cp rust-sidecar/target/x86_64-apple-darwin/release/ssg-eval-server zig-out/lib/darwin-x64/",
|
|
74
|
-
"build:native:windows": "cd native/rust && cargo build --release --target x86_64-pc-windows-gnu && cd .. && zig build -Doptimize=ReleaseFast -Dtarget=x86_64-windows-gnu -Drust-target=x86_64-pc-windows-gnu && mkdir -p zig-out/lib/win32-x64 && cp zig-out/bin/ssg_eval.dll zig-out/lib/win32-x64/libssg_eval.dll && cd rust-sidecar && cargo zigbuild --release --bin ssg-eval-server --target x86_64-pc-windows-gnu && cd .. && cp rust-sidecar/target/x86_64-pc-windows-gnu/release/ssg-eval-server.exe zig-out/lib/win32-x64/",
|
|
72
|
+
"build:native:linux-x64": "cd native/rust && cargo build --release --target x86_64-unknown-linux-gnu && cd .. && zig build -Doptimize=ReleaseFast -Dtarget=x86_64-linux-gnu -Drust-target=x86_64-unknown-linux-gnu --prefix zig-out/linux-x64 && mkdir -p zig-out/lib/linux-x64 && cp zig-out/linux-x64/lib/libssg_eval.so zig-out/lib/linux-x64/ && cp zig-out/linux-x64/bin/ssg-hook-fast zig-out/lib/linux-x64/ && cd rust-sidecar && cargo zigbuild --release --bin ssg-eval-server --target x86_64-unknown-linux-gnu && cd .. && cp rust-sidecar/target/x86_64-unknown-linux-gnu/release/ssg-eval-server zig-out/lib/linux-x64/",
|
|
73
|
+
"build:native:linux-arm64": "cd native/rust && cargo build --release --target aarch64-unknown-linux-gnu && cd .. && zig build -Doptimize=ReleaseFast -Dtarget=aarch64-linux-gnu -Drust-target=aarch64-unknown-linux-gnu --prefix zig-out/linux-arm64 && mkdir -p zig-out/lib/linux-arm64 && cp zig-out/linux-arm64/lib/libssg_eval.so zig-out/lib/linux-arm64/ && cp zig-out/linux-arm64/bin/ssg-hook-fast zig-out/lib/linux-arm64/ && cd rust-sidecar && cargo zigbuild --release --bin ssg-eval-server --target aarch64-unknown-linux-gnu && cd .. && cp rust-sidecar/target/aarch64-unknown-linux-gnu/release/ssg-eval-server zig-out/lib/linux-arm64/",
|
|
74
|
+
"build:native:darwin-arm64": "cd native/rust && cargo build --release --target aarch64-apple-darwin && cd .. && zig build -Doptimize=ReleaseFast -Dtarget=aarch64-macos -Drust-target=aarch64-apple-darwin --prefix zig-out/darwin-arm64 && mkdir -p zig-out/lib/darwin-arm64 && cp zig-out/darwin-arm64/lib/libssg_eval.dylib zig-out/lib/darwin-arm64/ && cp zig-out/darwin-arm64/bin/ssg-hook-fast zig-out/lib/darwin-arm64/ && cd rust-sidecar && cargo zigbuild --release --bin ssg-eval-server --target aarch64-apple-darwin && cd .. && cp rust-sidecar/target/aarch64-apple-darwin/release/ssg-eval-server zig-out/lib/darwin-arm64/",
|
|
75
|
+
"build:native:darwin-x64": "cd native/rust && cargo build --release --target x86_64-apple-darwin && cd .. && zig build -Doptimize=ReleaseFast -Dtarget=x86_64-macos -Drust-target=x86_64-apple-darwin --prefix zig-out/darwin-x64 && mkdir -p zig-out/lib/darwin-x64 && cp zig-out/darwin-x64/lib/libssg_eval.dylib zig-out/lib/darwin-x64/ && cp zig-out/darwin-x64/bin/ssg-hook-fast zig-out/lib/darwin-x64/ && cd rust-sidecar && cargo zigbuild --release --bin ssg-eval-server --target x86_64-apple-darwin && cd .. && cp rust-sidecar/target/x86_64-apple-darwin/release/ssg-eval-server zig-out/lib/darwin-x64/",
|
|
76
|
+
"build:native:windows": "cd native/rust && cargo build --release --target x86_64-pc-windows-gnu && cd .. && zig build -Doptimize=ReleaseFast -Dtarget=x86_64-windows-gnu -Drust-target=x86_64-pc-windows-gnu --prefix zig-out/win32-x64 && mkdir -p zig-out/lib/win32-x64 && cp zig-out/win32-x64/bin/ssg_eval.dll zig-out/lib/win32-x64/libssg_eval.dll && cd rust-sidecar && cargo zigbuild --release --bin ssg-eval-server --target x86_64-pc-windows-gnu && cd .. && cp rust-sidecar/target/x86_64-pc-windows-gnu/release/ssg-eval-server.exe zig-out/lib/win32-x64/",
|
|
75
77
|
"build:native:all": "bash ../sigmashake-dist/scripts/build-native-all.sh"
|
|
76
78
|
},
|
|
77
79
|
"keywords": [
|
package/public/assets/app.js
CHANGED
|
@@ -15,5 +15,5 @@ Error generating stack: `+e.message+`
|
|
|
15
15
|
${S.type===`ok`?`bg-green-500/10 border-green-500/20 text-green-400`:`bg-red-500/10 border-red-500/20 text-red-400`}`,children:[(0,I.jsxs)(`span`,{children:[S.type===`ok`?`✓ `:`✗ `,S.msg]}),(0,I.jsx)(`button`,{onClick:()=>C(null),className:`ml-3 opacity-60 hover:opacity-100 cursor-pointer`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,I.jsxs)(`div`,{className:`flex items-center bg-[#0d0d0d] border border-[#1c1c1c] rounded-lg p-0.5 shrink-0`,children:[(0,I.jsx)(`button`,{onClick:()=>l(`all`),className:`px-3 h-6 rounded-md text-[11px] font-medium transition-all cursor-pointer
|
|
16
16
|
${c===`all`?`bg-[#1e1e1e] text-white`:`text-[#555] hover:text-[#888]`}`,children:`All`}),(0,I.jsxs)(`button`,{onClick:()=>l(`installed`),className:`px-3 h-6 rounded-md text-[11px] font-medium transition-all cursor-pointer flex items-center gap-1.5
|
|
17
17
|
${c===`installed`?`bg-[#1e1e1e] text-white`:`text-[#555] hover:text-[#888]`}`,children:[`Installed`,ie>0&&(0,I.jsx)(`span`,{className:`text-[9px] bg-green-500/20 text-green-400 rounded-full px-1.5 py-0.5 font-bold`,children:ie})]})]}),(0,I.jsxs)(`div`,{className:`relative flex-1 min-w-[160px]`,children:[(0,I.jsxs)(`svg`,{className:`absolute left-2.5 top-1/2 -translate-y-1/2 text-[#444]`,width:`11`,height:`11`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:[(0,I.jsx)(`circle`,{cx:`11`,cy:`11`,r:`8`}),(0,I.jsx)(`line`,{x1:`21`,y1:`21`,x2:`16.65`,y2:`16.65`})]}),(0,I.jsx)(`input`,{type:`text`,placeholder:`Search rulesets…`,value:e,onChange:e=>t(e.target.value),className:`w-full bg-[#0d0d0d] border border-[#1c1c1c] text-[#aaa] text-xs rounded-lg pl-8 pr-3 h-8 focus:outline-none focus:border-[#333] placeholder:text-[#333]`})]}),(0,I.jsx)(`select`,{value:n,onChange:e=>r(e.target.value),className:`bg-[#0d0d0d] border border-[#1c1c1c] text-[#666] text-[11px] rounded-lg px-2.5 h-8 focus:outline-none focus:border-[#333] cursor-pointer`,children:Gn.map(e=>(0,I.jsx)(`option`,{value:e.value,children:e.label},e.value))}),(0,I.jsxs)(`select`,{value:i,onChange:e=>a(e.target.value),className:`bg-[#0d0d0d] border border-[#1c1c1c] text-[#666] text-[11px] rounded-lg px-2.5 h-8 focus:outline-none focus:border-[#333] cursor-pointer`,children:[(0,I.jsx)(`option`,{value:``,children:`Any decision`}),qn.filter(Boolean).map(e=>(0,I.jsx)(`option`,{value:e,children:e},e))]}),(0,I.jsxs)(`select`,{value:o,onChange:e=>s(e.target.value),className:`bg-[#0d0d0d] border border-[#1c1c1c] text-[#666] text-[11px] rounded-lg px-2.5 h-8 focus:outline-none focus:border-[#333] cursor-pointer`,children:[(0,I.jsx)(`option`,{value:``,children:`Any severity`}),Kn.filter(Boolean).map(e=>(0,I.jsx)(`option`,{value:e,children:e},e))]})]}),g&&u.length===0?(0,I.jsx)(`div`,{className:`grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3`,children:Array.from({length:6}).map((e,t)=>(0,I.jsx)(Jn,{},t))}):re.length===0?(0,I.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-16 text-center`,children:[(0,I.jsxs)(`svg`,{className:`text-[#222] mb-3`,width:`40`,height:`40`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.5`,children:[(0,I.jsx)(`circle`,{cx:`11`,cy:`11`,r:`8`}),(0,I.jsx)(`line`,{x1:`21`,y1:`21`,x2:`16.65`,y2:`16.65`})]}),(0,I.jsx)(`p`,{className:`text-sm text-[#444]`,children:c===`installed`?`No rulesets installed yet. Browse the hub and click Install.`:`No rulesets found${e?` matching "${e}"`:``}.`})]}):(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`div`,{className:`grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3`,children:re.map(e=>(0,I.jsx)(Xn,{rs:e,installingId:y,onInstall:T,flashId:x},e.id))}),f&&c===`all`&&(0,I.jsx)(`div`,{className:`flex justify-center pt-2`,children:(0,I.jsx)(`button`,{onClick:te,disabled:g,className:`h-8 px-5 rounded-lg text-xs font-medium text-[#666] border border-[#1c1c1c] hover:text-[#aaa] hover:border-[#2a2a2a] transition-all cursor-pointer disabled:opacity-40`,children:g?`Loading…`:`Load more`})})]})]})}var Qn={deny:`red`,block:`red`,ask:`amber`,allow:`green`,log:`gray`,force:`blue`};function $n({id:e}){let{data:t,error:n}=E(`/api/json/hub/${e}`),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(!1);if(n)return(0,I.jsxs)(`div`,{className:`text-sm text-red-400`,children:[(0,I.jsx)(`p`,{children:n}),(0,I.jsx)(`a`,{href:`/hub`,className:`text-amber-400 hover:underline mt-2 block`,children:`← Back to Hub`})]});if(!t)return(0,I.jsx)(`p`,{className:`text-sm text-[#555]`,children:`Loading ruleset…`});async function s(){o(!0);try{(await fetch(`/api/hub/install`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({id:e})})).ok&&i(!0)}finally{o(!1)}}return(0,I.jsxs)(`div`,{className:`space-y-6`,children:[(0,I.jsxs)(`div`,{className:`flex items-start justify-between gap-4`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`a`,{href:`/hub`,className:`text-xs text-[#555] hover:text-amber-400`,children:`← Hub`}),(0,I.jsx)(`h1`,{className:`text-xl font-semibold mt-1`,children:t.title}),(0,I.jsxs)(`p`,{className:`text-sm text-[#555] mt-0.5`,children:[`by `,t.author,` · v`,t.version,` ·`,` `,t.rule_count,` rule`,t.rule_count===1?``:`s`]})]}),(0,I.jsx)(zt,{variant:r?`secondary`:`primary`,onClick:s,disabled:a||r,children:r?`Installed`:a?`Installing…`:`Install`})]}),t.technologies.length>0&&(0,I.jsx)(`div`,{className:`flex flex-wrap gap-1.5`,children:t.technologies.map(e=>(0,I.jsx)(Lt,{variant:`blue`,children:e},e))}),t.github_repo&&(0,I.jsxs)(`p`,{className:`text-xs text-[#555]`,children:[`Source:`,` `,(0,I.jsx)(`span`,{className:`text-[#888]`,children:t.github_repo})]}),(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{children:(0,I.jsxs)(`span`,{className:`text-sm font-medium`,children:[`Rules (`,t.rules.length,`)`]})}),(0,I.jsx)(z,{className:`pt-0 space-y-4`,children:t.rules.map(e=>(0,I.jsxs)(`div`,{className:`border-t border-[#1a1a1a] pt-4 first:border-t-0 first:pt-0`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2 mb-2`,children:[(0,I.jsx)(Lt,{variant:Qn[e.decision]??`gray`,children:e.decision}),(0,I.jsx)(`code`,{className:`text-xs text-amber-400`,children:e.name}),e.capability&&(0,I.jsx)(Lt,{variant:`gray`,children:e.capability})]}),(0,I.jsx)(`p`,{className:`text-sm text-[#aaa] mb-2`,children:e.message}),(0,I.jsx)(Jt,{children:e.raw_text})]},e.id))})]})]})}function er(){let[e,t]=(0,_.useState)(null),[n,r]=(0,_.useState)(`idle`),[i,a]=(0,_.useState)(``),[o,s]=(0,_.useState)([]),[c,l]=(0,_.useState)(!1);async function u(){l(!0),a(``);try{let e=await fetch(`/api/hub/device-start`,{method:`POST`,headers:{Accept:`application/json`}}),n=await e.json();if(!e.ok){let t=n;t.error===`not_configured`?(r(`not_configured`),s(t.setup_steps??[]),a(t.message??`GitHub OAuth not configured.`)):(a(n.error??`HTTP ${e.status}`),r(`error`));return}t(n),r(`polling`)}catch(e){a(e instanceof Error?e.message:`Failed to start`),r(`error`)}finally{l(!1)}}return(0,_.useEffect)(()=>{if(n!==`polling`||!e)return;let t=setInterval(async()=>{try{let n=await(await fetch(`/api/hub/device-poll?flow=${e.flow_id}`,{headers:{Accept:`application/json`}})).json();n.status===`complete`?(clearInterval(t),r(`done`),a(`Connected as @${n.session?.login??`GitHub`}! You can now publish rulesets.`)):(n.status===`expired`||n.status===`error`)&&(clearInterval(t),r(`error`),a(n.error??`Authentication failed`))}catch{}},3e3);return()=>clearInterval(t)},[n,e]),(0,I.jsxs)(`div`,{className:`max-w-lg mx-auto space-y-5`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsxs)(`a`,{href:`/hub`,className:`inline-flex items-center gap-1.5 text-xs text-[#444] hover:text-amber-400 transition-colors mb-3`,children:[(0,I.jsx)(`svg`,{width:`11`,height:`11`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:(0,I.jsx)(`polyline`,{points:`15 18 9 12 15 6`})}),`Back to Hub`]}),(0,I.jsx)(`h1`,{className:`text-base font-semibold`,children:`Connect GitHub`}),(0,I.jsx)(`p`,{className:`text-xs text-[#444] mt-0.5`,children:`Authenticate with GitHub to publish rulesets to the Hub.`})]}),n===`not_configured`&&(0,I.jsx)(L,{children:(0,I.jsxs)(z,{className:`py-5 space-y-4`,children:[(0,I.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,I.jsx)(`span`,{className:`text-amber-400 shrink-0 mt-0.5`,children:(0,I.jsxs)(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:[(0,I.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,I.jsx)(`line`,{x1:`12`,y1:`8`,x2:`12`,y2:`12`}),(0,I.jsx)(`line`,{x1:`12`,y1:`16`,x2:`12.01`,y2:`16`})]})}),(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`p`,{className:`text-sm font-medium text-[#ccc]`,children:`GitHub OAuth not configured`}),(0,I.jsx)(`p`,{className:`text-xs text-[#555] mt-1 leading-relaxed`,children:i})]})]}),(0,I.jsxs)(`div`,{className:`border-t border-[#111] pt-4`,children:[(0,I.jsx)(`p`,{className:`text-xs font-medium text-[#888] mb-3`,children:`Setup steps:`}),(0,I.jsx)(`ol`,{className:`space-y-2`,children:o.map((e,t)=>(0,I.jsxs)(`li`,{className:`flex items-start gap-2.5 text-xs text-[#555]`,children:[(0,I.jsx)(`span`,{className:`shrink-0 w-5 h-5 rounded-full bg-[#1a1a1a] border border-[#222] text-[#444] text-[10px] flex items-center justify-center font-medium`,children:t+1}),(0,I.jsx)(`span`,{className:`mt-0.5 leading-relaxed`,children:e.replace(/^\d+\.\s+/,``)})]},t))})]}),(0,I.jsxs)(`div`,{className:`bg-[#0a0a0a] border border-[#1a1a1a] rounded-lg p-3`,children:[(0,I.jsx)(`p`,{className:`text-[10px] text-[#333] mb-1.5 uppercase tracking-wide font-medium`,children:`Quick start`}),(0,I.jsx)(`code`,{className:`text-[11px] text-amber-400/80 font-mono`,children:`export SSG_GITHUB_CLIENT_ID=<your-client-id>`}),(0,I.jsxs)(`p`,{className:`text-[11px] text-[#444] mt-1`,children:[`Then restart: `,(0,I.jsx)(`code`,{className:`text-[#666]`,children:`ssg serve`})]})]}),(0,I.jsx)(`a`,{href:`https://github.com/settings/applications/new`,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1.5 text-xs text-amber-400 hover:underline`,children:`Create GitHub OAuth App →`})]})}),n===`idle`&&(0,I.jsx)(L,{children:(0,I.jsxs)(z,{className:`py-5`,children:[(0,I.jsx)(`p`,{className:`text-xs text-[#555] mb-4 leading-relaxed`,children:`This uses GitHub's device authorization flow — no redirect URIs needed. You'll be shown a code to enter at github.com.`}),(0,I.jsx)(zt,{onClick:u,disabled:c,variant:`primary`,children:c?`Starting…`:`Connect with GitHub`})]})}),e&&n===`polling`&&(0,I.jsx)(L,{children:(0,I.jsxs)(z,{className:`py-5 space-y-4`,children:[(0,I.jsxs)(`div`,{className:`text-center`,children:[(0,I.jsx)(`p`,{className:`text-xs text-[#555] mb-2`,children:`Open this URL in your browser:`}),(0,I.jsx)(`a`,{href:e.verification_uri,target:`_blank`,rel:`noreferrer`,className:`text-sm text-amber-400 hover:underline font-mono`,children:e.verification_uri})]}),(0,I.jsxs)(`div`,{className:`border border-[#222] bg-[#0d0d0d] rounded-xl py-5 text-center`,children:[(0,I.jsx)(`p`,{className:`text-[10px] text-[#444] uppercase tracking-widest mb-2`,children:`Enter this code`}),(0,I.jsx)(`div`,{className:`text-4xl font-mono font-bold tracking-[0.25em] text-white`,children:e.user_code})]}),(0,I.jsxs)(`p`,{className:`text-[11px] text-[#444] text-center flex items-center justify-center gap-2`,children:[(0,I.jsx)(`svg`,{className:`animate-spin text-[#333]`,width:`11`,height:`11`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,children:(0,I.jsx)(`path`,{d:`M21 12a9 9 0 1 1-6.219-8.56`})}),`Waiting for GitHub authorization…`]})]})}),n===`done`&&(0,I.jsxs)(`div`,{className:`rounded-xl border border-green-500/20 bg-green-500/5 p-5 text-sm text-green-400 space-y-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,children:(0,I.jsx)(`polyline`,{points:`20 6 9 17 4 12`})}),(0,I.jsx)(`span`,{children:i})]}),(0,I.jsx)(`a`,{href:`/hub/publish`,className:`text-xs text-amber-400 hover:underline block mt-1`,children:`Publish a ruleset →`})]}),n===`error`&&i&&(0,I.jsxs)(`div`,{className:`rounded-xl border border-red-500/20 bg-red-500/5 p-4`,children:[(0,I.jsx)(`p`,{className:`text-sm text-red-400`,children:i}),(0,I.jsx)(`button`,{onClick:()=>{r(`idle`),a(``)},className:`text-xs text-[#555] hover:text-[#888] mt-3 cursor-pointer`,children:`← Try again`})]})]})}function tr(){let[e,t]=(0,_.useState)(``),[n,r]=(0,_.useState)(!1),[i,a]=(0,_.useState)(null);async function o(t){if(t.preventDefault(),e.trim()){r(!0),a(null);try{a(await(await fetch(`/api/hub/publish`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({repo_url:e.trim()})})).json())}catch(e){a({ok:!1,error:e instanceof Error?e.message:`Unknown error`})}finally{r(!1)}}}return(0,I.jsxs)(`div`,{className:`max-w-md mx-auto space-y-6`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`a`,{href:`/hub`,className:`text-xs text-[#555] hover:text-amber-400`,children:`← Hub`}),(0,I.jsx)(`h1`,{className:`text-xl font-semibold mt-1`,children:`Publish Ruleset`}),(0,I.jsx)(`p`,{className:`text-sm text-[#555] mt-1`,children:`Publish a GitHub repository containing .rules files to the Hub.`})]}),(0,I.jsx)(L,{children:(0,I.jsx)(z,{className:`py-4`,children:(0,I.jsxs)(`form`,{onSubmit:o,className:`space-y-4`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`label`,{className:`block text-xs text-[#888] mb-1`,children:`GitHub Repository URL`}),(0,I.jsx)(`input`,{type:`url`,placeholder:`https://github.com/owner/repo`,value:e,onChange:e=>t(e.target.value),required:!0,className:`w-full bg-[#0a0a0a] border border-[#222] text-[#ddd] text-sm rounded px-3 py-2 focus:outline-none focus:border-amber-400 placeholder:text-[#444]`})]}),(0,I.jsx)(zt,{type:`submit`,variant:`primary`,disabled:n,children:n?`Publishing…`:`Publish to Hub`})]})})}),i&&(0,I.jsx)(`div`,{className:`text-sm ${i.ok?`text-green-400`:`text-red-400`}`,children:i.ok?(0,I.jsxs)(I.Fragment,{children:[`Published!`,` `,i.id&&(0,I.jsx)(`a`,{href:`/hub/${i.id}`,className:`text-amber-400 hover:underline`,children:`View ruleset →`})]}):i.error??`Publish failed`})]})}function nr(e){return e===0?`—`:e<1e3?`${e}ns`:e<1e6?`${(e/1e3).toFixed(1)}µs`:`${(e/1e6).toFixed(1)}ms`}function rr(e){let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m ${t%60}s`:`${Math.floor(n/60)}h ${n%60}m`}function ir(e){let t=e<1e10?e*1e3:e,n=new Date(t);return`${String(n.getHours()).padStart(2,`0`)}:${String(n.getMinutes()).padStart(2,`0`)}:${String(n.getSeconds()).padStart(2,`0`)}`}function ar(e){let t=Math.round((Date.now()-e)/1e3);if(t<5)return`just now`;if(t<60)return`${t}s ago`;let n=Math.floor(t/60);return n<60?`${n}m ago`:`${Math.floor(n/60)}h ago`}function or({label:e,value:t,sub:n,accent:r}){return(0,I.jsxs)(`div`,{className:`bg-[#111] border border-[#222] rounded p-3`,children:[(0,I.jsx)(`div`,{className:`text-[10px] text-[#555] uppercase tracking-wider mb-1`,children:e}),(0,I.jsx)(`div`,{className:`text-xl font-mono font-semibold ${r??`text-[#e0e0e0]`}`,children:t}),n&&(0,I.jsx)(`div`,{className:`text-[10px] text-[#555] mt-0.5`,children:n})]})}var sr={allow:`text-green-400`,block:`text-red-400`,force:`text-purple-400`,log:`text-yellow-400`,ask:`text-cyan-400`,shadow:`text-[#666]`},cr={allow:`✓`,block:`✗`,force:`→`,log:`·`,ask:`?`,shadow:`~`};function lr({label:e,ns:t,maxNs:n}){let r=n>0?Math.min(100,t/n*100):0;return(0,I.jsxs)(`div`,{className:`flex items-center gap-2 text-xs`,children:[(0,I.jsx)(`span`,{className:`text-[#555] w-7 text-right`,children:e}),(0,I.jsx)(`div`,{className:`flex-1 bg-[#1a1a1a] rounded-full h-1.5 overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full rounded-full transition-all duration-300 ${t<1e5?`bg-green-500`:t<1e6?`bg-yellow-500`:`bg-red-500`}`,style:{width:`${r}%`}})}),(0,I.jsx)(`span`,{className:`font-mono text-[#aaa] w-14 text-right`,children:nr(t)})]})}function ur({value:e,max:t,threshold:n,breached:r}){let i=t>0?Math.min(100,e/t*100):0,a=t>0?Math.min(100,n/t*100):0;return(0,I.jsxs)(`div`,{className:`relative w-full bg-[#1a1a1a] rounded-full h-1.5`,children:[(0,I.jsx)(`div`,{className:`h-full rounded-full transition-all duration-500 ${r?`bg-red-500`:e/t>=.6?`bg-yellow-500`:`bg-green-500`}`,style:{width:`${i}%`}}),(0,I.jsx)(`div`,{className:`absolute top-0 h-full w-0.5 bg-amber-400/60`,style:{left:`${a}%`},title:`Limit: ${n}`})]})}function dr({limitsData:e,onSaved:t}){let[n,r]=(0,_.useState)(String(e.config.cpuLimitPct)),[i,a]=(0,_.useState)(String(e.config.memoryLimitMb)),[o,s]=(0,_.useState)(e.config.breachAction),[c,l]=(0,_.useState)(!1),[u,d]=(0,_.useState)(null);async function f(){l(!0),d(null);try{let e=await fetch(`/api/json/limits`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({cpu_limit_pct:parseFloat(n),memory_limit_mb:parseFloat(i),breach_action:o})});e.ok?t():d((await e.json()).error??`Save failed`)}catch{d(`Network error`)}finally{l(!1)}}return(0,I.jsxs)(`div`,{className:`space-y-3 text-xs`,children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`label`,{className:`text-[#555] block mb-1`,children:`CPU Limit (%)`}),(0,I.jsx)(`input`,{type:`number`,min:1,max:100,value:n,onChange:e=>r(e.target.value),className:`w-full bg-[#0a0a0a] border border-[#333] rounded px-2 py-1 text-[#e0e0e0] font-mono focus:outline-none focus:border-amber-500`})]}),(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`label`,{className:`text-[#555] block mb-1`,children:`Memory Limit (MB)`}),(0,I.jsx)(`input`,{type:`number`,min:1,value:i,onChange:e=>a(e.target.value),className:`w-full bg-[#0a0a0a] border border-[#333] rounded px-2 py-1 text-[#e0e0e0] font-mono focus:outline-none focus:border-amber-500`})]})]}),(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`label`,{className:`text-[#555] block mb-1`,children:`On breach`}),(0,I.jsxs)(`select`,{value:o,onChange:e=>s(e.target.value),className:`bg-[#0a0a0a] border border-[#333] rounded px-2 py-1 text-[#e0e0e0] focus:outline-none focus:border-amber-500`,children:[(0,I.jsx)(`option`,{value:`warn`,children:`Warn in UI only`}),(0,I.jsx)(`option`,{value:`log`,children:`Warn + write to audit log`})]})]}),u&&(0,I.jsx)(`p`,{className:`text-red-400`,children:u}),(0,I.jsx)(`button`,{onClick:f,disabled:c,className:`px-3 py-1.5 bg-amber-500 hover:bg-amber-400 disabled:opacity-50 text-black rounded text-xs font-medium transition-colors`,children:c?`Saving…`:`Save limits`})]})}function fr(){let e=se([`metrics-tick`,`audit-changed`,`limits-breach`]),[t,n]=(0,_.useState)(Date.now()),[r,i]=(0,_.useState)(0),[a,o]=(0,_.useState)([]),[s,c]=(0,_.useState)(0),[l,u]=(0,_.useState)(!1),d=(0,_.useRef)(null);(0,_.useEffect)(()=>{let e=setInterval(()=>n(Date.now()),1e3);return()=>clearInterval(e)},[]);let{data:f}=E(`/api/json/daemon-metrics`,[e[`metrics-tick`]]),{data:p,refetch:m}=E(`/api/json/limits`,[e[`limits-breach`]]),{data:h}=E(`/api/json/audit-tail?after=${r}&limit=50`,[e[`audit-changed`],e[`metrics-tick`]]);(0,_.useEffect)(()=>{h&&h.rows.length>0&&(i(e=>Math.max(e,h.maxId)),o(e=>{let t=new Set(e.map(e=>e.id));return[...h.rows.filter(e=>!t.has(e.id)),...e].slice(0,100)}))},[h]),(0,_.useEffect)(()=>{let e=f!==null;d.current===!1&&e&&c(e=>e+1),d.current=e},[f]);let g=f?rr(f.uptime_ms):null,v=f&&f.last_eval_at>0?ar(f.last_eval_at):null,y=f?p?.breaches.cpu?`text-red-400`:(f.cpu_pct??0)>=60?`text-yellow-400`:`text-green-400`:`text-[#e0e0e0]`,b=p?.breaches.memory?`text-red-400`:`text-[#e0e0e0]`;return(0,I.jsxs)(`div`,{className:`space-y-4`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,I.jsx)(`h1`,{className:`text-base font-semibold`,children:`Daemon Monitor`}),(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[s>0&&(0,I.jsxs)(Lt,{variant:`amber`,children:[s,` restart`,s===1?``:`s`]}),(0,I.jsx)(`span`,{className:`text-xs text-[#444] font-mono`,children:ir(t)})]})]}),p&&(p.breaches.cpu||p.breaches.memory)&&(0,I.jsxs)(`div`,{className:`border border-red-500/30 bg-red-500/5 rounded p-3 text-xs flex items-start gap-2`,children:[(0,I.jsx)(`span`,{className:`text-red-400 shrink-0`,children:`⚠`}),(0,I.jsxs)(`div`,{className:`space-y-0.5`,children:[p.breaches.cpu&&(0,I.jsxs)(`div`,{className:`text-red-300`,children:[`CPU limit exceeded: `,f?.cpu_pct??`?`,`% >`,` `,p.config.cpuLimitPct,`%`]}),p.breaches.memory&&(0,I.jsxs)(`div`,{className:`text-red-300`,children:[`Memory limit exceeded: `,f?.memory_rss_mb??`?`,`MB >`,` `,p.config.memoryLimitMb,`MB`]})]})]}),(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`text-xs font-medium text-[#888] pb-2`,children:`Daemon Status`}),(0,I.jsx)(z,{children:f===null?(0,I.jsxs)(`div`,{className:`flex items-center gap-2 text-sm`,children:[(0,I.jsx)(`span`,{className:`inline-block w-2 h-2 rounded-full bg-red-500 shrink-0`}),(0,I.jsx)(`span`,{className:`text-red-400 font-semibold`,children:`DOWN`}),(0,I.jsx)(`span`,{className:`text-[#555] text-xs`,children:`— socket not reachable`})]}):(0,I.jsxs)(`div`,{className:`flex items-center gap-4 text-sm flex-wrap`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`inline-block w-2 h-2 rounded-full bg-green-500 animate-pulse shrink-0`}),(0,I.jsx)(`span`,{className:`text-green-400 font-semibold`,children:`UP`})]}),(0,I.jsxs)(`span`,{className:`text-[#666] text-xs`,children:[`PID `,(0,I.jsx)(`span`,{className:`text-[#aaa] font-mono`,children:f.pid})]}),(0,I.jsxs)(`span`,{className:`text-[#666] text-xs`,children:[`uptime`,` `,(0,I.jsx)(`span`,{className:`text-[#aaa] font-mono`,children:g})]}),(0,I.jsxs)(`span`,{className:`text-[#666] text-xs`,children:[`mem`,` `,(0,I.jsxs)(`span`,{className:`text-[#aaa] font-mono`,children:[f.memory_rss_mb,`MB`]})]}),(0,I.jsxs)(`span`,{className:`text-[#666] text-xs`,children:[`cpu`,` `,(0,I.jsxs)(`span`,{className:`font-mono ${y}`,children:[f.cpu_pct,`%`]})]}),(0,I.jsxs)(`span`,{className:`text-[#666] text-xs`,children:[`last eval`,` `,(0,I.jsx)(`span`,{className:`text-[#aaa] font-mono`,children:v??`—`})]})]})})]}),(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{className:`text-xs font-medium text-[#888] pb-2 flex items-center justify-between`,children:[(0,I.jsxs)(`span`,{className:`flex items-center gap-2`,children:[`System Resources`,p&&(p.breaches.cpu||p.breaches.memory)&&(0,I.jsx)(`span`,{className:`text-[10px] text-red-400 border border-red-500/30 rounded px-1`,children:`limit exceeded`})]}),(0,I.jsx)(`button`,{onClick:()=>u(e=>!e),className:`text-[10px] text-[#555] hover:text-[#aaa] transition-colors`,children:l?`Hide limits`:`Configure limits`})]}),(0,I.jsxs)(z,{children:[f===null?(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`No data — daemon not running`}):(0,I.jsxs)(`div`,{className:`space-y-4`,children:[(0,I.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between text-xs`,children:[(0,I.jsx)(`span`,{className:`text-[#555]`,children:`CPU`}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(f.history.cpu_pct.length??0)>1&&(0,I.jsx)(Yt,{data:f.history.cpu_pct,width:80,height:20,color:p?.breaches.cpu?`#ef4444`:`#22c55e`,threshold:p?.config.cpuLimitPct,maxValue:100}),(0,I.jsxs)(`span`,{className:`font-mono font-semibold w-12 text-right ${y}`,children:[f.cpu_pct,`%`]})]})]}),(0,I.jsx)(ur,{value:f.cpu_pct,max:100,threshold:p?.config.cpuLimitPct??90,breached:p?.breaches.cpu??!1}),p&&(0,I.jsxs)(`div`,{className:`text-[10px] text-[#555]`,children:[`limit: `,p.config.cpuLimitPct,`%`]})]}),(0,I.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between text-xs`,children:[(0,I.jsx)(`span`,{className:`text-[#555]`,children:`Memory RSS`}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(f.history.memory_rss_mb.length??0)>1&&(0,I.jsx)(Yt,{data:f.history.memory_rss_mb,width:80,height:20,color:p?.breaches.memory?`#ef4444`:`#3b82f6`,threshold:p?.config.memoryLimitMb}),(0,I.jsxs)(`span`,{className:`font-mono font-semibold w-16 text-right ${b}`,children:[f.memory_rss_mb,`MB`]})]})]}),(0,I.jsx)(ur,{value:f.memory_rss_mb,max:Math.max(f.memory_rss_mb*1.5,p?.config.memoryLimitMb??512),threshold:p?.config.memoryLimitMb??512,breached:p?.breaches.memory??!1}),p&&(0,I.jsxs)(`div`,{className:`text-[10px] text-[#555]`,children:[`limit: `,p.config.memoryLimitMb,`MB`]})]}),(0,I.jsxs)(`div`,{className:`space-y-1`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between text-xs`,children:[(0,I.jsx)(`span`,{className:`text-[#555]`,children:`Heap`}),(0,I.jsxs)(`span`,{className:`font-mono text-[#aaa]`,children:[f.heap_used_mb,`MB / `,f.heap_total_mb,`MB`]})]}),(0,I.jsx)(`div`,{className:`w-full bg-[#1a1a1a] rounded-full h-1 overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full rounded-full bg-blue-500/60 transition-all duration-500`,style:{width:`${f.heap_total_mb>0?Math.min(100,f.heap_used_mb/f.heap_total_mb*100):0}%`}})})]})]}),l&&p&&(0,I.jsxs)(`div`,{className:`mt-4 pt-4 border-t border-[#1e1e1e]`,children:[(0,I.jsxs)(`p`,{className:`text-[11px] text-[#555] mb-3`,children:[`Thresholds trigger UI warnings. Values are persisted to`,` `,(0,I.jsx)(`code`,{children:`.sigmashake/config.toml`}),`.`]}),(0,I.jsx)(dr,{limitsData:p,onSaved:()=>{m(),u(!1)}})]})]})]}),(0,I.jsxs)(`div`,{className:`grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-2`,children:[(0,I.jsx)(or,{label:`Total evals`,value:f?.evals_total??`—`,accent:`text-[#e0e0e0]`}),(0,I.jsx)(or,{label:`Allow`,value:f?.decisions.allow??`—`,accent:`text-green-400`}),(0,I.jsx)(or,{label:`Block`,value:f?.decisions.block??`—`,accent:`text-red-400`}),(0,I.jsx)(or,{label:`Force`,value:f?.decisions.force??`—`,accent:`text-purple-400`}),(0,I.jsx)(or,{label:`Log`,value:f?.decisions.log??`—`,accent:`text-yellow-400`}),(0,I.jsx)(or,{label:`Ask`,value:f?.decisions.ask??`—`,accent:`text-cyan-400`})]}),(0,I.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-4`,children:[(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{className:`text-xs font-medium text-[#888] pb-2 flex items-center justify-between`,children:[(0,I.jsx)(`span`,{children:`Eval Latency`}),f&&(0,I.jsxs)(`span`,{className:`text-[10px] text-[#555]`,children:[f.latency.samples,` samples`]})]}),(0,I.jsx)(z,{children:f===null?(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`No data`}):(0,I.jsxs)(`div`,{className:`space-y-2`,children:[(0,I.jsx)(lr,{label:`p50`,ns:f.latency.p50_ns,maxNs:f.latency.max_ns}),(0,I.jsx)(lr,{label:`p95`,ns:f.latency.p95_ns,maxNs:f.latency.max_ns}),(0,I.jsx)(lr,{label:`p99`,ns:f.latency.p99_ns,maxNs:f.latency.max_ns}),(0,I.jsx)(lr,{label:`max`,ns:f.latency.max_ns,maxNs:f.latency.max_ns})]})})]}),(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`text-xs font-medium text-[#888] pb-2`,children:`Engine`}),(0,I.jsx)(z,{children:f===null?(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`No data`}):(0,I.jsxs)(`div`,{className:`space-y-2 text-xs`,children:[(0,I.jsxs)(`div`,{className:`flex justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[#555]`,children:`Native evals`}),(0,I.jsx)(`span`,{className:`font-mono text-[#aaa]`,children:f.engine.native_evals})]}),(0,I.jsxs)(`div`,{className:`flex justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[#555]`,children:`TS evals`}),(0,I.jsx)(`span`,{className:`font-mono text-[#aaa]`,children:f.engine.ts_evals})]}),(0,I.jsxs)(`div`,{className:`flex justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[#555]`,children:`Native %`}),(0,I.jsxs)(`span`,{className:`font-mono text-[#aaa]`,children:[f.engine.native_pct,`%`]})]}),(0,I.jsxs)(`div`,{className:`flex justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[#555]`,children:`Rule reloads`}),(0,I.jsx)(`span`,{className:`font-mono text-[#aaa]`,children:f.rule_reloads})]}),(0,I.jsxs)(`div`,{className:`flex justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[#555]`,children:`Rate limit trips`}),(0,I.jsx)(`span`,{className:`font-mono text-[#aaa]`,children:f.rate_limit_trips})]}),(0,I.jsxs)(`div`,{className:`flex justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[#555]`,children:`Loop guard blocks`}),(0,I.jsx)(`span`,{className:`font-mono text-[#aaa]`,children:f.loop_guard_blocks})]}),(0,I.jsxs)(`div`,{className:`flex justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[#555]`,children:`Connection errors`}),(0,I.jsx)(`span`,{className:`font-mono text-[#aaa]`,children:f.connection_errors})]})]})})]})]}),(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{className:`text-xs font-medium text-[#888] pb-2 flex items-center justify-between`,children:[(0,I.jsx)(`span`,{children:`Live Event Tail`}),(0,I.jsx)(`span`,{className:`text-[10px] text-[#444]`,children:`newest first · auto-updating`})]}),(0,I.jsx)(z,{children:a.length===0?(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`No events yet`}):(0,I.jsx)(`div`,{className:`space-y-0.5 font-mono text-xs max-h-96 overflow-y-auto`,children:a.map(e=>(0,I.jsxs)(`div`,{className:`flex items-center gap-2 py-0.5 border-b border-[#111] last:border-0`,children:[(0,I.jsx)(`span`,{className:`text-[#444] shrink-0 w-16`,children:ir(e.timestamp)}),e.tool===`__daemon`?(0,I.jsxs)(`span`,{className:`text-cyan-600`,children:[`⚙ daemon`,` `,(()=>{try{let t=JSON.parse(e.input??`{}`);return`${t.event??e.decision}${t.detail?` (${t.detail})`:``}`}catch{return e.decision}})()]}):(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`span`,{className:`shrink-0 w-16 ${sr[e.decision]??`text-[#666]`}`,children:[cr[e.decision]??`·`,` `,e.decision.padEnd(5)]}),(0,I.jsx)(`span`,{className:`text-[#aaa] shrink-0 w-24 truncate`,children:e.tool}),(0,I.jsx)(`span`,{className:`text-[#444] shrink-0 w-14 text-right`,children:nr(e.duration_ns)}),e.rule_id&&(0,I.jsx)(`a`,{href:`/rules?highlight=${encodeURIComponent(e.rule_id)}`,className:`text-amber-600 hover:text-amber-400 truncate`,title:e.rule_id,children:e.rule_id})]})]},e.id))})})]}),(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`text-xs font-medium text-[#888] pb-2`,children:`AI Agent Debug Endpoints`}),(0,I.jsxs)(z,{children:[(0,I.jsx)(`p`,{className:`text-[11px] text-[#555] mb-2`,children:`Agents can query these endpoints directly for automated triage:`}),(0,I.jsxs)(`div`,{className:`space-y-1 font-mono text-[11px]`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[#444]`,children:`GET`}),(0,I.jsx)(`a`,{href:`/api/json/daemon-metrics`,target:`_blank`,rel:`noreferrer`,className:`text-amber-600 hover:text-amber-400`,children:`/api/json/daemon-metrics`}),(0,I.jsx)(`span`,{className:`text-[#444]`,children:`— full metrics snapshot (cpu, memory, history, latency)`})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[#444]`,children:`GET`}),(0,I.jsx)(`a`,{href:`/api/json/limits`,target:`_blank`,rel:`noreferrer`,className:`text-amber-600 hover:text-amber-400`,children:`/api/json/limits`}),(0,I.jsx)(`span`,{className:`text-[#444]`,children:`— resource limits config + breach state`})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[#444]`,children:`GET`}),(0,I.jsx)(`a`,{href:`/api/json/audit-tail?after=0&limit=20`,target:`_blank`,rel:`noreferrer`,className:`text-amber-600 hover:text-amber-400`,children:`/api/json/audit-tail?after=0&limit=20`}),(0,I.jsx)(`span`,{className:`text-[#444]`,children:`— recent eval events`})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[#444]`,children:`GET`}),(0,I.jsx)(`a`,{href:`/api/json/daemon-status`,target:`_blank`,rel:`noreferrer`,className:`text-amber-600 hover:text-amber-400`,children:`/api/json/daemon-status`}),(0,I.jsx)(`span`,{className:`text-[#444]`,children:`— status, PID, log tail`})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[#444]`,children:`GET`}),(0,I.jsx)(`a`,{href:`/healthz`,target:`_blank`,rel:`noreferrer`,className:`text-amber-600 hover:text-amber-400`,children:`/healthz`}),(0,I.jsx)(`span`,{className:`text-[#444]`,children:`— process uptime`})]})]})]})]})]})}function pr(e){return e===0?`0 B`:e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:e<1024*1024*1024?`${(e/(1024*1024)).toFixed(2)} MB`:`${(e/(1024*1024*1024)).toFixed(2)} GB`}function mr(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/1024/1024).toFixed(1)}MB`}function hr(e){let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m ${t%60}s`:`${Math.floor(n/60)}h ${n%60}m`}function gr(e){return e?new Date(e*1e3).toLocaleString():`—`}function _r(e){if(!e||e===0)return`never`;let t=Math.round((Date.now()-e)/1e3);if(t<5)return`just now`;if(t<60)return`${t}s ago`;let n=Math.floor(t/60);return n<60?`${n}m ago`:`${Math.floor(n/60)}h ago`}function vr({children:e,className:t}){return(0,I.jsx)(`div`,{className:`text-[10px] font-medium uppercase tracking-widest text-[#444] mb-3 ${t??``}`,children:e})}function yr({label:e,value:t,mono:n=!0,accent:r}){return(0,I.jsxs)(`div`,{className:`flex items-baseline justify-between gap-4 py-1.5 border-b border-[#111] last:border-0`,children:[(0,I.jsx)(`span`,{className:`text-xs text-[#555] shrink-0`,children:e}),(0,I.jsx)(`span`,{className:`text-xs text-right truncate max-w-[65%] ${n?`font-mono`:``} ${r??`text-[#bbb]`}`,children:t})]})}function br({ok:e,label:t,badLabel:n}){return e?(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[10px] font-semibold uppercase tracking-wide text-green-400 border border-green-400/20 rounded px-1.5 py-0.5`,children:[`✓ `,t]}):(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[10px] font-semibold uppercase tracking-wide text-red-400 border border-red-400/20 rounded px-1.5 py-0.5`,children:[`✗ `,n??t]})}function xr({pct:e,total:t,max:n}){let r=e<60?`bg-green-500`:e<85?`bg-amber-400`:`bg-red-500`;return(0,I.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between text-xs`,children:[(0,I.jsxs)(`span`,{className:`text-[#555]`,children:[t.toLocaleString(),` / `,n.toLocaleString(),` rows`]}),(0,I.jsxs)(`span`,{className:`font-mono ${e>=85?`text-red-400`:e>=60?`text-amber-400`:`text-green-400`}`,children:[e,`%`]})]}),(0,I.jsx)(`div`,{className:`h-2 bg-[#111] rounded-full overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full rounded-full transition-all duration-500 ${r}`,style:{width:`${Math.min(100,e)}%`}})})]})}var Sr=3e3,Cr={log:`text-[#aaa]`,info:`text-blue-400`,warn:`text-amber-400`,error:`text-red-400`,debug:`text-[#666]`};function wr(e){return e.value==null?e.description?e.description:`[${e.type}]`:String(e.value)}function Tr(){let e=kn(),[t,n]=(0,_.useState)(!1),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)([]),[s,c]=(0,_.useState)(null),[l,u]=(0,_.useState)(!1),[d,f]=(0,_.useState)(!1),p=(0,_.useRef)(null),m=(0,_.useRef)(0);(0,_.useEffect)(()=>{p.current?.scrollIntoView({behavior:`smooth`})},[a]),(0,_.useEffect)(()=>{if(e.connected)return e.sendCommand(`Runtime.enable`).catch(()=>{}),e.onEvent(`Runtime.consoleAPICalled`,e=>{let t=e;o(e=>{let n=[...e,{id:m.current++,type:t.type??`log`,args:t.args??[],timestamp:t.timestamp??Date.now()}];return n.length>500?n.slice(-500):n})})},[e.connected]),(0,_.useEffect)(()=>{e.preconfiguredTarget&&!e.connected&&!e.connecting&&e.connect(e.preconfiguredTarget.id)},[e]),(0,_.useEffect)(()=>{!e.connected||d||t||r||(f(!0),(async()=>{try{await e.sendCommand(`Profiler.enable`),await e.sendCommand(`Profiler.start`),n(!0),setTimeout(async()=>{try{let t=await e.sendCommand(`Profiler.stop`);n(!1),i(t.profile)}catch{n(!1)}},Sr)}catch{}})(),e.sendCommand(`Runtime.evaluate`,{expression:`JSON.stringify(process.memoryUsage())`,returnByValue:!0}).then(e=>{c(JSON.parse(e.result.value))}).catch(()=>{}))},[e.connected,d,t,r]);let h=(0,_.useCallback)(async()=>{try{await e.sendCommand(`Profiler.enable`),await e.sendCommand(`Profiler.start`),n(!0),i(null)}catch(e){console.error(`Profiler.start failed:`,e)}},[e]),g=(0,_.useCallback)(async()=>{try{let t=await e.sendCommand(`Profiler.stop`);n(!1),i(t.profile)}catch(e){console.error(`Profiler.stop failed:`,e),n(!1)}},[e]),v=(0,_.useCallback)(async()=>{u(!0);try{let t=await e.sendCommand(`Runtime.evaluate`,{expression:`JSON.stringify(process.memoryUsage())`,returnByValue:!0});c(JSON.parse(t.result.value))}catch{}finally{u(!1)}},[e]),y=(0,_.useCallback)(()=>{e.preconfiguredTarget&&e.connect(e.preconfiguredTarget.id)},[e]);return e.active?e.connected?(0,I.jsxs)(`div`,{className:`space-y-5`,children:[(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{children:[(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Runtime Inspector`}),(0,I.jsxs)(`div`,{className:`ml-auto flex items-center gap-3`,children:[(0,I.jsxs)(`span`,{className:`text-xs text-green-400`,children:[`● Connected`,e.bunVersion?` — Bun v${e.bunVersion}`:``]}),(0,I.jsx)(zt,{variant:`ghost`,size:`sm`,onClick:e.disconnect,children:`Disconnect`})]})]}),e.error&&(0,I.jsx)(z,{children:(0,I.jsx)(`p`,{className:`text-xs text-red-400`,children:e.error})})]}),(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{children:[(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`CPU Profiler`}),(0,I.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[t&&(0,I.jsx)(`span`,{className:`text-xs text-red-400 animate-pulse`,children:`● Recording`}),t?(0,I.jsx)(zt,{variant:`danger`,size:`sm`,onClick:g,children:`Stop & Render`}):(0,I.jsx)(zt,{variant:`primary`,size:`sm`,onClick:h,children:`Start Recording`})]})]}),(0,I.jsx)(z,{children:r?(0,I.jsxs)(`div`,{className:`space-y-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-4 text-xs text-[#555]`,children:[(0,I.jsxs)(`span`,{children:[`Nodes: `,(0,I.jsx)(`span`,{className:`text-[#aaa]`,children:r.nodes.length})]}),(0,I.jsxs)(`span`,{children:[`Duration:`,` `,(0,I.jsxs)(`span`,{className:`text-[#aaa]`,children:[((r.endTime-r.startTime)/1e3).toFixed(0),`ms`]})]}),(0,I.jsxs)(`span`,{children:[`Samples: `,(0,I.jsx)(`span`,{className:`text-[#aaa]`,children:r.samples?.length??0})]})]}),(0,I.jsxs)(`div`,{className:`flex gap-3 text-[10px] text-[#555]`,children:[(0,I.jsxs)(`span`,{children:[(0,I.jsx)(`span`,{className:`inline-block w-2.5 h-2.5 rounded-sm mr-1`,style:{background:`#451a03`}}),`User code`]}),(0,I.jsxs)(`span`,{children:[(0,I.jsx)(`span`,{className:`inline-block w-2.5 h-2.5 rounded-sm mr-1`,style:{background:`#172554`}}),`Runtime (bun:/node:)`]}),(0,I.jsxs)(`span`,{children:[(0,I.jsx)(`span`,{className:`inline-block w-2.5 h-2.5 rounded-sm mr-1`,style:{background:`#1f2937`}}),`Native/other`]}),(0,I.jsxs)(`span`,{children:[(0,I.jsx)(`span`,{className:`inline-block w-2.5 h-2.5 rounded-sm mr-1`,style:{background:`#450a0a`}}),`GC/idle`]})]}),(0,I.jsx)(`div`,{className:`bg-[#0a0a0a] rounded-lg p-2 overflow-x-hidden`,children:(0,I.jsx)(In,{profile:r})})]}):(0,I.jsx)(`p`,{className:`text-xs text-[#555]`,children:t?`Recording CPU profile (auto-captures ${Sr/1e3}s)… perform actions in ssg to generate data.`:`Click "Start Recording", or wait for auto-capture on page load.`})})]}),(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{children:[(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Memory`}),(0,I.jsx)(zt,{variant:`ghost`,size:`sm`,onClick:v,disabled:l,className:`ml-auto`,children:l?`…`:`↻ Refresh`})]}),(0,I.jsx)(z,{children:s?(0,I.jsx)(`div`,{className:`grid grid-cols-4 gap-3`,children:[{label:`RSS`,value:mr(s.rss)},{label:`Heap Total`,value:mr(s.heapTotal)},{label:`Heap Used`,value:mr(s.heapUsed)},{label:`External`,value:mr(s.external)}].map(e=>(0,I.jsxs)(`div`,{className:`bg-[#0d0d0d] rounded-lg p-3 text-center`,children:[(0,I.jsx)(`div`,{className:`text-lg font-bold text-white tabular-nums`,children:e.value}),(0,I.jsx)(`div`,{className:`text-xs text-[#555] mt-0.5`,children:e.label})]},e.label))}):(0,I.jsx)(`p`,{className:`text-xs text-[#555]`,children:d?`Fetching memory metrics…`:`Click Refresh to fetch process.memoryUsage().`})})]}),(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{children:[(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Console`}),(0,I.jsx)(zt,{variant:`ghost`,size:`sm`,onClick:()=>o([]),className:`ml-auto`,children:`Clear`})]}),(0,I.jsx)(z,{children:(0,I.jsxs)(`div`,{className:`bg-[#0a0a0a] rounded-lg p-2 h-40 overflow-y-auto font-mono text-[11px]`,children:[a.length===0?(0,I.jsx)(`p`,{className:`text-[#444]`,children:`Console output will appear here…`}):a.map(e=>(0,I.jsxs)(`div`,{className:`py-0.5 border-b border-[#111] ${Cr[e.type]??`text-[#aaa]`}`,children:[(0,I.jsxs)(`span`,{className:`text-[#444] mr-2`,children:[`[`,e.type.toUpperCase(),`]`]}),e.args.map(wr).join(` `)]},e.id)),(0,I.jsx)(`div`,{ref:p})]})})]})]}):(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{className:`pb-2`,children:[(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Runtime Inspector`}),(0,I.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,I.jsx)(Lt,{variant:`amber`,children:e.connecting?`Connecting…`:`Available`}),!e.connecting&&(0,I.jsx)(zt,{variant:`ghost`,size:`sm`,onClick:y,children:`Connect`})]})]}),(0,I.jsx)(z,{children:(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:e.connecting?`Establishing WebSocket connection to Bun inspector…`:`Inspector is active but not connected. Click Connect to start profiling.`})})]}):(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{className:`pb-2`,children:[(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Runtime Inspector`}),(0,I.jsx)(Lt,{variant:`outline`,className:`ml-auto`,children:`Inactive`})]}),(0,I.jsx)(z,{children:(0,I.jsxs)(`p`,{className:`text-xs text-[#444]`,children:[`The Bun inspector is not active. Restart `,(0,I.jsx)(`code`,{className:`bg-[#111] px-1 rounded text-[10px]`,children:`ssg serve`}),` to enable it automatically.`]})})]})}function Er(){let[e,t]=(0,_.useState)(0),{data:n}=E(`/api/json/evald-log`,[e]),r=(0,_.useRef)(null);(0,_.useEffect)(()=>{let e=setInterval(()=>t(e=>e+1),5e3);return()=>clearInterval(e)},[]),(0,_.useEffect)(()=>{r.current&&r.current.scrollIntoView({behavior:`smooth`,block:`end`})},[n?.lines.length]);let i=n?.lines??[];return(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{className:`pb-2 flex flex-row items-center justify-between`,children:[(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Daemon Log`}),(0,I.jsxs)(`span`,{className:`text-[10px] text-[#444]`,children:[n?.path?n.path:`loading…`,` · last 200 lines · 5s refresh`]})]}),(0,I.jsxs)(z,{children:[n?.error&&(0,I.jsx)(`p`,{className:`text-xs text-red-400 mb-2`,children:n.error}),i.length===0&&!n?.error&&(0,I.jsxs)(`p`,{className:`text-xs text-[#555]`,children:[`No log entries yet. Start the daemon with`,` `,(0,I.jsx)(`code`,{className:`font-mono text-amber-600`,children:`ssg serve`}),` to generate log output.`]}),i.length>0&&(0,I.jsxs)(`pre`,{className:`bg-[#0a0a0a] rounded p-3 text-[10px] text-[#777] overflow-x-auto whitespace-pre-wrap break-all max-h-80 overflow-y-auto font-mono leading-relaxed`,children:[i.join(`
|
|
18
|
-
`),(0,I.jsx)(`div`,{ref:r})]})]})]})}function Dr(){let e=se([`metrics-tick`,`rules-changed`]),{data:t,refetch:n}=E(`/api/json/observability`,[e[`metrics-tick`],e[`rules-changed`]]),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(Date.now()),[s,c]=(0,_.useState)(`idle`),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(`idle`);(0,_.useEffect)(()=>{t&&o(Date.now())},[t]);let p=(0,_.useCallback)(async()=>{c(`loading`);try{let e=await(await fetch(`/api/rules/sync-to-db`,{method:`POST`})).json();if(e.ok){c(`done`);let t=(e.pruned_count??0)>0?` (${e.pruned_count} orphan(s) pruned)`:``;u((e.message??`Synced ${e.synced} rules`)+t),n()}else c(`error`),u(e.error??`Sync failed`)}catch(e){c(`error`),u(String(e))}},[n]),m=(0,_.useCallback)(async()=>{f(`loading`);try{await fetch(`/api/rules/force-reload`,{method:`POST`}),f(`done`),n(),setTimeout(()=>f(`idle`),3e3)}catch{f(`idle`)}},[n]),h=t?.db,g=t?.rules,v=t?.audit,y=t?.process,b=t?.flight_recorder,x=g?.drift_detected??!1;return(0,I.jsxs)(`div`,{className:`space-y-5`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`h1`,{className:`text-base font-semibold`,children:`Observability`}),(0,I.jsx)(`p`,{className:`text-xs text-[#444] mt-0.5`,children:`SQLite health, rule drift detection, runtime profiler, and diagnostics`})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,I.jsxs)(`span`,{className:`text-[10px] text-[#333] font-mono`,children:[`refreshed `,_r(a)]}),(0,I.jsx)(`button`,{onClick:n,className:`text-xs text-[#555] hover:text-amber-400 transition-colors px-2 py-1 border border-[#222] rounded`,children:`↻ Refresh`})]})]}),(0,I.jsxs)(L,{className:x?`border-red-500/40 shadow-red-900/10 shadow-lg`:`border-green-500/20`,children:[(0,I.jsxs)(R,{className:`flex items-center justify-between pb-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-sm font-semibold`,children:`Rule Drift Detector`}),(0,I.jsx)(`span`,{className:`text-[10px] text-[#444]`,children:`— .rules files vs SQLite`})]}),g&&(x?(0,I.jsx)(`span`,{className:`flex items-center gap-1.5 text-xs font-bold text-red-400 border border-red-400/30 rounded px-2 py-1 bg-red-500/5`,children:`⚠ DRIFT DETECTED`}):(0,I.jsx)(`span`,{className:`flex items-center gap-1.5 text-xs font-bold text-green-400 border border-green-400/30 rounded px-2 py-1 bg-green-500/5`,children:`✓ IN SYNC`}))]}),(0,I.jsx)(z,{children:g?(0,I.jsxs)(`div`,{className:`space-y-4`,children:[(0,I.jsx)(`div`,{className:`grid grid-cols-2 sm:grid-cols-4 gap-3`,children:[{label:`.rules Files`,value:g.file_count,sub:`${g.file_rule_count} rules total`},{label:`DB Rules`,value:g.db_rule_count,sub:`${g.db_enabled_count} enabled`},{label:`Only in Files`,value:g.drift_details.only_in_files.length,accent:g.drift_details.only_in_files.length>0?`text-amber-400`:`text-[#555]`},{label:`Only in DB`,value:g.drift_details.only_in_db.length,accent:g.drift_details.only_in_db.length>0?`text-red-400`:`text-[#555]`}].map(({label:e,value:t,sub:n,accent:r})=>(0,I.jsxs)(`div`,{className:`bg-[#0d0d0d] border border-[#1a1a1a] rounded p-3`,children:[(0,I.jsx)(`div`,{className:`text-[10px] text-[#444] uppercase tracking-wider mb-1`,children:e}),(0,I.jsx)(`div`,{className:`text-xl font-mono font-semibold ${r??`text-[#ddd]`}`,children:t}),n&&(0,I.jsx)(`div`,{className:`text-[10px] text-[#444] mt-0.5`,children:n})]},e))}),x&&(0,I.jsxs)(`div`,{children:[(0,I.jsxs)(`button`,{onClick:()=>i(e=>!e),className:`text-xs text-amber-400 hover:text-amber-300 flex items-center gap-1 transition-colors`,children:[r?`▾`:`▸`,` View drift details`]}),r&&(0,I.jsxs)(`div`,{className:`mt-3 space-y-3`,children:[g.drift_details.only_in_files.length>0&&(0,I.jsxs)(`div`,{children:[(0,I.jsxs)(`div`,{className:`text-[10px] text-amber-400/70 mb-1.5 uppercase tracking-wide`,children:[`In .rules files but NOT in DB — run `,(0,I.jsx)(`code`,{className:`bg-[#111] px-1 rounded`,children:`ssg sync`})]}),(0,I.jsx)(`div`,{className:`bg-[#0a0a0a] border border-amber-400/10 rounded p-2 space-y-0.5 max-h-40 overflow-y-auto`,children:g.drift_details.only_in_files.map(e=>(0,I.jsxs)(`div`,{className:`font-mono text-[11px] text-amber-300/70`,children:[`+ `,e]},e))})]}),g.drift_details.only_in_db.length>0&&(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`div`,{className:`text-[10px] text-red-400/70 mb-1.5 uppercase tracking-wide`,children:`In DB but NOT in any .rules file — orphaned rules`}),(0,I.jsx)(`div`,{className:`bg-[#0a0a0a] border border-red-400/10 rounded p-2 space-y-0.5 max-h-40 overflow-y-auto`,children:g.drift_details.only_in_db.map(e=>(0,I.jsxs)(`div`,{className:`font-mono text-[11px] text-red-300/70`,children:[`− `,e]},e))})]})]})]}),(0,I.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 pt-3 border-t border-[#111]`,children:[(0,I.jsx)(`button`,{onClick:p,disabled:s===`loading`,className:`inline-flex items-center gap-1.5 h-7 px-3 rounded-md text-xs font-medium bg-amber-500/10 text-amber-400 border border-amber-500/20 hover:bg-amber-500/20 hover:border-amber-500/40 transition-all cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed`,title:`Reads all .rules files and upserts them into SQLite. This eliminates drift and enables faster DB-based rule loading.`,children:s===`loading`?`⟳ Syncing…`:`↑ Sync Files → DB`}),(0,I.jsx)(`button`,{onClick:m,disabled:d===`loading`,className:`inline-flex items-center gap-1.5 h-7 px-3 rounded-md text-xs font-medium bg-[#1a1a1a] text-[#888] border border-[#222] hover:text-[#bbb] hover:border-[#333] transition-all cursor-pointer disabled:opacity-50`,title:`Invalidates the in-memory rules cache. The daemon will reload rules from DB (or files) on the next eval.`,children:d===`loading`?`⟳`:d===`done`?`✓ Reloaded`:`↻ Force Reload`}),(0,I.jsx)(`span`,{className:`text-[10px] text-[#333] ml-auto`,children:g.db_rule_count===0?`⚠ DB empty — daemon falls back to file-based loading (slower reload)`:`DB has ${g.db_rule_count} rules — daemon uses fast indexed queries`})]}),s===`done`&&(0,I.jsxs)(`div`,{className:`flex items-center justify-between rounded-md px-3 py-2 mt-2 text-xs font-medium bg-green-500/10 border border-green-500/20 text-green-400`,children:[(0,I.jsxs)(`span`,{children:[`✓ `,l]}),(0,I.jsx)(`button`,{onClick:()=>c(`idle`),className:`ml-3 shrink-0 px-2 py-0.5 rounded border border-current/30 hover:bg-white/5 transition-colors cursor-pointer`,children:`Dismiss`})]}),s===`error`&&(0,I.jsxs)(`div`,{className:`flex items-center justify-between rounded-md px-3 py-2 mt-2 text-xs font-medium bg-red-500/10 border border-red-500/20 text-red-400`,children:[(0,I.jsxs)(`span`,{children:[`✗ `,l]}),(0,I.jsx)(`button`,{onClick:()=>c(`idle`),className:`ml-3 shrink-0 px-2 py-0.5 rounded border border-current/30 hover:bg-white/5 transition-colors cursor-pointer`,children:`Dismiss`})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-4 text-[11px] text-[#444] pt-1 border-t border-[#111]`,children:[(0,I.jsxs)(`span`,{children:[`rules dir: `,(0,I.jsx)(`span`,{className:`font-mono text-[#555]`,children:g.rules_dir})]}),(0,I.jsxs)(`span`,{className:`ml-auto`,children:[`last reload: `,(0,I.jsx)(`span`,{className:`font-mono text-[#555]`,children:_r(g.last_reload_at)})]})]})]}):(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`Loading…`})})]}),(0,I.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-5`,children:[(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{className:`flex items-center justify-between pb-2`,children:[(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`SQLite Database`}),h&&!h.error&&(0,I.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,I.jsx)(br,{ok:h.journal_mode===`wal`,label:`WAL`,badLabel:`NO WAL`}),(0,I.jsx)(br,{ok:h.synchronous===`NORMAL`,label:`NORMAL`,badLabel:h.synchronous})]})]}),(0,I.jsx)(z,{children:h?h.error?(0,I.jsx)(`div`,{className:`text-xs text-red-400 font-mono bg-red-900/10 border border-red-500/20 rounded p-2`,children:h.error}):(0,I.jsxs)(`div`,{children:[(0,I.jsx)(vr,{children:`Storage`}),(0,I.jsx)(yr,{label:`File path`,value:h.path.replace(`/home/`,`~/../`)}),(0,I.jsx)(yr,{label:`File size`,value:pr(h.file_size_bytes)}),(0,I.jsx)(yr,{label:`Allocated`,value:`${pr(h.allocated_bytes)} (${h.page_count.toLocaleString()} pages × ${h.page_size}B)`}),(0,I.jsx)(vr,{className:`mt-4`,children:`PRAGMA Configuration`}),(0,I.jsx)(yr,{label:`journal_mode`,value:h.journal_mode,accent:h.journal_mode===`wal`?`text-green-400`:`text-amber-400`}),(0,I.jsx)(yr,{label:`synchronous`,value:h.synchronous,accent:h.synchronous===`NORMAL`?`text-green-400`:`text-amber-400`}),(0,I.jsx)(yr,{label:`cache_size`,value:`${h.cache_size_kb.toLocaleString()} KB (${Math.round(h.cache_size_kb/1024)} MB)`}),(0,I.jsx)(yr,{label:`page_size`,value:`${h.page_size.toLocaleString()} B`}),h.wal_checkpoint&&(0,I.jsx)(yr,{label:`WAL checkpoint`,value:`log ${h.wal_checkpoint.log}, checkpointed ${h.wal_checkpoint.checkpointed}, busy ${h.wal_checkpoint.busy}`}),(0,I.jsx)(vr,{className:`mt-4`,children:`Table Row Counts`}),h.tables.map(e=>(0,I.jsx)(yr,{label:e.name,value:e.row_count>=0?e.row_count.toLocaleString():`error`,accent:e.row_count<0?`text-red-400`:`text-[#bbb]`},e.name))]}):(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`Loading…`})})]}),(0,I.jsxs)(`div`,{className:`space-y-5`,children:[(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`pb-2`,children:(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Audit Log Capacity`})}),(0,I.jsx)(z,{children:v?(0,I.jsxs)(`div`,{className:`space-y-4`,children:[(0,I.jsx)(xr,{pct:v.utilization_pct,total:v.total_rows,max:v.max_rows}),(0,I.jsxs)(`div`,{className:`space-y-0`,children:[(0,I.jsx)(yr,{label:`Total rows`,value:v.total_rows.toLocaleString()}),(0,I.jsx)(yr,{label:`Rotation limit`,value:v.max_rows.toLocaleString()}),(0,I.jsx)(yr,{label:`Utilization`,value:`${v.utilization_pct}%`,accent:v.utilization_pct>=85?`text-red-400`:v.utilization_pct>=60?`text-amber-400`:`text-green-400`}),(0,I.jsx)(yr,{label:`Oldest entry`,value:gr(v.oldest_timestamp)}),(0,I.jsx)(yr,{label:`Newest entry`,value:gr(v.newest_timestamp)})]}),v.utilization_pct>=85&&(0,I.jsx)(`div`,{className:`text-[11px] text-red-400 bg-red-500/5 border border-red-500/20 rounded p-2`,children:`⚠ Audit log nearing rotation limit. Oldest entries will be purged automatically.`})]}):(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`Loading…`})})]}),(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`pb-2`,children:(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Process & Runtime`})}),(0,I.jsx)(z,{children:y?(0,I.jsxs)(`div`,{children:[(0,I.jsx)(yr,{label:`PID`,value:y.pid}),(0,I.jsx)(yr,{label:`Uptime`,value:hr(y.uptime_ms)}),(0,I.jsx)(yr,{label:`Memory (RSS)`,value:`${y.memory_rss_mb} MB`}),(0,I.jsx)(yr,{label:`Bun version`,value:y.bun_version}),(0,I.jsx)(yr,{label:`Node compat`,value:y.node_version}),(0,I.jsx)(yr,{label:`Platform`,value:`${y.platform} / ${y.arch}`})]}):(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`Loading…`})})]})]})]}),(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`pb-2`,children:(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Flight Recorder`})}),(0,I.jsx)(z,{children:b?(0,I.jsxs)(`div`,{className:`grid grid-cols-3 gap-4`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`div`,{className:`text-[10px] text-[#444] uppercase tracking-wider mb-1`,children:`Log File`}),(0,I.jsx)(`div`,{className:`text-xs font-mono text-[#bbb] truncate`,children:`…${b.path.slice(-50)}`})]}),(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`div`,{className:`text-[10px] text-[#444] uppercase tracking-wider mb-1`,children:`File Size`}),(0,I.jsx)(`div`,{className:`text-xs font-mono ${b.file_size_bytes===0?`text-[#444]`:`text-[#bbb]`}`,children:pr(b.file_size_bytes)})]}),(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`div`,{className:`text-[10px] text-[#444] uppercase tracking-wider mb-1`,children:`Approx. Entries`}),(0,I.jsx)(`div`,{className:`text-xs font-mono ${b.approx_entries===0?`text-[#444]`:`text-[#bbb]`}`,children:b.approx_entries===0?`—`:b.approx_entries.toLocaleString()})]})]}):(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`Loading…`})})]}),(0,I.jsx)(Tr,{}),(0,I.jsx)(Er,{}),(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`pb-2`,children:(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Observability API`})}),(0,I.jsxs)(z,{children:[(0,I.jsx)(`p`,{className:`text-[11px] text-[#444] mb-3`,children:`Machine-readable endpoints for automated monitoring and AI agent triage:`}),(0,I.jsx)(`div`,{className:`space-y-1.5 font-mono text-[11px]`,children:[[`/api/json/observability`,`SQLite health, rule drift, process info`],[`/api/json/daemon-metrics`,`Eval latency, decision counters, memory`],[`/api/json/audit-tail?after=0&limit=20`,`Recent eval events (live feed)`],[`/api/json/daemon-status`,`Daemon PID, status, log tail`],[`/api/json/evald-log`,`Last 200 lines of evald.log (daemon stderr)`],[`/healthz`,`Process liveness`],[`/readyz`,`SQLite liveness`]].map(([e,t])=>(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[#333]`,children:`GET`}),(0,I.jsx)(`a`,{href:e,target:`_blank`,rel:`noreferrer`,className:`text-amber-600 hover:text-amber-400 transition-colors`,children:e}),(0,I.jsxs)(`span`,{className:`text-[#333] hidden sm:inline`,children:[`— `,t]})]},e))})]})]})]})}var Or=`ssg-dashboard-tabs`,kr=2e3,Ar=6e3;function jr(){return`tab-${Date.now()}-${Math.random().toString(36).slice(2,7)}`}function Mr(){let[e,t]=(0,_.useState)(0),[n,r]=(0,_.useState)(!0),i=(0,_.useRef)(jr()),a=(0,_.useRef)(new Map);return(0,_.useEffect)(()=>{if(typeof BroadcastChannel>`u`)return;let e=new BroadcastChannel(Or);function n(){let e=Date.now();for(let[t,n]of a.current.entries())e-n>Ar&&a.current.delete(t);let n=a.current.size;t(n),r([...a.current.keys(),i.current].sort()[0]===i.current)}function o(e){let t=e.data;!t||t.id===i.current||(t.type===`leave`?a.current.delete(t.id):a.current.set(t.id,Date.now()),n())}e.addEventListener(`message`,o),e.postMessage({type:`join`,id:i.current});let s=setInterval(()=>{e.postMessage({type:`heartbeat`,id:i.current}),n()},kr),c=()=>{e.postMessage({type:`leave`,id:i.current})};return window.addEventListener(`beforeunload`,c),()=>{clearInterval(s),e.postMessage({type:`leave`,id:i.current}),e.removeEventListener(`message`,o),e.close(),window.removeEventListener(`beforeunload`,c)}},[]),{otherTabCount:e,isLeader:n}}var Nr=[{path:`/`,label:`Dashboard`},{path:`/rules`,label:`Rules`},{path:`/audit`,label:`Audit`},{path:`/approvals`,label:`Approvals`},{path:`/hub`,label:`Hub`},{path:`/profile`,label:`Profile`},{path:`/monitor`,label:`Monitor`},{path:`/observability`,label:`Observability`}];function Pr(){let{data:e}=E(`/api/json/daemon-status`,[se([`stats-changed`])[`stats-changed`]]),[t,n]=(0,_.useState)(!1),r=e?.status??`starting`,i=r===`running`?`bg-green-500`:r===`starting`?`bg-amber-400`:`bg-red-500`,a=r===`running`?`Daemon running`:r===`starting`?`Daemon starting…`:r===`error`?`Daemon error`:`Daemon stopped`;return(0,I.jsxs)(`div`,{className:`relative`,children:[(0,I.jsxs)(`button`,{onClick:()=>n(e=>!e),className:`flex items-center gap-1.5 text-xs text-[#666] hover:text-[#aaa] transition-colors`,title:a,children:[(0,I.jsx)(`span`,{className:`inline-block w-2 h-2 rounded-full ${i}`}),(0,I.jsx)(`span`,{className:`hidden sm:inline`,children:a})]}),t&&(0,I.jsxs)(`div`,{className:`absolute right-0 top-7 z-50 w-72 bg-[#111] border border-[#222] rounded-lg shadow-xl p-3 text-xs`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,I.jsx)(`span`,{className:`font-medium text-[#ddd]`,children:`Eval Daemon`}),(0,I.jsx)(`button`,{onClick:()=>n(!1),className:`text-[#555] hover:text-[#aaa]`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`space-y-1 text-[#888]`,children:[(0,I.jsxs)(`div`,{children:[`Status:`,` `,(0,I.jsx)(`span`,{className:r===`running`?`text-green-400`:r===`starting`?`text-amber-400`:`text-red-400`,children:r})]}),e?.pid&&(0,I.jsxs)(`div`,{children:[`PID: `,e.pid]})]}),e?.logTail&&e.logTail.length>0&&(0,I.jsxs)(`div`,{className:`mt-2`,children:[(0,I.jsx)(`div`,{className:`text-[#555] mb-1`,children:`Recent log:`}),(0,I.jsx)(`pre`,{className:`bg-[#0a0a0a] rounded p-2 text-[10px] text-[#777] overflow-x-auto whitespace-pre-wrap break-all max-h-32 overflow-y-auto`,children:e.logTail.join(`
|
|
19
|
-
`)})]})]})]})}function
|
|
18
|
+
`),(0,I.jsx)(`div`,{ref:r})]})]})]})}function Dr(){let e=se([`metrics-tick`,`rules-changed`]),{data:t,refetch:n}=E(`/api/json/observability`,[e[`metrics-tick`],e[`rules-changed`]]),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(Date.now()),[s,c]=(0,_.useState)(`idle`),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(`idle`);(0,_.useEffect)(()=>{t&&o(Date.now())},[t]);let p=(0,_.useCallback)(async()=>{c(`loading`);try{let e=await(await fetch(`/api/rules/sync-to-db`,{method:`POST`})).json();if(e.ok){c(`done`);let t=(e.pruned_count??0)>0?` (${e.pruned_count} orphan(s) pruned)`:``;u((e.message??`Synced ${e.synced} rules`)+t),n()}else c(`error`),u(e.error??`Sync failed`)}catch(e){c(`error`),u(String(e))}},[n]),m=(0,_.useCallback)(async()=>{f(`loading`);try{await fetch(`/api/rules/force-reload`,{method:`POST`}),f(`done`),n(),setTimeout(()=>f(`idle`),3e3)}catch{f(`idle`)}},[n]),h=t?.db,g=t?.rules,v=t?.audit,y=t?.process,b=t?.flight_recorder,x=g?.drift_detected??!1;return(0,I.jsxs)(`div`,{className:`space-y-5`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`h1`,{className:`text-base font-semibold`,children:`Observability`}),(0,I.jsx)(`p`,{className:`text-xs text-[#444] mt-0.5`,children:`SQLite health, rule drift detection, runtime profiler, and diagnostics`})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,I.jsxs)(`span`,{className:`text-[10px] text-[#333] font-mono`,children:[`refreshed `,_r(a)]}),(0,I.jsx)(`button`,{onClick:n,className:`text-xs text-[#555] hover:text-amber-400 transition-colors px-2 py-1 border border-[#222] rounded`,children:`↻ Refresh`})]})]}),(0,I.jsxs)(L,{className:x?`border-red-500/40 shadow-red-900/10 shadow-lg`:`border-green-500/20`,children:[(0,I.jsxs)(R,{className:`flex items-center justify-between pb-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-sm font-semibold`,children:`Rule Drift Detector`}),(0,I.jsx)(`span`,{className:`text-[10px] text-[#444]`,children:`— .rules files vs SQLite`})]}),g&&(x?(0,I.jsx)(`span`,{className:`flex items-center gap-1.5 text-xs font-bold text-red-400 border border-red-400/30 rounded px-2 py-1 bg-red-500/5`,children:`⚠ DRIFT DETECTED`}):(0,I.jsx)(`span`,{className:`flex items-center gap-1.5 text-xs font-bold text-green-400 border border-green-400/30 rounded px-2 py-1 bg-green-500/5`,children:`✓ IN SYNC`}))]}),(0,I.jsx)(z,{children:g?(0,I.jsxs)(`div`,{className:`space-y-4`,children:[(0,I.jsx)(`div`,{className:`grid grid-cols-2 sm:grid-cols-4 gap-3`,children:[{label:`.rules Files`,value:g.file_count,sub:`${g.file_rule_count} rules total`},{label:`DB Rules`,value:g.db_rule_count,sub:`${g.db_enabled_count} enabled`},{label:`Only in Files`,value:g.drift_details.only_in_files.length,accent:g.drift_details.only_in_files.length>0?`text-amber-400`:`text-[#555]`},{label:`Only in DB`,value:g.drift_details.only_in_db.length,accent:g.drift_details.only_in_db.length>0?`text-red-400`:`text-[#555]`}].map(({label:e,value:t,sub:n,accent:r})=>(0,I.jsxs)(`div`,{className:`bg-[#0d0d0d] border border-[#1a1a1a] rounded p-3`,children:[(0,I.jsx)(`div`,{className:`text-[10px] text-[#444] uppercase tracking-wider mb-1`,children:e}),(0,I.jsx)(`div`,{className:`text-xl font-mono font-semibold ${r??`text-[#ddd]`}`,children:t}),n&&(0,I.jsx)(`div`,{className:`text-[10px] text-[#444] mt-0.5`,children:n})]},e))}),x&&(0,I.jsxs)(`div`,{children:[(0,I.jsxs)(`button`,{onClick:()=>i(e=>!e),className:`text-xs text-amber-400 hover:text-amber-300 flex items-center gap-1 transition-colors`,children:[r?`▾`:`▸`,` View drift details`]}),r&&(0,I.jsxs)(`div`,{className:`mt-3 space-y-3`,children:[g.drift_details.only_in_files.length>0&&(0,I.jsxs)(`div`,{children:[(0,I.jsxs)(`div`,{className:`text-[10px] text-amber-400/70 mb-1.5 uppercase tracking-wide`,children:[`In .rules files but NOT in DB — run `,(0,I.jsx)(`code`,{className:`bg-[#111] px-1 rounded`,children:`ssg sync`})]}),(0,I.jsx)(`div`,{className:`bg-[#0a0a0a] border border-amber-400/10 rounded p-2 space-y-0.5 max-h-40 overflow-y-auto`,children:g.drift_details.only_in_files.map(e=>(0,I.jsxs)(`div`,{className:`font-mono text-[11px] text-amber-300/70`,children:[`+ `,e]},e))})]}),g.drift_details.only_in_db.length>0&&(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`div`,{className:`text-[10px] text-red-400/70 mb-1.5 uppercase tracking-wide`,children:`In DB but NOT in any .rules file — orphaned rules`}),(0,I.jsx)(`div`,{className:`bg-[#0a0a0a] border border-red-400/10 rounded p-2 space-y-0.5 max-h-40 overflow-y-auto`,children:g.drift_details.only_in_db.map(e=>(0,I.jsxs)(`div`,{className:`font-mono text-[11px] text-red-300/70`,children:[`− `,e]},e))})]})]})]}),(0,I.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 pt-3 border-t border-[#111]`,children:[(0,I.jsx)(`button`,{onClick:p,disabled:s===`loading`,className:`inline-flex items-center gap-1.5 h-7 px-3 rounded-md text-xs font-medium bg-amber-500/10 text-amber-400 border border-amber-500/20 hover:bg-amber-500/20 hover:border-amber-500/40 transition-all cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed`,title:`Reads all .rules files and upserts them into SQLite. This eliminates drift and enables faster DB-based rule loading.`,children:s===`loading`?`⟳ Syncing…`:`↑ Sync Files → DB`}),(0,I.jsx)(`button`,{onClick:m,disabled:d===`loading`,className:`inline-flex items-center gap-1.5 h-7 px-3 rounded-md text-xs font-medium bg-[#1a1a1a] text-[#888] border border-[#222] hover:text-[#bbb] hover:border-[#333] transition-all cursor-pointer disabled:opacity-50`,title:`Invalidates the in-memory rules cache. The daemon will reload rules from DB (or files) on the next eval.`,children:d===`loading`?`⟳`:d===`done`?`✓ Reloaded`:`↻ Force Reload`}),(0,I.jsx)(`span`,{className:`text-[10px] text-[#333] ml-auto`,children:g.db_rule_count===0?`⚠ DB empty — daemon falls back to file-based loading (slower reload)`:`DB has ${g.db_rule_count} rules — daemon uses fast indexed queries`})]}),s===`done`&&(0,I.jsxs)(`div`,{className:`flex items-center justify-between rounded-md px-3 py-2 mt-2 text-xs font-medium bg-green-500/10 border border-green-500/20 text-green-400`,children:[(0,I.jsxs)(`span`,{children:[`✓ `,l]}),(0,I.jsx)(`button`,{onClick:()=>c(`idle`),className:`ml-3 shrink-0 px-2 py-0.5 rounded border border-current/30 hover:bg-white/5 transition-colors cursor-pointer`,children:`Dismiss`})]}),s===`error`&&(0,I.jsxs)(`div`,{className:`flex items-center justify-between rounded-md px-3 py-2 mt-2 text-xs font-medium bg-red-500/10 border border-red-500/20 text-red-400`,children:[(0,I.jsxs)(`span`,{children:[`✗ `,l]}),(0,I.jsx)(`button`,{onClick:()=>c(`idle`),className:`ml-3 shrink-0 px-2 py-0.5 rounded border border-current/30 hover:bg-white/5 transition-colors cursor-pointer`,children:`Dismiss`})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-4 text-[11px] text-[#444] pt-1 border-t border-[#111]`,children:[(0,I.jsxs)(`span`,{children:[`rules dir: `,(0,I.jsx)(`span`,{className:`font-mono text-[#555]`,children:g.rules_dir})]}),(0,I.jsxs)(`span`,{className:`ml-auto`,children:[`last reload: `,(0,I.jsx)(`span`,{className:`font-mono text-[#555]`,children:_r(g.last_reload_at)})]})]})]}):(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`Loading…`})})]}),(0,I.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-5`,children:[(0,I.jsxs)(L,{children:[(0,I.jsxs)(R,{className:`flex items-center justify-between pb-2`,children:[(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`SQLite Database`}),h&&!h.error&&(0,I.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,I.jsx)(br,{ok:h.journal_mode===`wal`,label:`WAL`,badLabel:`NO WAL`}),(0,I.jsx)(br,{ok:h.synchronous===`NORMAL`,label:`NORMAL`,badLabel:h.synchronous})]})]}),(0,I.jsx)(z,{children:h?h.error?(0,I.jsx)(`div`,{className:`text-xs text-red-400 font-mono bg-red-900/10 border border-red-500/20 rounded p-2`,children:h.error}):(0,I.jsxs)(`div`,{children:[(0,I.jsx)(vr,{children:`Storage`}),(0,I.jsx)(yr,{label:`File path`,value:h.path.replace(`/home/`,`~/../`)}),(0,I.jsx)(yr,{label:`File size`,value:pr(h.file_size_bytes)}),(0,I.jsx)(yr,{label:`Allocated`,value:`${pr(h.allocated_bytes)} (${h.page_count.toLocaleString()} pages × ${h.page_size}B)`}),(0,I.jsx)(vr,{className:`mt-4`,children:`PRAGMA Configuration`}),(0,I.jsx)(yr,{label:`journal_mode`,value:h.journal_mode,accent:h.journal_mode===`wal`?`text-green-400`:`text-amber-400`}),(0,I.jsx)(yr,{label:`synchronous`,value:h.synchronous,accent:h.synchronous===`NORMAL`?`text-green-400`:`text-amber-400`}),(0,I.jsx)(yr,{label:`cache_size`,value:`${h.cache_size_kb.toLocaleString()} KB (${Math.round(h.cache_size_kb/1024)} MB)`}),(0,I.jsx)(yr,{label:`page_size`,value:`${h.page_size.toLocaleString()} B`}),h.wal_checkpoint&&(0,I.jsx)(yr,{label:`WAL checkpoint`,value:`log ${h.wal_checkpoint.log}, checkpointed ${h.wal_checkpoint.checkpointed}, busy ${h.wal_checkpoint.busy}`}),(0,I.jsx)(vr,{className:`mt-4`,children:`Table Row Counts`}),h.tables.map(e=>(0,I.jsx)(yr,{label:e.name,value:e.row_count>=0?e.row_count.toLocaleString():`error`,accent:e.row_count<0?`text-red-400`:`text-[#bbb]`},e.name))]}):(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`Loading…`})})]}),(0,I.jsxs)(`div`,{className:`space-y-5`,children:[(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`pb-2`,children:(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Audit Log Capacity`})}),(0,I.jsx)(z,{children:v?(0,I.jsxs)(`div`,{className:`space-y-4`,children:[(0,I.jsx)(xr,{pct:v.utilization_pct,total:v.total_rows,max:v.max_rows}),(0,I.jsxs)(`div`,{className:`space-y-0`,children:[(0,I.jsx)(yr,{label:`Total rows`,value:v.total_rows.toLocaleString()}),(0,I.jsx)(yr,{label:`Rotation limit`,value:v.max_rows.toLocaleString()}),(0,I.jsx)(yr,{label:`Utilization`,value:`${v.utilization_pct}%`,accent:v.utilization_pct>=85?`text-red-400`:v.utilization_pct>=60?`text-amber-400`:`text-green-400`}),(0,I.jsx)(yr,{label:`Oldest entry`,value:gr(v.oldest_timestamp)}),(0,I.jsx)(yr,{label:`Newest entry`,value:gr(v.newest_timestamp)})]}),v.utilization_pct>=85&&(0,I.jsx)(`div`,{className:`text-[11px] text-red-400 bg-red-500/5 border border-red-500/20 rounded p-2`,children:`⚠ Audit log nearing rotation limit. Oldest entries will be purged automatically.`})]}):(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`Loading…`})})]}),(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`pb-2`,children:(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Process & Runtime`})}),(0,I.jsx)(z,{children:y?(0,I.jsxs)(`div`,{children:[(0,I.jsx)(yr,{label:`PID`,value:y.pid}),(0,I.jsx)(yr,{label:`Uptime`,value:hr(y.uptime_ms)}),(0,I.jsx)(yr,{label:`Memory (RSS)`,value:`${y.memory_rss_mb} MB`}),(0,I.jsx)(yr,{label:`Bun version`,value:y.bun_version}),(0,I.jsx)(yr,{label:`Node compat`,value:y.node_version}),(0,I.jsx)(yr,{label:`Platform`,value:`${y.platform} / ${y.arch}`})]}):(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`Loading…`})})]})]})]}),(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`pb-2`,children:(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Flight Recorder`})}),(0,I.jsx)(z,{children:b?(0,I.jsxs)(`div`,{className:`grid grid-cols-3 gap-4`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`div`,{className:`text-[10px] text-[#444] uppercase tracking-wider mb-1`,children:`Log File`}),(0,I.jsx)(`div`,{className:`text-xs font-mono text-[#bbb] truncate`,children:`…${b.path.slice(-50)}`})]}),(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`div`,{className:`text-[10px] text-[#444] uppercase tracking-wider mb-1`,children:`File Size`}),(0,I.jsx)(`div`,{className:`text-xs font-mono ${b.file_size_bytes===0?`text-[#444]`:`text-[#bbb]`}`,children:pr(b.file_size_bytes)})]}),(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`div`,{className:`text-[10px] text-[#444] uppercase tracking-wider mb-1`,children:`Approx. Entries`}),(0,I.jsx)(`div`,{className:`text-xs font-mono ${b.approx_entries===0?`text-[#444]`:`text-[#bbb]`}`,children:b.approx_entries===0?`—`:b.approx_entries.toLocaleString()})]})]}):(0,I.jsx)(`p`,{className:`text-xs text-[#444]`,children:`Loading…`})})]}),(0,I.jsx)(Tr,{}),(0,I.jsx)(Er,{}),(0,I.jsxs)(L,{children:[(0,I.jsx)(R,{className:`pb-2`,children:(0,I.jsx)(`span`,{className:`text-sm font-medium`,children:`Observability API`})}),(0,I.jsxs)(z,{children:[(0,I.jsx)(`p`,{className:`text-[11px] text-[#444] mb-3`,children:`Machine-readable endpoints for automated monitoring and AI agent triage:`}),(0,I.jsx)(`div`,{className:`space-y-1.5 font-mono text-[11px]`,children:[[`/api/json/observability`,`SQLite health, rule drift, process info`],[`/api/json/daemon-metrics`,`Eval latency, decision counters, memory`],[`/api/json/audit-tail?after=0&limit=20`,`Recent eval events (live feed)`],[`/api/json/daemon-status`,`Daemon PID, status, log tail`],[`/api/json/evald-log`,`Last 200 lines of evald.log (daemon stderr)`],[`/healthz`,`Process liveness`],[`/readyz`,`SQLite liveness`]].map(([e,t])=>(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[#333]`,children:`GET`}),(0,I.jsx)(`a`,{href:e,target:`_blank`,rel:`noreferrer`,className:`text-amber-600 hover:text-amber-400 transition-colors`,children:e}),(0,I.jsxs)(`span`,{className:`text-[#333] hidden sm:inline`,children:[`— `,t]})]},e))})]})]})]})}var Or=`ssg-dashboard-tabs`,kr=2e3,Ar=6e3;function jr(){return`tab-${Date.now()}-${Math.random().toString(36).slice(2,7)}`}function Mr(){let[e,t]=(0,_.useState)(0),[n,r]=(0,_.useState)(!0),i=(0,_.useRef)(jr()),a=(0,_.useRef)(new Map);return(0,_.useEffect)(()=>{if(typeof BroadcastChannel>`u`)return;let e=new BroadcastChannel(Or);function n(){let e=Date.now();for(let[t,n]of a.current.entries())e-n>Ar&&a.current.delete(t);let n=a.current.size;t(n),r([...a.current.keys(),i.current].sort()[0]===i.current)}function o(e){let t=e.data;!t||t.id===i.current||(t.type===`leave`?a.current.delete(t.id):a.current.set(t.id,Date.now()),n())}e.addEventListener(`message`,o),e.postMessage({type:`join`,id:i.current});let s=setInterval(()=>{e.postMessage({type:`heartbeat`,id:i.current}),n()},kr),c=()=>{e.postMessage({type:`leave`,id:i.current})};return window.addEventListener(`beforeunload`,c),()=>{clearInterval(s),e.postMessage({type:`leave`,id:i.current}),e.removeEventListener(`message`,o),e.close(),window.removeEventListener(`beforeunload`,c)}},[]),{otherTabCount:e,isLeader:n}}var Nr=[{path:`/`,label:`Dashboard`},{path:`/rules`,label:`Rules`},{path:`/audit`,label:`Audit`},{path:`/approvals`,label:`Approvals`},{path:`/hub`,label:`Hub`},{path:`/profile`,label:`Profile`},{path:`/monitor`,label:`Monitor`},{path:`/observability`,label:`Observability`}];function Pr(e){let t=Math.max(0,e-Date.now()),n=Math.floor(t/1e3);if(n<60)return`${n}s`;let r=Math.floor(n/60);return r<60?`${r}m ${n%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function Fr(){let{data:e}=E(`/api/json/daemon-status`,[se([`stats-changed`])[`stats-changed`]]),[t,n]=(0,_.useState)(!1),[,r]=(0,_.useState)(0);(0,_.useEffect)(()=>{if(e?.status!==`degraded`||!e.hibernation)return;let t=setInterval(()=>r(e=>e+1),1e3);return()=>clearInterval(t)},[e?.status,e?.hibernation]);let i=e?.status??`starting`,a=i===`running`?`bg-green-500`:i===`starting`?`bg-amber-400`:i===`degraded`?`bg-amber-500`:`bg-red-500`,o=i===`degraded`&&e?.hibernation?Pr(e.hibernation.nextRetryAt):null,s=i===`running`?`Daemon running`:i===`starting`?`Daemon starting…`:i===`degraded`?`Daemon hibernating — retry in ${o??`…`}`:i===`error`?`Daemon error`:`Daemon stopped`;return(0,I.jsxs)(`div`,{className:`relative`,children:[(0,I.jsxs)(`button`,{onClick:()=>n(e=>!e),className:`flex items-center gap-1.5 text-xs text-[#666] hover:text-[#aaa] transition-colors`,title:s,children:[(0,I.jsx)(`span`,{className:`inline-block w-2 h-2 rounded-full ${a}`}),(0,I.jsx)(`span`,{className:`hidden sm:inline`,children:s})]}),t&&(0,I.jsxs)(`div`,{className:`absolute right-0 top-7 z-50 w-72 bg-[#111] border border-[#222] rounded-lg shadow-xl p-3 text-xs`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,I.jsx)(`span`,{className:`font-medium text-[#ddd]`,children:`Eval Daemon`}),(0,I.jsx)(`button`,{onClick:()=>n(!1),className:`text-[#555] hover:text-[#aaa]`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`space-y-1 text-[#888]`,children:[(0,I.jsxs)(`div`,{children:[`Status:`,` `,(0,I.jsx)(`span`,{className:i===`running`?`text-green-400`:i===`starting`||i===`degraded`?`text-amber-400`:`text-red-400`,children:i})]}),e?.pid&&(0,I.jsxs)(`div`,{children:[`PID: `,e.pid]}),i===`degraded`&&e?.hibernation&&(0,I.jsxs)(`div`,{className:`mt-1 rounded border border-amber-500/20 bg-amber-500/5 p-2 text-[10px] text-amber-300 space-y-0.5`,children:[(0,I.jsxs)(`div`,{children:[`Next retry: `,(0,I.jsx)(`span`,{className:`font-medium`,children:o})]}),(0,I.jsxs)(`div`,{children:[`Episode attempt: `,e.hibernation.attempt,e.hibernation.reason?` (${e.hibernation.reason})`:``]}),(0,I.jsx)(`div`,{className:`text-amber-400/70`,children:`Slow-tier supervisor is retrying at long backoff — no manual restart required.`})]})]}),e?.logTail&&e.logTail.length>0&&(0,I.jsxs)(`div`,{className:`mt-2`,children:[(0,I.jsx)(`div`,{className:`text-[#555] mb-1`,children:`Recent log:`}),(0,I.jsx)(`pre`,{className:`bg-[#0a0a0a] rounded p-2 text-[10px] text-[#777] overflow-x-auto whitespace-pre-wrap break-all max-h-32 overflow-y-auto`,children:e.logTail.join(`
|
|
19
|
+
`)})]})]})]})}function Ir(){let{data:e}=E(`/api/json/mcp-status`,[se([`audit-changed`])[`audit-changed`]]),t=e?.status??`inactive`;if(t===`inactive`)return null;let n=t===`active`?`bg-blue-500`:`bg-[#444]`,r=t===`active`?`MCP active`:`MCP idle`;return(0,I.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-[#555]`,title:t===`active`?`MCP server: ${e?.recentCount??0} evals in last 5 min`:`MCP server: ${e?.totalCount??0} total evals`,children:[(0,I.jsx)(`span`,{className:`inline-block w-2 h-2 rounded-full ${n}`}),(0,I.jsx)(`span`,{className:`hidden sm:inline`,children:r})]})}function Lr(e){if(e===`/`)return(0,I.jsx)(cn,{});if(e===`/rules`)return(0,I.jsx)(hn,{});if(e===`/audit`)return(0,I.jsx)(yn,{});if(e===`/approvals`)return(0,I.jsx)(On,{});if(e===`/profile`)return(0,I.jsx)(Un,{});if(e===`/hub/connect`)return(0,I.jsx)(er,{});if(e===`/hub/publish`)return(0,I.jsx)(tr,{});if(e.startsWith(`/hub/`)){let t=e.slice(5);if(t)return(0,I.jsx)($n,{id:t})}return e===`/hub`?(0,I.jsx)(Zn,{}):e===`/monitor`?(0,I.jsx)(fr,{}):e===`/observability`?(0,I.jsx)(Dr,{}):(0,I.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-24 text-[#555]`,children:[(0,I.jsx)(`p`,{className:`text-lg`,children:`404 — Page not found`}),(0,I.jsx)(`a`,{href:`/`,className:`mt-4 text-amber-400 hover:underline text-sm`,children:`Back to Dashboard`})]})}function Rr(e){history.pushState(null,``,e),window.dispatchEvent(new PopStateEvent(`popstate`))}function zr({count:e}){let[t,n]=(0,_.useState)(!1);return t||e===0?null:(0,I.jsx)(`div`,{className:`border-b border-amber-500/20 bg-amber-500/5 px-4 py-2`,children:(0,I.jsxs)(`div`,{className:`max-w-7xl mx-auto flex items-center gap-3`,children:[(0,I.jsxs)(`svg`,{className:`shrink-0 text-amber-400`,width:`14`,height:`14`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,I.jsx)(`path`,{d:`M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z`}),(0,I.jsx)(`line`,{x1:`12`,y1:`9`,x2:`12`,y2:`13`}),(0,I.jsx)(`line`,{x1:`12`,y1:`17`,x2:`12.01`,y2:`17`})]}),(0,I.jsxs)(`p`,{className:`text-xs text-amber-300 flex-1`,children:[(0,I.jsxs)(`span`,{className:`font-semibold`,children:[e,` other `,e===1?`tab is`:`tabs are`,` open.`]}),` `,`Each tab holds a live SSE connection. Browsers limit connections per origin — too many tabs will prevent this page from loading CSS and JS.`,` `,(0,I.jsx)(`span`,{className:`text-amber-400/70`,children:`Close other tabs to restore full live-update functionality.`})]}),(0,I.jsx)(`button`,{onClick:()=>n(!0),className:`text-amber-500/50 hover:text-amber-400 transition-colors shrink-0 cursor-pointer`,title:`Dismiss`,children:(0,I.jsxs)(`svg`,{width:`14`,height:`14`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,I.jsx)(`line`,{x1:`18`,y1:`6`,x2:`6`,y2:`18`}),(0,I.jsx)(`line`,{x1:`6`,y1:`6`,x2:`18`,y2:`18`})]})})]})})}function Br(){let[e,t]=(0,_.useState)(window.location.pathname),{otherTabCount:n}=Mr();(0,_.useEffect)(()=>{let e=()=>t(window.location.pathname);return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},[]),(0,_.useEffect)(()=>{let e=e=>{let t=e.target.closest(`a`);if(!t)return;let n=t.getAttribute(`href`);!n||n.startsWith(`http`)||n.startsWith(`//`)||(e.preventDefault(),Rr(n))};return document.addEventListener(`click`,e),()=>document.removeEventListener(`click`,e)},[]);let r=t=>t===`/`?e===`/`:e.startsWith(t);return(0,I.jsxs)(`div`,{className:`min-h-screen bg-[#080808] text-white`,children:[(0,I.jsxs)(`header`,{className:`border-b border-[#1e1e1e] sticky top-0 z-50 bg-[#080808]/95 backdrop-blur`,children:[(0,I.jsxs)(`div`,{className:`max-w-7xl mx-auto px-4 flex items-center h-12 gap-6`,children:[(0,I.jsx)(`span`,{className:`text-amber-400 font-bold text-sm tracking-tight select-none`,children:`ssg`}),(0,I.jsx)(`nav`,{className:`flex items-center gap-1`,children:Nr.map(e=>(0,I.jsx)(`a`,{href:e.path,className:`px-3 py-1.5 rounded text-sm transition-colors ${r(e.path)?`bg-[#1a1a1a] text-white`:`text-[#888] hover:text-white hover:bg-[#111]`}`,children:e.label},e.path))}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3 ml-auto`,children:[n>0&&(0,I.jsxs)(`span`,{className:`text-xs text-amber-400/70 border border-amber-500/20 rounded px-1.5 py-0.5`,title:`${n} other tab${n===1?``:`s`} open — may cause connection issues`,children:[n+1,` tabs open`]}),(0,I.jsx)(Ir,{}),(0,I.jsx)(Fr,{})]})]}),(0,I.jsx)(zr,{count:n})]}),(0,I.jsx)(`main`,{className:`max-w-7xl mx-auto px-4 py-6`,children:Lr(e)})]})}var Vr=document.getElementById(`app-root`);if(!Vr)throw Error(`Missing #app-root`);g.createRoot(Vr).render((0,I.jsx)(_.StrictMode,{children:(0,I.jsx)(Br,{})}));
|