failproofai 0.0.14-beta.2 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  10. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  11. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  12. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  13. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  14. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  21. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  22. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +9 -9
  23. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  24. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  25. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  26. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  35. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/index.html +1 -1
  38. package/.next/standalone/.next/server/app/index.rsc +14 -14
  39. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  40. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  41. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  42. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +9 -9
  43. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  44. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  45. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  47. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  48. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  51. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  54. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  57. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  58. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q2nbsl._.js +1 -1
  61. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +1 -1
  62. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1mrihkj._.js +1 -1
  63. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +1 -1
  64. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +1 -1
  65. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
  66. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  67. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__015_i4t._.js +2 -2
  68. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__03lv-pe._.js +2 -2
  69. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hdsupo._.js +2 -2
  70. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qeuy9c._.js +2 -2
  71. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s89hoe._.js +2 -2
  72. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ynf7tx._.js +2 -2
  73. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0twi4fj._.js → [root-of-the-server]__0zf8xlq._.js} +2 -2
  74. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__170799-._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17ai7sy._.js +2 -2
  76. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__09v9cwb._.js → [root-of-the-server]__1s2b6h0._.js} +2 -2
  77. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tkjqka._.js +2 -2
  78. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  79. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  80. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  81. package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_06xsmte.js → node_modules_html-to-image_es_index_0gkzjaa.js} +1 -1
  82. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +1 -1
  83. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  84. package/.next/standalone/.next/server/pages/404.html +1 -1
  85. package/.next/standalone/.next/server/pages/500.html +1 -1
  86. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  87. package/.next/standalone/.next/server/server-reference-manifest.json +10 -10
  88. package/.next/standalone/.next/static/chunks/{0pndjhcxfu-0t.js → 06z_ex1ts3n4s.js} +1 -1
  89. package/.next/standalone/.next/static/chunks/{396764jgd7-9j.js → 0o0ut0ugd0_-s.js} +1 -1
  90. package/.next/standalone/.next/static/chunks/{1-33f82_l32or.js → 0xl97x-874k-u.js} +1 -1
  91. package/.next/standalone/.next/static/chunks/19d7hqx8udopz.js +1 -0
  92. package/.next/standalone/.next/static/chunks/{29zkom4s9de2d.js → 29o4j32z643_a.js} +1 -1
  93. package/.next/standalone/.next/static/chunks/{1gg-8e9q_m__9.js → 2uh_4k4m296z5.js} +1 -1
  94. package/.next/standalone/.next/static/chunks/370sj2lgkw5ey.js +1 -0
  95. package/.next/standalone/.next/static/chunks/{2llkdafnaejw_.js → 3s8aaig91937v.js} +1 -1
  96. package/.next/standalone/.next/static/chunks/{0h-6ymo9v86b0.js → 42oeva1-w0z2d.js} +2 -2
  97. package/.next/standalone/app/components/log-viewer/entry-row.tsx +8 -3
  98. package/.next/standalone/app/components/raw-log-viewer.tsx +33 -15
  99. package/.next/standalone/app/policies/hooks-client.tsx +1 -1
  100. package/.next/standalone/lib/entry-keys.ts +36 -0
  101. package/.next/standalone/package.json +5 -4
  102. package/.next/standalone/server.js +1 -1
  103. package/dist/cli.mjs +2 -2
  104. package/lib/entry-keys.ts +36 -0
  105. package/package.json +5 -4
  106. package/.next/standalone/.next/static/chunks/1bg_g3g359c_d.js +0 -1
  107. package/.next/standalone/.next/static/chunks/388hgfqye67xa.js +0 -1
  108. /package/.next/standalone/.next/static/{YKxI22hC-F_nHp7MEKfb1 → WQRKgSfFekLcC_pvyzp4S}/_buildManifest.js +0 -0
  109. /package/.next/standalone/.next/static/{YKxI22hC-F_nHp7MEKfb1 → WQRKgSfFekLcC_pvyzp4S}/_clientMiddlewareManifest.js +0 -0
  110. /package/.next/standalone/.next/static/{YKxI22hC-F_nHp7MEKfb1 → WQRKgSfFekLcC_pvyzp4S}/_ssgManifest.js +0 -0
