{"version":3,"file":"index.cjs","names":["React","React","Button","RxButton","RxInput","RxTextarea","RxBadge","React","React","Button","React","Button","React","Button","React","Button","React","Button","React","Button","React","React","Button"],"sources":["../../src/dt/lib/guard.ts","../../src/dt/lib/styles.ts","../../src/dt/components/icons.tsx","../../src/dt/components/json-tree.tsx","../../src/dt/components/layout.tsx","../../src/dt/components/ui.tsx","../../src/dt/lib/format.ts","../../src/dt/panels/trace-tree.tsx","../../src/dt/panels/decision.tsx","../../src/dt/panels/flow.tsx","../../src/dt/panels/metrics.tsx","../../src/dt/panels/policies.tsx","../../src/dt/panels/roles.tsx","../../src/dt/panels/subjects.tsx","../../src/dt/iam-devtools.tsx","../../src/dt/lib/logo.ts","../../src/dt/iam-devtools-panel.tsx","../../src/dt/lib/flow.ts"],"sourcesContent":["import type { AccessControl } from '../../core/types'\nimport type { IamIDevtoolsEngine } from './types'\n\n/**\n * Hard production guard for the IAM devtools - default-block.\n *\n * Returns `true` ONLY when an explicit positive `development` signal is\n * present - either the bundler set `NODE_ENV=development` or the engine was\n * constructed in `'development'` mode. Absence of any signal blocks the\n * panel so the policy/role/subject readers cannot leak into raw-browser\n * bundles that don't shim `process` or into engines that don't surface\n * `mode` (CWE-200 / CWE-489).\n *\n * No escape hatch: to use devtools in a deployed environment, run a dev\n * build behind an admin-only route.\n *\n * @param engine - The runtime engine the panel would inspect.\n * @returns `true` when devtools MAY render, `false` to block.\n */\nexport function isDevtoolsAllowed(engine: IamIDevtoolsEngine): boolean {\n  // `process` may be undefined in raw-browser bundles that don't shim it;\n  // \"no process\" is not a development signal.\n  const nodeEnv: string | undefined =\n    typeof process !== 'undefined' ? (process as { env?: { NODE_ENV?: string } }).env?.NODE_ENV : undefined\n\n  // A bundler-set production signal always blocks, regardless of engine mode.\n  if (nodeEnv === 'production') return false\n\n  // Positive development signals - either side is sufficient.\n  if (nodeEnv === 'development') return true\n\n  const mode = readEngineMode(engine)\n  if (mode === 'development') return true\n\n  // No positive signal (or engine reports production / unknown) -> BLOCK.\n  return false\n}\n\n/**\n * Back-compat name kept for any external callers. Inverse of\n * {@link isDevtoolsAllowed} - `true` means \"do NOT mount\".\n *\n * @deprecated Prefer {@link isDevtoolsAllowed} for clarity.\n */\nexport function isDevtoolsBlocked(engine: IamIDevtoolsEngine): boolean {\n  return !isDevtoolsAllowed(engine)\n}\n\nfunction readEngineMode(engine: IamIDevtoolsEngine): AccessControl.Mode | undefined {\n  const candidate = engine as {\n    mode?: unknown\n    config?: { mode?: unknown }\n    _mode?: unknown\n  }\n  const raw = candidate.mode ?? candidate.config?.mode ?? candidate._mode\n  if (raw === 'production' || raw === 'development') return raw\n  return undefined\n}\n","const STYLE_ID = '__iam_dt_styles__'\n\n// Chrome + iam-dt-* utility CSS; theme tokens come from host via CSS vars.\nconst CSS = `\n.iam-dt-btn-wrap { position: fixed; z-index: 99998; }\n.iam-dt-btn-wrap[data-pos=\"bottom-right\"] { bottom: 20px; right: 20px; }\n.iam-dt-btn-wrap[data-pos=\"bottom-left\"]  { bottom: 20px; left: 20px; }\n.iam-dt-btn-wrap[data-pos=\"top-right\"]    { top: 20px; right: 20px; }\n.iam-dt-btn-wrap[data-pos=\"top-left\"]     { top: 20px; left: 20px; }\n\n.iam-dt-panel-wrap {\n  position: fixed; z-index: 99999;\n  display: flex; flex-direction: column;\n  transition: transform 240ms cubic-bezier(.32,.72,0,1), opacity 240ms ease;\n  will-change: transform, opacity;\n}\n.iam-dt-panel-wrap[data-pos=\"bottom\"] { left: 0; right: 0; bottom: 0; }\n.iam-dt-panel-wrap[data-pos=\"top\"]    { left: 0; right: 0; top: 0; }\n.iam-dt-panel-wrap[data-pos=\"left\"]   { top: 0; bottom: 0; left: 0; }\n.iam-dt-panel-wrap[data-pos=\"right\"]  { top: 0; bottom: 0; right: 0; }\n.iam-dt-panel-wrap[data-inset=\"1\"]    { padding: 12px; }\n\n.iam-dt-resize { position: absolute; background: transparent; transition: background 160ms ease; }\n.iam-dt-resize:hover { background: var(--ring, oklch(0.7 0 0)); }\n.iam-dt-resize--ns { left: 0; right: 0; height: 4px; cursor: ns-resize; }\n.iam-dt-resize--ew { top: 0; bottom: 0; width: 4px; cursor: ew-resize; }\n.iam-dt-panel-wrap[data-pos=\"bottom\"] .iam-dt-resize { top: 0; }\n.iam-dt-panel-wrap[data-pos=\"top\"] .iam-dt-resize    { bottom: 0; }\n.iam-dt-panel-wrap[data-pos=\"left\"] .iam-dt-resize   { right: 0; }\n.iam-dt-panel-wrap[data-pos=\"right\"] .iam-dt-resize  { left: 0; }\n\n@keyframes iam-dt-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n.iam-dt-spin { animation: iam-dt-spin 0.9s linear infinite; }\n\n/* Panel utility classes - use design tokens from the host's Tailwind theme. */\n.iam-dt-detail { flex: 1 1 auto; overflow: auto; min-height: 0; }\n.iam-dt-detail__head {\n  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;\n  padding: 8px 12px; background: var(--card); border-bottom: 1px solid var(--border);\n  position: sticky; top: 0; z-index: 1;\n}\n.iam-dt-detail__head code { font-family: ui-monospace, \"SF Mono\", Menlo, Consolas, monospace; font-size: 11px; color: var(--foreground); font-weight: 600; }\n.iam-dt-detail__meta { margin-left: auto; font-family: ui-monospace, monospace; font-size: 10px; color: var(--muted-foreground); }\n\n.iam-dt-listshell { display: flex; flex-direction: column; height: 100%; min-height: 0; }\n.iam-dt-listshell__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; background: var(--card); border-bottom: 1px solid var(--border); flex-shrink: 0; }\n.iam-dt-listshell__title { font-size: 10px; font-weight: 600; color: var(--muted-foreground); text-transform: uppercase; letter-spacing: 0.18em; }\n\n.iam-dt-trace__group { background: var(--card); border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }\n.iam-dt-trace__group-head { display: flex; width: 100%; align-items: center; gap: 8px; padding: 6px 10px; background: transparent; border: none; color: inherit; cursor: pointer; text-align: left; flex-wrap: wrap; transition: background 160ms ease; font-size: 11px; }\n.iam-dt-trace__group-head:hover { background: color-mix(in oklab, var(--muted) 50%, transparent); }\n.iam-dt-trace__group-body { padding: 8px 10px 10px 20px; display: flex; flex-direction: column; gap: 6px; border-top: 1px solid var(--border); }\n.iam-dt-trace__row { display: flex; align-items: center; gap: 8px; padding: 6px 10px; background: var(--card); border: 1px solid var(--border); border-radius: 6px; flex-wrap: wrap; }\n.iam-dt-trace__row code { font-family: ui-monospace, monospace; font-size: 11px; color: var(--foreground); }\n\n.iam-dt-stat { display: flex; flex-direction: column; gap: 4px; padding: 10px 12px; background: var(--card); border: 1px solid var(--border); border-radius: 8px; }\n.iam-dt-stat__label { font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.14em; color: var(--muted-foreground); }\n.iam-dt-stat__value { font-family: ui-monospace, monospace; font-size: 18px; font-weight: 700; color: var(--foreground); line-height: 1.1; letter-spacing: -0.02em; }\n.iam-dt-stat__hint { font-family: ui-monospace, monospace; font-size: 9px; color: var(--muted-foreground); }\n.iam-dt-stat-grid { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }\n\n.iam-dt-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }\n.iam-dt-col { display: flex; flex-direction: column; gap: 8px; }\n.iam-dt-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }\n@media (max-width: 600px) { .iam-dt-grid-2 { grid-template-columns: 1fr; } }\n.iam-dt-mute { color: var(--muted-foreground); font-family: ui-monospace, monospace; font-size: 10px; }\n.iam-dt-soft { color: var(--muted-foreground); }\n.iam-dt-pad { padding: 12px; }\n.iam-dt-sep { display: inline-block; width: 3px; height: 3px; background: currentColor; opacity: 0.5; border-radius: 50%; flex-shrink: 0; }\n\n.iam-dt-action { color: #60a5fa; font-weight: 600; }\n.iam-dt-resource { color: #fbbf24; font-weight: 600; }\n.iam-dt-effect-allow { color: #84cc16; font-weight: 700; }\n.iam-dt-effect-deny { color: #f87171; font-weight: 700; }\n\n.iam-dt-section__chev { display: inline-flex; align-items: center; justify-content: center; color: var(--muted-foreground); transition: transform 160ms ease; }\n.iam-dt-empty { padding: 32px 20px; text-align: center; font-size: 12px; color: var(--muted-foreground); }\n.iam-dt-empty--dashed { margin: 12px; padding: 20px; border: 1px dashed var(--border); border-radius: 8px; background: color-mix(in oklab, var(--card) 60%, transparent); }\n`\n\nexport function ensureStylesInjected() {\n  if (typeof document === 'undefined') return\n  if (document.getElementById(STYLE_ID)) return\n  const style = document.createElement('style')\n  style.id = STYLE_ID\n  style.textContent = CSS\n  document.head.appendChild(style)\n}\n","import type { CSSProperties } from 'react'\n\ninterface IconProps {\n  size?: number\n  className?: string\n  style?: CSSProperties\n}\n\nconst base = {\n  fill: 'none',\n  stroke: 'currentColor',\n  strokeWidth: 1.5,\n  strokeLinecap: 'round' as const,\n  strokeLinejoin: 'round' as const,\n}\n\nexport function ChevronDown({ size = 12, className, style }: IconProps) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 16 16\" {...base} className={className} style={style}>\n      <path d=\"M3 6l5 5 5-5\" />\n    </svg>\n  )\n}\n\nexport function ChevronRight({ size = 12, className, style }: IconProps) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 16 16\" {...base} className={className} style={style}>\n      <path d=\"M6 3l5 5-5 5\" />\n    </svg>\n  )\n}\n\nexport function Close({ size = 14, className, style }: IconProps) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 16 16\" {...base} className={className} style={style}>\n      <path d=\"M3 3l10 10M13 3L3 13\" />\n    </svg>\n  )\n}\n\nexport function Refresh({ size = 12, className, style }: IconProps) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 16 16\" {...base} className={className} style={style}>\n      <path d=\"M13.5 7a5.5 5.5 0 1 0-1.5 4M13.5 3v4h-4\" />\n    </svg>\n  )\n}\n\nexport function Search({ size = 12, className, style }: IconProps) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 16 16\" {...base} className={className} style={style}>\n      <circle cx=\"7\" cy=\"7\" r=\"4.5\" />\n      <path d=\"M10.5 10.5L14 14\" />\n    </svg>\n  )\n}\n\nexport function ArrowRight({ size = 12, className, style }: IconProps) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 16 16\" {...base} className={className} style={style}>\n      <path d=\"M3 8h10M9 4l4 4-4 4\" />\n    </svg>\n  )\n}\n\nexport function CornerUpRight({ size = 12, className, style }: IconProps) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 16 16\" {...base} className={className} style={style}>\n      <path d=\"M3 12V6a2 2 0 0 1 2-2h8M10 1l4 3-4 3\" />\n    </svg>\n  )\n}\n\nexport function Dot({ size = 4, className, style }: IconProps) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 4 4\" className={className} style={style}>\n      <circle cx=\"2\" cy=\"2\" r=\"2\" fill=\"currentColor\" />\n    </svg>\n  )\n}\n\nexport function Spinner({ size = 12, className, style }: IconProps) {\n  return (\n    <svg\n      width={size}\n      height={size}\n      viewBox=\"0 0 16 16\"\n      {...base}\n      className={className}\n      style={{ ...style, animation: 'iam-dt-spin 0.9s linear infinite' }}>\n      <path d=\"M8 1.5a6.5 6.5 0 1 1-6.5 6.5\" />\n    </svg>\n  )\n}\n\nexport function Check({ size = 12, className, style }: IconProps) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 16 16\" {...base} className={className} style={style}>\n      <path d=\"M3 8.5l3.5 3.5L13 5\" />\n    </svg>\n  )\n}\n\nexport function Minus({ size = 12, className, style }: IconProps) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 16 16\" {...base} className={className} style={style}>\n      <path d=\"M3 8h10\" />\n    </svg>\n  )\n}\n","import { cn } from '@gentleduck/libs/cn'\nimport React from 'react'\nimport { ChevronDown, ChevronRight } from './icons'\n\nexport interface IJsonTreeProps {\n  data: unknown\n  label?: string\n  defaultOpen?: boolean\n  level?: number\n}\n\nfunction typeOf(v: unknown): 'object' | 'array' | 'string' | 'number' | 'boolean' | 'null' | 'undefined' | 'function' {\n  if (v === null) return 'null'\n  if (Array.isArray(v)) return 'array'\n  if (typeof v === 'object') return 'object'\n  return typeof v as 'string' | 'number' | 'boolean' | 'undefined' | 'function'\n}\n\nfunction previewLen(v: unknown): string {\n  if (Array.isArray(v)) return `${v.length} ${v.length === 1 ? 'item' : 'items'}`\n  if (v && typeof v === 'object') {\n    const n = Object.keys(v as Record<string, unknown>).length\n    return `${n} ${n === 1 ? 'item' : 'items'}`\n  }\n  return ''\n}\n\nfunction Primitive({ value }: { value: unknown }) {\n  const t = typeOf(value)\n  if (t === 'string') return <span className=\"text-lime-400\">\"{String(value)}\"</span>\n  if (t === 'number') return <span className=\"text-amber-400\">{String(value)}</span>\n  if (t === 'boolean') return <span className=\"font-semibold text-sky-400\">{String(value)}</span>\n  if (t === 'null') return <span className=\"text-muted-foreground italic\">null</span>\n  if (t === 'undefined') return <span className=\"text-muted-foreground italic\">undefined</span>\n  if (t === 'function') return <span className=\"text-muted-foreground italic\">ƒ()</span>\n  return <span>{String(value)}</span>\n}\n\nexport function JsonTree({ data, label, defaultOpen = false, level = 0 }: IJsonTreeProps) {\n  const t = typeOf(data)\n  const isContainer = t === 'object' || t === 'array'\n  const [open, setOpen] = React.useState(defaultOpen || level === 0)\n\n  if (!isContainer) {\n    return (\n      <div className=\"font-mono text-[11px] leading-relaxed\">\n        <div className=\"flex items-baseline gap-1.5 pl-4\">\n          {label != null && <span className=\"text-sky-400\">{label}:</span>}\n          <Primitive value={data} />\n        </div>\n      </div>\n    )\n  }\n\n  const entries = Array.isArray(data)\n    ? (data as unknown[]).map((v, i) => [String(i), v] as const)\n    : Object.entries(data as Record<string, unknown>)\n  const summary = previewLen(data)\n\n  return (\n    <div className=\"font-mono text-[11px] leading-relaxed\">\n      <button\n        type=\"button\"\n        onClick={() => setOpen((o) => !o)}\n        className={cn('flex w-full items-baseline gap-1 rounded px-1 py-0.5 text-left hover:bg-muted/60')}>\n        <span className=\"inline-flex w-3 shrink-0 text-muted-foreground\">\n          {open ? <ChevronDown size={10} /> : <ChevronRight size={10} />}\n        </span>\n        {label != null && <span className=\"text-sky-400\">{label}:</span>}\n        <span className=\"text-muted-foreground\">{t === 'array' ? '[' : '{'}</span>\n        {!open && <span className=\"text-muted-foreground\">...{t === 'array' ? ']' : '}'}</span>}\n        <span className=\"ml-1.5 text-[9px] text-muted-foreground/60 italic\">{summary}</span>\n      </button>\n      {open && (\n        <div className=\"ml-3 border-border/60 border-l pl-2\">\n          {entries.map(([k, v]) => (\n            <JsonTree data={v} key={k} label={k} level={level + 1} />\n          ))}\n          <div className=\"pl-1 text-muted-foreground\">{t === 'array' ? ']' : '}'}</div>\n        </div>\n      )}\n    </div>\n  )\n}\n","import { cn } from '@gentleduck/libs/cn'\nimport React from 'react'\nimport { ChevronDown, ChevronRight, Search } from './icons'\n\nexport function SplitView({ left, right }: { left: React.ReactNode; right: React.ReactNode }) {\n  return (\n    <div className=\"grid h-full min-h-0 grid-cols-[300px_1fr] overflow-hidden\">\n      <aside className=\"flex h-full min-h-0 flex-col overflow-hidden border-r bg-card\">{left}</aside>\n      <section className=\"flex h-full min-h-0 flex-col overflow-hidden bg-background\">{right}</section>\n    </div>\n  )\n}\n\nexport function ListShell({\n  title,\n  count,\n  toolbar,\n  children,\n}: {\n  title?: string\n  count?: number\n  toolbar?: React.ReactNode\n  children: React.ReactNode\n}) {\n  return (\n    <div className=\"flex h-full min-h-0 flex-col\">\n      <div className=\"flex shrink-0 items-center justify-between gap-2 border-b bg-card px-3 py-2\">\n        <div className=\"flex items-center gap-2\">\n          {title && (\n            <h3 className=\"font-semibold text-[10px] text-muted-foreground uppercase tracking-[0.2em]\">{title}</h3>\n          )}\n          {typeof count === 'number' && (\n            <span className=\"inline-flex items-center rounded-full bg-muted px-1.5 py-0.5 font-mono font-semibold text-[9px] text-muted-foreground\">\n              {count}\n            </span>\n          )}\n        </div>\n        {toolbar}\n      </div>\n      <div className=\"flex-1 overflow-auto\">{children}</div>\n    </div>\n  )\n}\n\nexport function ListItem({\n  active,\n  onClick,\n  dot,\n  primary,\n  secondary,\n  trailing,\n}: {\n  active?: boolean\n  onClick?: () => void\n  dot?: string\n  primary: React.ReactNode\n  secondary?: React.ReactNode\n  trailing?: React.ReactNode\n}) {\n  return (\n    <button\n      type=\"button\"\n      onClick={onClick}\n      className={cn(\n        'group flex w-full items-center gap-2 border-border/50 border-b px-3 py-1.5 text-left transition-colors',\n        active ? 'bg-primary/10 hover:bg-primary/15' : 'hover:bg-muted/50',\n      )}>\n      {dot && <span aria-hidden className=\"h-1.5 w-1.5 shrink-0 rounded-full\" style={{ backgroundColor: dot }} />}\n      <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n        <div\n          className={cn(\n            'truncate font-mono text-[11px]',\n            active ? 'font-semibold text-foreground' : 'text-foreground',\n          )}>\n          {primary}\n        </div>\n        {secondary && <div className=\"truncate font-mono text-[9px] text-muted-foreground\">{secondary}</div>}\n      </div>\n      {trailing}\n    </button>\n  )\n}\n\nexport function Section({\n  title,\n  defaultOpen = true,\n  toolbar,\n  children,\n}: {\n  title: string\n  defaultOpen?: boolean\n  toolbar?: React.ReactNode\n  children: React.ReactNode\n}) {\n  const [open, setOpen] = React.useState(defaultOpen)\n  return (\n    <div className=\"border-b\">\n      <div className=\"flex items-center justify-between gap-2 bg-card/60 px-3 py-1.5\">\n        <button type=\"button\" onClick={() => setOpen((o) => !o)} className=\"flex flex-1 items-center gap-2 text-left\">\n          <span className=\"inline-flex w-3 text-muted-foreground\">\n            {open ? <ChevronDown size={10} /> : <ChevronRight size={10} />}\n          </span>\n          <h4 className=\"font-semibold text-[10px] text-muted-foreground uppercase tracking-[0.2em]\">{title}</h4>\n        </button>\n        {toolbar}\n      </div>\n      {open && <div className=\"px-3 py-2\">{children}</div>}\n    </div>\n  )\n}\n\nexport function DetailEmpty({ message }: { message: string }) {\n  return (\n    <div className=\"flex h-full items-center justify-center p-6 text-center text-muted-foreground text-xs\">\n      {message}\n    </div>\n  )\n}\n\nexport function FilterBar({\n  value,\n  onChange,\n  placeholder = 'Filter',\n  trailing,\n}: {\n  value: string\n  onChange: (v: string) => void\n  placeholder?: string\n  trailing?: React.ReactNode\n}) {\n  return (\n    <div className=\"flex shrink-0 items-center gap-2 border-b bg-card/60 px-2 py-1.5\">\n      <div className=\"relative flex flex-1 items-center\">\n        <Search className=\"pointer-events-none absolute left-2 text-muted-foreground\" size={11} />\n        <input\n          value={value}\n          onChange={(e) => onChange(e.target.value)}\n          placeholder={placeholder}\n          className=\"flex h-7 w-full rounded-md border border-input bg-background pr-2 pl-7 text-[11px] outline-none transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50\"\n        />\n      </div>\n      {trailing}\n    </div>\n  )\n}\n","import { cn } from '@gentleduck/libs/cn'\nimport { Badge as RxBadge } from '@gentleduck/registry-ui/badge'\nimport { Button as RxButton } from '@gentleduck/registry-ui/button'\nimport { CardContent, CardHeader, CardTitle, Card as RxCard } from '@gentleduck/registry-ui/card'\nimport { Input as RxInput } from '@gentleduck/registry-ui/input'\nimport { Textarea as RxTextarea } from '@gentleduck/registry-ui/textarea'\nimport type React from 'react'\n\nexport function Card({\n  title,\n  children,\n  actions,\n}: {\n  title?: string\n  children: React.ReactNode\n  actions?: React.ReactNode\n}) {\n  return (\n    <RxCard className=\"gap-0 overflow-hidden py-0\">\n      {(title || actions) && (\n        <CardHeader className=\"flex items-center justify-between gap-2 border-b px-3 py-2 [.border-b]:pb-2\">\n          {title && (\n            <CardTitle className=\"font-semibold text-[11px] text-muted-foreground uppercase tracking-wider\">\n              {title}\n            </CardTitle>\n          )}\n          {actions}\n        </CardHeader>\n      )}\n      <CardContent className=\"p-3 text-xs\">{children}</CardContent>\n    </RxCard>\n  )\n}\n\nexport function Button({\n  children,\n  onClick,\n  variant = 'default',\n  disabled,\n  type = 'button',\n  className,\n}: {\n  children: React.ReactNode\n  onClick?: () => void\n  variant?: 'default' | 'primary' | 'ghost' | 'danger'\n  disabled?: boolean\n  type?: 'button' | 'submit'\n  className?: string\n}) {\n  const rxVariant =\n    variant === 'primary' ? 'default' : variant === 'danger' ? 'destructive' : variant === 'ghost' ? 'ghost' : 'outline'\n  return (\n    <RxButton\n      className={cn('text-[11px]', className)}\n      disabled={disabled}\n      onClick={onClick}\n      size=\"sm\"\n      type={type}\n      variant={rxVariant}>\n      {children}\n    </RxButton>\n  )\n}\n\nexport function Field({ label, children }: { label: string; children: React.ReactNode }) {\n  return (\n    <div className=\"flex flex-col gap-1.5\">\n      <span className=\"font-semibold text-[10px] text-muted-foreground uppercase tracking-wider\">{label}</span>\n      {children}\n    </div>\n  )\n}\n\nexport function Input(props: React.InputHTMLAttributes<HTMLInputElement>) {\n  return <RxInput {...props} className={cn('h-7 text-xs', props.className)} />\n}\n\nexport function TextArea(props: React.TextareaHTMLAttributes<HTMLTextAreaElement>) {\n  return <RxTextarea {...props} className={cn('font-mono text-[11px] leading-relaxed', props.className)} />\n}\n\nexport function Badge({\n  children,\n  tone = 'neutral',\n  className,\n}: {\n  children: React.ReactNode\n  tone?: 'neutral' | 'allow' | 'deny' | 'info' | 'warn'\n  className?: string\n}) {\n  const variant =\n    tone === 'allow'\n      ? 'default'\n      : tone === 'deny'\n        ? 'destructive'\n        : tone === 'info'\n          ? 'secondary'\n          : tone === 'warn'\n            ? 'outline'\n            : 'outline'\n  const toneCls =\n    tone === 'allow'\n      ? 'bg-lime-500/10 text-lime-400 border-lime-500/35 hover:bg-lime-500/15'\n      : tone === 'deny'\n        ? 'bg-red-500/10 text-red-400 border-red-500/35 hover:bg-red-500/15'\n        : tone === 'info'\n          ? 'bg-sky-500/10 text-sky-400 border-sky-500/35 hover:bg-sky-500/15'\n          : tone === 'warn'\n            ? 'bg-amber-500/10 text-amber-400 border-amber-500/35 hover:bg-amber-500/15'\n            : ''\n  return (\n    <RxBadge\n      className={cn('h-5 rounded-full px-2 font-semibold text-[9px] uppercase tracking-wider', toneCls, className)}\n      variant={variant}>\n      {children}\n    </RxBadge>\n  )\n}\n\nexport function Empty({ message }: { message: string }) {\n  return (\n    <div className=\"rounded-md border border-border/60 border-dashed bg-muted/20 p-6 text-center text-muted-foreground text-xs\">\n      {message}\n    </div>\n  )\n}\n\nexport function Alert({ kind, children }: { kind: 'error' | 'success'; children: React.ReactNode }) {\n  return (\n    <div\n      className={cn(\n        'm-2 rounded-md px-3 py-2 font-medium text-[11px]',\n        kind === 'error' && 'border border-red-500/30 bg-red-500/10 text-red-400',\n        kind === 'success' && 'border border-lime-500/30 bg-lime-500/10 text-lime-400',\n      )}>\n      {children}\n    </div>\n  )\n}\n","import type { Explain } from '../../core/explain'\nimport type { AccessControl, IamPrimitives } from '../../core/types'\n\nexport function formatAttrValue(value: IamPrimitives.AttributeValue | undefined): string {\n  if (value === undefined) return '(undefined)'\n  if (value === null) return 'null'\n  if (typeof value === 'string') return JSON.stringify(value)\n  if (typeof value === 'number' || typeof value === 'boolean') return String(value)\n  if (Array.isArray(value))\n    return `[${value.map((v) => formatAttrValue(v as IamPrimitives.AttributeValue)).join(', ')}]`\n  return JSON.stringify(value)\n}\n\nexport function effectColor(effect: AccessControl.Effect): string {\n  return effect === 'allow' ? 'text-emerald-500' : 'text-rose-500'\n}\n\nexport function resultColor(result: boolean): string {\n  return result ? 'text-emerald-500' : 'text-rose-500'\n}\n\nexport function safeParseJson<T = unknown>(raw: string, fallback: T): { value: T; error?: string } {\n  const trimmed = raw.trim()\n  if (!trimmed) return { value: fallback }\n  try {\n    return { value: JSON.parse(trimmed) as T }\n  } catch (err) {\n    return { value: fallback, error: err instanceof Error ? err.message : String(err) }\n  }\n}\n\nexport function summarizeTrace(trace: Explain.Trace): string {\n  if (trace.type === 'condition') {\n    return `${trace.field} ${trace.operator} ${formatAttrValue(trace.expected)}`\n  }\n  const logic = trace.logic.toUpperCase()\n  return `${logic} (${trace.children.length})`\n}\n\nexport function countConditions(trace: Explain.Trace): number {\n  if (trace.type === 'condition') return 1\n  return trace.children.reduce((sum, c) => sum + countConditions(c), 0)\n}\n","import React from 'react'\nimport type { Explain } from '../../core/explain'\nimport { ArrowRight, ChevronDown, ChevronRight } from '../components/icons'\nimport { Badge } from '../components/ui'\nimport { formatAttrValue, summarizeTrace } from '../lib/format'\n\nfunction LeafNode({ leaf }: { leaf: Explain.ILeafTrace }) {\n  return (\n    <div className=\"iam-dt-trace__row\" style={{ flexDirection: 'column', alignItems: 'stretch' }}>\n      <div className=\"iam-dt-row\">\n        <Badge tone={leaf.result ? 'allow' : 'deny'}>{leaf.result ? 'PASS' : 'FAIL'}</Badge>\n        <code className=\"iam-dt-action\">{leaf.field}</code>\n        <code className=\"iam-dt-mute\">{leaf.operator}</code>\n      </div>\n      <div className=\"iam-dt-grid-2\" style={{ paddingLeft: 4, fontSize: 11 }}>\n        <div className=\"iam-dt-mute\">\n          expected: <code className=\"iam-dt-soft\">{formatAttrValue(leaf.expected)}</code>\n        </div>\n        <div className=\"iam-dt-mute\">\n          actual:{' '}\n          <code className={leaf.result ? 'iam-dt-effect-allow' : 'iam-dt-effect-deny'}>\n            {formatAttrValue(leaf.actual)}\n          </code>\n        </div>\n      </div>\n    </div>\n  )\n}\n\nfunction GroupNode({ group, depth = 0 }: { group: Explain.IGroupTrace; depth?: number }) {\n  const [open, setOpen] = React.useState(depth < 2)\n  return (\n    <div className=\"iam-dt-trace__group\">\n      <button onClick={() => setOpen(!open)} type=\"button\" className=\"iam-dt-trace__group-head\">\n        <span className=\"iam-dt-section__chev\">{open ? <ChevronDown /> : <ChevronRight />}</span>\n        <Badge tone={group.result ? 'allow' : 'deny'}>{group.logic.toUpperCase()}</Badge>\n        <span className=\"iam-dt-soft\" style={{ fontSize: 11 }}>\n          {summarizeTrace(group)}\n        </span>\n      </button>\n      {open && (\n        <div className=\"iam-dt-trace__group-body\">\n          {group.children.map((child) =>\n            child.type === 'condition' ? (\n              <LeafNode key={`leaf:${child.field}:${child.operator}`} leaf={child} />\n            ) : (\n              <GroupNode depth={depth + 1} group={child} key={`group:${child.logic}:${child.children.length}`} />\n            ),\n          )}\n        </div>\n      )}\n    </div>\n  )\n}\n\nfunction RuleTrace({ rule }: { rule: Explain.IRuleTrace }) {\n  const [open, setOpen] = React.useState(rule.matched)\n  return (\n    <div className=\"iam-dt-trace__group\">\n      <button onClick={() => setOpen(!open)} type=\"button\" className=\"iam-dt-trace__group-head\">\n        <span className=\"iam-dt-section__chev\">{open ? <ChevronDown /> : <ChevronRight />}</span>\n        <span\n          className={rule.effect === 'allow' ? 'iam-dt-effect-allow' : 'iam-dt-effect-deny'}\n          style={{ fontSize: 10, textTransform: 'uppercase' }}>\n          {rule.effect}\n        </span>\n        <code>{rule.ruleId}</code>\n        <Badge tone={rule.actionMatch ? 'allow' : 'neutral'}>act</Badge>\n        <Badge tone={rule.resourceMatch ? 'allow' : 'neutral'}>res</Badge>\n        <Badge tone={rule.conditionsMet ? 'allow' : 'deny'}>cond</Badge>\n        <Badge tone=\"warn\">p{rule.priority}</Badge>\n        {rule.matched && <Badge tone=\"allow\">matched</Badge>}\n      </button>\n      {open && (\n        <div className=\"iam-dt-trace__group-body\">\n          <GroupNode group={rule.conditions} />\n        </div>\n      )}\n    </div>\n  )\n}\n\nexport function IamTraceTree({ result }: { result: Explain.IResult }) {\n  return (\n    <div className=\"iam-dt-col\">\n      <div className=\"iam-dt-trace__row\">\n        <Badge tone={result.decision.allowed ? 'allow' : 'deny'}>\n          {result.decision.allowed ? 'ALLOWED' : 'DENIED'}\n        </Badge>\n        <span className=\"iam-dt-soft\" style={{ fontSize: 11 }}>\n          {result.summary}\n        </span>\n      </div>\n      {result.policies.length === 0 ? (\n        <div className=\"iam-dt-empty iam-dt-empty--dashed\">no policies evaluated</div>\n      ) : (\n        result.policies.map((p) => (\n          <div className=\"iam-dt-trace__group\" key={p.policyId} style={{ padding: 6 }}>\n            <div className=\"iam-dt-row\">\n              <code className=\"iam-dt-soft\">{p.policyName ?? p.policyId}</code>\n              <Badge tone={p.targetMatch ? 'allow' : 'neutral'}>target</Badge>\n              <Badge tone={p.result === 'allow' ? 'allow' : 'deny'}>{p.result}</Badge>\n              <code className=\"iam-dt-mute\" style={{ fontSize: 10 }}>\n                {p.algorithm}\n              </code>\n              {p.decidingRuleId && (\n                <code\n                  className=\"iam-dt-action\"\n                  style={{ fontSize: 10, display: 'inline-flex', alignItems: 'center', gap: 4 }}>\n                  <ArrowRight size={10} /> {p.decidingRuleId}\n                </code>\n              )}\n              <span className=\"iam-dt-detail__meta\">{p.reason}</span>\n            </div>\n            <div className=\"iam-dt-col\" style={{ marginTop: 6 }}>\n              {p.rules.map((r) => (\n                <RuleTrace key={r.ruleId} rule={r} />\n              ))}\n            </div>\n          </div>\n        ))\n      )}\n    </div>\n  )\n}\n","import React from 'react'\nimport type { Explain } from '../../core/explain'\nimport type { IamPrimitives } from '../../core/types'\nimport { Spinner } from '../components/icons'\nimport { JsonTree } from '../components/json-tree'\nimport { DetailEmpty, Section, SplitView } from '../components/layout'\nimport { Alert, Badge, Button, Field, Input, TextArea } from '../components/ui'\nimport { safeParseJson } from '../lib/format'\nimport type { IamIDecisionInput, IamIDevtoolsEngine } from '../lib/types'\nimport { IamTraceTree } from './trace-tree'\n\nconst INITIAL: IamIDecisionInput = {\n  subjectId: '',\n  action: '',\n  resourceType: '',\n  resourceId: '',\n  attributesJson: '{}',\n  environmentJson: '{}',\n  scope: '',\n}\n\nexport function IamDecisionInspector({\n  engine,\n  defaults,\n}: {\n  engine: IamIDevtoolsEngine\n  defaults?: Partial<IamIDecisionInput>\n}) {\n  const [input, setInput] = React.useState<IamIDecisionInput>({ ...INITIAL, ...defaults })\n  const [result, setResult] = React.useState<Explain.IResult | null>(null)\n  const [error, setError] = React.useState<string | null>(null)\n  const [pending, setPending] = React.useState(false)\n\n  const update = (patch: Partial<IamIDecisionInput>) => setInput((s) => ({ ...s, ...patch }))\n\n  async function run() {\n    setError(null)\n    setPending(true)\n    try {\n      const attrs = safeParseJson<Record<string, IamPrimitives.AttributeValue>>(input.attributesJson, {})\n      const env = safeParseJson<Record<string, unknown>>(input.environmentJson, {})\n      if (attrs.error) throw new Error(`attributes JSON: ${attrs.error}`)\n      if (env.error) throw new Error(`environment JSON: ${env.error}`)\n      const resource = { type: input.resourceType, id: input.resourceId || undefined, attributes: attrs.value }\n      const environment = { ...env.value, ...(input.scope ? { scope: input.scope } : {}) }\n      const trace = await engine.explain(input.subjectId, input.action, resource, environment)\n      setResult(trace)\n    } catch (err) {\n      setError(err instanceof Error ? err.message : String(err))\n    } finally {\n      setPending(false)\n    }\n  }\n\n  return (\n    <SplitView\n      left={\n        <div className=\"iam-dt-listshell\">\n          <div className=\"iam-dt-listshell__head\">\n            <h3 className=\"iam-dt-listshell__title\">Request</h3>\n            <Button disabled={pending} onClick={run} variant=\"primary\">\n              {pending ? <Spinner size={10} /> : null}\n              {pending ? 'running' : 'evaluate'}\n            </Button>\n          </div>\n          <div className=\"iam-dt-pad iam-dt-col\" style={{ overflow: 'auto' }}>\n            <Field label=\"subject id\">\n              <Input\n                onChange={(e) => update({ subjectId: e.target.value })}\n                placeholder=\"user-1\"\n                value={input.subjectId}\n              />\n            </Field>\n            <div className=\"iam-dt-grid-2\">\n              <Field label=\"action\">\n                <Input onChange={(e) => update({ action: e.target.value })} placeholder=\"read\" value={input.action} />\n              </Field>\n              <Field label=\"scope\">\n                <Input onChange={(e) => update({ scope: e.target.value })} placeholder=\"org-acme\" value={input.scope} />\n              </Field>\n            </div>\n            <div className=\"iam-dt-grid-2\">\n              <Field label=\"resource type\">\n                <Input\n                  onChange={(e) => update({ resourceType: e.target.value })}\n                  placeholder=\"post\"\n                  value={input.resourceType}\n                />\n              </Field>\n              <Field label=\"resource id\">\n                <Input\n                  onChange={(e) => update({ resourceId: e.target.value })}\n                  placeholder=\"p-1\"\n                  value={input.resourceId}\n                />\n              </Field>\n            </div>\n            <Field label=\"resource.attributes (JSON)\">\n              <TextArea\n                onChange={(e) => update({ attributesJson: e.target.value })}\n                rows={4}\n                value={input.attributesJson}\n              />\n            </Field>\n            <Field label=\"environment (JSON)\">\n              <TextArea\n                onChange={(e) => update({ environmentJson: e.target.value })}\n                rows={3}\n                value={input.environmentJson}\n              />\n            </Field>\n          </div>\n        </div>\n      }\n      right={\n        error ? (\n          <Alert kind=\"error\">{error}</Alert>\n        ) : !result ? (\n          <DetailEmpty message=\"Run an evaluation to see the trace.\" />\n        ) : (\n          <div className=\"iam-dt-detail\">\n            <div className=\"iam-dt-detail__head\">\n              <Badge tone={result.decision.allowed ? 'allow' : 'deny'}>\n                {result.decision.allowed ? 'allow' : 'deny'}\n              </Badge>\n              <code className=\"iam-dt-action\">{input.action}</code>\n              <span className=\"iam-dt-mute\">on</span>\n              <code className=\"iam-dt-resource\">{input.resourceType}</code>\n              <span className=\"iam-dt-detail__meta\">subject: {input.subjectId || '-'}</span>\n            </div>\n            <Section title=\"Reason\">\n              <p className=\"iam-dt-soft\" style={{ fontSize: 11 }}>\n                {result.summary}\n              </p>\n            </Section>\n            <Section title=\"Trace\">\n              <IamTraceTree result={result} />\n            </Section>\n            <Section defaultOpen={false} title=\"Raw result\">\n              <JsonTree data={result} defaultOpen />\n            </Section>\n          </div>\n        )\n      }\n    />\n  )\n}\n","import { cn } from '@gentleduck/libs/cn'\nimport React from 'react'\nimport { Refresh } from '../components/icons'\nimport { JsonTree } from '../components/json-tree'\nimport { DetailEmpty, FilterBar, ListItem, ListShell, Section, SplitView } from '../components/layout'\nimport { Badge, Button } from '../components/ui'\nimport type { IamIFlowEntry, IamIFlowRecorder } from '../lib/flow'\n\nfunction pad(n: number, w = 2) {\n  return String(n).padStart(w, '0')\n}\nfunction fmtTime(ts: number) {\n  const d = new Date(ts)\n  return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}.${pad(d.getMilliseconds(), 3)}`\n}\nfunction fmtAgo(ts: number, now: number) {\n  const ms = Math.max(0, now - ts)\n  if (ms < 1000) return `${ms}ms ago`\n  if (ms < 60_000) return `${Math.floor(ms / 1000)}s ago`\n  if (ms < 3_600_000) return `${Math.floor(ms / 60_000)}m ago`\n  return `${Math.floor(ms / 3_600_000)}h ago`\n}\n\nfunction ActionChip({ action }: { action: string }) {\n  return (\n    <code className=\"inline-flex h-6 items-center rounded-md border border-sky-500/30 bg-sky-500/10 px-2 font-mono font-semibold text-[11px] text-sky-500\">\n      {action}\n    </code>\n  )\n}\nfunction ResourceChip({ resource, resourceId }: { resource: string; resourceId?: string }) {\n  return (\n    <code className=\"inline-flex h-6 items-center gap-1 rounded-md border border-amber-500/30 bg-amber-500/10 px-2 font-mono font-semibold text-[11px] text-amber-500\">\n      {resource}\n      {resourceId && <span className=\"opacity-60\">#{resourceId}</span>}\n    </code>\n  )\n}\nfunction SubjectChip({ id }: { id: string }) {\n  const initial = id.replace(/^u-/, '').charAt(0).toUpperCase() || '?'\n  return (\n    <div className=\"inline-flex items-center gap-2 rounded-md border bg-card px-2 py-1\">\n      <span className=\"inline-flex h-5 w-5 items-center justify-center rounded-full bg-primary/15 font-bold font-mono text-[10px] text-primary\">\n        {initial}\n      </span>\n      <code className=\"font-mono font-semibold text-[11px] text-foreground\">{id}</code>\n    </div>\n  )\n}\n\nexport function IamFlowPanel({ flow }: { flow: IamIFlowRecorder }) {\n  const [entries, setEntries] = React.useState<readonly IamIFlowEntry[]>(() => flow.list())\n  const [selected, setSelected] = React.useState<number | null>(null)\n  const [filter, setFilter] = React.useState('')\n  const [showAllow, setShowAllow] = React.useState(true)\n  const [showDeny, setShowDeny] = React.useState(true)\n  const [now, setNow] = React.useState(Date.now())\n  const [copied, setCopied] = React.useState(false)\n\n  React.useEffect(() => {\n    const off = flow.subscribe(() => setEntries(flow.list().slice()))\n    return off\n  }, [flow])\n  React.useEffect(() => {\n    const id = setInterval(() => setNow(Date.now()), 1000)\n    return () => clearInterval(id)\n  }, [])\n\n  const q = filter.trim().toLowerCase()\n  const filtered = entries.filter((e) => {\n    if (!showAllow && e.allowed) return false\n    if (!showDeny && !e.allowed) return false\n    if (!q) return true\n    return (\n      e.subjectId.toLowerCase().includes(q) ||\n      e.action.toLowerCase().includes(q) ||\n      e.resource.toLowerCase().includes(q) ||\n      (e.resourceId ?? '').toLowerCase().includes(q)\n    )\n  })\n\n  const current = selected != null ? (flow.get(selected) ?? null) : null\n  const counts = React.useMemo(() => {\n    let allow = 0,\n      deny = 0\n    for (const e of entries) e.allowed ? allow++ : deny++\n    return { allow, deny }\n  }, [entries])\n\n  const copyEntry = async () => {\n    if (!current) return\n    try {\n      await navigator.clipboard.writeText(JSON.stringify(current, null, 2))\n      setCopied(true)\n      setTimeout(() => setCopied(false), 1500)\n    } catch {}\n  }\n\n  return (\n    <SplitView\n      left={\n        <ListShell\n          count={filtered.length}\n          title=\"Flow\"\n          toolbar={\n            <Button onClick={() => flow.clear()}>\n              <Refresh size={10} /> clear\n            </Button>\n          }>\n          <FilterBar onChange={setFilter} placeholder=\"Filter by subject, action, resource\" value={filter} />\n          <div className=\"flex items-center gap-1.5 border-b bg-card/40 px-3 py-2\">\n            <FilterPill active={showAllow} tone=\"allow\" onClick={() => setShowAllow((v) => !v)}>\n              allow <span className=\"opacity-70\">{counts.allow}</span>\n            </FilterPill>\n            <FilterPill active={showDeny} tone=\"deny\" onClick={() => setShowDeny((v) => !v)}>\n              deny <span className=\"opacity-70\">{counts.deny}</span>\n            </FilterPill>\n          </div>\n          {filtered.length === 0 && (\n            <DetailEmpty\n              message={\n                entries.length === 0\n                  ? 'No access checks recorded yet. Interact with the app to see live flow.'\n                  : 'No matches.'\n              }\n            />\n          )}\n          {filtered.map((e) => (\n            <ListItem\n              active={selected === e.id}\n              dot={e.allowed ? '#84cc16' : '#ef4444'}\n              key={e.id}\n              onClick={() => setSelected(e.id)}\n              primary={\n                <span className=\"inline-flex items-baseline gap-1.5\">\n                  <span className=\"font-semibold text-sky-500\">{e.action}</span>\n                  <span className=\"text-muted-foreground\">on</span>\n                  <span className=\"font-semibold text-amber-500\">{e.resource}</span>\n                  {e.resourceId && <span className=\"text-muted-foreground\">#{e.resourceId}</span>}\n                </span>\n              }\n              secondary={\n                <span className=\"inline-flex items-center gap-1.5\">\n                  {e.subjectId}\n                  <Dot />\n                  {fmtAgo(e.ts, now)}\n                  {typeof e.durationMs === 'number' && (\n                    <>\n                      <Dot />\n                      {e.durationMs.toFixed(1)}ms\n                    </>\n                  )}\n                </span>\n              }\n            />\n          ))}\n        </ListShell>\n      }\n      right={\n        !current ? (\n          <DetailEmpty message=\"Pick a check on the left to inspect.\" />\n        ) : (\n          <div className=\"flex h-full min-h-0 flex-col overflow-hidden\">\n            <header className=\"sticky top-0 z-10 flex shrink-0 flex-wrap items-center gap-2 border-b bg-card/60 px-4 py-3 backdrop-blur\">\n              <Badge tone={current.allowed ? 'allow' : 'deny'}>{current.allowed ? 'allow' : 'deny'}</Badge>\n              <ActionChip action={current.action} />\n              <span className=\"text-muted-foreground text-xs\">on</span>\n              <ResourceChip resource={current.resource} resourceId={current.resourceId} />\n              <span className=\"ml-auto inline-flex items-center gap-1.5 font-mono text-[10px] text-muted-foreground\">\n                {fmtTime(current.ts)}\n                {typeof current.durationMs === 'number' && (\n                  <>\n                    <Dot />\n                    {current.durationMs.toFixed(2)}ms\n                  </>\n                )}\n              </span>\n            </header>\n            <div className=\"flex-1 overflow-auto\">\n              <Section title=\"Subject\">\n                <div className=\"flex flex-wrap items-center gap-2\">\n                  <SubjectChip id={current.subjectId} />\n                  {current.scope && <Badge tone=\"info\">scope: {current.scope}</Badge>}\n                </div>\n              </Section>\n              {current.reason && (\n                <Section title=\"Reason\">\n                  <p className=\"whitespace-pre-wrap font-mono text-[11px] text-foreground/80 leading-relaxed\">\n                    {current.reason}\n                  </p>\n                </Section>\n              )}\n              {(current.decidingPolicy || current.decidingRule) && (\n                <Section title=\"Deciding\">\n                  <div className=\"flex flex-wrap gap-2\">\n                    {current.decidingPolicy && <Kv k=\"policy\" v={current.decidingPolicy} />}\n                    {current.decidingRule && <Kv k=\"rule\" v={current.decidingRule} />}\n                  </div>\n                </Section>\n              )}\n              {current.environment && Object.keys(current.environment).length > 0 && (\n                <Section defaultOpen={false} title=\"Environment\">\n                  <JsonTree data={current.environment} defaultOpen />\n                </Section>\n              )}\n              <Section defaultOpen={false} title=\"Raw entry\">\n                <JsonTree data={current} defaultOpen />\n              </Section>\n            </div>\n            <footer className=\"flex shrink-0 items-center justify-end gap-1.5 border-t bg-card/60 px-3 py-2\">\n              <Button onClick={copyEntry} variant=\"ghost\">\n                {copied ? 'copied' : 'copy entry'}\n              </Button>\n            </footer>\n          </div>\n        )\n      }\n    />\n  )\n}\n\nfunction FilterPill({\n  active,\n  tone,\n  onClick,\n  children,\n}: {\n  active: boolean\n  tone: 'allow' | 'deny'\n  onClick: () => void\n  children: React.ReactNode\n}) {\n  return (\n    <button\n      type=\"button\"\n      onClick={onClick}\n      className={cn(\n        'inline-flex h-6 items-center gap-1.5 rounded-full border px-2.5 font-mono font-semibold text-[10px] uppercase tracking-wider transition-all',\n        active && tone === 'allow' && 'border-lime-500/35 bg-lime-500/10 text-lime-500 hover:bg-lime-500/15',\n        active && tone === 'deny' && 'border-red-500/35 bg-red-500/10 text-red-500 hover:bg-red-500/15',\n        !active && 'border-border bg-transparent text-muted-foreground opacity-60 hover:opacity-100',\n      )}>\n      {children}\n    </button>\n  )\n}\n\nfunction Dot() {\n  return <span aria-hidden className=\"inline-block h-1 w-1 rounded-full bg-current opacity-40\" />\n}\n\nfunction Kv({ k, v }: { k: string; v: string }) {\n  return (\n    <div className=\"inline-flex items-center gap-1.5 rounded-md border bg-card px-2 py-1\">\n      <span className=\"font-mono text-[9px] text-muted-foreground uppercase tracking-wider\">{k}</span>\n      <code className=\"font-mono font-semibold text-[11px] text-foreground\">{v}</code>\n    </div>\n  )\n}\n","import React from 'react'\nimport { Refresh } from '../components/icons'\nimport { JsonTree } from '../components/json-tree'\nimport { Section } from '../components/layout'\nimport { Badge, Button, Empty } from '../components/ui'\nimport type { IamIDevtoolsEngine, IamIDevtoolsMetrics } from '../lib/types'\n\nfunction Stat({ label, value, hint }: { label: string; value: string | number; hint?: string }) {\n  return (\n    <div className=\"iam-dt-stat\">\n      <span className=\"iam-dt-stat__label\">{label}</span>\n      <span className=\"iam-dt-stat__value\">{value}</span>\n      {hint && <span className=\"iam-dt-stat__hint\">{hint}</span>}\n    </div>\n  )\n}\n\nexport function IamMetricsPanel({\n  engine,\n  metrics,\n  pollMs = 1000,\n}: {\n  engine: IamIDevtoolsEngine\n  metrics?: IamIDevtoolsMetrics\n  pollMs?: number\n}) {\n  const [stats, setStats] = React.useState(() => engine.stats())\n  const [snap, setSnap] = React.useState(() => metrics?.snapshot() ?? null)\n\n  React.useEffect(() => {\n    const id = setInterval(() => {\n      setStats(engine.stats())\n      if (metrics) setSnap(metrics.snapshot())\n    }, pollMs)\n    return () => clearInterval(id)\n  }, [engine, metrics, pollMs])\n\n  const allowRate = snap && snap.total > 0 ? Math.round((snap.allow / snap.total) * 100) : 0\n\n  return (\n    <div className=\"iam-dt-detail\">\n      <div className=\"iam-dt-detail__head\">\n        <span className=\"iam-dt-listshell__title\">Telemetry</span>\n        <Badge tone=\"info\">poll {pollMs}ms</Badge>\n        <span style={{ marginLeft: 'auto' }}>\n          <Button\n            onClick={() => {\n              engine.resetStats()\n              metrics?.reset()\n              setStats(engine.stats())\n              setSnap(metrics?.snapshot() ?? null)\n            }}>\n            <Refresh size={10} /> reset\n          </Button>\n        </span>\n      </div>\n      <Section title=\"Evaluations\">\n        {!metrics ? (\n          <Empty message=\"No metrics aggregator wired. Pass `metrics={...}` to enable telemetry.\" />\n        ) : !snap ? (\n          <Empty message=\"Waiting for first sample.\" />\n        ) : (\n          <div className=\"iam-dt-stat-grid\">\n            <Stat label=\"evals\" value={snap.total} />\n            <Stat hint={`${snap.allow} allow / ${snap.deny} deny`} label=\"allow rate\" value={`${allowRate}%`} />\n            <Stat hint=\"samples\" label=\"window\" value={snap.samples} />\n            <Stat hint=\"ms\" label=\"max\" value={snap.max.toFixed(2)} />\n            <Stat hint=\"ms\" label=\"p50\" value={snap.p50.toFixed(2)} />\n            <Stat hint=\"ms\" label=\"p95\" value={snap.p95.toFixed(2)} />\n            <Stat hint=\"ms\" label=\"p99\" value={snap.p99.toFixed(2)} />\n            <Stat label=\"deny\" value={snap.deny} />\n          </div>\n        )}\n      </Section>\n      <Section title={`Caches (${Object.keys(stats).length})`}>\n        <div className=\"iam-dt-stat-grid\">\n          {Object.entries(stats).map(([name, s]) => {\n            const total = s.hits + s.misses\n            const hit = total > 0 ? Math.round((s.hits / total) * 100) : 0\n            return (\n              <div className=\"iam-dt-stat\" key={name}>\n                <div className=\"iam-dt-row\" style={{ justifyContent: 'space-between' }}>\n                  <code style={{ fontSize: 11 }}>{name}</code>\n                  <Badge tone={hit > 80 ? 'allow' : hit > 50 ? 'info' : 'warn'}>{hit}%</Badge>\n                </div>\n                <span className=\"iam-dt-stat__hint\" style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>\n                  size {s.size}\n                  <span className=\"iam-dt-sep\" />\n                  {s.hits} hits / {s.misses} miss\n                </span>\n              </div>\n            )\n          })}\n        </div>\n      </Section>\n      <Section defaultOpen={false} title=\"Raw snapshot\">\n        <JsonTree data={{ stats, metrics: snap }} defaultOpen />\n      </Section>\n    </div>\n  )\n}\n","import React from 'react'\nimport type { AccessControl } from '../../core/types'\nimport { ChevronDown, ChevronRight, Refresh } from '../components/icons'\nimport { JsonTree } from '../components/json-tree'\nimport { DetailEmpty, FilterBar, ListItem, ListShell, Section, SplitView } from '../components/layout'\nimport { Alert, Badge, Button } from '../components/ui'\nimport type { IamIDevtoolsEngine } from '../lib/types'\n\nexport function IamPoliciesPanel({ engine }: { engine: IamIDevtoolsEngine }) {\n  const [policies, setPolicies] = React.useState<AccessControl.IPolicy[]>([])\n  const [selected, setSelected] = React.useState<string | null>(null)\n  const [error, setError] = React.useState<string | null>(null)\n  const [filter, setFilter] = React.useState('')\n\n  const load = React.useCallback(async () => {\n    try {\n      setError(null)\n      setPolicies(await engine.admin.listPolicies())\n    } catch (err) {\n      setError(err instanceof Error ? err.message : String(err))\n    }\n  }, [engine])\n\n  React.useEffect(() => {\n    void load()\n  }, [load])\n\n  const filtered = policies.filter(\n    (p) =>\n      p.id.toLowerCase().includes(filter.toLowerCase()) || (p.name ?? '').toLowerCase().includes(filter.toLowerCase()),\n  )\n  const current = policies.find((p) => p.id === selected) ?? null\n\n  return (\n    <SplitView\n      left={\n        <ListShell\n          count={filtered.length}\n          title=\"Policies\"\n          toolbar={\n            <Button onClick={load}>\n              <Refresh size={10} /> refresh\n            </Button>\n          }>\n          <FilterBar onChange={setFilter} placeholder=\"Filter policies\" value={filter} />\n          {error && <Alert kind=\"error\">{error}</Alert>}\n          {filtered.length === 0 && !error && <DetailEmpty message=\"No policies.\" />}\n          {filtered.map((p) => (\n            <ListItem\n              active={selected === p.id}\n              dot=\"#c4b5fd\"\n              key={p.id}\n              onClick={() => setSelected(p.id)}\n              primary={p.id}\n              secondary={\n                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>\n                  {p.rules.length} rules\n                  <span className=\"iam-dt-sep\" />\n                  {p.algorithm}\n                </span>\n              }\n              trailing={<Badge tone=\"info\">{p.algorithm}</Badge>}\n            />\n          ))}\n        </ListShell>\n      }\n      right={\n        !current ? (\n          <DetailEmpty message=\"Select a policy on the left.\" />\n        ) : (\n          <div className=\"iam-dt-detail\">\n            <div className=\"iam-dt-detail__head\">\n              <code>{current.id}</code>\n              <span className=\"iam-dt-mute\">{current.name}</span>\n              <Badge tone=\"info\">{current.algorithm}</Badge>\n              {current.version != null && <Badge>v{current.version}</Badge>}\n              <span className=\"iam-dt-detail__meta\">{current.rules.length} rules</span>\n            </div>\n            {current.description && (\n              <Section title=\"Description\">\n                <p className=\"iam-dt-soft\" style={{ fontSize: 11 }}>\n                  {current.description}\n                </p>\n              </Section>\n            )}\n            <Section title={`Rules (${current.rules.length})`}>\n              <div className=\"iam-dt-col\">\n                {current.rules.map((r) => (\n                  <RuleRow key={r.id} rule={r} />\n                ))}\n              </div>\n            </Section>\n            <Section defaultOpen={false} title=\"Raw\">\n              <JsonTree data={current} defaultOpen />\n            </Section>\n          </div>\n        )\n      }\n    />\n  )\n}\n\nfunction RuleRow({ rule }: { rule: AccessControl.IRule }) {\n  const [open, setOpen] = React.useState(false)\n  return (\n    <div className=\"iam-dt-trace__group\">\n      <button type=\"button\" onClick={() => setOpen((o) => !o)} className=\"iam-dt-trace__group-head\">\n        <span className=\"iam-dt-section__chev\">{open ? <ChevronDown /> : <ChevronRight />}</span>\n        <code>{rule.id}</code>\n        <Badge tone={rule.effect === 'allow' ? 'allow' : 'deny'}>{rule.effect}</Badge>\n        <Badge>p{rule.priority}</Badge>\n        <code className=\"iam-dt-action\">{rule.actions.join(', ')}</code>\n        <span className=\"iam-dt-mute\">on</span>\n        <code className=\"iam-dt-resource\">{rule.resources.join(', ')}</code>\n      </button>\n      {open && (\n        <div className=\"iam-dt-trace__group-body\">\n          {rule.description && (\n            <p className=\"iam-dt-soft\" style={{ fontSize: 11 }}>\n              {rule.description}\n            </p>\n          )}\n          {rule.conditions && <JsonTree data={rule.conditions} defaultOpen label=\"conditions\" />}\n        </div>\n      )}\n    </div>\n  )\n}\n","import React from 'react'\nimport type { AccessControl } from '../../core/types'\nimport { ChevronDown, ChevronRight, CornerUpRight, Refresh } from '../components/icons'\nimport { JsonTree } from '../components/json-tree'\nimport { DetailEmpty, FilterBar, ListItem, ListShell, Section, SplitView } from '../components/layout'\nimport { Alert, Badge, Button } from '../components/ui'\nimport type { IamIDevtoolsEngine } from '../lib/types'\n\nexport function IamRolesPanel({ engine }: { engine: IamIDevtoolsEngine }) {\n  const [roles, setRoles] = React.useState<AccessControl.IRole[]>([])\n  const [selected, setSelected] = React.useState<string | null>(null)\n  const [error, setError] = React.useState<string | null>(null)\n  const [filter, setFilter] = React.useState('')\n\n  const load = React.useCallback(async () => {\n    try {\n      setError(null)\n      setRoles(await engine.admin.listRoles())\n    } catch (err) {\n      setError(err instanceof Error ? err.message : String(err))\n    }\n  }, [engine])\n\n  React.useEffect(() => {\n    void load()\n  }, [load])\n\n  const filtered = roles.filter(\n    (r) =>\n      r.id.toLowerCase().includes(filter.toLowerCase()) || (r.name ?? '').toLowerCase().includes(filter.toLowerCase()),\n  )\n  const current = roles.find((r) => r.id === selected) ?? null\n\n  return (\n    <SplitView\n      left={\n        <ListShell\n          count={filtered.length}\n          title=\"Roles\"\n          toolbar={\n            <Button onClick={load}>\n              <Refresh size={10} /> refresh\n            </Button>\n          }>\n          <FilterBar onChange={setFilter} placeholder=\"Filter roles\" value={filter} />\n          {error && <Alert kind=\"error\">{error}</Alert>}\n          {filtered.length === 0 && !error && <DetailEmpty message=\"No roles.\" />}\n          {filtered.map((r) => (\n            <ListItem\n              active={selected === r.id}\n              dot=\"#86efac\"\n              key={r.id}\n              onClick={() => setSelected(r.id)}\n              primary={r.id}\n              secondary={\n                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>\n                  {r.permissions.length} perms\n                  {r.inherits?.length ? (\n                    <>\n                      <span className=\"iam-dt-sep\" />\n                      <CornerUpRight size={10} /> {r.inherits.join(', ')}\n                    </>\n                  ) : null}\n                </span>\n              }\n              trailing={<Badge tone=\"allow\">{r.permissions.length}</Badge>}\n            />\n          ))}\n        </ListShell>\n      }\n      right={\n        !current ? (\n          <DetailEmpty message=\"Select a role on the left.\" />\n        ) : (\n          <div className=\"iam-dt-detail\">\n            <div className=\"iam-dt-detail__head\">\n              <code>{current.id}</code>\n              <span className=\"iam-dt-mute\">{current.name}</span>\n              {current.scope && <Badge tone=\"info\">scope: {current.scope}</Badge>}\n            </div>\n            {current.description && (\n              <Section title=\"Description\">\n                <p className=\"iam-dt-soft\" style={{ fontSize: 11 }}>\n                  {current.description}\n                </p>\n              </Section>\n            )}\n            {current.inherits && current.inherits.length > 0 && (\n              <Section title=\"Inherits\">\n                <div className=\"iam-dt-row\">\n                  {current.inherits.map((id) => (\n                    <Badge key={id}>{id}</Badge>\n                  ))}\n                </div>\n              </Section>\n            )}\n            <Section title={`Permissions (${current.permissions.length})`}>\n              <div className=\"iam-dt-col\">\n                {current.permissions.map((p) => (\n                  <PermRow key={`${p.action}:${p.resource}:${p.scope ?? ''}`} perm={p} />\n                ))}\n              </div>\n            </Section>\n            <Section defaultOpen={false} title=\"Raw\">\n              <JsonTree data={current} defaultOpen />\n            </Section>\n          </div>\n        )\n      }\n    />\n  )\n}\n\nfunction PermRow({ perm }: { perm: AccessControl.IPermission }) {\n  const [open, setOpen] = React.useState(false)\n  const hasDetail = !!perm.conditions || !!perm.scope\n  return (\n    <div className=\"iam-dt-trace__group\">\n      <button\n        type=\"button\"\n        onClick={() => hasDetail && setOpen((o) => !o)}\n        className=\"iam-dt-trace__group-head\"\n        disabled={!hasDetail}>\n        <span className=\"iam-dt-section__chev\">{hasDetail ? open ? <ChevronDown /> : <ChevronRight /> : null}</span>\n        <code className=\"iam-dt-action\">{perm.action}</code>\n        <span className=\"iam-dt-mute\">on</span>\n        <code className=\"iam-dt-resource\">{perm.resource}</code>\n        {perm.scope && <Badge tone=\"info\">{perm.scope}</Badge>}\n        {perm.conditions && <Badge tone=\"warn\">cond</Badge>}\n      </button>\n      {open && hasDetail && perm.conditions && (\n        <div className=\"iam-dt-trace__group-body\">\n          <JsonTree data={perm.conditions} defaultOpen label=\"conditions\" />\n        </div>\n      )}\n    </div>\n  )\n}\n","import React from 'react'\nimport type { IamPrimitives } from '../../core/types'\nimport { JsonTree } from '../components/json-tree'\nimport { DetailEmpty, Section, SplitView } from '../components/layout'\nimport { Alert, Badge, Button, Field, Input, TextArea } from '../components/ui'\nimport { safeParseJson } from '../lib/format'\nimport type { IamIDevtoolsEngine } from '../lib/types'\n\nexport function IamSubjectsPanel({ engine }: { engine: IamIDevtoolsEngine }) {\n  const [subjectId, setSubjectId] = React.useState('')\n  const [attrs, setAttrs] = React.useState<IamPrimitives.Attributes | null>(null)\n  const [attrsDraft, setAttrsDraft] = React.useState('{}')\n  const [roleId, setRoleId] = React.useState('')\n  const [scope, setScope] = React.useState('')\n  const [busy, setBusy] = React.useState(false)\n  const [error, setError] = React.useState<string | null>(null)\n  const [status, setStatus] = React.useState<string | null>(null)\n\n  async function load() {\n    setError(null)\n    setStatus(null)\n    if (!subjectId) return setError('subject id required')\n    setBusy(true)\n    try {\n      const a = await engine.admin.getAttributes(subjectId)\n      setAttrs(a)\n      setAttrsDraft(JSON.stringify(a, null, 2))\n    } catch (err) {\n      setError(err instanceof Error ? err.message : String(err))\n    } finally {\n      setBusy(false)\n    }\n  }\n\n  async function saveAttrs() {\n    setError(null)\n    setStatus(null)\n    const parsed = safeParseJson<IamPrimitives.Attributes>(attrsDraft, {})\n    if (parsed.error) return setError(`attributes JSON: ${parsed.error}`)\n    setBusy(true)\n    try {\n      await engine.admin.setAttributes(subjectId, parsed.value)\n      setAttrs(parsed.value)\n      setStatus('attributes saved')\n    } catch (err) {\n      setError(err instanceof Error ? err.message : String(err))\n    } finally {\n      setBusy(false)\n    }\n  }\n\n  async function assign() {\n    setError(null)\n    setStatus(null)\n    if (!roleId) return setError('role id required')\n    setBusy(true)\n    try {\n      await engine.admin.assignRole(subjectId, roleId, scope || undefined)\n      setStatus(`assigned ${roleId}${scope ? ` @ ${scope}` : ''}`)\n    } catch (err) {\n      setError(err instanceof Error ? err.message : String(err))\n    } finally {\n      setBusy(false)\n    }\n  }\n\n  async function revoke() {\n    setError(null)\n    setStatus(null)\n    if (!roleId) return setError('role id required')\n    setBusy(true)\n    try {\n      await engine.admin.revokeRole(subjectId, roleId, scope || undefined)\n      setStatus(`revoked ${roleId}${scope ? ` @ ${scope}` : ''}`)\n    } catch (err) {\n      setError(err instanceof Error ? err.message : String(err))\n    } finally {\n      setBusy(false)\n    }\n  }\n\n  return (\n    <SplitView\n      left={\n        <div className=\"iam-dt-listshell\">\n          <div className=\"iam-dt-listshell__head\">\n            <h3 className=\"iam-dt-listshell__title\">Lookup</h3>\n          </div>\n          <div className=\"iam-dt-pad iam-dt-col\">\n            <Field label=\"subject id\">\n              <Input onChange={(e) => setSubjectId(e.target.value)} placeholder=\"user-1\" value={subjectId} />\n            </Field>\n            <Button disabled={busy} onClick={load} variant=\"primary\">\n              load\n            </Button>\n            {error && <Alert kind=\"error\">{error}</Alert>}\n            {status && <Alert kind=\"success\">{status}</Alert>}\n            {attrs && (\n              <div className=\"iam-dt-row\">\n                <Badge tone=\"info\">{Object.keys(attrs).length} attrs</Badge>\n              </div>\n            )}\n          </div>\n        </div>\n      }\n      right={\n        !subjectId ? (\n          <DetailEmpty message=\"Enter a subject id to inspect.\" />\n        ) : (\n          <div className=\"iam-dt-detail\">\n            <div className=\"iam-dt-detail__head\">\n              <code>{subjectId}</code>\n            </div>\n            <Section title=\"Snapshot\">\n              {attrs ? (\n                <JsonTree data={attrs} defaultOpen />\n              ) : (\n                <p className=\"iam-dt-mute\" style={{ fontSize: 11 }}>\n                  Load to view.\n                </p>\n              )}\n            </Section>\n            <Section defaultOpen={false} title=\"Edit attributes (JSON)\">\n              <div className=\"iam-dt-col\">\n                <TextArea onChange={(e) => setAttrsDraft(e.target.value)} rows={10} value={attrsDraft} />\n                <Button disabled={busy || !subjectId} onClick={saveAttrs} variant=\"primary\">\n                  save\n                </Button>\n              </div>\n            </Section>\n            <Section defaultOpen={false} title=\"Role assignment\">\n              <div className=\"iam-dt-col\">\n                <div className=\"iam-dt-grid-2\">\n                  <Field label=\"role id\">\n                    <Input onChange={(e) => setRoleId(e.target.value)} placeholder=\"editor\" value={roleId} />\n                  </Field>\n                  <Field label=\"scope (optional)\">\n                    <Input onChange={(e) => setScope(e.target.value)} placeholder=\"org-acme\" value={scope} />\n                  </Field>\n                </div>\n                <div className=\"iam-dt-row\">\n                  <Button disabled={busy || !subjectId} onClick={assign} variant=\"primary\">\n                    assign\n                  </Button>\n                  <Button disabled={busy || !subjectId} onClick={revoke} variant=\"danger\">\n                    revoke\n                  </Button>\n                </div>\n              </div>\n            </Section>\n          </div>\n        )\n      }\n    />\n  )\n}\n","import { cn } from '@gentleduck/libs/cn'\nimport React from 'react'\nimport type { IamIFlowRecorder } from './lib/flow'\nimport { isDevtoolsBlocked } from './lib/guard'\nimport { ensureStylesInjected } from './lib/styles'\nimport type { IamIDecisionInput, IamIDevtoolsEngine, IamIDevtoolsMetrics, IamPanelKey } from './lib/types'\nimport { IamDecisionInspector } from './panels/decision'\nimport { IamFlowPanel } from './panels/flow'\nimport { IamMetricsPanel } from './panels/metrics'\nimport { IamPoliciesPanel } from './panels/policies'\nimport { IamRolesPanel } from './panels/roles'\nimport { IamSubjectsPanel } from './panels/subjects'\n\nexport interface IIamDevtoolsInnerProps {\n  engine: IamIDevtoolsEngine\n  metrics?: IamIDevtoolsMetrics\n  flow?: IamIFlowRecorder\n  initialPanel?: IamPanelKey\n  defaultRequest?: Partial<IamIDecisionInput>\n  pollMs?: number\n  embedded?: boolean\n}\n\nconst TABS: { key: IamPanelKey; label: string; dot: string }[] = [\n  { key: 'flow', label: 'Flow', dot: '#84cc16' },\n  { key: 'decision', label: 'Decision', dot: '#60a5fa' },\n  { key: 'policies', label: 'Policies', dot: '#a78bfa' },\n  { key: 'roles', label: 'Roles', dot: '#34d399' },\n  { key: 'subjects', label: 'Subjects', dot: '#fbbf24' },\n  { key: 'metrics', label: 'Metrics', dot: '#ec4899' },\n]\n\n// Hard-no in production: admin reads here would leak the full auth model.\n// No prop escape hatch by design - see lib/guard.ts. The guard sits in a thin\n// wrapper so the inner component's hook order stays unconditional.\nexport function IamDevtoolsInner(props: IIamDevtoolsInnerProps) {\n  if (isDevtoolsBlocked(props.engine)) return null\n  return <IamDevtoolsInnerImpl {...props} />\n}\n\nfunction IamDevtoolsInnerImpl({\n  engine,\n  metrics,\n  flow,\n  initialPanel = 'flow',\n  defaultRequest,\n  pollMs,\n  embedded = false,\n}: IIamDevtoolsInnerProps) {\n  React.useEffect(() => {\n    ensureStylesInjected()\n  }, [])\n  const [active, setActive] = React.useState<IamPanelKey>(initialPanel)\n\n  const content = (\n    <>\n      <nav className=\"flex shrink-0 flex-wrap items-center gap-1 border-b bg-card px-2 py-1.5\">\n        {TABS.map((tab) => {\n          const isActive = active === tab.key\n          return (\n            <button\n              key={tab.key}\n              type=\"button\"\n              onClick={() => setActive(tab.key)}\n              className={cn(\n                'inline-flex h-7 items-center gap-1.5 rounded-md border px-2.5 font-medium text-[11px] transition-all',\n                isActive\n                  ? 'border-border bg-background text-foreground shadow-sm'\n                  : 'border-transparent text-muted-foreground hover:bg-muted/60 hover:text-foreground',\n              )}>\n              <span\n                aria-hidden\n                className=\"h-1.5 w-1.5 rounded-full\"\n                style={{\n                  backgroundColor: tab.dot,\n                  boxShadow: isActive ? `0 0 6px ${tab.dot}` : undefined,\n                  opacity: isActive ? 1 : 0.55,\n                }}\n              />\n              {tab.label}\n            </button>\n          )\n        })}\n      </nav>\n      <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\n        {active === 'flow' && flow && <IamFlowPanel flow={flow} />}\n        {active === 'flow' && !flow && (\n          <div className=\"m-3 rounded-md border border-border/60 border-dashed bg-muted/20 p-4 text-muted-foreground text-xs\">\n            No flow recorder wired. Pass <code className=\"font-mono\">flow=&#123;recorder&#125;</code> to the devtool and\n            bind it to your engine's <code className=\"font-mono\">afterEvaluate</code> hook.\n          </div>\n        )}\n        {active === 'decision' && <IamDecisionInspector defaults={defaultRequest} engine={engine} />}\n        {active === 'policies' && <IamPoliciesPanel engine={engine} />}\n        {active === 'roles' && <IamRolesPanel engine={engine} />}\n        {active === 'subjects' && <IamSubjectsPanel engine={engine} />}\n        {active === 'metrics' && <IamMetricsPanel engine={engine} metrics={metrics} pollMs={pollMs} />}\n      </div>\n    </>\n  )\n\n  if (embedded) {\n    return <div className=\"flex h-full min-h-0 flex-col overflow-hidden\">{content}</div>\n  }\n\n  return (\n    <div className=\"flex h-full min-h-0 flex-col overflow-hidden rounded-xl border bg-background text-foreground\">\n      {content}\n    </div>\n  )\n}\n","// Embedded gentleduck logo (white feather on black).\n// Source: /public/logo-dark.svg (root of monorepo).\n// Inlined so the devtool ships self-contained - no asset fetches.\nexport const GENTLEDUCK_LOGO_DATA_URL =\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDgAAAQ4CAYAAADsEGyPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAADUJSURBVHgB7d2/b1/V+cDxw7dIMCB7axbMP2BvlAGzBYZEnZqhpp3IEIsJd4jUASWqoF0gHZJOdYZELOAOkTrFA4ip6UCVyd46ESY62VMz8dXzoQ6B/PKPc+/nPue8XpLlUFoqwc1H3Lef85znTp069V0BAAAASOz/CgAAAEByAgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAAApCdwAAAAAOkJHAAAAEB6AgcAAACQnsABAAUAgOwEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9gQMAAABIT+AAAAAA0hM4AAAAgPQEDgAAACA9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AACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEhP4AAAAADSEzgAAACA9AQOAAAAID2BAwAAAEjv/wHL2txvR6WxjQAAAABJRU5ErkJggg=='\n","import { cn } from '@gentleduck/libs/cn'\nimport { Button } from '@gentleduck/registry-ui/button'\nimport React from 'react'\nimport { Close } from './components/icons'\nimport { IamDevtoolsInner, type IIamDevtoolsInnerProps } from './iam-devtools'\nimport { isDevtoolsBlocked } from './lib/guard'\nimport { GENTLEDUCK_LOGO_DATA_URL } from './lib/logo'\nimport { ensureStylesInjected } from './lib/styles'\n\nexport type ButtonPosition = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'relative'\nexport type PanelPosition = 'top' | 'bottom' | 'left' | 'right'\n\nexport interface IIamDevtoolsProps extends IIamDevtoolsInnerProps {\n  initialIsOpen?: boolean\n  buttonPosition?: ButtonPosition\n  position?: PanelPosition\n  hideButton?: boolean\n  storagePrefix?: string\n  /** Floating gutter in px around the panel. 0 = flush edges (default). */\n  inset?: number\n}\n\nconst DEFAULT_SIZE = 500\nconst MIN_SIZE = 220\nconst MAX_SIZE_VW = 0.9\nconst ANIM_MS = 240\n\nfunction loadState<T>(key: string, fallback: T): T {\n  if (typeof window === 'undefined') return fallback\n  try {\n    const raw = window.localStorage.getItem(key)\n    if (raw == null) return fallback\n    return JSON.parse(raw) as T\n  } catch {\n    return fallback\n  }\n}\nfunction saveState(key: string, value: unknown) {\n  if (typeof window === 'undefined') return\n  try {\n    window.localStorage.setItem(key, JSON.stringify(value))\n  } catch {}\n}\n\nfunction panelSize(position: PanelPosition, size: number): React.CSSProperties {\n  if (position === 'bottom' || position === 'top') return { height: size }\n  return { width: size }\n}\n\nfunction panelHidden(position: PanelPosition): string {\n  if (position === 'bottom') return 'translateY(100%)'\n  if (position === 'top') return 'translateY(-100%)'\n  if (position === 'right') return 'translateX(100%)'\n  return 'translateX(-100%)'\n}\n\n// Hard-no in production. No escape hatch - see lib/guard.ts. Guard sits in\n// a thin wrapper so the inner component's hook order stays unconditional.\nexport function IamDevtools(props: IIamDevtoolsProps) {\n  if (isDevtoolsBlocked(props.engine)) return null\n  return <IamDevtoolsImpl {...props} />\n}\n\nfunction IamDevtoolsImpl({\n  initialIsOpen = false,\n  buttonPosition = 'bottom-right',\n  position: positionProp,\n  hideButton = false,\n  storagePrefix = '__GENTLEDUCK_IAM_DEVTOOLS_V1',\n  inset = 0,\n  ...inner\n}: IIamDevtoolsProps) {\n  React.useEffect(() => {\n    ensureStylesInjected()\n  }, [])\n\n  const openKey = `${storagePrefix}_OPEN`\n  const sizeKey = `${storagePrefix}_SIZE`\n  const posKey = `${storagePrefix}_POSITION`\n\n  const [open, setOpen] = React.useState<boolean>(() => loadState(openKey, initialIsOpen))\n  const [mounted, setMounted] = React.useState<boolean>(() => loadState(openKey, initialIsOpen))\n  const [animateIn, setAnimateIn] = React.useState<boolean>(false)\n  const [size, setSize] = React.useState<number>(() => loadState(sizeKey, DEFAULT_SIZE))\n  const [position, setPosition] = React.useState<PanelPosition>(() => loadState(posKey, positionProp ?? 'bottom'))\n  const dragRef = React.useRef<{ start: number; size: number; axis: 'x' | 'y' } | null>(null)\n\n  React.useEffect(() => saveState(openKey, open), [open, openKey])\n  React.useEffect(() => saveState(sizeKey, size), [size, sizeKey])\n  React.useEffect(() => saveState(posKey, position), [position, posKey])\n  React.useEffect(() => {\n    if (positionProp) setPosition(positionProp)\n  }, [positionProp])\n\n  React.useEffect(() => {\n    let raf = 0\n    let timeout = 0\n    if (open) {\n      setMounted(true)\n      raf = requestAnimationFrame(() => {\n        raf = requestAnimationFrame(() => setAnimateIn(true))\n      })\n    } else {\n      setAnimateIn(false)\n      timeout = window.setTimeout(() => setMounted(false), ANIM_MS)\n    }\n    return () => {\n      cancelAnimationFrame(raf)\n      window.clearTimeout(timeout)\n    }\n  }, [open])\n\n  const onDragStart = (e: React.PointerEvent) => {\n    const axis: 'x' | 'y' = position === 'left' || position === 'right' ? 'x' : 'y'\n    dragRef.current = { start: axis === 'x' ? e.clientX : e.clientY, size, axis }\n    if (e.target instanceof Element) e.target.setPointerCapture(e.pointerId)\n  }\n  const onDragMove = (e: React.PointerEvent) => {\n    const d = dragRef.current\n    if (!d) return\n    const delta = (d.axis === 'x' ? e.clientX : e.clientY) - d.start\n    const sign = position === 'bottom' || position === 'right' ? -1 : 1\n    const max = (d.axis === 'x' ? window.innerWidth : window.innerHeight) * MAX_SIZE_VW\n    const next = Math.max(MIN_SIZE, Math.min(max, d.size + sign * delta))\n    setSize(next)\n  }\n  const onDragEnd = (e: React.PointerEvent) => {\n    dragRef.current = null\n    try {\n      if (e.target instanceof Element) e.target.releasePointerCapture(e.pointerId)\n    } catch {}\n  }\n\n  const cycleDock = () => {\n    const order: PanelPosition[] = ['bottom', 'right', 'top', 'left']\n    const idx = order.indexOf(position)\n    setPosition(order[(idx + 1) % order.length] as PanelPosition)\n  }\n\n  const resizeAxisCls = position === 'left' || position === 'right' ? 'iam-dt-resize--ew' : 'iam-dt-resize--ns'\n\n  return (\n    <>\n      {!hideButton && buttonPosition !== 'relative' && (\n        <div className=\"iam-dt-btn-wrap\" data-pos={buttonPosition}>\n          <button\n            aria-label=\"Open duck-iam devtools\"\n            onClick={() => setOpen(true)}\n            type=\"button\"\n            className={cn(\n              'inline-flex h-11 w-11 items-center justify-center rounded-xl border border-border bg-card text-foreground shadow-lg transition-all hover:-translate-y-0.5 hover:border-foreground hover:shadow-xl active:scale-95',\n              open && 'pointer-events-none scale-50 opacity-0',\n            )}>\n            <img\n              alt=\"\"\n              className=\"h-6 w-6 object-contain\"\n              draggable={false}\n              src={GENTLEDUCK_LOGO_DATA_URL}\n              style={{ width: 24, height: 24, objectFit: 'contain', display: 'block' }}\n            />\n          </button>\n        </div>\n      )}\n\n      {mounted && (\n        <div\n          className=\"iam-dt-panel-wrap\"\n          data-pos={position}\n          data-inset={inset > 0 ? '1' : undefined}\n          style={{\n            transform: animateIn ? 'translate(0,0)' : panelHidden(position),\n            opacity: animateIn ? 1 : 0,\n            ...panelSize(position, size),\n          }}>\n          <div\n            className={cn(\n              'flex h-full min-h-0 flex-col overflow-hidden border border-border bg-background text-foreground shadow-2xl',\n              inset > 0 && 'rounded-xl',\n              inset === 0 && position === 'bottom' && 'border-x-0 border-b-0',\n              inset === 0 && position === 'top' && 'border-x-0 border-t-0',\n              inset === 0 && position === 'left' && 'border-y-0 border-l-0',\n              inset === 0 && position === 'right' && 'border-y-0 border-r-0',\n            )}>\n            <div\n              className={cn('iam-dt-resize', resizeAxisCls)}\n              onPointerDown={onDragStart}\n              onPointerMove={onDragMove}\n              onPointerUp={onDragEnd}\n              onPointerCancel={onDragEnd}\n            />\n            <header className=\"flex shrink-0 items-center justify-between gap-4 border-b bg-card px-3 py-2\">\n              <div className=\"flex min-w-0 items-center gap-2\">\n                <span className=\"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-border bg-background\">\n                  <img\n                    alt=\"\"\n                    className=\"h-4 w-4 object-contain\"\n                    draggable={false}\n                    src={GENTLEDUCK_LOGO_DATA_URL}\n                    style={{ width: 16, height: 16, objectFit: 'contain', display: 'block' }}\n                  />\n                </span>\n                <div className=\"flex min-w-0 flex-col leading-tight\">\n                  <span className=\"font-bold text-xs tracking-tight\">duck-iam</span>\n                  <span className=\"font-mono text-[9px] text-muted-foreground uppercase tracking-[0.2em]\">\n                    devtools\n                  </span>\n                </div>\n                <span className=\"ml-2 inline-flex items-center gap-1 rounded-full border border-lime-500/30 bg-lime-500/10 px-2 py-0.5 font-mono font-semibold text-[9px] text-lime-400 uppercase\">\n                  <span aria-hidden className=\"h-1 w-1 animate-pulse rounded-full bg-lime-400\" />\n                  live\n                </span>\n              </div>\n              <div className=\"flex shrink-0 items-center gap-1\">\n                <Button\n                  size=\"sm\"\n                  variant=\"outline\"\n                  onClick={cycleDock}\n                  className=\"h-7 px-2 font-mono text-[10px] uppercase\">\n                  {position}\n                </Button>\n                <Button\n                  size=\"icon-sm\"\n                  variant=\"outline\"\n                  onClick={() => setOpen(false)}\n                  aria-label=\"Close devtools\"\n                  className=\"h-7 w-7 hover:border-red-500/50 hover:bg-red-500/10 hover:text-red-400\">\n                  <Close size={12} />\n                </Button>\n              </div>\n            </header>\n            <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\n              <IamDevtoolsInner {...inner} embedded />\n            </div>\n          </div>\n        </div>\n      )}\n    </>\n  )\n}\n","export interface IamIFlowEntry {\n  id: number\n  ts: number\n  subjectId: string\n  action: string\n  resource: string\n  resourceId?: string\n  scope?: string\n  allowed: boolean\n  durationMs?: number\n  reason?: string\n  decidingPolicy?: string\n  decidingRule?: string\n  environment?: Record<string, unknown>\n}\n\ntype IFlowRecordInput = Omit<IamIFlowEntry, 'id' | 'ts'> & { ts?: number }\n\nexport interface IamIFlowRecorder {\n  record(entry: IFlowRecordInput): IamIFlowEntry\n  list(): readonly IamIFlowEntry[]\n  get(id: number): IamIFlowEntry | undefined\n  clear(): void\n  subscribe(listener: () => void): () => void\n}\n\nexport interface IamIFlowRecorderOptions {\n  bufferSize?: number\n}\n\nconst DEFAULT_BUFFER = 250\n\nexport function iamCreateFlowRecorder(options: IamIFlowRecorderOptions = {}): IamIFlowRecorder {\n  const bufferSize = options.bufferSize ?? DEFAULT_BUFFER\n  let nextId = 1\n  let buffer: IamIFlowEntry[] = []\n  const listeners = new Set<() => void>()\n\n  function notify() {\n    for (const fn of listeners) {\n      try {\n        fn()\n      } catch (err) {\n        // Surface listener errors via console.error. Devtools only, so no\n        // operator-facing callback is needed.\n        // eslint-disable-next-line no-console\n        console.error('[@gentleduck/iam:dt:flow] listener threw - continuing', err)\n      }\n    }\n  }\n\n  return {\n    record(input) {\n      const entry: IamIFlowEntry = {\n        id: nextId++,\n        ts: input.ts ?? Date.now(),\n        subjectId: input.subjectId,\n        action: input.action,\n        resource: input.resource,\n        resourceId: input.resourceId,\n        scope: input.scope,\n        allowed: input.allowed,\n        durationMs: input.durationMs,\n        reason: input.reason,\n        decidingPolicy: input.decidingPolicy,\n        decidingRule: input.decidingRule,\n        environment: input.environment,\n      }\n      buffer.unshift(entry)\n      if (buffer.length > bufferSize) buffer.length = bufferSize\n      notify()\n      return entry\n    },\n    list() {\n      return buffer\n    },\n    get(id) {\n      return buffer.find((e) => e.id === id)\n    },\n    clear() {\n      buffer = []\n      notify()\n    },\n    subscribe(fn) {\n      listeners.add(fn)\n      return () => {\n        listeners.delete(fn)\n      }\n    },\n  }\n}\n"],"mappings":"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"}