@@ -1,6 +1,6 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,64245,e=>{"use strict";var t=e.i(43476),s=e.i(71645),r=e.i(74080),n=e.i(22016),a=e.i(84026),l=e.i(29407),i=e.i(16306),o=e.i(82954),c=e.i(16327),d=e.i(8734),m=e.i(89664),x=e.i(66794);let u=(0,e.i(56420).default)("code",[["path",{d:"m16 18 6-6-6-6",key:"eg8j8"}],["path",{d:"m8 6-6 6 6 6",key:"ppft3o"}]]);var p=e.i(63676),h=e.i(73520),g=e.i(95187);let f=(0,g.createServerReference)("4004958e33e75e8bc6435bea1e10b47c585428c48a",g.callServer,void 0,g.findSourceMapURL,"getHookActivityAction");var b=e.i(28744);let j=(0,g.createServerReference)("00925efb346984bdc719e3f5c64ef399a506463916",g.callServer,void 0,g.findSourceMapURL,"getHooksConfigAction"),v=(0,g.createServerReference)("60f231f254e13f18e70b324dcf5ed4a0f3909cc821",g.callServer,void 0,g.findSourceMapURL,"togglePolicyAction"),y=(0,g.createServerReference)("60eaa43afe7e6f103dc7e915dde3ce20123cb6b6a3",g.callServer,void 0,g.findSourceMapURL,"installHooksWebAction"),N=(0,g.createServerReference)("604cdba06bf5307f718455154e4aa9e5e55f615c2c",g.callServer,void 0,g.findSourceMapURL,"removeHooksWebAction"),w=(0,g.createServerReference)("60a6e124ded6fa483e861c0c05bdec6cdc54698bcd",g.callServer,void 0,g.findSourceMapURL,"updatePolicyParamsAction");var k=e.i(85881),S=e.i(12344),C=e.i(80060),_=e.i(2711),P=e.i(24578),I=e.i(34713),T=e.i(67881);function $({sessionId:e,transcriptPath:s,integration:r,cwd:a}){if(!e)return(0,t.jsx)("span",{className:"text-muted-foreground",children:"\\u2014"});let l=e?e.slice(0,8):"—",i="codex"===r||(s?.includes("/.codex/")??!1),o="copilot"===r||(s?.includes("/.copilot/session-state/")??!1),c="cursor"===r||(s?.includes("/.cursor/")??!1),d="opencode"===r||(s?.includes("/.local/share/opencode/")??!1)||(s?.includes("/.opencode/")??!1),m="pi"===r||(s?.includes("/.pi/")??!1);if(i||o||c||d||m){let s,r=a?(s=/^([A-Za-z]):[\\/](.*)$/.exec(a))?s[1]+"--"+s[2].replace(/[\\/]/g,"-"):a.replace(/[\\/]/g,"-"):i?"codex":o?"copilot":c?"cursor":d?"opencode":"pi";return(0,t.jsx)(n.default,{href:`/project/${encodeURIComponent(r)}/session/${encodeURIComponent(e)}`,className:"text-primary hover:underline font-mono",onClick:e=>e.stopPropagation(),children:l})}let x=s?function(e){let t=e.replace(/\\/g,"/").split("/").filter(Boolean);if(t.length<2)return null;let s=t[t.length-2];return!s||s.startsWith(".")?null:s}(s):null;return x?(0,t.jsx)(n.default,{href:`/project/${encodeURIComponent(x)}/session/${encodeURIComponent(e)}`,className:"text-primary hover:underline font-mono",onClick:e=>e.stopPropagation(),children:l}):(0,t.jsx)("span",{className:"text-muted-foreground font-mono",children:l})}function A({decision:e}){return"deny"===e?(0,t.jsxs)("span",{className:"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[0.65rem] font-semibold tracking-wide uppercase bg-red-500/10 text-red-400 border border-red-500/20",children:[(0,t.jsx)(l.ShieldX,{className:"h-3 w-3"}),"Deny"]}):"instruct"===e?(0,t.jsxs)("span",{className:"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[0.65rem] font-semibold tracking-wide uppercase bg-amber-500/10 text-amber-400 border border-amber-500/20",children:[(0,t.jsx)(i.ShieldAlert,{className:"h-3 w-3"}),"Instruct"]}):(0,t.jsxs)("span",{className:"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[0.65rem] font-semibold tracking-wide uppercase bg-emerald-500/10 text-emerald-400 border border-emerald-500/20",children:[(0,t.jsx)(a.ShieldCheck,{className:"h-3 w-3"}),"Allow"]})}function R({eventType:e}){return(0,t.jsx)("span",{className:"inline-flex items-center rounded px-1.5 py-0.5 text-[0.6rem] font-medium bg-muted text-muted-foreground border border-border/50",children:e})}function L({integration:e}){if(!e)return null;let s=(0,P.getCliLabel)(e),r=(0,P.getCliBadgeClasses)(e);return(0,t.jsx)("span",{className:`inline-flex items-center rounded px-1.5 py-0.5 text-[0.6rem] font-medium border ${r}`,title:`Agent CLI: ${s}`,children:s})}function E({mode:e}){let s="default"===e;return(0,t.jsx)("span",{title:e,className:`inline-block max-w-full truncate rounded px-1.5 py-0.5 align-middle text-[0.6rem] font-medium border ${s?"bg-sky-500/10 text-sky-400 border-sky-500/20":"bg-amber-500/10 text-amber-400 border-amber-500/20"}`,children:e})}function U({ms:e}){return(0,t.jsx)("span",{className:`font-mono text-[0.7rem] ${e>500?"text-red-400":e>100?"text-amber-400":"text-muted-foreground"}`,children:e<1e3?`${e}ms`:`${(e/1e3).toFixed(1)}s`})}function z({text:e,field:r}){let[n,a]=(0,s.useState)(!1),{capture:l}=(0,S.usePostHog)(),i=async t=>{t.stopPropagation(),l("activity_copy_clicked",{field:r??"unknown"});try{await navigator.clipboard.writeText(e),a(!0),setTimeout(()=>a(!1),1500)}catch{let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t),a(!0),setTimeout(()=>a(!1),1500)}};return(0,t.jsx)("button",{onClick:i,className:"inline-flex items-center justify-center h-5 w-5 rounded hover:bg-muted/50 text-muted-foreground hover:text-foreground transition-colors",title:"Copy",children:n?(0,t.jsx)(m.Check,{className:"h-3 w-3 text-emerald-400"}):(0,t.jsx)(d.Copy,{className:"h-3 w-3"})})}function F({value:e,onChange:s}){return(0,t.jsx)("div",{className:"inline-flex items-center rounded-md border border-border bg-muted/30 p-0.5",children:[{label:"All",value:""},{label:"Allow",value:"allow"},{label:"Instruct",value:"instruct"},{label:"Deny",value:"deny"}].map(r=>(0,t.jsx)("button",{onClick:()=>s(r.value),className:`px-2.5 py-1 text-[0.65rem] font-medium rounded transition-all ${e===r.value?"deny"===r.value?"bg-red-500/15 text-red-400 shadow-sm":"allow"===r.value?"bg-emerald-500/15 text-emerald-400 shadow-sm":"instruct"===r.value?"bg-amber-500/15 text-amber-400 shadow-sm":"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"}`,children:r.label},r.value))})}function D({stats:e}){let s=e.totalEvents>0?e.denyCount/e.totalEvents*100:0,r=s.toFixed(s>=10?0:1),n=0===e.denyCount?"":s>=5?" is-deny":s>=2?" is-warn":"";return(0,t.jsxs)("div",{className:"stat-bar",role:"group","aria-label":"Activity stats",children:[(0,t.jsxs)("div",{className:"stat-cell",children:[(0,t.jsx)("span",{className:"eyebrow",children:"total events"}),(0,t.jsx)("span",{className:"value",children:e.totalEvents.toLocaleString()}),(0,t.jsx)("span",{className:"meta",children:"across all installed agents"})]}),(0,t.jsxs)("div",{className:"stat-cell",children:[(0,t.jsx)("span",{className:"eyebrow",children:"deny rate"}),(0,t.jsxs)("span",{className:`value${n}`,children:[r,"%"]}),(0,t.jsxs)("span",{className:"meta",children:[e.denyCount.toLocaleString()," of ",e.totalEvents.toLocaleString()," denied"]})]}),(0,t.jsxs)("div",{className:"stat-cell",children:[(0,t.jsx)("span",{className:"eyebrow",children:"top policy"}),(0,t.jsx)("span",{className:"value",style:{fontSize:16,fontWeight:500,color:e.topPolicy?"var(--accent-pink)":"var(--dim)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:e.topPolicy??void 0,children:e.topPolicy??"—"}),(0,t.jsx)("span",{className:"meta",children:"most-evaluated policy in scope"})]})]})}function O({item:e}){return(0,t.jsx)("tr",{children:(0,t.jsx)("td",{colSpan:11,className:"px-0 py-0",children:(0,t.jsxs)("div",{className:"activity-detail animate-expand text-xs",children:[(0,t.jsxs)("span",{className:"activity-detail-eyebrow",children:[(0,t.jsx)("span",{"aria-hidden":"true",children:"\\u25be"}),"event detail"]}),(0,t.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-2",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"Session ID: "}),(0,t.jsx)("span",{className:"font-mono text-foreground",children:e.sessionId??"—"}),e.sessionId&&(0,t.jsx)(z,{text:e.sessionId,field:"session_id"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"CWD: "}),(0,t.jsx)("span",{className:"font-mono text-foreground",children:e.cwd??"—"}),e.cwd&&(0,t.jsx)(z,{text:e.cwd,field:"cwd"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"Transcript: "}),(0,t.jsx)("span",{className:"font-mono text-foreground break-all",children:e.transcriptPath??"—"}),e.transcriptPath?.startsWith("opencode-db://")&&(0,t.jsx)("span",{className:"text-muted-foreground ml-1",children:"(stored in opencode DB)"})]})]}),e.policyNames&&e.policyNames.length>1&&(0,t.jsxs)("div",{style:{marginTop:8},children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"Policies: "}),(0,t.jsx)("span",{className:"font-mono text-foreground",children:e.policyNames.join(", ")})]}),e.reason&&(0,t.jsxs)("div",{style:{marginTop:8},children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"Full reason: "}),(0,t.jsx)("span",{className:"text-foreground",children:e.reason})]})]})})})}function B({hooksInstalled:e,onSwitchTab:r}){let{intervalSec:n}=(0,k.useAutoRefresh)(),{capture:a}=(0,S.usePostHog)(),l=(0,C.useUrlParams)(),i=(0,s.useRef)(!1),[d,m]=(0,s.useState)(()=>(0,_.paramToPage)(l.get("page"))),[x,u]=(0,s.useState)(null),[p,g]=(0,s.useState)(null),[j,v]=(0,s.useState)(()=>{let e=l.get("decision");return"allow"===e||"deny"===e||"instruct"===e?e:""}),[y,N]=(0,s.useState)(()=>l.get("event")??""),[w,T]=(0,s.useState)(()=>l.get("policy")??""),[z,W]=(0,s.useState)(()=>l.get("session")??""),[H,M]=(0,s.useState)(()=>{let e=l.get("cli");return(0,P.isKnownCli)(e)?e:""}),X=(0,s.useRef)(null),J=(0,s.useRef)(!0),K=(0,s.useRef)({filterDecision:j,filterEventType:y,filterPolicy:w,filterSessionId:z,filterCli:H});K.current={filterDecision:j,filterEventType:y,filterPolicy:w,filterSessionId:z,filterCli:H},(0,s.useEffect)(()=>{if(!i.current){i.current=!0;return}l.setAll({decision:j||void 0,event:y||void 0,policy:w||void 0,session:z||void 0,cli:H||void 0,page:(0,_.pageToParam)(d)})},[j,y,w,z,H,d]);let q=""!==j||""!==y||""!==w||""!==z||""!==H,G=(0,s.useCallback)(async e=>{try{let t,{filterDecision:s,filterEventType:r,filterPolicy:n,filterSessionId:a,filterCli:l}=K.current;t=""!==s||""!==r||""!==n||""!==a||""!==l?await (0,b.searchHookActivityAction)({decision:s||void 0,eventType:r||void 0,policyName:n||void 0,sessionId:a||void 0,integration:l||void 0},e):await f(e),u(t)}catch{}},[]);(0,s.useEffect)(()=>{G(d);let e=setInterval(()=>G(d),n>0?1e3*n:5e3);return()=>clearInterval(e)},[d,G,n]),(0,s.useEffect)(()=>(X.current&&clearTimeout(X.current),X.current=setTimeout(()=>{if(m(1),g(null),G(1),J.current){J.current=!1;return}a("activity_filter_changed",{active_filter_count:+(""!==j)+ +(""!==y)+ +(""!==w)+ +(""!==z)+ +(""!==H),has_decision:""!==j,has_event_type:""!==y,has_policy:""!==w,has_session:""!==z,has_cli:""!==H,decision:j||null,event_type:y||null,cli:H||null})},300),()=>{X.current&&clearTimeout(X.current)}),[j,y,w,z,H]);let V=x?.entries??[],Z=x?.totalPages??1;return(0,t.jsxs)(t.Fragment,{children:[x?.stats&&x.stats.totalEvents>0&&(0,t.jsx)("div",{style:{marginBottom:18},children:(0,t.jsx)(D,{stats:x.stats})}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"filter-bar",children:[(0,t.jsxs)("div",{className:"filter-group",children:[(0,t.jsx)("span",{className:"filter-label",children:"decision"}),(0,t.jsx)(F,{value:j,onChange:v})]}),(0,t.jsxs)("div",{className:"filter-group",children:[(0,t.jsx)("span",{className:"filter-label",children:"event"}),(0,t.jsxs)("select",{value:y,onChange:e=>N(e.target.value),className:"filter-input",children:[(0,t.jsx)("option",{value:"",children:"all events"}),(0,t.jsx)("option",{value:"PreToolUse",children:"PreToolUse"}),(0,t.jsx)("option",{value:"PostToolUse",children:"PostToolUse"}),(0,t.jsx)("option",{value:"SessionStart",children:"SessionStart"}),(0,t.jsx)("option",{value:"SessionEnd",children:"SessionEnd"}),(0,t.jsx)("option",{value:"UserPromptSubmit",children:"UserPromptSubmit"}),(0,t.jsx)("option",{value:"PermissionRequest",children:"PermissionRequest"})]})]}),(0,t.jsxs)("div",{className:"filter-group",children:[(0,t.jsx)("span",{className:"filter-label",children:"cli"}),(0,t.jsxs)("select",{value:H,onChange:e=>{let t=e.target.value;M(""===t||(0,P.isKnownCli)(t)?t:"")},className:"filter-input","aria-label":"Filter by CLI",children:[(0,t.jsx)("option",{value:"",children:"all clis"}),P.KNOWN_CLI_IDS.map(e=>(0,t.jsx)("option",{value:e,children:(0,P.getCliLabel)(e)},e))]})]}),(0,t.jsxs)("div",{className:"filter-group filter-group--grow",children:[(0,t.jsx)("span",{className:"filter-label",children:"policy"}),(0,t.jsx)("input",{type:"text",value:w,onChange:e=>T(e.target.value),placeholder:"filter by policy\\u2026",className:"filter-input"})]}),(0,t.jsxs)("div",{className:"filter-group filter-group--grow",children:[(0,t.jsx)("span",{className:"filter-label",children:"session"}),(0,t.jsx)("input",{type:"text",value:z,onChange:e=>W(e.target.value),placeholder:"filter by session…",className:"filter-input"})]}),q&&(0,t.jsx)("button",{type:"button",className:"filter-clear",onClick:()=>{v(""),N(""),M(""),T(""),W("")},"aria-label":"Clear all filters",children:"[ clear ]"})]}),0===V.length?(0,t.jsxs)("div",{className:"flex flex-col items-center justify-center py-16 px-4 text-center",children:[(0,t.jsx)(o.Shield,{className:"h-12 w-12 text-muted-foreground/30"}),!1===e?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-sm text-muted-foreground mt-4 font-medium",children:"Policies are not installed"}),(0,t.jsxs)("p",{className:"text-xs text-muted-foreground mt-1 max-w-sm",children:["Go to the"," ",(0,t.jsx)("button",{className:"underline hover:text-foreground transition-colors",onClick:()=>r?.("policies"),children:"Policies tab"})," ","and click ",(0,t.jsx)("span",{className:"font-mono bg-muted px-1 rounded",children:"Install"})," to enable policy monitoring."]})]}):(0,t.jsx)("p",{className:"text-sm text-muted-foreground mt-4",children:q?"No matching activity.":"Waiting for hook events…"})]}):(0,t.jsx)("div",{className:"overflow-x-auto activity-table-wrap",children:(0,t.jsxs)("table",{className:"w-full text-xs activity-table",style:{tableLayout:"fixed"},children:[(0,t.jsxs)("colgroup",{children:[(0,t.jsx)("col",{style:{width:32}}),(0,t.jsx)("col",{style:{width:"7%"}}),(0,t.jsx)("col",{style:{width:"9%"}}),(0,t.jsx)("col",{style:{width:"12%"}}),(0,t.jsx)("col",{style:{width:"11%"}}),(0,t.jsx)("col",{style:{width:"9%"}}),(0,t.jsx)("col",{style:{width:"13%"}}),(0,t.jsx)("col",{style:{width:"12%"}}),(0,t.jsx)("col",{style:{width:"11%"}}),(0,t.jsx)("col",{style:{width:"8%"}}),(0,t.jsx)("col",{style:{width:"8%"}})]}),(0,t.jsx)("thead",{className:"activity-thead",children:(0,t.jsxs)("tr",{children:[(0,t.jsx)("th",{className:"px-4 py-3"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Time"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Decision"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Event"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"CLI"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Tool"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Policy"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Reason"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Mode"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Duration"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Session"})]})}),(0,t.jsx)("tbody",{className:"divide-y divide-border/30",children:V.map((e,r)=>{let n="deny"===e.decision,l=p===r,i="instruct"===e.decision;return(0,t.jsxs)(s.default.Fragment,{children:[(0,t.jsxs)("tr",{onClick:()=>{g(e=>{let t=e===r?null:r,s=V[r];return a("activity_row_toggled",{expanded:null!==t,decision:s?.decision??null,policy_name:s?.policyName??null,event_type:s?.eventType??null}),t})},className:`activity-data-row cursor-pointer transition-colors ${n?"bg-red-500/[0.03] hover:bg-red-500/[0.07] border-l-2 border-l-red-500/40":i?"bg-amber-500/[0.03] hover:bg-amber-500/[0.07] border-l-2 border-l-amber-500/40":r%2==0?"hover:bg-muted/30":"bg-muted/[0.04] hover:bg-muted/30"} ${l?"bg-muted/20":""}`,children:[(0,t.jsx)("td",{className:"px-4 py-2",children:(0,t.jsx)(c.ChevronDown,{className:`h-3.5 w-3.5 text-muted-foreground transition-transform duration-150 ${l?"rotate-0":"-rotate-90"}`})}),(0,t.jsx)("td",{className:"px-3 py-2 text-muted-foreground whitespace-nowrap",title:new Date(e.timestamp).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}),children:(0,I.formatRelativeTime)(e.timestamp)}),(0,t.jsx)("td",{className:"px-3 py-2",children:(0,t.jsx)(A,{decision:e.decision})}),(0,t.jsx)("td",{className:"px-3 py-2",children:(0,t.jsx)(R,{eventType:e.eventType})}),(0,t.jsx)("td",{className:"px-3 py-2",children:(0,t.jsx)(L,{integration:e.integration})}),(0,t.jsx)("td",{className:"px-3 py-2 font-mono text-foreground",children:e.toolName??"—"}),(0,t.jsx)("td",{className:"px-3 py-2 font-mono text-foreground",children:e.policyNames&&e.policyNames.length>1?(0,t.jsxs)("span",{title:e.policyNames.join(", "),children:[e.policyNames[0],(0,t.jsxs)("span",{className:"text-muted-foreground text-[0.6rem]",children:[" +",e.policyNames.length-1]})]}):e.policyName??"—"}),(0,t.jsx)("td",{className:"px-3 py-2 text-muted-foreground truncate",title:e.reason??"",children:e.reason??"—"}),(0,t.jsx)("td",{className:"px-3 py-2",children:e.permissionMode?(0,t.jsx)(E,{mode:e.permissionMode}):"—"}),(0,t.jsx)("td",{className:"px-3 py-2",children:(0,t.jsx)(U,{ms:e.durationMs})}),(0,t.jsx)("td",{className:"px-3 py-2",title:e.sessionId??"",children:(0,t.jsx)($,{sessionId:e.sessionId,transcriptPath:e.transcriptPath,integration:e.integration,cwd:e.cwd})})]}),l&&(0,t.jsx)(O,{item:e})]},`${e.timestamp}-${r}`)})})]})}),(0,t.jsx)(h.default,{currentPage:d,totalPages:Z,onPageChange:e=>{a("activity_pagination_changed",{from_page:d,to_page:e,total_pages:Z}),m(e),g(null)}})]})]})}function W({enabled:e,onChange:s,disabled:r}){return(0,t.jsx)("button",{onClick:s,disabled:r,className:`relative inline-flex h-4 w-7 shrink-0 items-center rounded-full transition-colors disabled:opacity-40 ${e?"bg-emerald-500":"bg-muted-foreground/30"}`,"aria-label":e?"Disable policy":"Enable policy",children:(0,t.jsx)("span",{className:`inline-block h-3 w-3 rounded-full bg-white shadow transition-transform ${e?"translate-x-3.5":"translate-x-0.5"}`})})}function H({policy:e,onClose:r,onSave:n}){let a=e.params??{},l=e.currentParams??{},[i,o]=(0,s.useState)(()=>{let e={};for(let[t,s]of Object.entries(a)){let r=t in l?l[t]:s.default;e[t]=r}return e});(0,s.useEffect)(()=>{let e=e=>{"Escape"===e.key&&r()};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[r]);let c=(e,t)=>{o(s=>({...s,[e]:t}))};return(0,t.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50",onClick:e=>{e.target===e.currentTarget&&r()},children:(0,t.jsxs)("div",{className:"bg-card border border-border rounded-lg shadow-xl w-full max-w-lg mx-4 max-h-[80vh] flex flex-col",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-b border-border",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-mono font-semibold text-foreground",children:e.name}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5",children:e.description})]}),(0,t.jsx)("button",{onClick:r,className:"text-muted-foreground hover:text-foreground transition-colors",children:(0,t.jsx)(p.X,{className:"h-4 w-4"})})]}),(0,t.jsx)("div",{className:"overflow-y-auto flex-1 px-4 py-4 space-y-4",children:Object.entries(a).map(([e,s])=>(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-semibold text-foreground mb-1 font-mono",children:e}),(0,t.jsx)("p",{className:"text-[0.65rem] text-muted-foreground mb-1.5",children:s.description}),((e,s)=>{let r=i[e];if("boolean"===s.type)return(0,t.jsxs)("label",{className:"flex items-center gap-2 cursor-pointer",children:[(0,t.jsx)("input",{type:"checkbox",checked:!!r,onChange:t=>c(e,t.target.checked),className:"rounded border-border"}),(0,t.jsx)("span",{className:"text-xs text-muted-foreground",children:s.description})]});if("number"===s.type)return(0,t.jsx)("input",{type:"number",value:"number"==typeof r?r:"",onChange:t=>c(e,Number(t.target.value)),className:"w-full h-7 rounded border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-primary/40"});if("string[]"===s.type){let s=Array.isArray(r)?r.join("\n"):"";return(0,t.jsx)("textarea",{value:s,onChange:t=>c(e,t.target.value.split("\n").filter(e=>""!==e.trim())),rows:4,placeholder:"One entry per line",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground font-mono focus:outline-none focus:ring-2 focus:ring-primary/40 resize-y"})}if("pattern[]"===s.type){let s=Array.isArray(r)?r:[];return(0,t.jsxs)("div",{className:"space-y-1.5",children:[s.map((r,n)=>(0,t.jsxs)("div",{className:"flex gap-1.5 items-center",children:[(0,t.jsx)("input",{type:"text",value:r.regex,onChange:t=>{let r=[...s];r[n]={...r[n],regex:t.target.value},c(e,r)},placeholder:"regex",className:"flex-1 h-6 rounded border border-border bg-background px-2 text-xs font-mono focus:outline-none focus:ring-2 focus:ring-primary/40"}),(0,t.jsx)("input",{type:"text",value:r.label,onChange:t=>{let r=[...s];r[n]={...r[n],label:t.target.value},c(e,r)},placeholder:"label",className:"flex-1 h-6 rounded border border-border bg-background px-2 text-xs focus:outline-none focus:ring-2 focus:ring-primary/40"}),(0,t.jsx)("button",{onClick:()=>c(e,s.filter((e,t)=>t!==n)),className:"text-muted-foreground/50 hover:text-destructive transition-colors",children:(0,t.jsx)(p.X,{className:"h-3.5 w-3.5"})})]},n)),(0,t.jsx)("button",{onClick:()=>c(e,[...s,{regex:"",label:""}]),className:"text-xs text-primary hover:underline",children:"+ Add pattern"})]})}return(0,t.jsx)("input",{type:"text",value:"string"==typeof r?r:"",onChange:t=>c(e,t.target.value),className:"w-full h-7 rounded border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-primary/40"})})(e,s)]},e))}),(0,t.jsxs)("div",{className:"flex items-center justify-end gap-2 px-4 py-3 border-t border-border",children:[(0,t.jsx)(T.Button,{variant:"outline",size:"sm",onClick:r,className:"h-7 text-xs",children:"Cancel"}),(0,t.jsx)(T.Button,{size:"sm",onClick:()=>n(i),className:"h-7 text-xs",children:"Save"})]})]})})}function M({message:e,onDismiss:s,onInstall:n,isPending:a}){let{capture:l}=(0,S.usePostHog)();return(0,r.createPortal)((0,t.jsxs)("div",{className:"fixed top-4 right-4 z-[9999] w-full max-w-sm",style:{animation:"slideInFromRight 0.25s ease-out"},children:[(0,t.jsx)("style",{children:`
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,64245,e=>{"use strict";var t=e.i(43476),s=e.i(71645),r=e.i(74080),n=e.i(22016),a=e.i(84026),l=e.i(29407),i=e.i(16306),o=e.i(82954),c=e.i(16327),d=e.i(8734),m=e.i(89664),x=e.i(66794);let u=(0,e.i(56420).default)("code",[["path",{d:"m16 18 6-6-6-6",key:"eg8j8"}],["path",{d:"m8 6-6 6 6 6",key:"ppft3o"}]]);var p=e.i(63676),h=e.i(73520),f=e.i(95187);let g=(0,f.createServerReference)("409a8011f18d94f84f5ebf30534677b4a8b6d81578",f.callServer,void 0,f.findSourceMapURL,"getHookActivityAction");var b=e.i(52951);let j=(0,f.createServerReference)("006d7443e613357829b40adaac068a115508df626b",f.callServer,void 0,f.findSourceMapURL,"getHooksConfigAction"),v=(0,f.createServerReference)("60072e86b97598b4347d7bdd6d89d607b1da0ce91b",f.callServer,void 0,f.findSourceMapURL,"togglePolicyAction"),y=(0,f.createServerReference)("60bf2ae748eb1404cd8cbd03c3fa8ece7d62ecdc1e",f.callServer,void 0,f.findSourceMapURL,"installHooksWebAction"),N=(0,f.createServerReference)("604ea829f89db034e3b8d54f85742b44192a13cf9f",f.callServer,void 0,f.findSourceMapURL,"removeHooksWebAction"),w=(0,f.createServerReference)("60cf60cbd7c61987a905fddb52447f5f33a926715f",f.callServer,void 0,f.findSourceMapURL,"updatePolicyParamsAction");var k=e.i(85881),S=e.i(12344),C=e.i(80060),_=e.i(2711),P=e.i(24578),I=e.i(34713),T=e.i(67881);function $({sessionId:e,transcriptPath:s,integration:r,cwd:a}){if(!e)return(0,t.jsx)("span",{className:"text-muted-foreground",children:"\\u2014"});let l=e?e.slice(0,8):"—",i="codex"===r||(s?.includes("/.codex/")??!1),o="copilot"===r||(s?.includes("/.copilot/session-state/")??!1),c="cursor"===r||(s?.includes("/.cursor/")??!1),d="opencode"===r||(s?.includes("/.local/share/opencode/")??!1)||(s?.includes("/.opencode/")??!1),m="pi"===r||(s?.includes("/.pi/")??!1);if(i||o||c||d||m){let s,r=a?(s=/^([A-Za-z]):[\\/](.*)$/.exec(a))?s[1]+"--"+s[2].replace(/[\\/]/g,"-"):a.replace(/[\\/]/g,"-"):i?"codex":o?"copilot":c?"cursor":d?"opencode":"pi";return(0,t.jsx)(n.default,{href:`/project/${encodeURIComponent(r)}/session/${encodeURIComponent(e)}`,className:"text-primary hover:underline font-mono",onClick:e=>e.stopPropagation(),children:l})}let x=s?function(e){let t=e.replace(/\\/g,"/").split("/").filter(Boolean);if(t.length<2)return null;let s=t[t.length-2];return!s||s.startsWith(".")?null:s}(s):null;return x?(0,t.jsx)(n.default,{href:`/project/${encodeURIComponent(x)}/session/${encodeURIComponent(e)}`,className:"text-primary hover:underline font-mono",onClick:e=>e.stopPropagation(),children:l}):(0,t.jsx)("span",{className:"text-muted-foreground font-mono",children:l})}function A({decision:e}){return"deny"===e?(0,t.jsxs)("span",{className:"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[0.65rem] font-semibold tracking-wide uppercase bg-red-500/10 text-red-400 border border-red-500/20",children:[(0,t.jsx)(l.ShieldX,{className:"h-3 w-3"}),"Deny"]}):"instruct"===e?(0,t.jsxs)("span",{className:"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[0.65rem] font-semibold tracking-wide uppercase bg-amber-500/10 text-amber-400 border border-amber-500/20",children:[(0,t.jsx)(i.ShieldAlert,{className:"h-3 w-3"}),"Instruct"]}):(0,t.jsxs)("span",{className:"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[0.65rem] font-semibold tracking-wide uppercase bg-emerald-500/10 text-emerald-400 border border-emerald-500/20",children:[(0,t.jsx)(a.ShieldCheck,{className:"h-3 w-3"}),"Allow"]})}function R({eventType:e}){return(0,t.jsx)("span",{className:"inline-flex items-center rounded px-1.5 py-0.5 text-[0.6rem] font-medium bg-muted text-muted-foreground border border-border/50",children:e})}function L({integration:e}){if(!e)return null;let s=(0,P.getCliLabel)(e),r=(0,P.getCliBadgeClasses)(e);return(0,t.jsx)("span",{className:`inline-flex items-center rounded px-1.5 py-0.5 text-[0.6rem] font-medium border ${r}`,title:`Agent CLI: ${s}`,children:s})}function E({mode:e}){let s="default"===e;return(0,t.jsx)("span",{title:e,className:`inline-block max-w-full truncate rounded px-1.5 py-0.5 align-middle text-[0.6rem] font-medium border ${s?"bg-sky-500/10 text-sky-400 border-sky-500/20":"bg-amber-500/10 text-amber-400 border-amber-500/20"}`,children:e})}function U({ms:e}){return(0,t.jsx)("span",{className:`font-mono text-[0.7rem] ${e>500?"text-red-400":e>100?"text-amber-400":"text-muted-foreground"}`,children:e<1e3?`${e}ms`:`${(e/1e3).toFixed(1)}s`})}function z({text:e,field:r}){let[n,a]=(0,s.useState)(!1),{capture:l}=(0,S.usePostHog)(),i=async t=>{t.stopPropagation(),l("activity_copy_clicked",{field:r??"unknown"});try{await navigator.clipboard.writeText(e),a(!0),setTimeout(()=>a(!1),1500)}catch{let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t),a(!0),setTimeout(()=>a(!1),1500)}};return(0,t.jsx)("button",{onClick:i,className:"inline-flex items-center justify-center h-5 w-5 rounded hover:bg-muted/50 text-muted-foreground hover:text-foreground transition-colors",title:"Copy",children:n?(0,t.jsx)(m.Check,{className:"h-3 w-3 text-emerald-400"}):(0,t.jsx)(d.Copy,{className:"h-3 w-3"})})}function F({value:e,onChange:s}){return(0,t.jsx)("div",{className:"inline-flex items-center rounded-md border border-border bg-muted/30 p-0.5",children:[{label:"All",value:""},{label:"Allow",value:"allow"},{label:"Instruct",value:"instruct"},{label:"Deny",value:"deny"}].map(r=>(0,t.jsx)("button",{onClick:()=>s(r.value),className:`px-2.5 py-1 text-[0.65rem] font-medium rounded transition-all ${e===r.value?"deny"===r.value?"bg-red-500/15 text-red-400 shadow-sm":"allow"===r.value?"bg-emerald-500/15 text-emerald-400 shadow-sm":"instruct"===r.value?"bg-amber-500/15 text-amber-400 shadow-sm":"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"}`,children:r.label},r.value))})}function D({stats:e}){let s=e.totalEvents>0?e.denyCount/e.totalEvents*100:0,r=s.toFixed(s>=10?0:1),n=0===e.denyCount?"":s>=5?" is-deny":s>=2?" is-warn":"";return(0,t.jsxs)("div",{className:"stat-bar",role:"group","aria-label":"Activity stats",children:[(0,t.jsxs)("div",{className:"stat-cell",children:[(0,t.jsx)("span",{className:"eyebrow",children:"total events"}),(0,t.jsx)("span",{className:"value",children:e.totalEvents.toLocaleString()}),(0,t.jsx)("span",{className:"meta",children:"across all installed agents"})]}),(0,t.jsxs)("div",{className:"stat-cell",children:[(0,t.jsx)("span",{className:"eyebrow",children:"deny rate"}),(0,t.jsxs)("span",{className:`value${n}`,children:[r,"%"]}),(0,t.jsxs)("span",{className:"meta",children:[e.denyCount.toLocaleString()," of ",e.totalEvents.toLocaleString()," denied"]})]}),(0,t.jsxs)("div",{className:"stat-cell",children:[(0,t.jsx)("span",{className:"eyebrow",children:"top policy"}),(0,t.jsx)("span",{className:"value",style:{fontSize:16,fontWeight:500,color:e.topPolicy?"var(--accent-pink)":"var(--dim)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:e.topPolicy??void 0,children:e.topPolicy??"—"}),(0,t.jsx)("span",{className:"meta",children:"most-evaluated policy in scope"})]})]})}function O({item:e}){return(0,t.jsx)("tr",{children:(0,t.jsx)("td",{colSpan:11,className:"px-0 py-0",children:(0,t.jsxs)("div",{className:"activity-detail animate-expand text-xs",children:[(0,t.jsxs)("span",{className:"activity-detail-eyebrow",children:[(0,t.jsx)("span",{"aria-hidden":"true",children:"\\u25be"}),"event detail"]}),(0,t.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-2",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"Session ID: "}),(0,t.jsx)("span",{className:"font-mono text-foreground",children:e.sessionId??"—"}),e.sessionId&&(0,t.jsx)(z,{text:e.sessionId,field:"session_id"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"CWD: "}),(0,t.jsx)("span",{className:"font-mono text-foreground",children:e.cwd??"—"}),e.cwd&&(0,t.jsx)(z,{text:e.cwd,field:"cwd"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"Transcript: "}),(0,t.jsx)("span",{className:"font-mono text-foreground break-all",children:e.transcriptPath??"—"}),e.transcriptPath?.startsWith("opencode-db://")&&(0,t.jsx)("span",{className:"text-muted-foreground ml-1",children:"(stored in opencode DB)"})]})]}),e.policyNames&&e.policyNames.length>1&&(0,t.jsxs)("div",{style:{marginTop:8},children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"Policies: "}),(0,t.jsx)("span",{className:"font-mono text-foreground",children:e.policyNames.join(", ")})]}),e.reason&&(0,t.jsxs)("div",{style:{marginTop:8},children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"Full reason: "}),(0,t.jsx)("span",{className:"text-foreground",children:e.reason})]})]})})})}function B({hooksInstalled:e,onSwitchTab:r}){let{intervalSec:n}=(0,k.useAutoRefresh)(),{capture:a}=(0,S.usePostHog)(),l=(0,C.useUrlParams)(),i=(0,s.useRef)(!1),[d,m]=(0,s.useState)(()=>(0,_.paramToPage)(l.get("page"))),[x,u]=(0,s.useState)(null),[p,f]=(0,s.useState)(null),[j,v]=(0,s.useState)(()=>{let e=l.get("decision");return"allow"===e||"deny"===e||"instruct"===e?e:""}),[y,N]=(0,s.useState)(()=>l.get("event")??""),[w,T]=(0,s.useState)(()=>l.get("policy")??""),[z,W]=(0,s.useState)(()=>l.get("session")??""),[H,M]=(0,s.useState)(()=>{let e=l.get("cli");return(0,P.isKnownCli)(e)?e:""}),X=(0,s.useRef)(null),J=(0,s.useRef)(!0),K=(0,s.useRef)({filterDecision:j,filterEventType:y,filterPolicy:w,filterSessionId:z,filterCli:H});K.current={filterDecision:j,filterEventType:y,filterPolicy:w,filterSessionId:z,filterCli:H},(0,s.useEffect)(()=>{if(!i.current){i.current=!0;return}l.setAll({decision:j||void 0,event:y||void 0,policy:w||void 0,session:z||void 0,cli:H||void 0,page:(0,_.pageToParam)(d)})},[j,y,w,z,H,d]);let q=""!==j||""!==y||""!==w||""!==z||""!==H,G=(0,s.useCallback)(async e=>{try{let t,{filterDecision:s,filterEventType:r,filterPolicy:n,filterSessionId:a,filterCli:l}=K.current;t=""!==s||""!==r||""!==n||""!==a||""!==l?await (0,b.searchHookActivityAction)({decision:s||void 0,eventType:r||void 0,policyName:n||void 0,sessionId:a||void 0,integration:l||void 0},e):await g(e),u(t)}catch{}},[]);(0,s.useEffect)(()=>{G(d);let e=setInterval(()=>G(d),n>0?1e3*n:5e3);return()=>clearInterval(e)},[d,G,n]),(0,s.useEffect)(()=>(X.current&&clearTimeout(X.current),X.current=setTimeout(()=>{if(m(1),f(null),G(1),J.current){J.current=!1;return}a("activity_filter_changed",{active_filter_count:+(""!==j)+ +(""!==y)+ +(""!==w)+ +(""!==z)+ +(""!==H),has_decision:""!==j,has_event_type:""!==y,has_policy:""!==w,has_session:""!==z,has_cli:""!==H,decision:j||null,event_type:y||null,cli:H||null})},300),()=>{X.current&&clearTimeout(X.current)}),[j,y,w,z,H]);let V=x?.entries??[],Z=x?.totalPages??1;return(0,t.jsxs)(t.Fragment,{children:[x?.stats&&x.stats.totalEvents>0&&(0,t.jsx)("div",{style:{marginBottom:18},children:(0,t.jsx)(D,{stats:x.stats})}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"filter-bar",children:[(0,t.jsxs)("div",{className:"filter-group",children:[(0,t.jsx)("span",{className:"filter-label",children:"decision"}),(0,t.jsx)(F,{value:j,onChange:v})]}),(0,t.jsxs)("div",{className:"filter-group",children:[(0,t.jsx)("span",{className:"filter-label",children:"event"}),(0,t.jsxs)("select",{value:y,onChange:e=>N(e.target.value),className:"filter-input",children:[(0,t.jsx)("option",{value:"",children:"all events"}),(0,t.jsx)("option",{value:"PreToolUse",children:"PreToolUse"}),(0,t.jsx)("option",{value:"PostToolUse",children:"PostToolUse"}),(0,t.jsx)("option",{value:"SessionStart",children:"SessionStart"}),(0,t.jsx)("option",{value:"SessionEnd",children:"SessionEnd"}),(0,t.jsx)("option",{value:"UserPromptSubmit",children:"UserPromptSubmit"}),(0,t.jsx)("option",{value:"PermissionRequest",children:"PermissionRequest"})]})]}),(0,t.jsxs)("div",{className:"filter-group",children:[(0,t.jsx)("span",{className:"filter-label",children:"cli"}),(0,t.jsxs)("select",{value:H,onChange:e=>{let t=e.target.value;M(""===t||(0,P.isKnownCli)(t)?t:"")},className:"filter-input","aria-label":"Filter by CLI",children:[(0,t.jsx)("option",{value:"",children:"all clis"}),P.KNOWN_CLI_IDS.map(e=>(0,t.jsx)("option",{value:e,children:(0,P.getCliLabel)(e)},e))]})]}),(0,t.jsxs)("div",{className:"filter-group filter-group--grow",children:[(0,t.jsx)("span",{className:"filter-label",children:"policy"}),(0,t.jsx)("input",{type:"text",value:w,onChange:e=>T(e.target.value),placeholder:"filter by policy…",className:"filter-input"})]}),(0,t.jsxs)("div",{className:"filter-group filter-group--grow",children:[(0,t.jsx)("span",{className:"filter-label",children:"session"}),(0,t.jsx)("input",{type:"text",value:z,onChange:e=>W(e.target.value),placeholder:"filter by session…",className:"filter-input"})]}),q&&(0,t.jsx)("button",{type:"button",className:"filter-clear",onClick:()=>{v(""),N(""),M(""),T(""),W("")},"aria-label":"Clear all filters",children:"[ clear ]"})]}),0===V.length?(0,t.jsxs)("div",{className:"flex flex-col items-center justify-center py-16 px-4 text-center",children:[(0,t.jsx)(o.Shield,{className:"h-12 w-12 text-muted-foreground/30"}),!1===e?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-sm text-muted-foreground mt-4 font-medium",children:"Policies are not installed"}),(0,t.jsxs)("p",{className:"text-xs text-muted-foreground mt-1 max-w-sm",children:["Go to the"," ",(0,t.jsx)("button",{className:"underline hover:text-foreground transition-colors",onClick:()=>r?.("policies"),children:"Policies tab"})," ","and click ",(0,t.jsx)("span",{className:"font-mono bg-muted px-1 rounded",children:"Install"})," to enable policy monitoring."]})]}):(0,t.jsx)("p",{className:"text-sm text-muted-foreground mt-4",children:q?"No matching activity.":"Waiting for hook events…"})]}):(0,t.jsx)("div",{className:"overflow-x-auto activity-table-wrap",children:(0,t.jsxs)("table",{className:"w-full text-xs activity-table",style:{tableLayout:"fixed"},children:[(0,t.jsxs)("colgroup",{children:[(0,t.jsx)("col",{style:{width:32}}),(0,t.jsx)("col",{style:{width:"7%"}}),(0,t.jsx)("col",{style:{width:"9%"}}),(0,t.jsx)("col",{style:{width:"12%"}}),(0,t.jsx)("col",{style:{width:"11%"}}),(0,t.jsx)("col",{style:{width:"9%"}}),(0,t.jsx)("col",{style:{width:"13%"}}),(0,t.jsx)("col",{style:{width:"12%"}}),(0,t.jsx)("col",{style:{width:"11%"}}),(0,t.jsx)("col",{style:{width:"8%"}}),(0,t.jsx)("col",{style:{width:"8%"}})]}),(0,t.jsx)("thead",{className:"activity-thead",children:(0,t.jsxs)("tr",{children:[(0,t.jsx)("th",{className:"px-4 py-3"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Time"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Decision"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Event"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"CLI"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Tool"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Policy"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Reason"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Mode"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Duration"}),(0,t.jsx)("th",{className:"px-3 py-3 activity-th",children:"Session"})]})}),(0,t.jsx)("tbody",{className:"divide-y divide-border/30",children:V.map((e,r)=>{let n="deny"===e.decision,l=p===r,i="instruct"===e.decision;return(0,t.jsxs)(s.default.Fragment,{children:[(0,t.jsxs)("tr",{onClick:()=>{f(e=>{let t=e===r?null:r,s=V[r];return a("activity_row_toggled",{expanded:null!==t,decision:s?.decision??null,policy_name:s?.policyName??null,event_type:s?.eventType??null}),t})},className:`activity-data-row cursor-pointer transition-colors ${n?"bg-red-500/[0.03] hover:bg-red-500/[0.07] border-l-2 border-l-red-500/40":i?"bg-amber-500/[0.03] hover:bg-amber-500/[0.07] border-l-2 border-l-amber-500/40":r%2==0?"hover:bg-muted/30":"bg-muted/[0.04] hover:bg-muted/30"} ${l?"bg-muted/20":""}`,children:[(0,t.jsx)("td",{className:"px-4 py-2",children:(0,t.jsx)(c.ChevronDown,{className:`h-3.5 w-3.5 text-muted-foreground transition-transform duration-150 ${l?"rotate-0":"-rotate-90"}`})}),(0,t.jsx)("td",{className:"px-3 py-2 text-muted-foreground whitespace-nowrap",title:new Date(e.timestamp).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}),children:(0,I.formatRelativeTime)(e.timestamp)}),(0,t.jsx)("td",{className:"px-3 py-2",children:(0,t.jsx)(A,{decision:e.decision})}),(0,t.jsx)("td",{className:"px-3 py-2",children:(0,t.jsx)(R,{eventType:e.eventType})}),(0,t.jsx)("td",{className:"px-3 py-2",children:(0,t.jsx)(L,{integration:e.integration})}),(0,t.jsx)("td",{className:"px-3 py-2 font-mono text-foreground",children:e.toolName??"—"}),(0,t.jsx)("td",{className:"px-3 py-2 font-mono text-foreground",children:e.policyNames&&e.policyNames.length>1?(0,t.jsxs)("span",{title:e.policyNames.join(", "),children:[e.policyNames[0],(0,t.jsxs)("span",{className:"text-muted-foreground text-[0.6rem]",children:[" +",e.policyNames.length-1]})]}):e.policyName??"—"}),(0,t.jsx)("td",{className:"px-3 py-2 text-muted-foreground truncate",title:e.reason??"",children:e.reason??"—"}),(0,t.jsx)("td",{className:"px-3 py-2",children:e.permissionMode?(0,t.jsx)(E,{mode:e.permissionMode}):"—"}),(0,t.jsx)("td",{className:"px-3 py-2",children:(0,t.jsx)(U,{ms:e.durationMs})}),(0,t.jsx)("td",{className:"px-3 py-2",title:e.sessionId??"",children:(0,t.jsx)($,{sessionId:e.sessionId,transcriptPath:e.transcriptPath,integration:e.integration,cwd:e.cwd})})]}),l&&(0,t.jsx)(O,{item:e})]},`${e.timestamp}-${r}`)})})]})}),(0,t.jsx)(h.default,{currentPage:d,totalPages:Z,onPageChange:e=>{a("activity_pagination_changed",{from_page:d,to_page:e,total_pages:Z}),m(e),f(null)}})]})]})}function W({enabled:e,onChange:s,disabled:r}){return(0,t.jsx)("button",{onClick:s,disabled:r,className:`relative inline-flex h-4 w-7 shrink-0 items-center rounded-full transition-colors disabled:opacity-40 ${e?"bg-emerald-500":"bg-muted-foreground/30"}`,"aria-label":e?"Disable policy":"Enable policy",children:(0,t.jsx)("span",{className:`inline-block h-3 w-3 rounded-full bg-white shadow transition-transform ${e?"translate-x-3.5":"translate-x-0.5"}`})})}function H({policy:e,onClose:r,onSave:n}){let a=e.params??{},l=e.currentParams??{},[i,o]=(0,s.useState)(()=>{let e={};for(let[t,s]of Object.entries(a)){let r=t in l?l[t]:s.default;e[t]=r}return e});(0,s.useEffect)(()=>{let e=e=>{"Escape"===e.key&&r()};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[r]);let c=(e,t)=>{o(s=>({...s,[e]:t}))};return(0,t.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50",onClick:e=>{e.target===e.currentTarget&&r()},children:(0,t.jsxs)("div",{className:"bg-card border border-border rounded-lg shadow-xl w-full max-w-lg mx-4 max-h-[80vh] flex flex-col",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-b border-border",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-mono font-semibold text-foreground",children:e.name}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5",children:e.description})]}),(0,t.jsx)("button",{onClick:r,className:"text-muted-foreground hover:text-foreground transition-colors",children:(0,t.jsx)(p.X,{className:"h-4 w-4"})})]}),(0,t.jsx)("div",{className:"overflow-y-auto flex-1 px-4 py-4 space-y-4",children:Object.entries(a).map(([e,s])=>(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-semibold text-foreground mb-1 font-mono",children:e}),(0,t.jsx)("p",{className:"text-[0.65rem] text-muted-foreground mb-1.5",children:s.description}),((e,s)=>{let r=i[e];if("boolean"===s.type)return(0,t.jsxs)("label",{className:"flex items-center gap-2 cursor-pointer",children:[(0,t.jsx)("input",{type:"checkbox",checked:!!r,onChange:t=>c(e,t.target.checked),className:"rounded border-border"}),(0,t.jsx)("span",{className:"text-xs text-muted-foreground",children:s.description})]});if("number"===s.type)return(0,t.jsx)("input",{type:"number",value:"number"==typeof r?r:"",onChange:t=>c(e,Number(t.target.value)),className:"w-full h-7 rounded border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-primary/40"});if("string[]"===s.type){let s=Array.isArray(r)?r.join("\n"):"";return(0,t.jsx)("textarea",{value:s,onChange:t=>c(e,t.target.value.split("\n").filter(e=>""!==e.trim())),rows:4,placeholder:"One entry per line",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground font-mono focus:outline-none focus:ring-2 focus:ring-primary/40 resize-y"})}if("pattern[]"===s.type){let s=Array.isArray(r)?r:[];return(0,t.jsxs)("div",{className:"space-y-1.5",children:[s.map((r,n)=>(0,t.jsxs)("div",{className:"flex gap-1.5 items-center",children:[(0,t.jsx)("input",{type:"text",value:r.regex,onChange:t=>{let r=[...s];r[n]={...r[n],regex:t.target.value},c(e,r)},placeholder:"regex",className:"flex-1 h-6 rounded border border-border bg-background px-2 text-xs font-mono focus:outline-none focus:ring-2 focus:ring-primary/40"}),(0,t.jsx)("input",{type:"text",value:r.label,onChange:t=>{let r=[...s];r[n]={...r[n],label:t.target.value},c(e,r)},placeholder:"label",className:"flex-1 h-6 rounded border border-border bg-background px-2 text-xs focus:outline-none focus:ring-2 focus:ring-primary/40"}),(0,t.jsx)("button",{onClick:()=>c(e,s.filter((e,t)=>t!==n)),className:"text-muted-foreground/50 hover:text-destructive transition-colors",children:(0,t.jsx)(p.X,{className:"h-3.5 w-3.5"})})]},n)),(0,t.jsx)("button",{onClick:()=>c(e,[...s,{regex:"",label:""}]),className:"text-xs text-primary hover:underline",children:"+ Add pattern"})]})}return(0,t.jsx)("input",{type:"text",value:"string"==typeof r?r:"",onChange:t=>c(e,t.target.value),className:"w-full h-7 rounded border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-primary/40"})})(e,s)]},e))}),(0,t.jsxs)("div",{className:"flex items-center justify-end gap-2 px-4 py-3 border-t border-border",children:[(0,t.jsx)(T.Button,{variant:"outline",size:"sm",onClick:r,className:"h-7 text-xs",children:"Cancel"}),(0,t.jsx)(T.Button,{size:"sm",onClick:()=>n(i),className:"h-7 text-xs",children:"Save"})]})]})})}function M({message:e,onDismiss:s,onInstall:n,isPending:a}){let{capture:l}=(0,S.usePostHog)();return(0,r.createPortal)((0,t.jsxs)("div",{className:"fixed top-4 right-4 z-[9999] w-full max-w-sm",style:{animation:"slideInFromRight 0.25s ease-out"},children:[(0,t.jsx)("style",{children:`
2
2
  @keyframes slideInFromRight {
3
3
  from { transform: translateX(calc(100% + 1rem)); opacity: 0; }
4
4
  to { transform: translateX(0); opacity: 1; }
5
5
  }
6
- `}),(0,t.jsxs)("div",{className:"rounded-lg border border-red-500/40 bg-red-950/95 shadow-2xl shadow-red-900/40 overflow-hidden backdrop-blur-sm",children:[(0,t.jsx)("div",{className:"h-0.5 w-full bg-gradient-to-r from-red-600 via-red-400 to-red-600"}),(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsxs)("div",{className:"flex items-start gap-3",children:[(0,t.jsx)("div",{className:"shrink-0 mt-0.5 flex h-5 w-5 items-center justify-center rounded-full bg-red-500 ring-2 ring-red-500/30",children:(0,t.jsx)(p.X,{className:"h-3 w-3 text-white",strokeWidth:3})}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsx)("p",{className:"text-[0.65rem] font-bold uppercase tracking-widest text-red-400 mb-0.5",children:"Error"}),(0,t.jsx)("p",{className:"text-sm text-red-100 leading-snug",children:e})]}),(0,t.jsx)("button",{onClick:s,className:"shrink-0 -mt-0.5 -mr-0.5 rounded p-0.5 text-red-400/60 transition-colors hover:bg-red-500/20 hover:text-red-200","aria-label":"Dismiss",children:(0,t.jsx)(p.X,{className:"h-4 w-4"})})]}),(0,t.jsxs)("div",{className:"mt-3 flex gap-2",children:[(0,t.jsx)(T.Button,{size:"sm",onClick:()=>{l("hooks_install_from_error_clicked",{error_message:e.slice(0,200)}),s(),n()},disabled:a,className:"h-7 flex-1 border-0 bg-red-500 px-3 text-xs font-semibold text-white hover:bg-red-400 disabled:opacity-50",children:"Install hooks"}),(0,t.jsx)(T.Button,{variant:"ghost",size:"sm",onClick:s,className:"h-7 px-3 text-xs text-red-400 hover:bg-red-500/10 hover:text-red-200",children:"Dismiss"})]})]})]})]}),document.body)}function X({onHooksInstallChange:e}){let[r,n]=(0,s.useState)(null),[a,l]=(0,s.useTransition)(),[i,c]=(0,s.useState)(null),[d,m]=(0,s.useState)(null),[p,h]=(0,s.useState)(null),[g,f]=(0,s.useState)(()=>new Set),b=(0,s.useRef)(!1),{capture:k}=(0,S.usePostHog)(),C=(0,s.useCallback)((e,t)=>{k("action_error_displayed",{error_type:e,error_message:t.slice(0,200)}),c(t)},[k]),_=(0,s.useCallback)(async()=>{try{let t=await j();n(t),e?.(t.clis.some(e=>e.installed))}catch{}},[e]);(0,s.useEffect)(()=>{_()},[_]),(0,s.useEffect)(()=>{r&&(b.current?f(new Set(r.clis.filter(e=>e.installed).map(e=>e.id))):(b.current=!0,f(new Set(r.clis.filter(e=>e.installed||e.detected).map(e=>e.id)))))},[r?.clis]);let I=(0,s.useMemo)(()=>new Set((r?.clis??[]).filter(e=>e.installed).map(e=>e.id)),[r?.clis]),$=(0,s.useMemo)(()=>{let e=[],t=[];for(let s of r?.clis??[]){let r=g.has(s.id);r&&!I.has(s.id)&&e.push(s.id),!r&&I.has(s.id)&&t.push(s.id)}return{toInstall:e,toRemove:t}},[r?.clis,g,I]),A=$.toInstall.length>0||$.toRemove.length>0,R=()=>{let{toInstall:e,toRemove:t}=$;(0!==e.length||0!==t.length)&&(k("cli_install_remove_submitted",{to_install:e,to_remove:t,count_install:e.length,count_remove:t.length}),l(async()=>{try{c(null),e.length>0&&await y("user",e),t.length>0&&await N("user",t)}catch(e){C("cli_apply",e instanceof Error?e.message:"Failed to apply changes.")}finally{await _()}}))};if(!r)return(0,t.jsx)("div",{className:"flex items-center justify-center py-16",children:(0,t.jsx)("span",{className:"text-sm text-muted-foreground",children:"Loading\\u2026"})});let L=r.clis.some(e=>e.installed),E=I.size,U=g.size,z=Array.from(new Set(r.policies.map(e=>e.category)));return(0,t.jsxs)(t.Fragment,{children:[p&&(0,t.jsx)(H,{policy:p,onClose:()=>{k("policy_config_modal_closed",{policy_name:p.name,action:"cancel"}),h(null)},onSave:e=>{if(!p)return;let t=p.name;h(null),l(async()=>{try{c(null),await w(t,e),await _()}catch(e){C("param_update",e instanceof Error?e.message:"Failed to save configuration.")}})}}),(0,t.jsxs)("div",{className:"bg-card border border-border rounded-lg overflow-hidden",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-4 px-5 py-3.5 border-b border-border/60 bg-muted/10",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3 min-w-0 flex-wrap",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{className:`h-2 w-2 rounded-full transition-shadow ${L?"bg-emerald-400 shadow-[0_0_8px_rgba(52,211,153,0.6)]":"bg-muted-foreground/40"}`,"aria-hidden":!0}),(0,t.jsx)("span",{className:"text-[0.65rem] uppercase tracking-[0.2em] font-mono text-foreground/90",children:"Integrations"})]}),(0,t.jsx)("span",{className:"text-[0.65rem] font-mono text-muted-foreground/40",children:"·"}),(0,t.jsxs)("div",{className:"text-[0.65rem] uppercase tracking-[0.2em] font-mono text-muted-foreground",children:[(0,t.jsx)("span",{className:"text-foreground tabular-nums",children:E.toString().padStart(2,"0")}),(0,t.jsxs)("span",{className:"opacity-50",children:[" / 0",r.clis.length," active"]})]}),A&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"text-[0.65rem] font-mono text-muted-foreground/40",children:"·"}),(0,t.jsxs)("span",{className:"inline-flex items-center gap-1.5 text-[0.65rem] uppercase tracking-[0.2em] font-mono text-pink-400",children:[(0,t.jsx)("span",{className:"h-1 w-1 rounded-full bg-pink-400 animate-pulse"}),$.toInstall.length+$.toRemove.length," pending"]})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2 shrink-0",children:[(0,t.jsx)(T.Button,{variant:"outline",size:"sm",onClick:()=>{let e=Array.from(I).filter(e=>g.has(e));0!==e.length&&(k("cli_reinstall_submitted",{cli_ids:e,count:e.length}),l(async()=>{try{c(null),await y("user",e)}catch(e){C("cli_reinstall",e instanceof Error?e.message:"Failed to reinstall.")}finally{await _()}}))},disabled:a||0===U,className:"text-xs h-7 px-3 font-mono",children:"Reinstall"}),(0,t.jsx)(T.Button,{variant:"default",size:"sm",onClick:R,disabled:a||!A,className:"text-xs h-7 px-3 font-mono",children:"Apply changes"})]})]}),(0,t.jsx)("div",{className:"divide-y divide-border/30 border-b border-border/60",children:r.clis.map((e,s)=>{let n=g.has(e.id),l=I.has(e.id),i=n!==l,o=(0,P.getCliBadgeClasses)(e.id),c=o.split(" ").find(e=>e.startsWith("text-"))??"text-foreground";return(0,t.jsxs)("label",{className:`group relative flex items-center gap-3 pl-6 pr-5 py-3 cursor-pointer transition-colors hover:bg-muted/15 ${i?"bg-pink-500/[0.04]":""}`,children:[(0,t.jsx)("div",{className:`absolute left-0 top-0 bottom-0 w-[3px] ${c} bg-current transition-opacity ${n?"opacity-100":"opacity-25 group-hover:opacity-60"}`,"aria-hidden":!0}),(0,t.jsx)("div",{className:"font-mono text-[0.65rem] text-muted-foreground/40 tabular-nums w-6 select-none",children:(s+1).toString().padStart(2,"0")}),(0,t.jsxs)("div",{className:"relative shrink-0",children:[(0,t.jsx)("input",{type:"checkbox",checked:n,onChange:()=>{var t;return t=e.id,void f(e=>{let s=new Set(e),n=!s.has(t);n?s.add(t):s.delete(t);let a=r?.clis.find(e=>e.id===t);return k("cli_selection_toggled",{cli_id:t,checked:n,current_state:a?.installed?"installed":a?.detected?"detected":"inactive"}),s})},disabled:a,className:"sr-only peer","aria-label":`Toggle ${e.label}`}),(0,t.jsx)("div",{className:`h-[18px] w-[18px] rounded-sm border transition-all peer-focus-visible:ring-2 peer-focus-visible:ring-primary/40 ${n?"bg-primary border-primary":"bg-background/50 border-border group-hover:border-foreground/40"}`,children:n&&(0,t.jsx)("svg",{viewBox:"0 0 18 18",className:"h-full w-full text-primary-foreground",fill:"none","aria-hidden":!0,children:(0,t.jsx)("path",{d:"M4 9.5L7.5 12.5L14 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),(0,t.jsx)("div",{className:"min-w-[150px] shrink-0",children:(0,t.jsx)("div",{className:"text-sm font-medium text-foreground",children:e.label})}),(0,t.jsxs)("div",{className:"flex items-center gap-1.5 shrink-0",children:[l?(0,t.jsxs)("span",{className:`inline-flex items-center gap-1.5 px-2 py-0.5 rounded-sm text-[0.6rem] uppercase tracking-[0.15em] font-mono border ${o}`,children:[(0,t.jsx)("span",{className:"h-1 w-1 rounded-full bg-current shadow-[0_0_4px_currentColor]"}),"Active"]}):e.detected?(0,t.jsxs)("span",{className:"inline-flex items-center gap-1.5 px-2 py-0.5 rounded-sm text-[0.6rem] uppercase tracking-[0.15em] font-mono border border-border/60 text-muted-foreground/80 bg-muted/20",children:[(0,t.jsx)("span",{className:"h-1 w-1 rounded-full bg-current opacity-60"}),"Detected"]}):(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-[0.6rem] uppercase tracking-[0.15em] font-mono border border-border/30 text-muted-foreground/40",children:"Inactive"}),i&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-[0.6rem] uppercase tracking-[0.15em] font-mono border border-pink-500/40 text-pink-400 bg-pink-500/10",children:n?"+ install":"− remove"})]}),(0,t.jsx)("div",{className:"ml-auto hidden lg:block text-[0.7rem] font-mono text-muted-foreground/50 truncate max-w-[420px] group-hover:text-muted-foreground/80 transition-colors",title:e.settingsPath,children:e.settingsPath})]},e.id)})}),(0,t.jsxs)("div",{className:"flex items-center gap-2 px-4 py-2 border-b border-border/40 bg-muted/5",children:[(0,t.jsxs)("span",{className:"text-xs text-muted-foreground",children:[(0,t.jsx)("span",{className:"font-semibold text-foreground",children:r.enabledPolicies.length})," / ",r.policies.length+(r.customPolicies?.length??0)," ","policies enabled"]}),L&&(0,t.jsxs)("span",{className:"text-[0.65rem] text-muted-foreground/60",children:["· shared across ",E," active CLI",1===E?"":"s"]})]}),i&&(0,t.jsx)("div",{className:"px-4 py-2 bg-red-500/10 border-b border-red-500/20 text-xs text-red-400",children:i}),d&&(0,t.jsx)(M,{message:d,onDismiss:()=>m(null),onInstall:R,isPending:a}),z.map(e=>{let s=r.policies.filter(t=>t.category===e),i=s.filter(e=>e.enabled).length;return(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between px-4 py-2.5 bg-muted/20 border-b border-border/50",children:[(0,t.jsx)("span",{className:"text-[0.7rem] font-semibold uppercase tracking-wider text-muted-foreground",children:e}),(0,t.jsxs)("span",{className:"text-[0.7rem] text-muted-foreground",children:[i," / ",s.length," enabled"]})]}),s.map(e=>(0,t.jsxs)("div",{className:"flex items-start gap-3 px-4 py-3 border-b border-border/20 hover:bg-muted/20 transition-colors",children:[(0,t.jsx)("div",{className:"mt-0.5 shrink-0",children:(0,t.jsx)(W,{enabled:e.enabled,onChange:()=>{var t,s;return t=e.name,s=e.enabled,void(!r||(!r.clis.some(e=>e.installed)?m("Policies are not installed. Install policies to continue."):(m(null),n(e=>e?{...e,policies:e.policies.map(e=>e.name===t?{...e,enabled:!s}:e),enabledPolicies:s?e.enabledPolicies.filter(e=>e!==t):[...e.enabledPolicies,t]}:e),l(async()=>{try{await v(t,!s)}catch{C("policy_toggle","Failed to save policy change."),_()}}))))},disabled:a})}),(0,t.jsxs)("div",{className:"flex items-center gap-1.5 min-w-0 w-56 shrink-0 mt-0.5",children:[(0,t.jsx)("span",{className:"text-xs font-mono text-foreground truncate",children:e.name}),e.beta&&(0,t.jsx)("span",{className:"shrink-0 text-[0.6rem] px-1 py-0.5 rounded border bg-violet-500/10 text-violet-400 border-violet-500/20",children:"beta"})]}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsx)("span",{className:"text-xs text-muted-foreground leading-relaxed",children:e.description}),e.eventScope&&(0,t.jsx)("span",{className:"block text-[0.65rem] text-muted-foreground/40 font-mono mt-0.5 hidden lg:block",children:e.eventScope}),e.params&&Object.keys(e.params).length>0&&(0,t.jsx)("div",{className:"flex flex-wrap gap-1 mt-1.5",children:Object.entries(e.params).map(([s,r])=>{let n=e.currentParams?.[s]??r.default,a=JSON.stringify(n)!==JSON.stringify(r.default);return(0,t.jsxs)("span",{className:`inline-flex items-center gap-1 font-mono text-[0.6rem] px-1.5 py-0.5 rounded border ${a?"bg-primary/10 text-primary/70 border-primary/20":"bg-muted/40 text-muted-foreground/55 border-border/40"}`,children:[(0,t.jsxs)("span",{className:"opacity-70",children:[s,":"]}),(0,t.jsx)("span",{children:function(e,t){if("string[]"===e||"pattern[]"===e){let s=Array.isArray(t)?t:[];return 0===s.length?"none":"pattern[]"===e?`${s.length} pattern${1!==s.length?"s":""}`:1===s.length?String(s[0]).slice(0,24):`${s.length} values`}return"boolean"===e?t?"on":"off":null==t||""===t?"—":String(t).slice(0,32)}(r.type,n)})]},s)})})]}),e.params&&Object.keys(e.params).length>0&&(0,t.jsx)("button",{className:"shrink-0 mt-0.5 text-muted-foreground hover:text-primary transition-colors",onClick:()=>{let t=Object.entries(e.params??{}).filter(([t,s])=>JSON.stringify(e.currentParams?.[t]??s.default)!==JSON.stringify(s.default)).length;k("policy_config_modal_opened",{policy_name:e.name,param_count:Object.keys(e.params??{}).length,has_customized_params:t>0,customized_count:t}),h(e)},title:"Edit parameters",children:(0,t.jsx)(x.Settings,{className:"h-3.5 w-3.5"})})]},e.name))]},e)}),r.customPoliciesPath&&(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between px-4 py-2.5 bg-muted/20 border-b border-border/50",children:[(0,t.jsx)("span",{className:"text-[0.7rem] font-semibold uppercase tracking-wider text-muted-foreground",children:"Custom Policies"}),(0,t.jsxs)("span",{className:"text-[0.7rem] text-muted-foreground",children:[r.customPolicies?.length??0," detected"]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3 px-4 py-3 border-b border-border/20",children:[(0,t.jsx)(u,{className:"h-3.5 w-3.5 text-muted-foreground shrink-0"}),(0,t.jsx)("span",{className:"text-xs font-mono text-muted-foreground truncate",children:r.customPoliciesPath})]}),(0,t.jsxs)("div",{className:"flex items-start gap-2 px-4 py-2.5 border-b border-border/20 bg-muted/10",children:[(0,t.jsx)(o.Shield,{className:"h-3.5 w-3.5 text-muted-foreground/60 shrink-0 mt-0.5"}),(0,t.jsx)("p",{className:"text-[0.7rem] text-muted-foreground/70 leading-relaxed",children:"Custom policies are always active. To add, remove, or reorder them, edit the JS file above."})]}),r.customPolicies?.map(e=>(0,t.jsxs)("div",{className:"flex items-start gap-3 px-4 py-3 border-b border-border/20 hover:bg-muted/20 transition-colors",children:[(0,t.jsx)("div",{className:"h-4 w-7 shrink-0 mt-0.5"}),(0,t.jsx)("div",{className:"flex items-center gap-1.5 min-w-0 w-56 shrink-0 mt-0.5",children:(0,t.jsx)("span",{className:"text-xs font-mono text-foreground truncate",children:e.name})}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[e.description&&(0,t.jsx)("span",{className:"text-xs text-muted-foreground leading-relaxed",children:e.description}),e.eventScope&&(0,t.jsx)("span",{className:"block text-[0.65rem] text-muted-foreground/40 font-mono mt-0.5 hidden lg:block",children:e.eventScope})]})]},e.name))]})]})]})}function J({activeTab:e,onChange:s}){return(0,t.jsx)("div",{className:"tabs",style:{padding:0,marginBottom:24},children:[{id:"activity",label:"Activity"},{id:"policies",label:"Configure"}].map(r=>(0,t.jsx)("button",{type:"button",onClick:()=>s(r.id),className:`tab${e===r.id?" is-active":""}`,children:r.label.toLowerCase()},r.id))})}e.s(["default",0,function({initialTab:e="activity"}){let r=(0,C.useUrlParams)(),{capture:n}=(0,S.usePostHog)(),[a,l]=(0,s.useState)(e),[i,o]=(0,s.useState)(void 0),[c,d]=(0,s.useState)(null),[m,x]=(0,s.useState)([]);(0,s.useEffect)(()=>{j().then(e=>{o(e.clis.some(e=>e.installed)),d({enabled:e.enabledPolicies.length,total:e.policies.length+(e.customPolicies?.length??0)}),x(e.clis.filter(e=>e.installed).map(e=>e.label))}).catch(()=>o(void 0))},[]);let u=0===m.length?"Policy evaluations":m.length<=3?`Policy evaluations across ${m.join(", ")}`:`Policy evaluations across ${m.length} agents`,p=e=>{e!==a&&n("policies_tab_switched",{tab:e,from_tab:a}),l(e),r.setAll({tab:"activity"===e?void 0:e})};return(0,t.jsx)("main",{className:"report",children:(0,t.jsxs)("section",{className:"section","data-screen-label":"policies",children:[(0,t.jsx)("h2",{style:{fontFamily:"var(--font-mono)",fontSize:24,fontWeight:600,letterSpacing:"-0.01em",color:"var(--ink)",margin:"0 0 16px"},children:"activity"===a?"Policies":"Configure Policies"}),"activity"===a?(0,t.jsxs)("div",{style:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:32,flexWrap:"wrap",margin:"0 0 24px"},children:[(0,t.jsxs)("div",{style:{fontFamily:"var(--font-mono)",fontSize:14,color:"var(--ink-2)",lineHeight:1.7,flex:"1 1 480px",minWidth:0},children:[u,c&&(0,t.jsxs)("span",{style:{color:"var(--dim)"},children:[" · ","enabled policies"," ",(0,t.jsxs)("span",{style:{color:"var(--ink)",fontVariantNumeric:"tabular-nums"},children:[c.enabled,"/",c.total]})]})]}),(0,t.jsxs)("div",{style:{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:6,flex:"0 0 auto"},children:[(0,t.jsx)("span",{style:{fontFamily:"var(--font-mono)",fontSize:10,letterSpacing:"0.22em",textTransform:"uppercase",color:"var(--dim)"},children:"want to change which policies fire?"}),(0,t.jsx)("button",{type:"button",className:"btn btn-primary",onClick:()=>p("policies"),children:"[ configure policies → ]"})]})]}):(0,t.jsx)("p",{style:{fontFamily:"var(--font-mono)",fontSize:14,color:"var(--ink-2)",lineHeight:1.7,maxWidth:720,margin:"0 0 24px"},children:"switch policies on or off across your installed agent CLIs."}),(0,t.jsx)(J,{activeTab:a,onChange:p}),"activity"===a?(0,t.jsx)(B,{hooksInstalled:i,onSwitchTab:p}):(0,t.jsx)(X,{onHooksInstallChange:o})]})})}],64245)}]);
6
+ `}),(0,t.jsxs)("div",{className:"rounded-lg border border-red-500/40 bg-red-950/95 shadow-2xl shadow-red-900/40 overflow-hidden backdrop-blur-sm",children:[(0,t.jsx)("div",{className:"h-0.5 w-full bg-gradient-to-r from-red-600 via-red-400 to-red-600"}),(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsxs)("div",{className:"flex items-start gap-3",children:[(0,t.jsx)("div",{className:"shrink-0 mt-0.5 flex h-5 w-5 items-center justify-center rounded-full bg-red-500 ring-2 ring-red-500/30",children:(0,t.jsx)(p.X,{className:"h-3 w-3 text-white",strokeWidth:3})}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsx)("p",{className:"text-[0.65rem] font-bold uppercase tracking-widest text-red-400 mb-0.5",children:"Error"}),(0,t.jsx)("p",{className:"text-sm text-red-100 leading-snug",children:e})]}),(0,t.jsx)("button",{onClick:s,className:"shrink-0 -mt-0.5 -mr-0.5 rounded p-0.5 text-red-400/60 transition-colors hover:bg-red-500/20 hover:text-red-200","aria-label":"Dismiss",children:(0,t.jsx)(p.X,{className:"h-4 w-4"})})]}),(0,t.jsxs)("div",{className:"mt-3 flex gap-2",children:[(0,t.jsx)(T.Button,{size:"sm",onClick:()=>{l("hooks_install_from_error_clicked",{error_message:e.slice(0,200)}),s(),n()},disabled:a,className:"h-7 flex-1 border-0 bg-red-500 px-3 text-xs font-semibold text-white hover:bg-red-400 disabled:opacity-50",children:"Install hooks"}),(0,t.jsx)(T.Button,{variant:"ghost",size:"sm",onClick:s,className:"h-7 px-3 text-xs text-red-400 hover:bg-red-500/10 hover:text-red-200",children:"Dismiss"})]})]})]})]}),document.body)}function X({onHooksInstallChange:e}){let[r,n]=(0,s.useState)(null),[a,l]=(0,s.useTransition)(),[i,c]=(0,s.useState)(null),[d,m]=(0,s.useState)(null),[p,h]=(0,s.useState)(null),[f,g]=(0,s.useState)(()=>new Set),b=(0,s.useRef)(!1),{capture:k}=(0,S.usePostHog)(),C=(0,s.useCallback)((e,t)=>{k("action_error_displayed",{error_type:e,error_message:t.slice(0,200)}),c(t)},[k]),_=(0,s.useCallback)(async()=>{try{let t=await j();n(t),e?.(t.clis.some(e=>e.installed))}catch{}},[e]);(0,s.useEffect)(()=>{_()},[_]),(0,s.useEffect)(()=>{r&&(b.current?g(new Set(r.clis.filter(e=>e.installed).map(e=>e.id))):(b.current=!0,g(new Set(r.clis.filter(e=>e.installed||e.detected).map(e=>e.id)))))},[r?.clis]);let I=(0,s.useMemo)(()=>new Set((r?.clis??[]).filter(e=>e.installed).map(e=>e.id)),[r?.clis]),$=(0,s.useMemo)(()=>{let e=[],t=[];for(let s of r?.clis??[]){let r=f.has(s.id);r&&!I.has(s.id)&&e.push(s.id),!r&&I.has(s.id)&&t.push(s.id)}return{toInstall:e,toRemove:t}},[r?.clis,f,I]),A=$.toInstall.length>0||$.toRemove.length>0,R=()=>{let{toInstall:e,toRemove:t}=$;(0!==e.length||0!==t.length)&&(k("cli_install_remove_submitted",{to_install:e,to_remove:t,count_install:e.length,count_remove:t.length}),l(async()=>{try{c(null),e.length>0&&await y("user",e),t.length>0&&await N("user",t)}catch(e){C("cli_apply",e instanceof Error?e.message:"Failed to apply changes.")}finally{await _()}}))};if(!r)return(0,t.jsx)("div",{className:"flex items-center justify-center py-16",children:(0,t.jsx)("span",{className:"text-sm text-muted-foreground",children:"Loading\\u2026"})});let L=r.clis.some(e=>e.installed),E=I.size,U=f.size,z=Array.from(new Set(r.policies.map(e=>e.category)));return(0,t.jsxs)(t.Fragment,{children:[p&&(0,t.jsx)(H,{policy:p,onClose:()=>{k("policy_config_modal_closed",{policy_name:p.name,action:"cancel"}),h(null)},onSave:e=>{if(!p)return;let t=p.name;h(null),l(async()=>{try{c(null),await w(t,e),await _()}catch(e){C("param_update",e instanceof Error?e.message:"Failed to save configuration.")}})}}),(0,t.jsxs)("div",{className:"bg-card border border-border rounded-lg overflow-hidden",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-4 px-5 py-3.5 border-b border-border/60 bg-muted/10",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3 min-w-0 flex-wrap",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{className:`h-2 w-2 rounded-full transition-shadow ${L?"bg-emerald-400 shadow-[0_0_8px_rgba(52,211,153,0.6)]":"bg-muted-foreground/40"}`,"aria-hidden":!0}),(0,t.jsx)("span",{className:"text-[0.65rem] uppercase tracking-[0.2em] font-mono text-foreground/90",children:"Integrations"})]}),(0,t.jsx)("span",{className:"text-[0.65rem] font-mono text-muted-foreground/40",children:"·"}),(0,t.jsxs)("div",{className:"text-[0.65rem] uppercase tracking-[0.2em] font-mono text-muted-foreground",children:[(0,t.jsx)("span",{className:"text-foreground tabular-nums",children:E.toString().padStart(2,"0")}),(0,t.jsxs)("span",{className:"opacity-50",children:[" / 0",r.clis.length," active"]})]}),A&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"text-[0.65rem] font-mono text-muted-foreground/40",children:"·"}),(0,t.jsxs)("span",{className:"inline-flex items-center gap-1.5 text-[0.65rem] uppercase tracking-[0.2em] font-mono text-pink-400",children:[(0,t.jsx)("span",{className:"h-1 w-1 rounded-full bg-pink-400 animate-pulse"}),$.toInstall.length+$.toRemove.length," pending"]})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2 shrink-0",children:[(0,t.jsx)(T.Button,{variant:"outline",size:"sm",onClick:()=>{let e=Array.from(I).filter(e=>f.has(e));0!==e.length&&(k("cli_reinstall_submitted",{cli_ids:e,count:e.length}),l(async()=>{try{c(null),await y("user",e)}catch(e){C("cli_reinstall",e instanceof Error?e.message:"Failed to reinstall.")}finally{await _()}}))},disabled:a||0===U,className:"text-xs h-7 px-3 font-mono",children:"Reinstall"}),(0,t.jsx)(T.Button,{variant:"default",size:"sm",onClick:R,disabled:a||!A,className:"text-xs h-7 px-3 font-mono",children:"Apply changes"})]})]}),(0,t.jsx)("div",{className:"divide-y divide-border/30 border-b border-border/60",children:r.clis.map((e,s)=>{let n=f.has(e.id),l=I.has(e.id),i=n!==l,o=(0,P.getCliBadgeClasses)(e.id),c=o.split(" ").find(e=>e.startsWith("text-"))??"text-foreground";return(0,t.jsxs)("label",{className:`group relative flex items-center gap-3 pl-6 pr-5 py-3 cursor-pointer transition-colors hover:bg-muted/15 ${i?"bg-pink-500/[0.04]":""}`,children:[(0,t.jsx)("div",{className:`absolute left-0 top-0 bottom-0 w-[3px] ${c} bg-current transition-opacity ${n?"opacity-100":"opacity-25 group-hover:opacity-60"}`,"aria-hidden":!0}),(0,t.jsx)("div",{className:"font-mono text-[0.65rem] text-muted-foreground/40 tabular-nums w-6 select-none",children:(s+1).toString().padStart(2,"0")}),(0,t.jsxs)("div",{className:"relative shrink-0",children:[(0,t.jsx)("input",{type:"checkbox",checked:n,onChange:()=>{var t;return t=e.id,void g(e=>{let s=new Set(e),n=!s.has(t);n?s.add(t):s.delete(t);let a=r?.clis.find(e=>e.id===t);return k("cli_selection_toggled",{cli_id:t,checked:n,current_state:a?.installed?"installed":a?.detected?"detected":"inactive"}),s})},disabled:a,className:"sr-only peer","aria-label":`Toggle ${e.label}`}),(0,t.jsx)("div",{className:`h-[18px] w-[18px] rounded-sm border transition-all peer-focus-visible:ring-2 peer-focus-visible:ring-primary/40 ${n?"bg-primary border-primary":"bg-background/50 border-border group-hover:border-foreground/40"}`,children:n&&(0,t.jsx)("svg",{viewBox:"0 0 18 18",className:"h-full w-full text-primary-foreground",fill:"none","aria-hidden":!0,children:(0,t.jsx)("path",{d:"M4 9.5L7.5 12.5L14 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),(0,t.jsx)("div",{className:"min-w-[150px] shrink-0",children:(0,t.jsx)("div",{className:"text-sm font-medium text-foreground",children:e.label})}),(0,t.jsxs)("div",{className:"flex items-center gap-1.5 shrink-0",children:[l?(0,t.jsxs)("span",{className:`inline-flex items-center gap-1.5 px-2 py-0.5 rounded-sm text-[0.6rem] uppercase tracking-[0.15em] font-mono border ${o}`,children:[(0,t.jsx)("span",{className:"h-1 w-1 rounded-full bg-current shadow-[0_0_4px_currentColor]"}),"Active"]}):e.detected?(0,t.jsxs)("span",{className:"inline-flex items-center gap-1.5 px-2 py-0.5 rounded-sm text-[0.6rem] uppercase tracking-[0.15em] font-mono border border-border/60 text-muted-foreground/80 bg-muted/20",children:[(0,t.jsx)("span",{className:"h-1 w-1 rounded-full bg-current opacity-60"}),"Detected"]}):(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-[0.6rem] uppercase tracking-[0.15em] font-mono border border-border/30 text-muted-foreground/40",children:"Inactive"}),i&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-[0.6rem] uppercase tracking-[0.15em] font-mono border border-pink-500/40 text-pink-400 bg-pink-500/10",children:n?"+ install":"− remove"})]}),(0,t.jsx)("div",{className:"ml-auto hidden lg:block text-[0.7rem] font-mono text-muted-foreground/50 truncate max-w-[420px] group-hover:text-muted-foreground/80 transition-colors",title:e.settingsPath,children:e.settingsPath})]},e.id)})}),(0,t.jsxs)("div",{className:"flex items-center gap-2 px-4 py-2 border-b border-border/40 bg-muted/5",children:[(0,t.jsxs)("span",{className:"text-xs text-muted-foreground",children:[(0,t.jsx)("span",{className:"font-semibold text-foreground",children:r.enabledPolicies.length})," / ",r.policies.length+(r.customPolicies?.length??0)," ","policies enabled"]}),L&&(0,t.jsxs)("span",{className:"text-[0.65rem] text-muted-foreground/60",children:["· shared across ",E," active CLI",1===E?"":"s"]})]}),i&&(0,t.jsx)("div",{className:"px-4 py-2 bg-red-500/10 border-b border-red-500/20 text-xs text-red-400",children:i}),d&&(0,t.jsx)(M,{message:d,onDismiss:()=>m(null),onInstall:R,isPending:a}),z.map(e=>{let s=r.policies.filter(t=>t.category===e),i=s.filter(e=>e.enabled).length;return(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between px-4 py-2.5 bg-muted/20 border-b border-border/50",children:[(0,t.jsx)("span",{className:"text-[0.7rem] font-semibold uppercase tracking-wider text-muted-foreground",children:e}),(0,t.jsxs)("span",{className:"text-[0.7rem] text-muted-foreground",children:[i," / ",s.length," enabled"]})]}),s.map(e=>(0,t.jsxs)("div",{className:"flex items-start gap-3 px-4 py-3 border-b border-border/20 hover:bg-muted/20 transition-colors",children:[(0,t.jsx)("div",{className:"mt-0.5 shrink-0",children:(0,t.jsx)(W,{enabled:e.enabled,onChange:()=>{var t,s;return t=e.name,s=e.enabled,void(!r||(!r.clis.some(e=>e.installed)?m("Policies are not installed. Install policies to continue."):(m(null),n(e=>e?{...e,policies:e.policies.map(e=>e.name===t?{...e,enabled:!s}:e),enabledPolicies:s?e.enabledPolicies.filter(e=>e!==t):[...e.enabledPolicies,t]}:e),l(async()=>{try{await v(t,!s)}catch{C("policy_toggle","Failed to save policy change."),_()}}))))},disabled:a})}),(0,t.jsxs)("div",{className:"flex items-center gap-1.5 min-w-0 w-56 shrink-0 mt-0.5",children:[(0,t.jsx)("span",{className:"text-xs font-mono text-foreground truncate",children:e.name}),e.beta&&(0,t.jsx)("span",{className:"shrink-0 text-[0.6rem] px-1 py-0.5 rounded border bg-violet-500/10 text-violet-400 border-violet-500/20",children:"beta"})]}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsx)("span",{className:"text-xs text-muted-foreground leading-relaxed",children:e.description}),e.eventScope&&(0,t.jsx)("span",{className:"block text-[0.65rem] text-muted-foreground/40 font-mono mt-0.5 hidden lg:block",children:e.eventScope}),e.params&&Object.keys(e.params).length>0&&(0,t.jsx)("div",{className:"flex flex-wrap gap-1 mt-1.5",children:Object.entries(e.params).map(([s,r])=>{let n=e.currentParams?.[s]??r.default,a=JSON.stringify(n)!==JSON.stringify(r.default);return(0,t.jsxs)("span",{className:`inline-flex items-center gap-1 font-mono text-[0.6rem] px-1.5 py-0.5 rounded border ${a?"bg-primary/10 text-primary/70 border-primary/20":"bg-muted/40 text-muted-foreground/55 border-border/40"}`,children:[(0,t.jsxs)("span",{className:"opacity-70",children:[s,":"]}),(0,t.jsx)("span",{children:function(e,t){if("string[]"===e||"pattern[]"===e){let s=Array.isArray(t)?t:[];return 0===s.length?"none":"pattern[]"===e?`${s.length} pattern${1!==s.length?"s":""}`:1===s.length?String(s[0]).slice(0,24):`${s.length} values`}return"boolean"===e?t?"on":"off":null==t||""===t?"—":String(t).slice(0,32)}(r.type,n)})]},s)})})]}),e.params&&Object.keys(e.params).length>0&&(0,t.jsx)("button",{className:"shrink-0 mt-0.5 text-muted-foreground hover:text-primary transition-colors",onClick:()=>{let t=Object.entries(e.params??{}).filter(([t,s])=>JSON.stringify(e.currentParams?.[t]??s.default)!==JSON.stringify(s.default)).length;k("policy_config_modal_opened",{policy_name:e.name,param_count:Object.keys(e.params??{}).length,has_customized_params:t>0,customized_count:t}),h(e)},title:"Edit parameters",children:(0,t.jsx)(x.Settings,{className:"h-3.5 w-3.5"})})]},e.name))]},e)}),r.customPoliciesPath&&(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between px-4 py-2.5 bg-muted/20 border-b border-border/50",children:[(0,t.jsx)("span",{className:"text-[0.7rem] font-semibold uppercase tracking-wider text-muted-foreground",children:"Custom Policies"}),(0,t.jsxs)("span",{className:"text-[0.7rem] text-muted-foreground",children:[r.customPolicies?.length??0," detected"]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3 px-4 py-3 border-b border-border/20",children:[(0,t.jsx)(u,{className:"h-3.5 w-3.5 text-muted-foreground shrink-0"}),(0,t.jsx)("span",{className:"text-xs font-mono text-muted-foreground truncate",children:r.customPoliciesPath})]}),(0,t.jsxs)("div",{className:"flex items-start gap-2 px-4 py-2.5 border-b border-border/20 bg-muted/10",children:[(0,t.jsx)(o.Shield,{className:"h-3.5 w-3.5 text-muted-foreground/60 shrink-0 mt-0.5"}),(0,t.jsx)("p",{className:"text-[0.7rem] text-muted-foreground/70 leading-relaxed",children:"Custom policies are always active. To add, remove, or reorder them, edit the JS file above."})]}),r.customPolicies?.map(e=>(0,t.jsxs)("div",{className:"flex items-start gap-3 px-4 py-3 border-b border-border/20 hover:bg-muted/20 transition-colors",children:[(0,t.jsx)("div",{className:"h-4 w-7 shrink-0 mt-0.5"}),(0,t.jsx)("div",{className:"flex items-center gap-1.5 min-w-0 w-56 shrink-0 mt-0.5",children:(0,t.jsx)("span",{className:"text-xs font-mono text-foreground truncate",children:e.name})}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[e.description&&(0,t.jsx)("span",{className:"text-xs text-muted-foreground leading-relaxed",children:e.description}),e.eventScope&&(0,t.jsx)("span",{className:"block text-[0.65rem] text-muted-foreground/40 font-mono mt-0.5 hidden lg:block",children:e.eventScope})]})]},e.name))]})]})]})}function J({activeTab:e,onChange:s}){return(0,t.jsx)("div",{className:"tabs",style:{padding:0,marginBottom:24},children:[{id:"activity",label:"Activity"},{id:"policies",label:"Configure"}].map(r=>(0,t.jsx)("button",{type:"button",onClick:()=>s(r.id),className:`tab${e===r.id?" is-active":""}`,children:r.label.toLowerCase()},r.id))})}e.s(["default",0,function({initialTab:e="activity"}){let r=(0,C.useUrlParams)(),{capture:n}=(0,S.usePostHog)(),[a,l]=(0,s.useState)(e),[i,o]=(0,s.useState)(void 0),[c,d]=(0,s.useState)(null),[m,x]=(0,s.useState)([]);(0,s.useEffect)(()=>{j().then(e=>{o(e.clis.some(e=>e.installed)),d({enabled:e.enabledPolicies.length,total:e.policies.length+(e.customPolicies?.length??0)}),x(e.clis.filter(e=>e.installed).map(e=>e.label))}).catch(()=>o(void 0))},[]);let u=0===m.length?"Policy evaluations":m.length<=3?`Policy evaluations across ${m.join(", ")}`:`Policy evaluations across ${m.length} agents`,p=e=>{e!==a&&n("policies_tab_switched",{tab:e,from_tab:a}),l(e),r.setAll({tab:"activity"===e?void 0:e})};return(0,t.jsx)("main",{className:"report",children:(0,t.jsxs)("section",{className:"section","data-screen-label":"policies",children:[(0,t.jsx)("h2",{style:{fontFamily:"var(--font-mono)",fontSize:24,fontWeight:600,letterSpacing:"-0.01em",color:"var(--ink)",margin:"0 0 16px"},children:"activity"===a?"Policies":"Configure Policies"}),"activity"===a?(0,t.jsxs)("div",{style:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:32,flexWrap:"wrap",margin:"0 0 24px"},children:[(0,t.jsxs)("div",{style:{fontFamily:"var(--font-mono)",fontSize:14,color:"var(--ink-2)",lineHeight:1.7,flex:"1 1 480px",minWidth:0},children:[u,c&&(0,t.jsxs)("span",{style:{color:"var(--dim)"},children:[" · ","enabled policies"," ",(0,t.jsxs)("span",{style:{color:"var(--ink)",fontVariantNumeric:"tabular-nums"},children:[c.enabled,"/",c.total]})]})]}),(0,t.jsxs)("div",{style:{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:6,flex:"0 0 auto"},children:[(0,t.jsx)("span",{style:{fontFamily:"var(--font-mono)",fontSize:10,letterSpacing:"0.22em",textTransform:"uppercase",color:"var(--dim)"},children:"want to change which policies fire?"}),(0,t.jsx)("button",{type:"button",className:"btn btn-primary",onClick:()=>p("policies"),children:"[ configure policies → ]"})]})]}):(0,t.jsx)("p",{style:{fontFamily:"var(--font-mono)",fontSize:14,color:"var(--ink-2)",lineHeight:1.7,maxWidth:720,margin:"0 0 24px"},children:"switch policies on or off across your installed agent CLIs."}),(0,t.jsx)(J,{activeTab:a,onChange:p}),"activity"===a?(0,t.jsx)(B,{hooksInstalled:i,onSwitchTab:p}):(0,t.jsx)(X,{onHooksInstallChange:o})]})})}],64245)}]);
@@ -1,6 +1,7 @@
1
- import React, { useState, useCallback, useEffect } from "react";
1
+ import React, { useState, useCallback, useEffect, useMemo } from "react";
2
2
  import { Workflow, ChevronRight } from "lucide-react";
3
3
  import type { LogEntry, ToolUseBlock } from "@/lib/log-entries";
4
+ import { buildEntryKeys } from "@/lib/entry-keys";
4
5
  import { cn } from "@/lib/utils";
5
6
  import { ENTRY_BORDER_COLORS } from "./constants";
6
7
  import { TypeBadge } from "./type-badge";
@@ -39,6 +40,10 @@ export function SubagentToolCard({ block, subagentEntries, projectName, sessionI
39
40
 
40
41
  const hasEntries = subagentEntries && subagentEntries.length > 0;
41
42
 
43
+ // Same stable-key treatment as the top-level list — subagent transcripts from
44
+ // uuid-less CLIs collide on timestamp just as readily.
45
+ const subagentKeys = useMemo(() => buildEntryKeys(subagentEntries ?? []), [subagentEntries]);
46
+
42
47
  return (
43
48
  <div className="border border-border/50 rounded-lg p-3 bg-muted/10">
44
49
  {/* Header */}
@@ -94,12 +99,12 @@ export function SubagentToolCard({ block, subagentEntries, projectName, sessionI
94
99
  {subagentEntries && subagentEntries.map((entry) =>
95
100
  entry.type === "queue-operation" ? (
96
101
  <QueueDivider
97
- key={entry.uuid || entry.timestamp}
102
+ key={subagentKeys.get(entry)}
98
103
  entry={entry}
99
104
  />
100
105
  ) : (
101
106
  <EntryRow
102
- key={entry.uuid || entry.timestamp}
107
+ key={subagentKeys.get(entry)}
103
108
  entry={entry}
104
109
  projectName={projectName}
105
110
  sessionId={sessionId}
@@ -9,6 +9,7 @@ import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useSta
9
9
  import { useWindowVirtualizer } from "@tanstack/react-virtual";
10
10
  import { ChevronDown, Wrench } from "lucide-react";
11
11
  import type { LogEntry, ToolUseBlock } from "@/lib/log-entries";
12
+ import { buildEntryKeys } from "@/lib/entry-keys";
12
13
  import { StatsBar } from "@/app/components/log-viewer/stats-bar";
13
14
  import { QueueDivider } from "@/app/components/log-viewer/queue-divider";
14
15
  import { EntryRow } from "@/app/components/log-viewer/entry-row";
@@ -123,8 +124,11 @@ function estimateSize(entry: LogEntry): number {
123
124
 
124
125
  type QueueOperationEntry = Extract<LogEntry, { type: "queue-operation" }>;
125
126
 
126
- function getSegmentId(entry: QueueOperationEntry): string {
127
- return `${entry.uuid}-${entry.timestampMs}`;
127
+ // Segment ids come from the same stable-key map as the rows, so uuid-less
128
+ // transcripts (Codex, Copilot, Cursor, Pi) can't collapse two dividers that
129
+ // happen to share a millisecond into one segment.
130
+ function getSegmentId(entry: QueueOperationEntry, keys: Map<LogEntry, string>): string {
131
+ return keys.get(entry) ?? `${entry.uuid}-${entry.timestampMs}`;
128
132
  }
129
133
 
130
134
  /**
@@ -132,7 +136,7 @@ function getSegmentId(entry: QueueOperationEntry): string {
132
136
  * to the count of non-queue-operation entries in its segment (entries after
133
137
  * it until the next queue-operation or end of list).
134
138
  */
135
- function computeSegments(entries: LogEntry[]): Map<string, number> {
139
+ function computeSegments(entries: LogEntry[], keys: Map<LogEntry, string>): Map<string, number> {
136
140
  const segments = new Map<string, number>();
137
141
  let currentId: string | null = null;
138
142
  let count = 0;
@@ -142,7 +146,7 @@ function computeSegments(entries: LogEntry[]): Map<string, number> {
142
146
  if (currentId !== null) {
143
147
  segments.set(currentId, count);
144
148
  }
145
- currentId = getSegmentId(entry);
149
+ currentId = getSegmentId(entry, keys);
146
150
  count = 0;
147
151
  } else if (currentId !== null) {
148
152
  count++;
@@ -154,11 +158,11 @@ function computeSegments(entries: LogEntry[]): Map<string, number> {
154
158
  return segments;
155
159
  }
156
160
 
157
- function filterVisibleEntries(entries: LogEntry[], collapsedSessions: Set<string>): LogEntry[] {
161
+ function filterVisibleEntries(entries: LogEntry[], collapsedSessions: Set<string>, keys: Map<LogEntry, string>): LogEntry[] {
158
162
  let currentCollapsed = false;
159
163
  return entries.filter((entry) => {
160
164
  if (entry.type === "queue-operation") {
161
- currentCollapsed = collapsedSessions.has(getSegmentId(entry as QueueOperationEntry));
165
+ currentCollapsed = collapsedSessions.has(getSegmentId(entry as QueueOperationEntry, keys));
162
166
  return true; // dividers are always visible
163
167
  }
164
168
  return !currentCollapsed;
@@ -234,11 +238,16 @@ function VirtualizedEntryList({ entries, entriesBySource, projectName, sessionId
234
238
  };
235
239
  }, []);
236
240
 
237
- const segments = useMemo(() => computeSegments(entries), [entries]);
241
+ // One identity per entry, shared by the React key, the segment ids and the
242
+ // virtualizer's measurement cache — all three must agree or rows get
243
+ // measured against the wrong entry.
244
+ const entryKeys = useMemo(() => buildEntryKeys(entries), [entries]);
245
+
246
+ const segments = useMemo(() => computeSegments(entries, entryKeys), [entries, entryKeys]);
238
247
 
239
248
  const visibleEntries = useMemo(
240
- () => filterVisibleEntries(entries, collapsedSessions),
241
- [entries, collapsedSessions],
249
+ () => filterVisibleEntries(entries, collapsedSessions, entryKeys),
250
+ [entries, collapsedSessions, entryKeys],
242
251
  );
243
252
 
244
253
  // UUID-to-index map for visible entries
@@ -303,14 +312,14 @@ function VirtualizedEntryList({ entries, entriesBySource, projectName, sessionId
303
312
  let currentSegmentId: string | null = null;
304
313
  for (const entry of entries) {
305
314
  if (entry.type === "queue-operation") {
306
- currentSegmentId = getSegmentId(entry);
315
+ currentSegmentId = getSegmentId(entry, entryKeys);
307
316
  } else if (entry.uuid === lookupUuid && currentSegmentId) {
308
317
  return currentSegmentId;
309
318
  }
310
319
  }
311
320
  }
312
321
  return null;
313
- }, [highlightedUuid, parentUuidForSubagent, entries, uuidToIndex]);
322
+ }, [highlightedUuid, parentUuidForSubagent, entries, uuidToIndex, entryKeys]);
314
323
 
315
324
  useEffect(() => {
316
325
  if (!segmentToExpand) return;
@@ -337,9 +346,18 @@ function VirtualizedEntryList({ entries, entriesBySource, projectName, sessionId
337
346
  });
338
347
  }, []);
339
348
 
349
+ // getItemKey must match the React key. Without it the virtualizer defaults to
350
+ // keying its size/element caches by index, so collapsing a segment shifts
351
+ // every index and replays one entry's cached height onto a different entry.
352
+ const getItemKey = useCallback(
353
+ (index: number) => entryKeys.get(visibleEntries[index]) ?? index,
354
+ [entryKeys, visibleEntries],
355
+ );
356
+
340
357
  const virtualizer = useWindowVirtualizer({
341
358
  count: visibleEntries.length,
342
359
  estimateSize: (index) => estimateSize(visibleEntries[index]),
360
+ getItemKey,
343
361
  overscan: 5,
344
362
  scrollMargin,
345
363
  });
@@ -370,7 +388,7 @@ function VirtualizedEntryList({ entries, entriesBySource, projectName, sessionId
370
388
  const isTarget = !!highlightedUuid && entry.uuid === (parentUuidForSubagent ?? highlightedUuid);
371
389
  return (
372
390
  <div
373
- key={entry.type === "queue-operation" ? getSegmentId(entry) : (entry.uuid || entry.timestamp)}
391
+ key={virtualRow.key}
374
392
  data-index={virtualRow.index}
375
393
  ref={virtualizer.measureElement}
376
394
  style={{
@@ -384,9 +402,9 @@ function VirtualizedEntryList({ entries, entriesBySource, projectName, sessionId
384
402
  {entry.type === "queue-operation" ? (
385
403
  <QueueDivider
386
404
  entry={entry}
387
- isCollapsed={collapsedSessions.has(getSegmentId(entry))}
388
- entryCount={segments.get(getSegmentId(entry)) ?? 0}
389
- onToggle={() => handleToggleSegment(getSegmentId(entry))}
405
+ isCollapsed={collapsedSessions.has(getSegmentId(entry, entryKeys))}
406
+ entryCount={segments.get(getSegmentId(entry, entryKeys)) ?? 0}
407
+ onToggle={() => handleToggleSegment(getSegmentId(entry, entryKeys))}
390
408
  />
391
409
  ) : (
392
410
  <EntryRow
@@ -575,7 +575,7 @@ function ActivityTab({
575
575
  type="text"
576
576
  value={filterPolicy}
577
577
  onChange={(e) => setFilterPolicy(e.target.value)}
578
- placeholder="filter by policy\u2026"
578
+ placeholder="filter by policy"
579
579
  className="filter-input"
580
580
  />
581
581
  </div>
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Stable per-entry identity for the log viewer.
3
+ *
4
+ * Deliberately standalone and dependency-free: `lib/log-entries.ts` reaches
5
+ * fs/promises through its project-resolution imports, so a *value* import of
6
+ * it from a client component drags node:fs into the browser bundle and the
7
+ * session page 500s. Client code may only import types from there.
8
+ */
9
+ import type { LogEntry } from "./log-entries";
10
+
11
+ /**
12
+ * Assigns every entry a unique, render-stable identity.
13
+ *
14
+ * Not every CLI writes a per-record `uuid` — Codex, Copilot, Cursor and Pi
15
+ * transcripts have none, so `baseEntry` leaves it "". Keying rows off
16
+ * `uuid || timestamp` therefore collapses to the timestamp, which those CLIs
17
+ * reuse freely (one 771-record Codex session: 93 timestamps shared by 2-5
18
+ * records each). Duplicate React keys break reconciliation, and in the
19
+ * virtualized log list that strands orphaned DOM nodes stacked on top of live
20
+ * rows — they keep their old transform and never recover (#292 follow-up).
21
+ *
22
+ * Collisions are disambiguated by occurrence order, so keys stay stable for as
23
+ * long as the parsed entry list is — which is what React and the virtualizer's
24
+ * measurement cache both require.
25
+ */
26
+ export function buildEntryKeys(entries: LogEntry[]): Map<LogEntry, string> {
27
+ const keys = new Map<LogEntry, string>();
28
+ const seen = new Map<string, number>();
29
+ for (const entry of entries) {
30
+ const base = entry.uuid || `${entry._source}:${entry.timestamp}`;
31
+ const n = seen.get(base) ?? 0;
32
+ seen.set(base, n + 1);
33
+ keys.set(entry, n === 0 ? base : `${base}#${n}`);
34
+ }
35
+ return keys;
36
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "failproofai",
3
- "version": "0.0.14-beta.2",
3
+ "version": "0.0.14",
4
4
  "description": "The easiest way to manage policies that keep your AI agents reliable, on-task, and running autonomously — for Claude Code & the Agents SDK",
5
5
  "bin": {
6
6
  "failproofai": "./dist/cli.mjs"
@@ -71,11 +71,11 @@
71
71
  "access": "public"
72
72
  },
73
73
  "devDependencies": {
74
- "@anthropic-ai/sdk": "^0.111.0",
74
+ "@anthropic-ai/sdk": "^0.112.4",
75
75
  "@mdx-js/mdx": "^3.1.1",
76
76
  "@tailwindcss/postcss": "^4.3.1",
77
77
  "@tanstack/react-virtual": "^3.14.3",
78
- "@testing-library/jest-dom": "^6.9.1",
78
+ "@testing-library/jest-dom": "^7.0.0",
79
79
  "@testing-library/react": "^16.3.2",
80
80
  "@testing-library/user-event": "^14.6.1",
81
81
  "@types/node": "26.1.1",
@@ -106,6 +106,7 @@
106
106
  "postcss": "8.5.14",
107
107
  "eslint-plugin-react-hooks": "7.0.1",
108
108
  "vite": "8.0.16",
109
- "undici": "7.28.0"
109
+ "undici": "7.28.0",
110
+ "brace-expansion": "5.0.7"
110
111
  }
111
112
  }
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
9
9
  const hostname = process.env.HOSTNAME || '0.0.0.0'
10
10
 
11
11
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
12
- const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"0.0.14-beta.2"},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/failproofai/failproofai","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","outputFileTracingExcludes":{"*":["node_modules/@img/**","node_modules/sharp/**"]},"turbopack":{"root":"/home/runner/work/failproofai/failproofai"},"distDirRoot":".next"}
12
+ const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"0.0.14"},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/failproofai/failproofai","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","outputFileTracingExcludes":{"*":["node_modules/@img/**","node_modules/sharp/**"]},"turbopack":{"root":"/home/runner/work/failproofai/failproofai"},"distDirRoot":".next"}
13
13
 
14
14
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
15
15
 
package/dist/cli.mjs CHANGED
@@ -19,7 +19,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
19
19
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
20
 
21
21
  // package.json
22
- var version2 = "0.0.14-beta.2";
22
+ var version2 = "0.0.14";
23
23
  var init_package = () => {};
24
24
 
25
25
  // src/posthog-key.ts
@@ -22857,7 +22857,7 @@ import { realpathSync as realpathSync4 } from "fs";
22857
22857
  import { dirname as dirname9, resolve as resolve18 } from "path";
22858
22858
  import { fileURLToPath as fileURLToPath4 } from "url";
22859
22859
  // package.json
22860
- var version = "0.0.14-beta.2";
22860
+ var version = "0.0.14";
22861
22861
 
22862
22862
  // bin/failproofai.mjs
22863
22863
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Stable per-entry identity for the log viewer.
3
+ *
4
+ * Deliberately standalone and dependency-free: `lib/log-entries.ts` reaches
5
+ * fs/promises through its project-resolution imports, so a *value* import of
6
+ * it from a client component drags node:fs into the browser bundle and the
7
+ * session page 500s. Client code may only import types from there.
8
+ */
9
+ import type { LogEntry } from "./log-entries";
10
+
11
+ /**
12
+ * Assigns every entry a unique, render-stable identity.
13
+ *
14
+ * Not every CLI writes a per-record `uuid` — Codex, Copilot, Cursor and Pi
15
+ * transcripts have none, so `baseEntry` leaves it "". Keying rows off
16
+ * `uuid || timestamp` therefore collapses to the timestamp, which those CLIs
17
+ * reuse freely (one 771-record Codex session: 93 timestamps shared by 2-5
18
+ * records each). Duplicate React keys break reconciliation, and in the
19
+ * virtualized log list that strands orphaned DOM nodes stacked on top of live
20
+ * rows — they keep their old transform and never recover (#292 follow-up).
21
+ *
22
+ * Collisions are disambiguated by occurrence order, so keys stay stable for as
23
+ * long as the parsed entry list is — which is what React and the virtualizer's
24
+ * measurement cache both require.
25
+ */
26
+ export function buildEntryKeys(entries: LogEntry[]): Map<LogEntry, string> {
27
+ const keys = new Map<LogEntry, string>();
28
+ const seen = new Map<string, number>();
29
+ for (const entry of entries) {
30
+ const base = entry.uuid || `${entry._source}:${entry.timestamp}`;
31
+ const n = seen.get(base) ?? 0;
32
+ seen.set(base, n + 1);
33
+ keys.set(entry, n === 0 ? base : `${base}#${n}`);
34
+ }
35
+ return keys;
36
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "failproofai",
3
- "version": "0.0.14-beta.2",
3
+ "version": "0.0.14",
4
4
  "description": "The easiest way to manage policies that keep your AI agents reliable, on-task, and running autonomously — for Claude Code & the Agents SDK",
5
5
  "bin": {
6
6
  "failproofai": "./dist/cli.mjs"
@@ -71,11 +71,11 @@
71
71
  "access": "public"
72
72
  },
73
73
  "devDependencies": {
74
- "@anthropic-ai/sdk": "^0.111.0",
74
+ "@anthropic-ai/sdk": "^0.112.4",
75
75
  "@mdx-js/mdx": "^3.1.1",
76
76
  "@tailwindcss/postcss": "^4.3.1",
77
77
  "@tanstack/react-virtual": "^3.14.3",
78
- "@testing-library/jest-dom": "^6.9.1",
78
+ "@testing-library/jest-dom": "^7.0.0",
79
79
  "@testing-library/react": "^16.3.2",
80
80
  "@testing-library/user-event": "^14.6.1",
81
81
  "@types/node": "26.1.1",
@@ -106,6 +106,7 @@
106
106
  "postcss": "8.5.14",
107
107
  "eslint-plugin-react-hooks": "7.0.1",
108
108
  "vite": "8.0.16",
109
- "undici": "7.28.0"
109
+ "undici": "7.28.0",
110
+ "brace-expansion": "5.0.7"
110
111
  }
111
112
  }