nlm-memory 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli/classify-parity.js +1 -1
- package/dist/cli/classify-parity.js.map +1 -1
- package/dist/cli/nlm.js +314 -55
- package/dist/cli/nlm.js.map +1 -1
- package/dist/core/classifier/prompt.d.ts +70 -0
- package/dist/core/classifier/prompt.js +71 -2
- package/dist/core/classifier/prompt.js.map +1 -1
- package/dist/core/exemplars/extract-exemplar.d.ts +36 -0
- package/dist/core/exemplars/extract-exemplar.js +177 -0
- package/dist/core/exemplars/extract-exemplar.js.map +1 -0
- package/dist/core/exemplars/ingest-exemplar.d.ts +30 -0
- package/dist/core/exemplars/ingest-exemplar.js +71 -0
- package/dist/core/exemplars/ingest-exemplar.js.map +1 -0
- package/dist/core/exemplars/recall-code.d.ts +25 -0
- package/dist/core/exemplars/recall-code.js +49 -0
- package/dist/core/exemplars/recall-code.js.map +1 -0
- package/dist/core/facts/backfill-facts.d.ts +4 -2
- package/dist/core/facts/backfill-facts.js +18 -27
- package/dist/core/facts/backfill-facts.js.map +1 -1
- package/dist/core/hook/strip-injected-context.d.ts +24 -0
- package/dist/core/hook/strip-injected-context.js +73 -0
- package/dist/core/hook/strip-injected-context.js.map +1 -0
- package/dist/core/ingest/ingest-session.d.ts +4 -2
- package/dist/core/ingest/ingest-session.js +12 -4
- package/dist/core/ingest/ingest-session.js.map +1 -1
- package/dist/core/providers/provider-registry.d.ts +31 -11
- package/dist/core/providers/provider-registry.js +27 -13
- package/dist/core/providers/provider-registry.js.map +1 -1
- package/dist/core/recall-facts/fact-recall-service.js +75 -28
- package/dist/core/recall-facts/fact-recall-service.js.map +1 -1
- package/dist/core/scheduler/scheduler.d.ts +4 -2
- package/dist/core/scheduler/scheduler.js +26 -15
- package/dist/core/scheduler/scheduler.js.map +1 -1
- package/dist/core/sources/source-registry.d.ts +36 -12
- package/dist/core/sources/source-registry.js +59 -44
- package/dist/core/sources/source-registry.js.map +1 -1
- package/dist/core/storage/backup-rotation.d.ts +38 -0
- package/dist/core/storage/backup-rotation.js +82 -0
- package/dist/core/storage/backup-rotation.js.map +1 -0
- package/dist/core/storage/null-code-exemplar-store.d.ts +21 -0
- package/dist/core/storage/null-code-exemplar-store.js +19 -0
- package/dist/core/storage/null-code-exemplar-store.js.map +1 -0
- package/dist/core/storage/pg-fact-store.d.ts +2 -0
- package/dist/core/storage/pg-fact-store.js +34 -3
- package/dist/core/storage/pg-fact-store.js.map +1 -1
- package/dist/core/storage/pg-session-store.d.ts +14 -4
- package/dist/core/storage/pg-session-store.js +123 -2
- package/dist/core/storage/pg-session-store.js.map +1 -1
- package/dist/core/storage/pg-storage.d.ts +11 -2
- package/dist/core/storage/pg-storage.js +14 -2
- package/dist/core/storage/pg-storage.js.map +1 -1
- package/dist/core/storage/pg-tx-context.d.ts +2 -0
- package/dist/core/storage/pg-tx-context.js +12 -0
- package/dist/core/storage/pg-tx-context.js.map +1 -1
- package/dist/core/storage/sqlite-code-exemplar-store.d.ts +40 -0
- package/dist/core/storage/sqlite-code-exemplar-store.js +247 -0
- package/dist/core/storage/sqlite-code-exemplar-store.js.map +1 -0
- package/dist/core/storage/sqlite-fact-store.d.ts +2 -0
- package/dist/core/storage/sqlite-fact-store.js +30 -2
- package/dist/core/storage/sqlite-fact-store.js.map +1 -1
- package/dist/core/storage/sqlite-session-store.d.ts +21 -0
- package/dist/core/storage/sqlite-session-store.js +23 -0
- package/dist/core/storage/sqlite-session-store.js.map +1 -1
- package/dist/core/storage/sqlite-storage.d.ts +6 -0
- package/dist/core/storage/sqlite-storage.js +14 -2
- package/dist/core/storage/sqlite-storage.js.map +1 -1
- package/dist/core/storage/supersedence-log.d.ts +8 -0
- package/dist/core/storage/supersedence-log.js +19 -0
- package/dist/core/storage/supersedence-log.js.map +1 -1
- package/dist/hook/prompt-recall-hook.d.ts +5 -4
- package/dist/hook/prompt-recall-hook.js +12 -7
- package/dist/hook/prompt-recall-hook.js.map +1 -1
- package/dist/http/app.d.ts +7 -1
- package/dist/http/app.js +226 -83
- package/dist/http/app.js.map +1 -1
- package/dist/install/codex.d.ts +29 -1
- package/dist/install/codex.js +117 -15
- package/dist/install/codex.js.map +1 -1
- package/dist/install/cursor.d.ts +4 -4
- package/dist/install/cursor.js +7 -7
- package/dist/install/cursor.js.map +1 -1
- package/dist/install/health.d.ts +56 -0
- package/dist/install/health.js +133 -0
- package/dist/install/health.js.map +1 -0
- package/dist/install/setup.js +1 -1
- package/dist/install/setup.js.map +1 -1
- package/dist/install/windsurf.d.ts +4 -4
- package/dist/install/windsurf.js +7 -7
- package/dist/install/windsurf.js.map +1 -1
- package/dist/llm/classifier-box.d.ts +4 -0
- package/dist/llm/classifier-box.js +9 -2
- package/dist/llm/classifier-box.js.map +1 -1
- package/dist/llm/ollama-client.d.ts +19 -1
- package/dist/llm/ollama-client.js +14 -6
- package/dist/llm/ollama-client.js.map +1 -1
- package/dist/llm/ollama-code-embedder.d.ts +28 -0
- package/dist/llm/ollama-code-embedder.js +73 -0
- package/dist/llm/ollama-code-embedder.js.map +1 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.js +132 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/ports/code-embedder.d.ts +27 -0
- package/dist/ports/code-embedder.js +15 -0
- package/dist/ports/code-embedder.js.map +1 -0
- package/dist/ports/code-exemplar-store.d.ts +45 -0
- package/dist/ports/code-exemplar-store.js +11 -0
- package/dist/ports/code-exemplar-store.js.map +1 -0
- package/dist/ports/fact-store.d.ts +0 -0
- package/dist/ports/fact-store.js.map +1 -1
- package/dist/ports/storage.d.ts +8 -0
- package/dist/shared/types.d.ts +35 -0
- package/dist/ui/assets/{index-Fr5AMEPj.js → index-CVo7KKw2.js} +1 -1
- package/dist/ui/assets/{index-C74N8APQ.css → index-DCuQrzJH.css} +1 -1
- package/dist/ui/index.html +2 -2
- package/migrations/021_code_exemplars.sql +51 -0
- package/migrations/022_facts_retired_at.sql +17 -0
- package/migrations/pg/021_code_exemplars.sql +45 -0
- package/migrations/pg/022_facts_retired_at.sql +12 -0
- package/nlm/index.js +6 -1
- package/package.json +3 -2
- package/plugin/.codex-plugin/plugin.json +2 -2
- package/plugin/hooks/hooks.json +13 -2
- package/plugin/scripts/prompt-recall-hook.mjs +7 -1
- package/plugin/scripts/session-start-hook.mjs +275 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--surface-0:#161616;--surface-1:#1d1d1d;--surface-2:#242424;--surface-float:#2c2c2c;--bg-1:var(--surface-float);--bg-2:var(--surface-2);--border-1:#262626;--border-2:#303030;--border-3:#3d3d3d;--border-4:#525252;--text-1:#e8e8e8;--text-2:#b0b0b0;--text-3:#686868;--text-4:#383838;--accent:#e8ff6e;--accent-dim:#e8ff6e1f;--accent-glow:#e8ff6e0f;--warn:#f93;--warn-dim:#ff99331f;--danger:#ff6b35;--danger-dim:#ff6b3512;--danger-glow:#ff6b351f;--font-mono:"IBM Plex Mono", "Fira Code", ui-monospace, monospace;--text-xs:10px;--text-sm:11px;--text-base:13px;--text-md:15px;--text-lg:18px;--text-xl:22px;--text-stat:36px;--lh-tight:1.3;--lh-base:1.5;--lh-loose:1.7;--page-x:28px;--section-gap:24px;--r-sm:3px;--r-md:5px;--r-lg:7px;--ease-fast:.1s ease;--ease:.15s ease;--ease-slow:.3s ease;--z-base:0;--z-raised:1;--z-sticky:10;--z-sidenav:20;--z-dropdown:30;--z-overlay:40;--z-drawer-bg:50;--z-drawer:60;--z-palette-bg:70;--z-palette:80;--z-tooltip:90;--z-toast:100}*,:before,:after{box-sizing:border-box;margin:0;padding:0}html{background-color:var(--surface-0)}body{color:var(--text-1);font-family:var(--font-mono);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-image:radial-gradient(100% 40% at 50% -8%,#e8ff6e08 0%,#0000 100%);background-attachment:fixed;min-height:100vh}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{background:var(--surface-1)}::-webkit-scrollbar-thumb{background:var(--border-3);border-radius:2px}@keyframes fadeSlideIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-delay:0s!important}}.skeleton{background:linear-gradient(90deg, var(--surface-1) 0%, var(--surface-2) 50%, var(--surface-1) 100%);vertical-align:middle;background-size:200% 100%;animation:1.2s ease-in-out infinite skeleton-shimmer;display:inline-block}@keyframes skeleton-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.skeleton{background:var(--surface-2);animation:none}}.card{background:var(--surface-1);border:1px solid var(--border-2);border-radius:var(--r-md)}.card-lift{transition:border-color var(--ease), background var(--ease)}.card-lift:hover{background:var(--surface-2);border-color:var(--border-3)}.btn{font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;border-radius:var(--r-sm);border:1px solid var(--border-3);color:var(--text-2);cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:border-color var(--ease), color var(--ease), background var(--ease);background:0 0;align-items:center;gap:5px;padding:5px 12px;text-decoration:none;display:inline-flex}.btn:hover{border-color:var(--border-4);color:var(--text-1)}.btn:active{background:var(--surface-2)}.btn.active{background:var(--surface-2);border-color:var(--border-3);color:var(--text-1)}.btn-primary{background:var(--accent);border-color:var(--accent);color:#080808;font-weight:600}.btn-primary:hover{color:#080808;background:#d4eb5e;border-color:#d4eb5e}.btn-accent{color:var(--accent);border-color:#e8ff6e40}.btn-accent:hover{background:var(--accent-glow);border-color:#e8ff6e66}.btn-danger:hover{border-color:var(--danger);color:var(--danger)}.btn.small{font-size:var(--text-xs);padding:3px 9px}.form-row{flex-wrap:wrap;align-items:center;gap:12px;margin:12px 0;display:flex}.form-row.between{justify-content:space-between}.form-row.tight{gap:8px}.form-row .form-label{color:var(--text-3);font-size:var(--text-xs)}input[type=file].file-input{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-3);max-width:24rem}input[type=file].file-input::file-selector-button{font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;border-radius:var(--r-sm);border:1px solid var(--border-3);color:var(--text-2);cursor:pointer;transition:border-color var(--ease), color var(--ease), background var(--ease);background:0 0;align-items:center;margin-right:10px;padding:5px 12px;display:inline-flex}input[type=file].file-input::file-selector-button:hover{border-color:var(--border-4);color:var(--text-1)}input[type=file].file-input:disabled{cursor:not-allowed}input[type=file].file-input:disabled::file-selector-button{opacity:.5;cursor:not-allowed}.chip{font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.06em;text-transform:lowercase;border-radius:var(--r-sm);border:1px solid var(--border-1);color:var(--text-3);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;transition:border-color var(--ease), color var(--ease), background var(--ease);background:0 0;align-items:center;gap:4px;padding:3px 9px;display:inline-flex}.chip:hover{border-color:var(--border-3);color:var(--text-2)}.chip.active{border-color:var(--border-3);color:var(--text-1);background:var(--surface-2);box-shadow:inset 0 0 0 1px var(--border-3);font-weight:600}.chip[data-severity=critical].active{color:var(--danger);background:var(--danger-dim);border-color:#ff6b3566}.chip[data-severity=high].active{color:#c42;background:#cc44220f;border-color:#cc442259}.chip[data-severity=medium].active{color:var(--warn);background:var(--warn-dim);border-color:#ff993359}.chip[data-severity=low].active{border-color:var(--border-3);color:var(--text-2);background:var(--surface-2)}.chip[data-status=active].active{color:var(--accent);background:var(--accent-glow);border-color:#e8ff6e4d}.chip[data-status=idle].active{color:#ffcc80}.chip[data-length].active{color:var(--text-1)}.chip[data-marker].active{color:var(--accent);background:var(--accent-glow);border-color:#e8ff6e4d}.panel-float{-webkit-backdrop-filter:blur(18px);border:1px solid var(--border-3);border-radius:var(--r-md);background:#101010f5;box-shadow:0 12px 40px #000000a6,0 0 0 1px #ffffff08}.nav-link{color:var(--text-3);border-radius:var(--r-sm);font-size:var(--text-sm);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;transition:color var(--ease), border-color var(--ease), background var(--ease);background:0 0;border:1px solid #0000;align-items:center;padding:4px 10px;text-decoration:none;display:inline-flex}.nav-link:hover{color:var(--text-2);border-color:var(--border-3)}.nav-link.active{background:var(--surface-2);border-color:var(--border-3);color:var(--text-1)}.search-input{background:var(--surface-1);border:1px solid var(--border-2);color:var(--text-1);font-family:var(--font-mono);font-size:var(--text-xs);border-radius:var(--r-sm);letter-spacing:.04em;transition:border-color var(--ease);outline:none;padding:5px 10px}.search-input:focus{border-color:var(--border-3)}.search-input::placeholder{color:var(--text-4);letter-spacing:.06em}.ctrl-btn{background:var(--surface-1);border:1px solid var(--border-2);color:var(--text-2);font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;border-radius:var(--r-sm);cursor:pointer;white-space:nowrap;transition:border-color var(--ease), color var(--ease), background var(--ease);padding:4px 10px}.ctrl-btn:hover{border-color:var(--border-3);color:var(--text-1)}.ctrl-btn.active{background:var(--surface-2);border-color:var(--border-3);color:var(--accent)}.ctrl-btn[data-active="1"]{color:var(--accent);border-color:#e8ff6e40}.ctrl-label{font-size:var(--text-sm);color:var(--text-3);letter-spacing:.06em;text-transform:uppercase;flex-shrink:0}.subnav{border-bottom:1px solid var(--border-1);gap:0;padding:0 28px;display:flex}.subnav-link{font-size:var(--text-sm);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);transition:color var(--ease), border-color var(--ease);border-bottom:2px solid #0000;margin-bottom:-1px;padding:10px 14px;text-decoration:none}.subnav-link:hover{color:var(--text-2)}.subnav-link.active{color:var(--accent);border-bottom-color:var(--accent)}.page-shell{background:var(--surface-0);height:100vh;display:flex;overflow:hidden}.page-main{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.app-header{z-index:var(--z-sticky);height:52px;padding:0 var(--page-x);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid var(--border-1);background:#161616e6;align-items:center;gap:20px;display:flex;position:sticky;top:0}.app-header .wordmark-page{font-size:var(--text-sm);color:var(--text-3);letter-spacing:.04em;text-transform:lowercase}.app-header .header-spacer{flex:1}.app-header .status-dot{background:var(--accent);width:7px;height:7px;box-shadow:0 0 6px var(--accent-dim);border-radius:50%;animation:2s ease-in-out infinite pulse-dot}@keyframes pulse-dot{0%,to{opacity:1}50%{opacity:.4}}.app-header .header-info{font-size:var(--text-xs);color:var(--text-3);letter-spacing:.04em}.sidenav{background:var(--surface-1);border-right:1px solid var(--border-1);width:180px;height:100vh;transition:width var(--ease);z-index:var(--z-sidenav);flex-direction:column;flex-shrink:0;display:flex;position:sticky;top:0;overflow:hidden}.sidenav.collapsed{width:52px}.sidenav-header{border-bottom:1px solid var(--border-1);flex-shrink:0;justify-content:space-between;align-items:center;height:52px;padding:0 8px 0 16px;display:flex}.sidenav-wordmark{font-size:var(--text-sm);font-family:var(--font-mono);letter-spacing:.2em;text-transform:uppercase;color:var(--accent);-webkit-user-select:none;user-select:none;white-space:nowrap;transition:opacity var(--ease-fast), width var(--ease-fast);overflow:hidden}.sidenav.collapsed .sidenav-wordmark{opacity:0;width:0;padding:0}.sidenav-toggle{color:var(--text-3);cursor:pointer;border-radius:var(--r-sm);transition:color var(--ease), background var(--ease);background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:5px;display:flex}.sidenav-toggle:hover{color:var(--text-1);background:var(--surface-2)}.sidenav.collapsed .sidenav-header{justify-content:center;padding:0 8px}.sidenav-items{flex-direction:column;flex:1;gap:2px;padding:10px 8px;display:flex;overflow:hidden}.sidenav-item{border-radius:var(--r-sm);font-size:var(--text-sm);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);transition:color var(--ease), background var(--ease), border-color var(--ease);-webkit-user-select:none;user-select:none;white-space:nowrap;border-left:3px solid #0000;align-items:center;gap:9px;padding:8px 10px;text-decoration:none;display:flex;position:relative;overflow:hidden}.sidenav-item:hover{color:var(--text-1);background:var(--surface-2)}.sidenav-item.active{color:var(--text-1);border-left-color:var(--accent);background:var(--accent-glow)}.item-icon{opacity:.7;flex-shrink:0;align-items:center;display:flex}.sidenav-item.active .item-icon{opacity:1}.item-label{transition:opacity var(--ease-fast)}.sidenav.collapsed .item-label{display:none}.sidenav.collapsed .sidenav-item{border-left:3px solid #0000;justify-content:center;gap:0;padding:8px}.sidenav.collapsed .sidenav-item.active{border-left-color:var(--accent)}.sidenav.collapsed .sidenav-item:after{content:attr(data-label);background:var(--surface-float);color:var(--text-1);font-size:var(--text-xs);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;border-radius:var(--r-sm);border:1px solid var(--border-2);white-space:nowrap;pointer-events:none;opacity:0;transition:opacity var(--ease-fast);z-index:var(--z-tooltip);padding:4px 8px;position:absolute;top:50%;left:calc(100% + 8px);transform:translateY(-50%)}.sidenav.collapsed .sidenav-item:hover:after{opacity:1}.sidenav-footer{border-top:1px solid var(--border-1);flex-shrink:0;padding:8px}.sidenav-data{font-size:var(--text-xs)}.update-banner{background:var(--bg-2);border:1px solid var(--border-1);font-family:var(--font-sans);border-radius:6px;margin-bottom:8px;padding:8px 10px}.update-banner-head{justify-content:space-between;align-items:center;gap:8px;display:flex}.update-banner-version{color:var(--text-1)}.update-banner-dismiss{color:var(--text-3);cursor:pointer;background:0 0;border:none;padding:0 4px;font-size:16px;line-height:1}.update-banner-dismiss:hover{color:var(--text-1)}.update-banner-body{color:var(--text-2,var(--text-1));margin:4px 0 6px}.update-banner-cmd{background:var(--bg-1);border:1px solid var(--border-1);color:var(--text-1);white-space:nowrap;border-radius:4px;margin-bottom:6px;padding:4px 6px;overflow-x:auto}.update-banner-actions{justify-content:space-between;align-items:center;gap:8px;display:flex}.update-banner-copy{background:var(--accent);color:var(--bg-1);cursor:pointer;font-family:var(--font-mono);font-size:var(--text-xs);border:none;border-radius:4px;padding:4px 8px}.update-banner-link{color:var(--text-3);text-underline-offset:2px;text-decoration:underline}.update-banner-link:hover{color:var(--text-1)}.update-banner-nudge{background:var(--bg-1);border-left:2px solid var(--accent);color:var(--text-2,var(--text-1));border-radius:3px;margin:8px 0 0;padding:6px 8px}.update-banner-nudge code{background:var(--bg-0,var(--bg-1));border-radius:3px;padding:1px 4px}.update-banner--collapsed{cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;width:100%;margin-bottom:8px;padding:6px 0;display:flex}.update-dot{color:var(--accent);font-size:14px;line-height:1;animation:2.6s ease-in-out infinite nlm-update-pulse}@keyframes nlm-update-pulse{0%,to{opacity:.45}50%{opacity:1}}.live-page{flex-direction:column;flex:1;min-height:0;display:flex}.live-status{padding:12px var(--page-x) 4px;align-items:center;gap:8px;display:flex}.live-status-dot{border-radius:50%;flex-shrink:0;width:7px;height:7px}.live-status-live{background:var(--accent);box-shadow:0 0 6px var(--accent)}.live-status-connecting{background:var(--text-3)}.live-status-reconnecting{background:var(--warn);animation:1.2s ease-in-out infinite pulse-dot}.live-status-label{font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;color:var(--text-2)}.live-board{padding:4px var(--page-x) 20px;flex:1;grid-template-columns:repeat(3,1fr);gap:16px;min-height:0;display:grid}.live-col{background:var(--surface-1);border:1px solid var(--border-2);border-radius:var(--r-md);flex-direction:column;min-height:0;display:flex;overflow:hidden}.live-col-head{border-bottom:1px solid var(--border-1);justify-content:space-between;align-items:baseline;padding:10px 14px;display:flex}.live-col-title{font-size:var(--text-sm);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--text-2)}.live-col-count{font-size:var(--text-xs);color:var(--text-3);font-family:var(--font-mono)}.live-col-body{flex:1;overflow:hidden auto}.live-row{border-bottom:1px solid var(--border-1);overflow-wrap:anywhere;min-width:0;padding:8px 14px;animation:.2s ease-out fadeSlideIn}.live-row .label,.live-row .body,.live-row .meta{overflow-wrap:anywhere;word-break:break-word;min-width:0}.live-row:last-child{border-bottom:none}.clickable:focus-visible,.bar-item-clickable:focus-visible,.kpi-clickable:focus-visible{outline:1px solid var(--accent);outline-offset:-1px}.clickable[aria-busy=true],.clickable.is-disabled,.bar-item-clickable[aria-busy=true],.bar-item-clickable.is-disabled{opacity:.5;pointer-events:none}.live-row.clickable{cursor:pointer;transition:background var(--ease)}.live-row.clickable:hover{background:var(--surface-2)}.live-row.is-new{animation:.2s ease-out fadeSlideIn,1.2s ease-out liveFlash}.live-row.is-related{background:var(--accent-glow);border-left:2px solid var(--accent);padding-left:12px}@keyframes liveFlash{0%{background:var(--accent-glow)}to{background:0 0}}.live-row .label{color:var(--text-1);font-size:var(--text-base);line-height:var(--lh-tight)}.live-row .body{color:var(--text-3);font-size:var(--text-sm);line-height:var(--lh-tight);margin-top:3px}.live-row .meta{color:var(--text-3);font-size:var(--text-xs);letter-spacing:.04em;margin-top:4px}.live-tag{font-size:var(--text-xs);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;border-radius:var(--r-sm);background:var(--surface-2);color:var(--text-2);border:1px solid var(--border-2);margin-right:6px;padding:1px 6px;display:inline-block}.live-tag[data-kind=decision]{background:var(--accent-glow);color:var(--accent);border-color:#e8ff6e40}.live-tag[data-kind=open]{background:var(--warn-dim);color:var(--warn);border-color:#ff993340}.live-empty{text-align:center;color:var(--text-3);font-size:var(--text-xs);letter-spacing:.06em;text-transform:uppercase;padding:32px 16px}.stub-shell{padding:80px var(--page-x);text-align:center;color:var(--text-3);font-size:var(--text-base);line-height:var(--lh-loose)}.stub-shell .stub-name{color:var(--accent);font-size:var(--text-md);text-transform:lowercase;letter-spacing:.04em;margin-bottom:12px;display:block}.stub-shell .stub-hint{color:var(--text-4);font-size:var(--text-sm)}.page-pad{padding:20px var(--page-x) 60px;flex:1;min-width:0;min-height:0;overflow-y:auto}.page-title{font-size:var(--text-lg);font-family:var(--font-mono);color:var(--text-1);margin-bottom:16px;font-weight:500}.page-header{align-items:center;gap:24px;margin-bottom:24px;padding-top:8px;display:flex}.subnav+.page-header,.subnav+.page-title{gap:28px;margin-top:28px;margin-bottom:28px;padding-top:0}.page-header .page-title,.form-row.between .page-title{margin-bottom:0}.page-header .header-spacer,.thread-header .header-spacer,.river-toolbar .header-spacer{flex:1}.section-title{font-size:var(--text-sm);text-transform:uppercase;letter-spacing:.06em;color:var(--text-3);margin:24px 0 8px;font-weight:500}.muted{color:var(--text-3)}.muted.small{font-size:var(--text-xs);letter-spacing:.04em}.muted.error{color:var(--danger)}.right{text-align:right}.mono{font-family:var(--font-mono)}.small{font-size:var(--text-xs)}code,.code-block{font-family:var(--font-mono);font-size:var(--text-sm);background:var(--surface-2);border:1px solid var(--border-2);border-radius:var(--r-sm);color:var(--text-1);padding:2px 6px}.code-block{margin:8px 0;padding:10px 14px;display:block}.settings-grid{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;margin-top:16px;display:grid}.settings-card{color:var(--text-1);flex-direction:column;gap:6px;padding:14px;text-decoration:none;display:flex}.settings-card-title{font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;color:var(--accent);font-weight:500}.settings-card-body{color:var(--text-2);font-size:var(--text-sm)}.kv-list{grid-template-columns:max-content 1fr;gap:6px 16px;margin-top:12px;display:grid}.kv-label{color:var(--text-3);font-size:var(--text-sm);letter-spacing:.04em}.kv-value{color:var(--text-1);font-size:var(--text-sm)}.kv-value.mono{font-family:var(--font-mono);word-break:break-all}.form-grid{gap:12px;max-width:420px;margin-top:12px;display:grid}.form-field{flex-direction:column;gap:4px;display:flex}.form-label{font-size:var(--text-xs);color:var(--text-3);letter-spacing:.06em;text-transform:uppercase}.form-input{background:var(--surface-1);border:1px solid var(--border-2);color:var(--text-1);font-family:var(--font-mono);font-size:var(--text-sm);border-radius:var(--r-sm);transition:border-color var(--ease);padding:6px 10px}.form-input:hover:not(:disabled){border-color:var(--border-3)}.form-input:focus{border-color:var(--border-4);outline:none}.form-input:focus-visible{outline:1px solid var(--accent);outline-offset:-1px}.form-input:disabled,.form-input.is-disabled{opacity:.5;cursor:not-allowed}.form-input[aria-invalid=true],.form-input.is-invalid{border-color:var(--danger)}.form-input[aria-invalid=true]:focus-visible,.form-input.is-invalid:focus-visible{outline-color:var(--danger);border-color:var(--danger)}.form-error{color:var(--danger);font-size:var(--text-xs);margin:4px 0 0}.data-table{border-collapse:collapse;width:100%;font-size:var(--text-sm);margin-top:12px}.data-table th{text-align:left;font-weight:500;font-size:var(--text-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);border-bottom:1px solid var(--border-2);padding:8px 10px}.data-table th.right{text-align:right}.data-table td{border-bottom:1px solid var(--border-1);color:var(--text-1);vertical-align:middle;padding:7px 10px}.data-table tr:hover td{background:var(--surface-2)}.canonical .dot{vertical-align:middle;margin-right:8px}.topic-name{align-items:baseline;gap:8px;display:inline-flex}.topic-name .muted.small.mono{font-size:var(--text-xs);opacity:.7}.dot{border-radius:50%;flex-shrink:0;width:8px;height:8px;display:inline-block}.dot.lg{width:14px;height:14px}.chip-inline{border-radius:var(--r-sm);border:1px solid var(--border-2);background:var(--surface-2);color:var(--text-2);font-family:var(--font-mono);font-size:var(--text-xs);letter-spacing:.04em;text-transform:lowercase;align-items:center;gap:4px;padding:2px 8px;display:inline-flex}.chip-inline.status-active{color:var(--accent);background:var(--accent-glow);border-color:#e8ff6e40}.chip-inline.status-idle{color:#ffcc80;border-color:#ffcc8040}.chip-inline.status-closed{color:var(--text-2)}.chip-inline.status-superseded{color:var(--text-3);text-decoration:line-through}.chip-inline.status-replaced{color:var(--text-3)}.chip-inline.status-retired{color:var(--danger);background:var(--danger-dim);border-color:#ff6b3540}.chip-inline.status-stale{color:var(--warn);background:var(--warn-dim);border-color:#ff993340}.chip-inline.severity-high{color:var(--danger);background:var(--danger-dim);border-color:#ff6b3559}.chip-inline.severity-medium{color:var(--warn);background:var(--warn-dim);border-color:#ff993359}.chip-inline.severity-low{color:var(--text-2);border-color:var(--border-3);background:var(--surface-2)}.chip-x{color:inherit;cursor:pointer;background:0 0;border:none;padding:0 0 0 4px;font-size:12px;line-height:1}.kpi-row{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:18px;display:grid}.kpi{background:var(--surface-1);border:1px solid var(--border-2);border-radius:var(--r-md);flex-direction:column;gap:4px;padding:14px 16px;display:flex}.kpi-label{font-size:var(--text-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--text-3)}.kpi-value{font-size:var(--text-stat);font-family:var(--font-mono);color:var(--text-1);line-height:1}.kpi-hint{font-size:var(--text-xs);color:var(--text-3)}.kpi-sparkline{gap:8px}.sparkline{align-items:flex-end;gap:4px;height:40px;display:flex}.spark-bar{background:var(--accent);opacity:.7;border-radius:1px;flex:1;min-height:2px}.pulse-grid{grid-template:"coherence recent stale"1fr"runtimes recent stale"1fr/1fr 1fr 1fr;gap:12px;height:calc(100vh - 280px);min-height:360px;margin-top:6px;display:grid}.pulse-area-coherence{grid-area:coherence}.pulse-area-runtimes{grid-area:runtimes}.pulse-area-recent{grid-area:recent}.pulse-area-stale{grid-area:stale}.pulse-scroll-card{flex-direction:column;min-height:0;display:flex;overflow:hidden}.pulse-scroll-card .card-head{flex-shrink:0}.kpi,.pulse-grid>.card{transition:outline-color var(--ease), border-color var(--ease);outline-offset:-1px;outline:1px solid #0000}.kpi:hover{outline-color:#ffffff8c}.kpi-clickable{cursor:pointer;color:inherit;text-decoration:none}.kpi-clickable:hover .kpi-value{color:var(--accent)}.kpi-clickable:hover{border-color:var(--border-3)}.pulse-grid>.pulse-scroll-card:hover{outline-color:#ffffff8c}.pulse-scroll-body{flex:1;min-height:0;overflow:hidden auto}.card-head{border-bottom:1px solid var(--border-1);justify-content:space-between;align-items:baseline;padding:10px 14px;display:flex}.card-head h3{font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;color:var(--text-2);font-weight:500}.bar-stack{flex-direction:column;padding:4px 0;display:flex}.bar-item{border:0;border-bottom:1px solid var(--border-1);text-align:left;width:100%;color:inherit;font:inherit;background:0 0;grid-template-columns:80px 1fr auto;align-items:center;gap:10px;padding:8px 14px;display:grid}.bar-stack .bar-item:last-child{border-bottom:none}.bar-item-clickable{cursor:pointer;transition:background var(--ease)}.bar-item-clickable:hover{background:var(--surface-2)}.bar-item-clickable:hover .bar-label{color:var(--accent)}.bar-item[disabled]{cursor:default;opacity:.5}.bar-label{font-size:var(--text-sm);color:var(--text-2)}.bar-track{background:var(--surface-2);border-radius:4px;height:8px;overflow:hidden}.bar-fill{height:100%;transition:width var(--ease-slow)}.bar-fill.tone-active{background:var(--accent)}.bar-fill.tone-warn{background:var(--warn)}.bar-fill.tone-danger{background:var(--danger)}.bar-value{font-size:var(--text-sm);color:var(--text-1);text-align:right;white-space:nowrap;min-width:96px}.bar-pct{margin-left:2px}.recall-head{justify-content:space-between;align-items:flex-start;gap:24px;margin-bottom:20px;display:flex}.recall-note{max-width:60ch;margin:0;line-height:1.5}.recall-block{margin-bottom:28px}.recall-block-head{margin-bottom:14px}.recall-block-head .page-title{margin-bottom:2px}.recall-block-head p{max-width:70ch;margin:0}.recall-empty{font-size:var(--text-sm);padding:18px}.recall-cards{grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px;margin-top:14px;display:grid}.recall-bars .bar-item{grid-template-columns:140px 1fr auto}.recall-bar-label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.recall-bars .bar-value{min-width:0}@media (width<=720px){.recall-head{flex-direction:column;gap:12px}}.runtime-list{margin:0;padding:4px 0;list-style:none}.runtime-row{border-bottom:1px solid var(--border-1);grid-template-columns:12px 1fr auto auto;align-items:center;gap:10px;padding:8px 14px;display:grid}.runtime-row:last-child{border-bottom:none}.runtime-dot{background:var(--text-3);border-radius:50%;width:8px;height:8px;box-shadow:0 0 0 2px #ffffff0a}.runtime-dot.runtime-active{background:var(--accent);box-shadow:0 0 6px #e8ff6e99}.runtime-dot.runtime-idle{background:var(--warn)}.runtime-dot.runtime-dormant{background:var(--text-3);opacity:.5}.runtime-name{color:var(--text-1);font-size:var(--text-sm)}.runtime-counts{white-space:nowrap}.runtime-counts-sep{opacity:.5;margin:0 6px}.runtime-counts-prev{opacity:.7}.runtime-age{text-align:right;min-width:60px}.runtime-row.clickable{cursor:pointer;transition:background var(--ease)}.runtime-row.clickable:hover{background:var(--surface-2)}.runtime-row.clickable:hover .runtime-name{color:var(--accent)}.runtime-topics{flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:4px;display:flex}.alert-list{padding:4px 0;list-style:none}.alert-row{border-bottom:1px solid var(--border-1);grid-template-columns:auto auto 1fr;align-items:center;gap:10px;padding:7px 14px;display:grid}.alert-entity{color:var(--text-1);font-size:var(--text-sm);text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.alert-summary{-webkit-line-clamp:1;text-overflow:ellipsis;color:var(--text-3);font-size:var(--text-xs);letter-spacing:.04em;min-width:0;line-height:var(--lh-base);-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.alert-row.clickable{cursor:pointer;transition:background var(--ease)}.alert-row.clickable:hover{background:var(--surface-2)}.alert-row.clickable:hover .alert-entity{color:var(--accent)}.drawer-actions{flex-wrap:wrap;gap:6px;margin:14px 0 6px;display:flex}.session-list{list-style:none}.session-list.compact .session-row{border-bottom:1px solid var(--border-1);padding:6px 0}.session-row{border-bottom:1px solid var(--border-1);grid-template-columns:auto 1fr auto;align-items:center;gap:10px;padding:8px 14px;display:grid}.session-row-detail{grid-template-columns:auto 1fr auto}.session-row-main{flex-direction:column;gap:2px;min-width:0;display:flex}.session-label{color:var(--text-1);font-size:var(--text-sm);white-space:nowrap;text-overflow:ellipsis;text-decoration:none;overflow:hidden}a.session-label:hover{color:var(--accent)}.session-meta{color:var(--text-3);font-size:var(--text-xs);letter-spacing:.04em}@media (width<=1100px){.pulse-grid{grid-template:"coherence runtimes""recent recent""stale stale"/1fr 1fr;height:auto;min-height:0}.pulse-scroll-body{max-height:360px}}@media (width<=700px){.pulse-grid{grid-template-columns:1fr;grid-template-areas:"coherence""runtimes""recent""stale"}}.search-bar{align-items:center;gap:10px;margin-bottom:12px;display:flex}.search-input.search-big{font-size:var(--text-md);flex:1;padding:10px 14px}.search-meta{margin:8px 0}.thread-header{align-items:center;gap:14px;margin-bottom:16px;display:flex}.thread-header .page-title{margin-bottom:0}.thread-grid{grid-template-columns:1fr 1fr;gap:12px;margin-bottom:18px;display:grid}.marker-list{max-height:360px;list-style:none;overflow-y:auto}.marker-row{border-bottom:1px solid var(--border-1);grid-template-columns:auto auto 1fr auto;align-items:baseline;gap:10px;padding:7px 14px;display:grid}.marker-text{color:var(--text-1);font-size:var(--text-sm);min-width:0}.marker-timestamp{font-variant-numeric:tabular-nums;white-space:nowrap}.marker-action-select{min-width:130px;font-size:var(--text-xs)}.marker-editor{align-items:center;gap:6px;display:inline-flex}.marker-editor-input{min-width:260px}.entity-grid{grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px;margin-top:16px;list-style:none;display:grid}.entity-card{color:var(--text-1);align-items:center;gap:8px;padding:10px 12px;text-decoration:none;display:flex}.entity-name{font-size:var(--text-sm);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}@media (width<=800px){.thread-grid{grid-template-columns:1fr}}.river-toolbar{align-items:center;gap:12px;margin-bottom:16px;display:flex}.river-toolbar .page-title{font-size:var(--text-lg);margin-bottom:0}.river-grid{--river-label-w:200px;--river-row-gap:3px;--river-cell-gap:2px;--river-cell-h:20px;gap:var(--river-row-gap);flex-direction:column;width:100%;padding:12px;display:flex}.river-grid.river-density-compact{--river-row-gap:1px;--river-cell-gap:1px;--river-cell-h:10px}.river-grid.river-density-spacious{--river-row-gap:6px;--river-cell-gap:4px;--river-cell-h:24px}.river-row{grid-template-columns:var(--river-label-w) 1fr;align-items:center;gap:6px;width:100%;min-width:0;display:grid}.river-row-dates{margin-bottom:2px}.river-lane-label{border-radius:var(--r-sm);color:var(--text-2);font-size:var(--text-sm);white-space:nowrap;align-items:center;gap:6px;width:100%;min-width:0;padding:2px 6px;text-decoration:none;display:flex;overflow:hidden}.river-lane-label:hover{background:var(--surface-2);color:var(--text-1)}.river-lane-label--header{background:0 0;padding:0}.river-lane-name{text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.river-cells{grid-template-columns:repeat(var(--cells,1), minmax(0, 1fr));gap:var(--river-cell-gap);width:100%;min-width:0;display:grid}.river-date-cell{font-size:var(--text-xs);color:var(--text-2);letter-spacing:.04em;text-align:center;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.river-cell{height:var(--river-cell-h);background:var(--surface-2);border-radius:2px;min-width:0}.river-cell.tier-1{background:#e8ff6e33}.river-cell.tier-2{background:#e8ff6e66}.river-cell.tier-3{background:#e8ff6ea6}.river-cell.tier-4{background:var(--accent)}.river-cell.has-corrections{box-shadow:inset 0 -2px #ffb400b3}.alert-row{grid-template-columns:auto minmax(0,max-content) minmax(0,1fr) auto}.alert-actions{align-items:center;gap:6px;display:flex}.alert-actions .chip{font-size:var(--text-xs);padding:2px 8px}.row-actions{gap:6px;display:flex}.row-actions .chip{font-size:var(--text-xs);padding:2px 8px}.row-busy{opacity:.5;pointer-events:none;transition:opacity var(--ease)}.form-input-inline{font-size:var(--text-xs);letter-spacing:.04em;padding:3px 8px}.river-grid{-webkit-user-select:none;user-select:none;position:relative}.river-drag-rect{background:var(--accent-glow);border-left:1px dashed var(--accent);border-right:1px dashed var(--accent);pointer-events:none;z-index:var(--z-raised);position:absolute;top:0;bottom:0}.river-lane-label{text-align:left;cursor:pointer;font-family:var(--font-mono);background:0 0;border:none}.river-cell{transition:outline-color var(--ease);outline-offset:1px;z-index:var(--z-base);outline:1px solid #0000;position:relative}.river-cell:hover{z-index:var(--z-raised);outline-color:#ffffffb3}.river-hover{background:var(--surface-float);border:1px solid var(--border-3);border-radius:var(--r-sm);font-size:var(--text-xs);pointer-events:none;z-index:var(--z-tooltip);align-items:center;gap:8px;padding:6px 10px;display:flex;position:fixed;box-shadow:0 6px 20px #00000080}.river-hover-name{color:var(--text-1);font-size:var(--text-sm)}.session-row.clickable{cursor:pointer;transition:background var(--ease)}.session-row.clickable:hover{background:var(--surface-2)}.session-row.clickable:hover .session-label{color:var(--accent)}.session-row-end{align-items:center;gap:8px;display:flex}.session-row.is-replaced{opacity:.55}.earlier-versions-list{border-left:2px solid var(--border-2);margin-left:28px;list-style:none}.earlier-versions-list .session-row{padding-left:10px}.link-button{color:var(--text-3);font-family:var(--font-mono);font-size:var(--text-xs);cursor:pointer;letter-spacing:.04em;background:0 0;border:none;padding:0}.link-button:hover{color:var(--accent)}.drawer-backdrop{z-index:var(--z-drawer-bg);background:#0000008c;animation:.15s fadeIn;position:fixed;inset:0}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.session-drawer{background:var(--surface-1);border-left:1px solid var(--border-3);width:min(560px,100vw);z-index:var(--z-drawer);flex-direction:column;animation:.18s slideInRight;display:flex;position:fixed;top:0;bottom:0;right:0;box-shadow:-16px 0 40px #0000008c}.coherence-drawer{width:min(480px,100vw)}@keyframes slideInRight{0%{opacity:0;transform:translate(20px)}to{opacity:1;transform:translate(0)}}.drawer-head{border-bottom:1px solid var(--border-1);align-items:center;gap:10px;padding:14px 18px;display:flex}.drawer-title{font-size:var(--text-md);font-family:var(--font-mono);color:var(--text-1);text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:500;overflow:hidden}.drawer-close{color:var(--text-3);cursor:pointer;background:0 0;border:none;padding:0 6px;font-size:24px;line-height:1}.drawer-close:hover{color:var(--text-1)}.drawer-body{flex:1;min-height:0;padding:16px 18px 80px;overflow-y:auto}.drawer-paragraph.drawer-hint{color:var(--text-2);margin:0 0 16px}.coherence-session-list .session-row{transition:background var(--ease);grid-template-columns:auto 1fr auto auto}.coherence-session-list .coherence-meta{white-space:nowrap}.coherence-session-list .session-row{cursor:pointer}.coherence-session-list .session-row:hover{background:var(--surface-2)}.coherence-session-list .session-row:hover .session-label{color:var(--accent)}.coherence-session-list .session-row[aria-busy=true]{opacity:.5;pointer-events:none}.coherence-session-list .chip[data-bucket=active].active{color:var(--accent);background:var(--accent-glow);border-color:#e8ff6e4d}.coherence-session-list .chip[data-bucket=sparse].active{color:var(--warn);background:var(--warn-dim);border-color:#ff993359}.coherence-session-list .chip[data-bucket=stale].active{color:var(--danger);background:var(--danger-dim);border-color:#ff6b3566}.coherence-drawer .drawer-body{flex-direction:column;padding-bottom:0;display:flex;overflow:hidden}.coherence-session-list{flex:1;min-height:0;overflow-y:auto}.coherence-drawer .pagination{border-top:1px solid var(--border-1);flex-shrink:0;margin-top:0}.coherence-drawer .pagination.pagination-compact{padding:10px 18px}.merge-picker{background:var(--surface-2);border:1px solid var(--border-2);border-radius:6px;margin-bottom:12px;padding:12px}.merge-result-list{max-height:240px;margin:8px 0 0;padding:0;list-style:none;overflow-y:auto}.merge-result-row{cursor:pointer;border-radius:4px;align-items:center;gap:8px;padding:6px 8px;display:flex}.merge-result-row:hover{background:var(--surface-float)}.merge-result-row.is-selected{outline:2px solid var(--accent);outline-offset:-2px;background:var(--surface-float)}.coherence-rows-dimmed{opacity:.4;pointer-events:none}.coherence-filters{flex-direction:column;gap:8px;margin-bottom:12px;display:flex}.coherence-search{width:100%}.coherence-filter-row{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.drawer-section{font-size:var(--text-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);margin:18px 0 8px;font-weight:500}.drawer-list{font-size:var(--text-sm);color:var(--text-1);flex-direction:column;gap:8px;list-style:none;display:flex}.drawer-list li{align-items:baseline;gap:8px;display:flex}.drawer-paragraph{font-size:var(--text-sm);color:var(--text-1);line-height:var(--lh-loose)}.drawer-body-text{background:var(--surface-0);border:1px solid var(--border-1);border-radius:var(--r-sm);font-size:var(--text-xs);color:var(--text-2);white-space:pre-wrap;word-break:break-word;max-height:360px;line-height:var(--lh-base);padding:10px 12px;overflow-y:auto}.entity-chips{flex-wrap:wrap;gap:6px;display:flex}.entity-chips-row{align-items:center;margin-top:4px}.supersedence-banner{border-radius:var(--r-sm);font-size:var(--text-sm);flex-wrap:wrap;align-items:baseline;gap:6px;margin-bottom:10px;padding:8px 12px;display:flex}.supersedence-banner--superseded{color:var(--danger);background:#ff6b3514;border:1px solid #ff6b3540}.supersedence-banner--supersedes{border:1px solid var(--border-2);color:var(--text-2);background:#a8a8a80f}.supersedence-label{white-space:nowrap;font-weight:500}.supersedence-ids{flex-wrap:wrap;gap:4px;display:flex}.supersedence-id{color:inherit;opacity:.8}.supersedence-link{cursor:pointer;font-family:var(--font-mono);font-size:var(--text-xs);color:inherit;text-underline-offset:2px;background:0 0;border:none;padding:0;text-decoration:underline}.supersedence-link:hover{opacity:.75}.drawer-menu{position:relative}.drawer-menu-trigger{color:var(--text-3);font-size:var(--text-lg);cursor:pointer;background:0 0;border:none;border-radius:4px;padding:4px 8px;line-height:1}.drawer-menu-trigger:hover{color:var(--text-1);background:var(--bg-2)}.drawer-menu-trigger:disabled{opacity:.4;cursor:not-allowed}.drawer-menu-list{z-index:var(--z-dropdown);background:var(--bg-1);border:1px solid var(--border-1);border-radius:6px;min-width:200px;margin:0;padding:4px;list-style:none;position:absolute;top:calc(100% + 4px);right:0;box-shadow:0 6px 20px #00000059}.drawer-menu-item{text-align:left;width:100%;color:var(--text-1);font-family:var(--font-sans);font-size:var(--text-sm);cursor:pointer;background:0 0;border:none;border-radius:4px;padding:8px 10px;display:block}.drawer-menu-item:hover:not(:disabled){background:var(--bg-2)}.drawer-menu-item:disabled{opacity:.4;cursor:not-allowed}.palette-backdrop{z-index:var(--z-palette-bg);background:#0000008c;position:fixed;inset:0}.supersede-palette{background:var(--bg-1);border:1px solid var(--border-1);width:min(640px,92vw);max-height:76vh;z-index:var(--z-palette);border-radius:8px;flex-direction:column;display:flex;position:fixed;top:12vh;left:50%;transform:translate(-50%);box-shadow:0 24px 60px #00000073}.palette-head{border-bottom:1px solid var(--border-1);align-items:center;gap:10px;padding:12px 16px;display:flex}.palette-title{font-family:var(--font-mono);font-size:var(--text-md);color:var(--text-1);flex:1}.palette-body{flex-direction:column;flex:1;gap:12px;padding:14px 16px;display:flex;overflow-y:auto}.palette-context{background:var(--bg-2);border-left:2px solid var(--border-2);border-radius:4px;grid-template-columns:auto 1fr;gap:4px 10px;padding:10px 12px;display:grid}.palette-context-label{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-3);text-transform:uppercase;letter-spacing:.04em}.palette-context-value{color:var(--text-1);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.palette-context-id{color:var(--text-3);grid-column:2}.palette-field-label{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-3);text-transform:uppercase;letter-spacing:.04em}.palette-input{box-sizing:border-box;background:var(--bg-2);border:1px solid var(--border-1);width:100%;color:var(--text-1);font-size:var(--text-sm);border-radius:4px;padding:8px 10px}.palette-input:focus{border-color:var(--accent);outline:none}.palette-list{border:1px solid var(--border-1);border-radius:4px;max-height:280px;margin:0;padding:0;list-style:none;overflow-y:auto}.palette-row{cursor:pointer;border-bottom:1px solid var(--border-1);grid-template-columns:80px 110px minmax(0,1fr) minmax(80px,160px);align-items:center;gap:10px;padding:6px 10px;display:grid}.palette-row-id{text-overflow:ellipsis;white-space:nowrap;text-align:right;overflow:hidden}.palette-row:last-child{border-bottom:none}.palette-row--hot{background:var(--bg-2)}.palette-row:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.palette-row[aria-selected=true] .palette-row-date,.palette-row[aria-selected=true] .palette-row-runtime,.palette-row[aria-selected=true] .palette-row-id{color:var(--text-2,var(--text-1))}.palette-row-label{color:var(--text-1);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.palette-empty{text-align:center;padding:10px}.palette-pick{background:var(--bg-2);border-left:2px solid var(--accent);border-radius:4px;grid-template-columns:auto 1fr auto;gap:4px 10px;padding:10px 12px;display:grid}.palette-pick .palette-context-id{grid-column:2/3}.palette-undo{border:1px solid var(--border-1);color:var(--text-3);cursor:pointer;font-size:var(--text-xs);background:0 0;border-radius:4px;grid-area:1/3/span 2;align-self:center;padding:4px 8px}.palette-undo:hover:not(:disabled){color:var(--text-1);border-color:var(--border-2)}.palette-error{color:#f0a0a0;font-size:var(--text-sm);background:#dc50501f;border:1px solid #dc505059;border-radius:4px;padding:8px 10px}.palette-foot{border-top:1px solid var(--border-1);justify-content:space-between;align-items:center;gap:12px;padding:10px 16px;display:flex}.palette-hint{font-family:var(--font-mono)}.palette-confirm{background:var(--accent);color:var(--bg-1);cursor:pointer;font-family:var(--font-mono);font-size:var(--text-sm);border:none;border-radius:4px;padding:8px 14px}.palette-confirm:disabled{opacity:.4;cursor:not-allowed}.card-head.card-head-stack{flex-direction:column;align-items:stretch;gap:8px;padding:10px 14px 12px}.card-head-row{justify-content:space-between;align-items:baseline;display:flex}.card-filters{flex-wrap:wrap;gap:12px;display:flex}.filter-group{gap:4px;display:flex}.filter-group .chip{font-size:var(--text-xs);padding:2px 8px}.thread-sessions-head{align-items:center;gap:12px;margin:24px 0 8px;display:flex}.thread-sessions-title{flex-shrink:0;margin:0}.thread-sessions-head .search-input{flex:1}.thread-filters{flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:8px;display:flex}.thread-filters .filter-group{flex-wrap:wrap}.pagination{border-top:1px solid var(--border-1);flex-wrap:wrap;align-items:center;gap:16px;margin-top:4px;padding:14px 0 4px;display:flex}.page-size{align-items:center;gap:8px;display:flex}.page-nav{align-items:center;gap:4px;display:flex}.page-nav .chip:disabled{opacity:.4;cursor:not-allowed}.page-indicator{font-size:var(--text-sm);color:var(--text-2);text-align:center;min-width:60px;padding:0 8px}.marker-row-promotable{grid-template-columns:auto 1fr auto auto;align-items:baseline;gap:10px;display:grid}.marker-row-promotable .marker-actions{align-items:baseline;gap:6px;display:flex}.promote-chip{font-size:var(--text-xs);color:var(--accent);background:var(--accent-glow);border-color:#e8ff6e4d;padding:2px 8px}.promote-chip:hover{color:var(--accent);background:var(--accent-dim);border-color:#e8ff6e8c}.promote-editor{align-items:center;gap:6px;min-width:280px;display:flex}.promote-input{flex:1;min-width:200px}.pagination.pagination-compact{font-size:var(--text-xs);flex-wrap:wrap;gap:10px;padding:10px 0 4px}.pagination.pagination-compact .page-indicator{min-width:40px;font-size:var(--text-xs);padding:0 4px}.pagination.pagination-compact .chip{font-size:var(--text-xs);padding:1px 6px}.pagination.pagination-compact .form-label{font-size:9px}.river-date-cell--month-start{border-left:1px solid var(--border-2);padding-left:3px}.river-legend{align-items:center;gap:3px;display:flex}.river-legend-cell{background:var(--surface-2);border-radius:2px;width:12px;height:12px}.river-legend-cell.tier-1{background:#e8ff6e33}.river-legend-cell.tier-2{background:#e8ff6e66}.river-legend-cell.tier-3{background:#e8ff6ea6}.river-legend-cell.tier-4{background:var(--accent)}.empty-row{color:var(--text-2);font-size:var(--text-sm);padding:16px 14px}.list-action-row{padding:8px 14px}.toast-host{z-index:var(--z-toast);pointer-events:none;flex-direction:column;gap:8px;max-width:min(420px,100vw - 48px);display:flex;position:fixed;bottom:24px;right:24px}.toast{background:var(--surface-float);border:1px solid var(--border-3);border-left:3px solid var(--text-2);border-radius:var(--r-md);font-size:var(--text-sm);color:var(--text-1);pointer-events:auto;align-items:flex-start;gap:8px;padding:10px 12px;animation:.2s ease-out fadeSlideIn;display:flex;box-shadow:0 12px 32px #00000073}.toast-success{border-left-color:var(--accent)}.toast-error{border-left-color:var(--danger)}.toast-info{border-left-color:var(--text-2)}.toast-message{line-height:var(--lh-base);flex:1}.toast-close{color:var(--text-3);cursor:pointer;font-size:var(--text-lg);background:0 0;border:0;margin-top:-2px;padding:0 2px;line-height:1}.toast-close:hover{color:var(--text-1)}.tooltip-anchor{display:inline-flex;position:relative}.tooltip{background:var(--surface-float);color:var(--text-1);border:1px solid var(--border-3);border-radius:var(--r-sm);font-size:var(--text-xs);font-family:var(--font-mono);letter-spacing:.04em;text-align:center;pointer-events:none;opacity:0;width:max-content;max-width:240px;transition:opacity var(--ease-fast), transform var(--ease-fast);z-index:var(--z-tooltip);padding:4px 8px;position:absolute;left:50%;transform:translate(-50%)translateY(-4px)}.tooltip-top .tooltip{margin-bottom:4px;bottom:100%}.tooltip-bottom .tooltip{margin-top:4px;top:100%}.tooltip-anchor:hover .tooltip,.tooltip-anchor:focus-within .tooltip{opacity:1;transform:translate(-50%)translateY(0)}.confirm-dialog{background:var(--surface-float);border:1px solid var(--border-3);border-radius:var(--r-md);width:min(440px,92vw);z-index:var(--z-palette);padding:20px 22px 16px;animation:.2s ease-out fadeSlideIn;position:fixed;top:22vh;left:50%;transform:translate(-50%);box-shadow:0 24px 60px #0000008c}.confirm-title{font-family:var(--font-mono);font-size:var(--text-base);color:var(--text-1);letter-spacing:.04em;margin:0 0 8px}.confirm-message{color:var(--text-2);font-size:var(--text-sm);line-height:var(--lh-base);margin:0 0 16px}.confirm-actions{justify-content:flex-end;gap:8px;display:flex}.session-meta{-webkit-line-clamp:2;line-clamp:2;white-space:normal;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.search-wrap{align-items:center;display:flex;position:relative}.search-wrap .search-input{width:100%;padding-right:28px}.search-clear{color:var(--text-3);cursor:pointer;background:0 0;border:none;align-items:center;padding:0;display:flex;position:absolute;right:6px}.search-clear:hover{color:var(--text-1)}.drawer-nav{flex-shrink:0;align-items:center;gap:4px;display:flex}.drawer-nav-btn{border:1px solid var(--border-2);color:var(--text-3);cursor:pointer;border-radius:var(--r-sm);transition:color var(--ease), border-color var(--ease), background var(--ease);background:0 0;justify-content:center;align-items:center;padding:3px;display:flex}.drawer-nav-btn:hover:not(:disabled){color:var(--text-1);border-color:var(--border-3);background:var(--surface-2)}.drawer-nav-btn:disabled{opacity:.35;cursor:not-allowed}.dot-pulse{animation:2s ease-in-out infinite dot-pulse}@keyframes dot-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.6;transform:scale(1.35)}}.search-hint{margin:8px 0 12px}.search-header{z-index:var(--z-sticky);background:var(--surface-0);border-bottom:1px solid var(--border-1);margin-bottom:16px;padding-bottom:12px;position:sticky;top:0}.session-row.is-selected{background:var(--surface-2);border-left:2px solid var(--accent);padding-left:12px}.live-tag[data-kind=summary]{background:var(--surface-2);color:var(--text-2)}.live-tag[data-kind=label]{background:var(--surface-2);color:var(--text-1)}.live-tag[data-kind=entity]{background:var(--accent-glow);color:var(--accent);border-color:#e8ff6e40}.match-snippet{color:var(--text-2);font-size:var(--text-xs);line-height:var(--lh-base);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin-top:4px;display:-webkit-box;overflow:hidden}.match-snippet mark{color:var(--accent);background:#e8ff6e26;border-radius:2px;padding:0 2px}.empty-row-full-width{grid-column:1/-1}.section-title-xs{font-size:.875rem}.merge-picker p{margin-bottom:8px}.merge-picker .filter-group{margin-top:8px}.river-row-skeleton{margin-bottom:3px}.river-card-skeleton{padding:12px}.search-wrap-full{flex:1}.thread-filters-wrap{flex-wrap:wrap}.search-meta-clear{margin-left:8px}.session-meta-entity{margin-right:4px}.session-row-end-col{flex-direction:column;align-items:flex-end;gap:4px;display:flex}.thread-sessions-head-mt{margin-top:16px}.search-wrap-compact{max-width:320px}.skeleton-display-contents{display:contents}.skeleton-column-gap{flex-direction:column;gap:8px;display:flex}.card-accent{border-color:var(--accent);margin-top:1rem;padding:1rem}.card-accent-padded{padding:.5rem;overflow:auto}.section-title-no-mt{margin-top:0}.card-wide-input input{min-width:28rem}.card-data-validated{border-color:var(--accent);margin-top:.75rem;padding:.75rem 1rem}.data-validated-text{margin:0}
|
|
1
|
+
:root{--surface-0:#161616;--surface-1:#1d1d1d;--surface-2:#242424;--surface-float:#2c2c2c;--bg-1:var(--surface-float);--bg-2:var(--surface-2);--border-1:#262626;--border-2:#303030;--border-3:#3d3d3d;--border-4:#525252;--text-1:#e8e8e8;--text-2:#b0b0b0;--text-3:#686868;--text-4:#383838;--accent:#e8ff6e;--accent-dim:#e8ff6e1f;--accent-glow:#e8ff6e0f;--warn:#f93;--warn-dim:#ff99331f;--danger:#ff6b35;--danger-dim:#ff6b3512;--danger-glow:#ff6b351f;--font-mono:"IBM Plex Mono", "Fira Code", ui-monospace, monospace;--text-xs:10px;--text-sm:11px;--text-base:13px;--text-md:15px;--text-lg:18px;--text-xl:22px;--text-stat:36px;--lh-tight:1.3;--lh-base:1.5;--lh-loose:1.7;--page-x:28px;--section-gap:24px;--r-sm:3px;--r-md:5px;--r-lg:7px;--ease-fast:.1s ease;--ease:.15s ease;--ease-slow:.3s ease;--z-base:0;--z-raised:1;--z-sticky:10;--z-sidenav:20;--z-dropdown:30;--z-overlay:40;--z-drawer-bg:50;--z-drawer:60;--z-palette-bg:70;--z-palette:80;--z-tooltip:90;--z-toast:100}*,:before,:after{box-sizing:border-box;margin:0;padding:0}html{background-color:var(--surface-0)}body{color:var(--text-1);font-family:var(--font-mono);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-image:radial-gradient(100% 40% at 50% -8%,#e8ff6e08 0%,#0000 100%);background-attachment:fixed;min-height:100vh}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{background:var(--surface-1)}::-webkit-scrollbar-thumb{background:var(--border-3);border-radius:2px}@keyframes fadeSlideIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-delay:0s!important}}.skeleton{background:linear-gradient(90deg, var(--surface-1) 0%, var(--surface-2) 50%, var(--surface-1) 100%);vertical-align:middle;background-size:200% 100%;animation:1.2s ease-in-out infinite skeleton-shimmer;display:inline-block}@keyframes skeleton-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.skeleton{background:var(--surface-2);animation:none}}.card{background:var(--surface-1);border:1px solid var(--border-2);border-radius:var(--r-md)}.card-lift{transition:border-color var(--ease), background var(--ease)}.card-lift:hover{background:var(--surface-2);border-color:var(--border-3)}.btn{font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;border-radius:var(--r-sm);border:1px solid var(--border-3);color:var(--text-2);cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:border-color var(--ease), color var(--ease), background var(--ease);background:0 0;align-items:center;gap:5px;padding:5px 12px;text-decoration:none;display:inline-flex}.btn:hover{border-color:var(--border-4);color:var(--text-1)}.btn:active{background:var(--surface-2)}.btn.active{background:var(--surface-2);border-color:var(--border-3);color:var(--text-1)}.btn-primary{background:var(--accent);border-color:var(--accent);color:#080808;font-weight:600}.btn-primary:hover{color:#080808;background:#d4eb5e;border-color:#d4eb5e}.btn-accent{color:var(--accent);border-color:#e8ff6e40}.btn-accent:hover{background:var(--accent-glow);border-color:#e8ff6e66}.btn-danger:hover{border-color:var(--danger);color:var(--danger)}.btn.small{font-size:var(--text-xs);padding:3px 9px}.form-row{flex-wrap:wrap;align-items:center;gap:12px;margin:12px 0;display:flex}.form-row.between{justify-content:space-between}.form-row.tight{gap:8px}.form-row .form-label{color:var(--text-3);font-size:var(--text-xs)}input[type=file].file-input{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-3);max-width:24rem}input[type=file].file-input::file-selector-button{font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;border-radius:var(--r-sm);border:1px solid var(--border-3);color:var(--text-2);cursor:pointer;transition:border-color var(--ease), color var(--ease), background var(--ease);background:0 0;align-items:center;margin-right:10px;padding:5px 12px;display:inline-flex}input[type=file].file-input::file-selector-button:hover{border-color:var(--border-4);color:var(--text-1)}input[type=file].file-input:disabled{cursor:not-allowed}input[type=file].file-input:disabled::file-selector-button{opacity:.5;cursor:not-allowed}.chip{font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.06em;text-transform:lowercase;border-radius:var(--r-sm);border:1px solid var(--border-1);color:var(--text-3);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;transition:border-color var(--ease), color var(--ease), background var(--ease);background:0 0;align-items:center;gap:4px;padding:3px 9px;display:inline-flex}.chip:hover{border-color:var(--border-3);color:var(--text-2)}.chip.active{border-color:var(--border-3);color:var(--text-1);background:var(--surface-2);box-shadow:inset 0 0 0 1px var(--border-3);font-weight:600}.chip[data-severity=critical].active{color:var(--danger);background:var(--danger-dim);border-color:#ff6b3566}.chip[data-severity=high].active{color:#c42;background:#cc44220f;border-color:#cc442259}.chip[data-severity=medium].active{color:var(--warn);background:var(--warn-dim);border-color:#ff993359}.chip[data-severity=low].active{border-color:var(--border-3);color:var(--text-2);background:var(--surface-2)}.chip[data-status=active].active{color:var(--accent);background:var(--accent-glow);border-color:#e8ff6e4d}.chip[data-status=idle].active{color:#ffcc80}.chip[data-length].active{color:var(--text-1)}.chip[data-marker].active{color:var(--accent);background:var(--accent-glow);border-color:#e8ff6e4d}.panel-float{-webkit-backdrop-filter:blur(18px);border:1px solid var(--border-3);border-radius:var(--r-md);background:#101010f5;box-shadow:0 12px 40px #000000a6,0 0 0 1px #ffffff08}.nav-link{color:var(--text-3);border-radius:var(--r-sm);font-size:var(--text-sm);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;transition:color var(--ease), border-color var(--ease), background var(--ease);background:0 0;border:1px solid #0000;align-items:center;padding:4px 10px;text-decoration:none;display:inline-flex}.nav-link:hover{color:var(--text-2);border-color:var(--border-3)}.nav-link.active{background:var(--surface-2);border-color:var(--border-3);color:var(--text-1)}.search-input{background:var(--surface-1);border:1px solid var(--border-2);color:var(--text-1);font-family:var(--font-mono);font-size:var(--text-xs);border-radius:var(--r-sm);letter-spacing:.04em;transition:border-color var(--ease);outline:none;padding:5px 10px}.search-input:focus{border-color:var(--border-3)}.search-input::placeholder{color:var(--text-4);letter-spacing:.06em}.ctrl-btn{background:var(--surface-1);border:1px solid var(--border-2);color:var(--text-2);font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;border-radius:var(--r-sm);cursor:pointer;white-space:nowrap;transition:border-color var(--ease), color var(--ease), background var(--ease);padding:4px 10px}.ctrl-btn:hover{border-color:var(--border-3);color:var(--text-1)}.ctrl-btn.active{background:var(--surface-2);border-color:var(--border-3);color:var(--accent)}.ctrl-btn[data-active="1"]{color:var(--accent);border-color:#e8ff6e40}.ctrl-label{font-size:var(--text-sm);color:var(--text-3);letter-spacing:.06em;text-transform:uppercase;flex-shrink:0}.subnav{border-bottom:1px solid var(--border-1);gap:0;padding:0 28px;display:flex}.subnav-link{font-size:var(--text-sm);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);transition:color var(--ease), border-color var(--ease);border-bottom:2px solid #0000;margin-bottom:-1px;padding:10px 14px;text-decoration:none}.subnav-link:hover{color:var(--text-2)}.subnav-link.active{color:var(--accent);border-bottom-color:var(--accent)}.page-shell{background:var(--surface-0);height:100vh;display:flex;overflow:hidden}.page-main{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.app-header{z-index:var(--z-sticky);height:52px;padding:0 var(--page-x);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid var(--border-1);background:#161616e6;align-items:center;gap:20px;display:flex;position:sticky;top:0}.app-header .wordmark-page{font-size:var(--text-sm);color:var(--text-3);letter-spacing:.04em;text-transform:lowercase}.app-header .header-spacer{flex:1}.app-header .status-dot{background:var(--accent);width:7px;height:7px;box-shadow:0 0 6px var(--accent-dim);border-radius:50%;animation:2s ease-in-out infinite pulse-dot}@keyframes pulse-dot{0%,to{opacity:1}50%{opacity:.4}}.app-header .header-info{font-size:var(--text-xs);color:var(--text-3);letter-spacing:.04em}.sidenav{background:var(--surface-1);border-right:1px solid var(--border-1);width:180px;height:100vh;transition:width var(--ease);z-index:var(--z-sidenav);flex-direction:column;flex-shrink:0;display:flex;position:sticky;top:0;overflow:hidden}.sidenav.collapsed{width:52px}.sidenav-header{border-bottom:1px solid var(--border-1);flex-shrink:0;justify-content:space-between;align-items:center;height:52px;padding:0 8px 0 16px;display:flex}.sidenav-wordmark{font-size:var(--text-sm);font-family:var(--font-mono);letter-spacing:.2em;text-transform:uppercase;color:var(--accent);-webkit-user-select:none;user-select:none;white-space:nowrap;transition:opacity var(--ease-fast), width var(--ease-fast);overflow:hidden}.sidenav.collapsed .sidenav-wordmark{opacity:0;width:0;padding:0}.sidenav-toggle{color:var(--text-3);cursor:pointer;border-radius:var(--r-sm);transition:color var(--ease), background var(--ease);background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:5px;display:flex}.sidenav-toggle:hover{color:var(--text-1);background:var(--surface-2)}.sidenav.collapsed .sidenav-header{justify-content:center;padding:0 8px}.sidenav-items{flex-direction:column;flex:1;gap:2px;padding:10px 8px;display:flex;overflow:hidden}.sidenav-item{border-radius:var(--r-sm);font-size:var(--text-sm);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);transition:color var(--ease), background var(--ease), border-color var(--ease);-webkit-user-select:none;user-select:none;white-space:nowrap;border-left:3px solid #0000;align-items:center;gap:9px;padding:8px 10px;text-decoration:none;display:flex;position:relative;overflow:hidden}.sidenav-item:hover{color:var(--text-1);background:var(--surface-2)}.sidenav-item.active{color:var(--text-1);border-left-color:var(--accent);background:var(--accent-glow)}.item-icon{opacity:.7;flex-shrink:0;align-items:center;display:flex}.sidenav-item.active .item-icon{opacity:1}.item-label{transition:opacity var(--ease-fast)}.sidenav.collapsed .item-label{display:none}.sidenav.collapsed .sidenav-item{border-left:3px solid #0000;justify-content:center;gap:0;padding:8px}.sidenav.collapsed .sidenav-item.active{border-left-color:var(--accent)}.sidenav.collapsed .sidenav-item:after{content:attr(data-label);background:var(--surface-float);color:var(--text-1);font-size:var(--text-xs);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;border-radius:var(--r-sm);border:1px solid var(--border-2);white-space:nowrap;pointer-events:none;opacity:0;transition:opacity var(--ease-fast);z-index:var(--z-tooltip);padding:4px 8px;position:absolute;top:50%;left:calc(100% + 8px);transform:translateY(-50%)}.sidenav.collapsed .sidenav-item:hover:after{opacity:1}.sidenav-footer{border-top:1px solid var(--border-1);flex-shrink:0;padding:8px}.sidenav-data{font-size:var(--text-xs)}.update-banner{background:var(--bg-2);border:1px solid var(--border-1);font-family:var(--font-sans);border-radius:6px;margin-bottom:8px;padding:8px 10px}.update-banner-head{justify-content:space-between;align-items:center;gap:8px;display:flex}.update-banner-version{color:var(--text-1)}.update-banner-dismiss{color:var(--text-3);cursor:pointer;background:0 0;border:none;padding:0 4px;font-size:16px;line-height:1}.update-banner-dismiss:hover{color:var(--text-1)}.update-banner-body{color:var(--text-2,var(--text-1));margin:4px 0 6px}.update-banner-cmd{background:var(--bg-1);border:1px solid var(--border-1);color:var(--text-1);white-space:nowrap;border-radius:4px;margin-bottom:6px;padding:4px 6px;overflow-x:auto}.update-banner-actions{justify-content:space-between;align-items:center;gap:8px;display:flex}.update-banner-copy{background:var(--accent);color:var(--bg-1);cursor:pointer;font-family:var(--font-mono);font-size:var(--text-xs);border:none;border-radius:4px;padding:4px 8px}.update-banner-link{color:var(--text-3);text-underline-offset:2px;text-decoration:underline}.update-banner-link:hover{color:var(--text-1)}.update-banner-nudge{background:var(--bg-1);border-left:2px solid var(--accent);color:var(--text-2,var(--text-1));border-radius:3px;margin:8px 0 0;padding:6px 8px}.update-banner-nudge code{background:var(--bg-0,var(--bg-1));border-radius:3px;padding:1px 4px}.update-banner--collapsed{cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;width:100%;margin-bottom:8px;padding:6px 0;display:flex}.update-dot{color:var(--accent);font-size:14px;line-height:1;animation:2.6s ease-in-out infinite nlm-update-pulse}@keyframes nlm-update-pulse{0%,to{opacity:.45}50%{opacity:1}}.live-page{flex-direction:column;flex:1;min-height:0;display:flex}.live-status{padding:12px var(--page-x) 4px;align-items:center;gap:8px;display:flex}.live-status-dot{border-radius:50%;flex-shrink:0;width:7px;height:7px}.live-status-live{background:var(--accent);box-shadow:0 0 6px var(--accent)}.live-status-connecting{background:var(--text-3)}.live-status-reconnecting{background:var(--warn);animation:1.2s ease-in-out infinite pulse-dot}.live-status-label{font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;color:var(--text-2)}.live-board{padding:4px var(--page-x) 20px;flex:1;grid-template-columns:repeat(3,1fr);gap:16px;min-height:0;display:grid}.live-col{background:var(--surface-1);border:1px solid var(--border-2);border-radius:var(--r-md);flex-direction:column;min-height:0;display:flex;overflow:hidden}.live-col-head{border-bottom:1px solid var(--border-1);justify-content:space-between;align-items:baseline;padding:10px 14px;display:flex}.live-col-title{font-size:var(--text-sm);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--text-2)}.live-col-count{font-size:var(--text-xs);color:var(--text-3);font-family:var(--font-mono)}.live-col-body{flex:1;overflow:hidden auto}.live-row{border-bottom:1px solid var(--border-1);overflow-wrap:anywhere;min-width:0;padding:8px 14px;animation:.2s ease-out fadeSlideIn}.live-row .label,.live-row .body,.live-row .meta{overflow-wrap:anywhere;word-break:break-word;min-width:0}.live-row:last-child{border-bottom:none}.clickable:focus-visible,.bar-item-clickable:focus-visible,.kpi-clickable:focus-visible{outline:1px solid var(--accent);outline-offset:-1px}.clickable[aria-busy=true],.clickable.is-disabled,.bar-item-clickable[aria-busy=true],.bar-item-clickable.is-disabled{opacity:.5;pointer-events:none}.live-row.clickable{cursor:pointer;transition:background var(--ease)}.live-row.clickable:hover{background:var(--surface-2)}.live-row.is-new{animation:.2s ease-out fadeSlideIn,1.2s ease-out liveFlash}.live-row.is-related{background:var(--accent-glow);border-left:2px solid var(--accent);padding-left:12px}@keyframes liveFlash{0%{background:var(--accent-glow)}to{background:0 0}}.live-row .label{color:var(--text-1);font-size:var(--text-base);line-height:var(--lh-tight)}.live-row .body{color:var(--text-3);font-size:var(--text-sm);line-height:var(--lh-tight);margin-top:3px}.live-row .meta{color:var(--text-3);font-size:var(--text-xs);letter-spacing:.04em;margin-top:4px}.live-tag{font-size:var(--text-xs);font-family:var(--font-mono);letter-spacing:.06em;text-transform:uppercase;border-radius:var(--r-sm);background:var(--surface-2);color:var(--text-2);border:1px solid var(--border-2);margin-right:6px;padding:1px 6px;display:inline-block}.live-tag[data-kind=decision]{background:var(--accent-glow);color:var(--accent);border-color:#e8ff6e40}.live-tag[data-kind=open]{background:var(--warn-dim);color:var(--warn);border-color:#ff993340}.live-empty{text-align:center;color:var(--text-3);font-size:var(--text-xs);letter-spacing:.06em;text-transform:uppercase;padding:32px 16px}.stub-shell{padding:80px var(--page-x);text-align:center;color:var(--text-3);font-size:var(--text-base);line-height:var(--lh-loose)}.stub-shell .stub-name{color:var(--accent);font-size:var(--text-md);text-transform:lowercase;letter-spacing:.04em;margin-bottom:12px;display:block}.stub-shell .stub-hint{color:var(--text-4);font-size:var(--text-sm)}.page-pad{padding:20px var(--page-x) 60px;flex:1;min-width:0;min-height:0;overflow-y:auto}.page-title{font-size:var(--text-lg);font-family:var(--font-mono);color:var(--text-1);margin-bottom:16px;font-weight:500}.page-header{align-items:center;gap:24px;margin-bottom:24px;padding-top:8px;display:flex}.subnav+.page-header,.subnav+.page-title{gap:28px;margin-top:28px;margin-bottom:28px;padding-top:0}.page-header .page-title,.form-row.between .page-title{margin-bottom:0}.page-header .header-spacer,.thread-header .header-spacer,.river-toolbar .header-spacer{flex:1}.section-title{font-size:var(--text-sm);text-transform:uppercase;letter-spacing:.06em;color:var(--text-3);margin:24px 0 8px;font-weight:500}.muted{color:var(--text-3)}.muted.small{font-size:var(--text-xs);letter-spacing:.04em}.muted.error{color:var(--danger)}.right{text-align:right}.mono{font-family:var(--font-mono)}.small{font-size:var(--text-xs)}code,.code-block{font-family:var(--font-mono);font-size:var(--text-sm);background:var(--surface-2);border:1px solid var(--border-2);border-radius:var(--r-sm);color:var(--text-1);padding:2px 6px}.code-block{margin:8px 0;padding:10px 14px;display:block}.settings-grid{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;margin-top:16px;display:grid}.settings-card{color:var(--text-1);flex-direction:column;gap:6px;padding:14px;text-decoration:none;display:flex}.settings-card-title{font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;color:var(--accent);font-weight:500}.settings-card-body{color:var(--text-2);font-size:var(--text-sm)}.kv-list{grid-template-columns:max-content 1fr;gap:6px 16px;margin-top:12px;display:grid}.kv-label{color:var(--text-3);font-size:var(--text-sm);letter-spacing:.04em}.kv-value{color:var(--text-1);font-size:var(--text-sm)}.kv-value.mono{font-family:var(--font-mono);word-break:break-all}.form-grid{gap:12px;max-width:420px;margin-top:12px;display:grid}.form-field{flex-direction:column;gap:4px;display:flex}.form-label{font-size:var(--text-xs);color:var(--text-3);letter-spacing:.06em;text-transform:uppercase}.form-input{background:var(--surface-1);border:1px solid var(--border-2);color:var(--text-1);font-family:var(--font-mono);font-size:var(--text-sm);border-radius:var(--r-sm);transition:border-color var(--ease);padding:6px 10px}.form-input:hover:not(:disabled){border-color:var(--border-3)}.form-input:focus{border-color:var(--border-4);outline:none}.form-input:focus-visible{outline:1px solid var(--accent);outline-offset:-1px}.form-input:disabled,.form-input.is-disabled{opacity:.5;cursor:not-allowed}.form-input[aria-invalid=true],.form-input.is-invalid{border-color:var(--danger)}.form-input[aria-invalid=true]:focus-visible,.form-input.is-invalid:focus-visible{outline-color:var(--danger);border-color:var(--danger)}.form-error{color:var(--danger);font-size:var(--text-xs);margin:4px 0 0}.data-table{border-collapse:collapse;width:100%;font-size:var(--text-sm);margin-top:12px}.data-table th{text-align:left;font-weight:500;font-size:var(--text-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);border-bottom:1px solid var(--border-2);padding:8px 10px}.data-table th.right{text-align:right}.data-table td{border-bottom:1px solid var(--border-1);color:var(--text-1);vertical-align:middle;padding:7px 10px}.data-table tr:hover td{background:var(--surface-2)}.canonical .dot{vertical-align:middle;margin-right:8px}.topic-name{align-items:baseline;gap:8px;display:inline-flex}.topic-name .muted.small.mono{font-size:var(--text-xs);opacity:.7}.dot{border-radius:50%;flex-shrink:0;width:8px;height:8px;display:inline-block}.dot.lg{width:14px;height:14px}.chip-inline{border-radius:var(--r-sm);border:1px solid var(--border-2);background:var(--surface-2);color:var(--text-2);font-family:var(--font-mono);font-size:var(--text-xs);letter-spacing:.04em;text-transform:lowercase;align-items:center;gap:4px;padding:2px 8px;display:inline-flex}.chip-inline.status-active{color:var(--accent);background:var(--accent-glow);border-color:#e8ff6e40}.chip-inline.status-idle{color:#ffcc80;border-color:#ffcc8040}.chip-inline.status-closed{color:var(--text-2)}.chip-inline.status-superseded{color:var(--text-3);text-decoration:line-through}.chip-inline.status-replaced{color:var(--text-3)}.chip-inline.status-retired{color:var(--danger);background:var(--danger-dim);border-color:#ff6b3540}.chip-inline.status-stale{color:var(--warn);background:var(--warn-dim);border-color:#ff993340}.chip-inline.severity-high{color:var(--danger);background:var(--danger-dim);border-color:#ff6b3559}.chip-inline.severity-medium{color:var(--warn);background:var(--warn-dim);border-color:#ff993359}.chip-inline.severity-low{color:var(--text-2);border-color:var(--border-3);background:var(--surface-2)}.chip-x{color:inherit;cursor:pointer;background:0 0;border:none;padding:0 0 0 4px;font-size:12px;line-height:1}.kpi-row{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:18px;display:grid}.kpi{background:var(--surface-1);border:1px solid var(--border-2);border-radius:var(--r-md);flex-direction:column;gap:4px;padding:14px 16px;display:flex}.kpi-label{font-size:var(--text-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--text-3)}.kpi-value{font-size:var(--text-stat);font-family:var(--font-mono);color:var(--text-1);line-height:1}.kpi-hint{font-size:var(--text-xs);color:var(--text-3)}.kpi-sparkline{gap:8px}.sparkline{align-items:flex-end;gap:4px;height:40px;display:flex}.spark-bar{background:var(--accent);opacity:.7;border-radius:1px;flex:1;min-height:2px}.pulse-grid{grid-template:"coherence recent stale"1fr"runtimes recent stale"1fr/1fr 1fr 1fr;gap:12px;height:calc(100vh - 280px);min-height:360px;margin-top:6px;display:grid}.pulse-area-coherence{grid-area:coherence}.pulse-area-runtimes{grid-area:runtimes}.pulse-area-recent{grid-area:recent}.pulse-area-stale{grid-area:stale}.pulse-scroll-card{flex-direction:column;min-height:0;display:flex;overflow:hidden}.pulse-scroll-card .card-head{flex-shrink:0}.kpi,.pulse-grid>.card{transition:outline-color var(--ease), border-color var(--ease);outline-offset:-1px;outline:1px solid #0000}.kpi:hover{outline-color:#ffffff8c}.kpi-clickable{cursor:pointer;color:inherit;text-decoration:none}.kpi-clickable:hover .kpi-value{color:var(--accent)}.kpi-clickable:hover{border-color:var(--border-3)}.pulse-grid>.pulse-scroll-card:hover{outline-color:#ffffff8c}.pulse-scroll-body{flex:1;min-height:0;overflow:hidden auto}.card-head{border-bottom:1px solid var(--border-1);justify-content:space-between;align-items:baseline;padding:10px 14px;display:flex}.card-head h3{font-size:var(--text-sm);letter-spacing:.06em;text-transform:uppercase;color:var(--text-2);font-weight:500}.bar-stack{flex-direction:column;padding:4px 0;display:flex}.bar-item{border:0;border-bottom:1px solid var(--border-1);text-align:left;width:100%;color:inherit;font:inherit;background:0 0;grid-template-columns:80px 1fr auto;align-items:center;gap:10px;padding:8px 14px;display:grid}.bar-stack .bar-item:last-child{border-bottom:none}.bar-item-clickable{cursor:pointer;transition:background var(--ease)}.bar-item-clickable:hover{background:var(--surface-2)}.bar-item-clickable:hover .bar-label{color:var(--accent)}.bar-item[disabled]{cursor:default;opacity:.5}.bar-label{font-size:var(--text-sm);color:var(--text-2)}.bar-track{background:var(--surface-2);border-radius:4px;height:8px;overflow:hidden}.bar-fill{height:100%;transition:width var(--ease-slow)}.bar-fill.tone-active{background:var(--accent)}.bar-fill.tone-warn{background:var(--warn)}.bar-fill.tone-danger{background:var(--danger)}.bar-value{font-size:var(--text-sm);color:var(--text-1);text-align:right;white-space:nowrap;min-width:96px}.bar-pct{margin-left:2px}.recall-head{justify-content:space-between;align-items:flex-start;gap:24px;margin-bottom:20px;display:flex}.recall-note{max-width:60ch;margin:0;line-height:1.5}.recall-block{margin-bottom:28px}.recall-block-head{margin-bottom:14px}.recall-block-head .page-title{margin-bottom:2px}.recall-block-head p{max-width:70ch;margin:0}.recall-empty{font-size:var(--text-sm);padding:18px}.recall-cards{grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px;margin-top:14px;display:grid}.recall-bars .bar-item{grid-template-columns:140px 1fr auto}.recall-bar-label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.recall-bars .bar-value{min-width:0}@media (width<=720px){.recall-head{flex-direction:column;gap:12px}}.runtime-list{margin:0;padding:4px 0;list-style:none}.runtime-row{border-bottom:1px solid var(--border-1);grid-template-columns:12px 1fr auto auto;align-items:center;gap:10px;padding:8px 14px;display:grid}.runtime-row:last-child{border-bottom:none}.runtime-dot{background:var(--text-3);border-radius:50%;width:8px;height:8px;box-shadow:0 0 0 2px #ffffff0a}.runtime-dot.runtime-active{background:var(--accent);box-shadow:0 0 6px #e8ff6e99}.runtime-dot.runtime-idle{background:var(--warn)}.runtime-dot.runtime-dormant{background:var(--text-3);opacity:.5}.runtime-name{color:var(--text-1);font-size:var(--text-sm)}.runtime-counts{white-space:nowrap}.runtime-counts-sep{opacity:.5;margin:0 6px}.runtime-counts-prev{opacity:.7}.runtime-age{text-align:right;min-width:60px}.runtime-row.clickable{cursor:pointer;transition:background var(--ease)}.runtime-row.clickable:hover{background:var(--surface-2)}.runtime-row.clickable:hover .runtime-name{color:var(--accent)}.runtime-topics{flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:4px;display:flex}.alert-list{padding:4px 0;list-style:none}.alert-row{border-bottom:1px solid var(--border-1);grid-template-columns:auto auto 1fr;align-items:center;gap:10px;padding:7px 14px;display:grid}.alert-entity{color:var(--text-1);font-size:var(--text-sm);text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.alert-summary{-webkit-line-clamp:1;text-overflow:ellipsis;color:var(--text-3);font-size:var(--text-xs);letter-spacing:.04em;min-width:0;line-height:var(--lh-base);-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.alert-row.clickable{cursor:pointer;transition:background var(--ease)}.alert-row.clickable:hover{background:var(--surface-2)}.alert-row.clickable:hover .alert-entity{color:var(--accent)}.drawer-actions{flex-wrap:wrap;gap:6px;margin:14px 0 6px;display:flex}.session-list{list-style:none}.session-list.compact .session-row{border-bottom:1px solid var(--border-1);padding:6px 0}.session-row{border-bottom:1px solid var(--border-1);grid-template-columns:auto 1fr auto;align-items:center;gap:10px;padding:8px 14px;display:grid}.session-row-detail{grid-template-columns:auto 1fr auto}.session-row-main{flex-direction:column;gap:2px;min-width:0;display:flex}.session-label{color:var(--text-1);font-size:var(--text-sm);white-space:nowrap;text-overflow:ellipsis;text-decoration:none;overflow:hidden}a.session-label:hover{color:var(--accent)}.session-meta{color:var(--text-3);font-size:var(--text-xs);letter-spacing:.04em;-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}@media (width<=1100px){.pulse-grid{grid-template:"coherence runtimes""recent recent""stale stale"/1fr 1fr;height:auto;min-height:0}.pulse-scroll-body{max-height:360px}}@media (width<=700px){.pulse-grid{grid-template-columns:1fr;grid-template-areas:"coherence""runtimes""recent""stale"}}.search-bar{align-items:center;gap:10px;margin-bottom:12px;display:flex}.search-input.search-big{font-size:var(--text-md);flex:1;padding:10px 14px}.search-meta{margin:8px 0}.thread-header{align-items:center;gap:14px;margin-bottom:16px;display:flex}.thread-header .page-title{margin-bottom:0}.thread-grid{grid-template-columns:1fr 1fr;gap:12px;margin-bottom:18px;display:grid}.marker-list{max-height:360px;list-style:none;overflow-y:auto}.marker-row{border-bottom:1px solid var(--border-1);grid-template-columns:auto auto 1fr auto;align-items:baseline;gap:10px;padding:7px 14px;display:grid}.marker-text{color:var(--text-1);font-size:var(--text-sm);min-width:0}.marker-timestamp{font-variant-numeric:tabular-nums;white-space:nowrap}.marker-action-select{min-width:130px;font-size:var(--text-xs)}.marker-editor{align-items:center;gap:6px;display:inline-flex}.marker-editor-input{min-width:260px}.entity-grid{grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px;margin-top:16px;list-style:none;display:grid}.entity-card{color:var(--text-1);align-items:center;gap:8px;padding:10px 12px;text-decoration:none;display:flex}.entity-name{font-size:var(--text-sm);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}@media (width<=800px){.thread-grid{grid-template-columns:1fr}}.river-toolbar{align-items:center;gap:12px;margin-bottom:16px;display:flex}.river-toolbar .page-title{font-size:var(--text-lg);margin-bottom:0}.river-grid{--river-label-w:200px;--river-row-gap:3px;--river-cell-gap:2px;--river-cell-h:20px;gap:var(--river-row-gap);flex-direction:column;width:100%;padding:12px;display:flex}.river-grid.river-density-compact{--river-row-gap:1px;--river-cell-gap:1px;--river-cell-h:10px}.river-grid.river-density-spacious{--river-row-gap:6px;--river-cell-gap:4px;--river-cell-h:24px}.river-row{grid-template-columns:var(--river-label-w) 1fr;align-items:center;gap:6px;width:100%;min-width:0;display:grid}.river-row-dates{margin-bottom:2px}.river-lane-label{border-radius:var(--r-sm);color:var(--text-2);font-size:var(--text-sm);white-space:nowrap;align-items:center;gap:6px;width:100%;min-width:0;padding:2px 6px;text-decoration:none;display:flex;overflow:hidden}.river-lane-label:hover{background:var(--surface-2);color:var(--text-1)}.river-lane-label--header{background:0 0;padding:0}.river-lane-name{text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.river-cells{grid-template-columns:repeat(var(--cells,1), minmax(0, 1fr));gap:var(--river-cell-gap);width:100%;min-width:0;display:grid}.river-date-cell{font-size:var(--text-xs);color:var(--text-2);letter-spacing:.04em;text-align:center;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.river-cell{height:var(--river-cell-h);background:var(--surface-2);border-radius:2px;min-width:0}.river-cell.tier-1{background:#e8ff6e33}.river-cell.tier-2{background:#e8ff6e66}.river-cell.tier-3{background:#e8ff6ea6}.river-cell.tier-4{background:var(--accent)}.river-cell.has-corrections{box-shadow:inset 0 -2px #ffb400b3}.alert-row{grid-template-columns:auto minmax(0,max-content) minmax(0,1fr) auto}.alert-actions{align-items:center;gap:6px;display:flex}.alert-actions .chip{font-size:var(--text-xs);padding:2px 8px}.row-actions{gap:6px;display:flex}.row-actions .chip{font-size:var(--text-xs);padding:2px 8px}.row-busy{opacity:.5;pointer-events:none;transition:opacity var(--ease)}.form-input-inline{font-size:var(--text-xs);letter-spacing:.04em;padding:3px 8px}.river-grid{-webkit-user-select:none;user-select:none;position:relative}.river-drag-rect{background:var(--accent-glow);border-left:1px dashed var(--accent);border-right:1px dashed var(--accent);pointer-events:none;z-index:var(--z-raised);position:absolute;top:0;bottom:0}.river-lane-label{text-align:left;cursor:pointer;font-family:var(--font-mono);background:0 0;border:none}.river-cell{transition:outline-color var(--ease);outline-offset:1px;z-index:var(--z-base);outline:1px solid #0000;position:relative}.river-cell:hover{z-index:var(--z-raised);outline-color:#ffffffb3}.river-hover{background:var(--surface-float);border:1px solid var(--border-3);border-radius:var(--r-sm);font-size:var(--text-xs);pointer-events:none;z-index:var(--z-tooltip);align-items:center;gap:8px;padding:6px 10px;display:flex;position:fixed;box-shadow:0 6px 20px #00000080}.river-hover-name{color:var(--text-1);font-size:var(--text-sm)}.session-row.clickable{cursor:pointer;transition:background var(--ease)}.session-row.clickable:hover{background:var(--surface-2)}.session-row.clickable:hover .session-label{color:var(--accent)}.session-row-end{align-items:center;gap:8px;display:flex}.session-row.is-replaced{opacity:.55}.earlier-versions-list{border-left:2px solid var(--border-2);margin-left:28px;list-style:none}.earlier-versions-list .session-row{padding-left:10px}.link-button{color:var(--text-3);font-family:var(--font-mono);font-size:var(--text-xs);cursor:pointer;letter-spacing:.04em;background:0 0;border:none;padding:0}.link-button:hover{color:var(--accent)}.drawer-backdrop{z-index:var(--z-drawer-bg);background:#0000008c;animation:.15s fadeIn;position:fixed;inset:0}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.session-drawer{background:var(--surface-1);border-left:1px solid var(--border-3);width:min(560px,100vw);z-index:var(--z-drawer);flex-direction:column;animation:.18s slideInRight;display:flex;position:fixed;top:0;bottom:0;right:0;box-shadow:-16px 0 40px #0000008c}.coherence-drawer{width:min(480px,100vw)}@keyframes slideInRight{0%{opacity:0;transform:translate(20px)}to{opacity:1;transform:translate(0)}}.drawer-head{border-bottom:1px solid var(--border-1);align-items:center;gap:10px;padding:14px 18px;display:flex}.drawer-title{font-size:var(--text-md);font-family:var(--font-mono);color:var(--text-1);text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:500;overflow:hidden}.drawer-close{color:var(--text-3);cursor:pointer;background:0 0;border:none;padding:0 6px;font-size:24px;line-height:1}.drawer-close:hover{color:var(--text-1)}.drawer-body{flex:1;min-height:0;padding:16px 18px 80px;overflow-y:auto}.drawer-paragraph.drawer-hint{color:var(--text-2);margin:0 0 16px}.coherence-session-list .session-row{transition:background var(--ease);grid-template-columns:auto 1fr auto auto}.coherence-session-list .coherence-meta{white-space:nowrap}.coherence-session-list .session-row{cursor:pointer}.coherence-session-list .session-row:hover{background:var(--surface-2)}.coherence-session-list .session-row:hover .session-label{color:var(--accent)}.coherence-session-list .session-row[aria-busy=true]{opacity:.5;pointer-events:none}.coherence-session-list .chip[data-bucket=active].active{color:var(--accent);background:var(--accent-glow);border-color:#e8ff6e4d}.coherence-session-list .chip[data-bucket=sparse].active{color:var(--warn);background:var(--warn-dim);border-color:#ff993359}.coherence-session-list .chip[data-bucket=stale].active{color:var(--danger);background:var(--danger-dim);border-color:#ff6b3566}.coherence-drawer .drawer-body{flex-direction:column;padding-bottom:0;display:flex;overflow:hidden}.coherence-session-list{flex:1;min-height:0;overflow-y:auto}.coherence-drawer .pagination{border-top:1px solid var(--border-1);flex-shrink:0;margin-top:0}.coherence-drawer .pagination.pagination-compact{padding:10px 18px}.merge-picker{background:var(--surface-2);border:1px solid var(--border-2);border-radius:6px;margin-bottom:12px;padding:12px}.merge-result-list{max-height:240px;margin:8px 0 0;padding:0;list-style:none;overflow-y:auto}.merge-result-row{cursor:pointer;border-radius:4px;align-items:center;gap:8px;padding:6px 8px;display:flex}.merge-result-row:hover{background:var(--surface-float)}.merge-result-row.is-selected{outline:2px solid var(--accent);outline-offset:-2px;background:var(--surface-float)}.coherence-rows-dimmed{opacity:.4;pointer-events:none}.coherence-filters{flex-direction:column;gap:8px;margin-bottom:12px;display:flex}.coherence-search{width:100%}.coherence-filter-row{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.drawer-section{font-size:var(--text-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);margin:18px 0 8px;font-weight:500}.drawer-list{font-size:var(--text-sm);color:var(--text-1);flex-direction:column;gap:8px;list-style:none;display:flex}.drawer-list li{align-items:baseline;gap:8px;display:flex}.drawer-paragraph{font-size:var(--text-sm);color:var(--text-1);line-height:var(--lh-loose)}.drawer-body-text{background:var(--surface-0);border:1px solid var(--border-1);border-radius:var(--r-sm);font-size:var(--text-xs);color:var(--text-2);white-space:pre-wrap;word-break:break-word;max-height:360px;line-height:var(--lh-base);padding:10px 12px;overflow-y:auto}.entity-chips{flex-wrap:wrap;gap:6px;display:flex}.entity-chips-row{align-items:center;margin-top:4px}.supersedence-banner{border-radius:var(--r-sm);font-size:var(--text-sm);flex-wrap:wrap;align-items:baseline;gap:6px;margin-bottom:10px;padding:8px 12px;display:flex}.supersedence-banner--superseded{color:var(--danger);background:#ff6b3514;border:1px solid #ff6b3540}.supersedence-banner--supersedes{border:1px solid var(--border-2);color:var(--text-2);background:#a8a8a80f}.supersedence-label{white-space:nowrap;font-weight:500}.supersedence-ids{flex-wrap:wrap;gap:4px;display:flex}.supersedence-id{color:inherit;opacity:.8}.supersedence-link{cursor:pointer;font-family:var(--font-mono);font-size:var(--text-xs);color:inherit;text-underline-offset:2px;background:0 0;border:none;padding:0;text-decoration:underline}.supersedence-link:hover{opacity:.75}.drawer-menu{position:relative}.drawer-menu-trigger{color:var(--text-3);font-size:var(--text-lg);cursor:pointer;background:0 0;border:none;border-radius:4px;padding:4px 8px;line-height:1}.drawer-menu-trigger:hover{color:var(--text-1);background:var(--bg-2)}.drawer-menu-trigger:disabled{opacity:.4;cursor:not-allowed}.drawer-menu-list{z-index:var(--z-dropdown);background:var(--bg-1);border:1px solid var(--border-1);border-radius:6px;min-width:200px;margin:0;padding:4px;list-style:none;position:absolute;top:calc(100% + 4px);right:0;box-shadow:0 6px 20px #00000059}.drawer-menu-item{text-align:left;width:100%;color:var(--text-1);font-family:var(--font-sans);font-size:var(--text-sm);cursor:pointer;background:0 0;border:none;border-radius:4px;padding:8px 10px;display:block}.drawer-menu-item:hover:not(:disabled){background:var(--bg-2)}.drawer-menu-item:disabled{opacity:.4;cursor:not-allowed}.palette-backdrop{z-index:var(--z-palette-bg);background:#0000008c;position:fixed;inset:0}.supersede-palette{background:var(--bg-1);border:1px solid var(--border-1);width:min(640px,92vw);max-height:76vh;z-index:var(--z-palette);border-radius:8px;flex-direction:column;display:flex;position:fixed;top:12vh;left:50%;transform:translate(-50%);box-shadow:0 24px 60px #00000073}.palette-head{border-bottom:1px solid var(--border-1);align-items:center;gap:10px;padding:12px 16px;display:flex}.palette-title{font-family:var(--font-mono);font-size:var(--text-md);color:var(--text-1);flex:1}.palette-body{flex-direction:column;flex:1;gap:12px;padding:14px 16px;display:flex;overflow-y:auto}.palette-context{background:var(--bg-2);border-left:2px solid var(--border-2);border-radius:4px;grid-template-columns:auto 1fr;gap:4px 10px;padding:10px 12px;display:grid}.palette-context-label{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-3);text-transform:uppercase;letter-spacing:.04em}.palette-context-value{color:var(--text-1);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.palette-context-id{color:var(--text-3);grid-column:2}.palette-field-label{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-3);text-transform:uppercase;letter-spacing:.04em}.palette-input{box-sizing:border-box;background:var(--bg-2);border:1px solid var(--border-1);width:100%;color:var(--text-1);font-size:var(--text-sm);border-radius:4px;padding:8px 10px}.palette-input:focus{border-color:var(--accent);outline:none}.palette-list{border:1px solid var(--border-1);border-radius:4px;max-height:280px;margin:0;padding:0;list-style:none;overflow-y:auto}.palette-row{cursor:pointer;border-bottom:1px solid var(--border-1);grid-template-columns:80px 110px minmax(0,1fr) minmax(80px,160px);align-items:center;gap:10px;padding:6px 10px;display:grid}.palette-row-id{text-overflow:ellipsis;white-space:nowrap;text-align:right;overflow:hidden}.palette-row:last-child{border-bottom:none}.palette-row--hot{background:var(--bg-2)}.palette-row:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.palette-row[aria-selected=true] .palette-row-date,.palette-row[aria-selected=true] .palette-row-runtime,.palette-row[aria-selected=true] .palette-row-id{color:var(--text-2,var(--text-1))}.palette-row-label{color:var(--text-1);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.palette-empty{text-align:center;padding:10px}.palette-pick{background:var(--bg-2);border-left:2px solid var(--accent);border-radius:4px;grid-template-columns:auto 1fr auto;gap:4px 10px;padding:10px 12px;display:grid}.palette-pick .palette-context-id{grid-column:2/3}.palette-undo{border:1px solid var(--border-1);color:var(--text-3);cursor:pointer;font-size:var(--text-xs);background:0 0;border-radius:4px;grid-area:1/3/span 2;align-self:center;padding:4px 8px}.palette-undo:hover:not(:disabled){color:var(--text-1);border-color:var(--border-2)}.palette-error{color:#f0a0a0;font-size:var(--text-sm);background:#dc50501f;border:1px solid #dc505059;border-radius:4px;padding:8px 10px}.palette-foot{border-top:1px solid var(--border-1);justify-content:space-between;align-items:center;gap:12px;padding:10px 16px;display:flex}.palette-hint{font-family:var(--font-mono)}.palette-confirm{background:var(--accent);color:var(--bg-1);cursor:pointer;font-family:var(--font-mono);font-size:var(--text-sm);border:none;border-radius:4px;padding:8px 14px}.palette-confirm:disabled{opacity:.4;cursor:not-allowed}.card-head.card-head-stack{flex-direction:column;align-items:stretch;gap:8px;padding:10px 14px 12px}.card-head-row{justify-content:space-between;align-items:baseline;display:flex}.card-filters{flex-wrap:wrap;gap:12px;display:flex}.filter-group{gap:4px;display:flex}.filter-group .chip{font-size:var(--text-xs);padding:2px 8px}.thread-sessions-head{align-items:center;gap:12px;margin:24px 0 8px;display:flex}.thread-sessions-title{flex-shrink:0;margin:0}.thread-sessions-head .search-input{flex:1}.thread-filters{flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:8px;display:flex}.thread-filters .filter-group{flex-wrap:wrap}.pagination{border-top:1px solid var(--border-1);flex-wrap:wrap;align-items:center;gap:16px;margin-top:4px;padding:14px 0 4px;display:flex}.page-size{align-items:center;gap:8px;display:flex}.page-nav{align-items:center;gap:4px;display:flex}.page-nav .chip:disabled{opacity:.4;cursor:not-allowed}.page-indicator{font-size:var(--text-sm);color:var(--text-2);text-align:center;min-width:60px;padding:0 8px}.marker-row-promotable{grid-template-columns:auto 1fr auto auto;align-items:baseline;gap:10px;display:grid}.marker-row-promotable .marker-actions{align-items:baseline;gap:6px;display:flex}.promote-chip{font-size:var(--text-xs);color:var(--accent);background:var(--accent-glow);border-color:#e8ff6e4d;padding:2px 8px}.promote-chip:hover{color:var(--accent);background:var(--accent-dim);border-color:#e8ff6e8c}.promote-editor{align-items:center;gap:6px;min-width:280px;display:flex}.promote-input{flex:1;min-width:200px}.pagination.pagination-compact{font-size:var(--text-xs);flex-wrap:wrap;gap:10px;padding:10px 0 4px}.pagination.pagination-compact .page-indicator{min-width:40px;font-size:var(--text-xs);padding:0 4px}.pagination.pagination-compact .chip{font-size:var(--text-xs);padding:1px 6px}.pagination.pagination-compact .form-label{font-size:9px}.river-date-cell--month-start{border-left:1px solid var(--border-2);padding-left:3px}.river-legend{align-items:center;gap:3px;display:flex}.river-legend-cell{background:var(--surface-2);border-radius:2px;width:12px;height:12px}.river-legend-cell.tier-1{background:#e8ff6e33}.river-legend-cell.tier-2{background:#e8ff6e66}.river-legend-cell.tier-3{background:#e8ff6ea6}.river-legend-cell.tier-4{background:var(--accent)}.empty-row{color:var(--text-2);font-size:var(--text-sm);padding:16px 14px}.list-action-row{padding:8px 14px}.toast-host{z-index:var(--z-toast);pointer-events:none;flex-direction:column;gap:8px;max-width:min(420px,100vw - 48px);display:flex;position:fixed;bottom:24px;right:24px}.toast{background:var(--surface-float);border:1px solid var(--border-3);border-left:3px solid var(--text-2);border-radius:var(--r-md);font-size:var(--text-sm);color:var(--text-1);pointer-events:auto;align-items:flex-start;gap:8px;padding:10px 12px;animation:.2s ease-out fadeSlideIn;display:flex;box-shadow:0 12px 32px #00000073}.toast-success{border-left-color:var(--accent)}.toast-error{border-left-color:var(--danger)}.toast-info{border-left-color:var(--text-2)}.toast-message{line-height:var(--lh-base);flex:1}.toast-close{color:var(--text-3);cursor:pointer;font-size:var(--text-lg);background:0 0;border:0;margin-top:-2px;padding:0 2px;line-height:1}.toast-close:hover{color:var(--text-1)}.tooltip-anchor{display:inline-flex;position:relative}.tooltip{background:var(--surface-float);color:var(--text-1);border:1px solid var(--border-3);border-radius:var(--r-sm);font-size:var(--text-xs);font-family:var(--font-mono);letter-spacing:.04em;text-align:center;pointer-events:none;opacity:0;width:max-content;max-width:240px;transition:opacity var(--ease-fast), transform var(--ease-fast);z-index:var(--z-tooltip);padding:4px 8px;position:absolute;left:50%;transform:translate(-50%)translateY(-4px)}.tooltip-top .tooltip{margin-bottom:4px;bottom:100%}.tooltip-bottom .tooltip{margin-top:4px;top:100%}.tooltip-anchor:hover .tooltip,.tooltip-anchor:focus-within .tooltip{opacity:1;transform:translate(-50%)translateY(0)}.confirm-dialog{background:var(--surface-float);border:1px solid var(--border-3);border-radius:var(--r-md);width:min(440px,92vw);z-index:var(--z-palette);padding:20px 22px 16px;animation:.2s ease-out fadeSlideIn;position:fixed;top:22vh;left:50%;transform:translate(-50%);box-shadow:0 24px 60px #0000008c}.confirm-title{font-family:var(--font-mono);font-size:var(--text-base);color:var(--text-1);letter-spacing:.04em;margin:0 0 8px}.confirm-message{color:var(--text-2);font-size:var(--text-sm);line-height:var(--lh-base);margin:0 0 16px}.confirm-actions{justify-content:flex-end;gap:8px;display:flex}.session-meta{-webkit-line-clamp:2;line-clamp:2;white-space:normal;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.search-wrap{align-items:center;display:flex;position:relative}.search-wrap .search-input{width:100%;padding-right:28px}.search-clear{color:var(--text-3);cursor:pointer;background:0 0;border:none;align-items:center;padding:0;display:flex;position:absolute;right:6px}.search-clear:hover{color:var(--text-1)}.drawer-nav{flex-shrink:0;align-items:center;gap:4px;display:flex}.drawer-nav-btn{border:1px solid var(--border-2);color:var(--text-3);cursor:pointer;border-radius:var(--r-sm);transition:color var(--ease), border-color var(--ease), background var(--ease);background:0 0;justify-content:center;align-items:center;padding:3px;display:flex}.drawer-nav-btn:hover:not(:disabled){color:var(--text-1);border-color:var(--border-3);background:var(--surface-2)}.drawer-nav-btn:disabled{opacity:.35;cursor:not-allowed}.dot-pulse{animation:2s ease-in-out infinite dot-pulse}@keyframes dot-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.6;transform:scale(1.35)}}.search-hint{margin:8px 0 12px}.search-header{z-index:var(--z-sticky);background:var(--surface-0);border-bottom:1px solid var(--border-1);margin-bottom:16px;padding-bottom:12px;position:sticky;top:0}.session-row.is-selected{background:var(--surface-2);border-left:2px solid var(--accent);padding-left:12px}.live-tag[data-kind=summary]{background:var(--surface-2);color:var(--text-2)}.live-tag[data-kind=label]{background:var(--surface-2);color:var(--text-1)}.live-tag[data-kind=entity]{background:var(--accent-glow);color:var(--accent);border-color:#e8ff6e40}.match-snippet{color:var(--text-2);font-size:var(--text-xs);line-height:var(--lh-base);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin-top:4px;display:-webkit-box;overflow:hidden}.match-snippet mark{color:var(--accent);background:#e8ff6e26;border-radius:2px;padding:0 2px}.empty-row-full-width{grid-column:1/-1}.section-title-xs{font-size:.875rem}.merge-picker p{margin-bottom:8px}.merge-picker .filter-group{margin-top:8px}.river-row-skeleton{margin-bottom:3px}.river-card-skeleton{padding:12px}.search-wrap-full{flex:1}.thread-filters-wrap{flex-wrap:wrap}.search-meta-clear{margin-left:8px}.session-meta-entity{margin-right:4px}.session-row-end-col{flex-direction:column;align-items:flex-end;gap:4px;display:flex}.thread-sessions-head-mt{margin-top:16px}.search-wrap-compact{max-width:320px}.skeleton-display-contents{display:contents}.skeleton-column-gap{flex-direction:column;gap:8px;display:flex}.card-accent{border-color:var(--accent);margin-top:1rem;padding:1rem}.card-accent-padded{padding:.5rem;overflow:auto}.section-title-no-mt{margin-top:0}.card-wide-input input{min-width:28rem}.card-data-validated{border-color:var(--accent);margin-top:.75rem;padding:.75rem 1rem}.data-validated-text{margin:0}
|
package/dist/ui/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>nlm memory</title>
|
|
7
|
-
<script type="module" crossorigin src="/ui/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/ui/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/ui/assets/index-CVo7KKw2.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/ui/assets/index-DCuQrzJH.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
-- Migration 021: code_exemplars — code-exemplar recall lane.
|
|
2
|
+
--
|
|
3
|
+
-- Sibling to signals: stores concrete code chunks with deterministic outcome
|
|
4
|
+
-- labels so agents can pull "what code passed/failed a gate like this" at
|
|
5
|
+
-- implementation time. Append-only on id, no supersedence, no LLM in the
|
|
6
|
+
-- labeling loop (outcome comes from git-survival + test exit code).
|
|
7
|
+
--
|
|
8
|
+
-- Gated behind NLM_CODE_EXEMPLARS_ENABLED=1 (default off). The tables are
|
|
9
|
+
-- created unconditionally so migrations stay idempotent; the feature flag
|
|
10
|
+
-- controls ingest and retrieval paths in the application layer.
|
|
11
|
+
|
|
12
|
+
CREATE TABLE IF NOT EXISTS code_exemplars (
|
|
13
|
+
id TEXT PRIMARY KEY, -- sha256(install_scope|repo|code_hash|outcome)[:16]
|
|
14
|
+
install_scope TEXT NOT NULL,
|
|
15
|
+
signal_id TEXT, -- soft link to signals.id (may be null)
|
|
16
|
+
session_id TEXT, -- soft link to the originating session
|
|
17
|
+
repo TEXT NOT NULL,
|
|
18
|
+
model TEXT NOT NULL, -- model that produced the code (any vendor)
|
|
19
|
+
lang TEXT, -- detected language (ts, py, go, ...)
|
|
20
|
+
task_context TEXT NOT NULL, -- one/two lines: what this code was for
|
|
21
|
+
code TEXT NOT NULL, -- the chunk (hunk / function / file slice)
|
|
22
|
+
code_hash TEXT NOT NULL, -- sha256 of normalised code, for dedup
|
|
23
|
+
outcome TEXT NOT NULL CHECK (outcome IN ('pass','fail','fix','exhausted')),
|
|
24
|
+
git_sha TEXT, -- commit the chunk landed in, if known
|
|
25
|
+
survived INTEGER, -- nullable; lazily filled (1=lived, 0=reverted)
|
|
26
|
+
ts TEXT NOT NULL,
|
|
27
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
-- Aggregation / recall hot path: scope + repo + outcome-class filter.
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_exemplars_scope_repo
|
|
32
|
+
ON code_exemplars(install_scope, repo, outcome);
|
|
33
|
+
|
|
34
|
+
-- Retention prune: cap-eviction scan and optional clock-based prune.
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_exemplars_ts
|
|
36
|
+
ON code_exemplars(ts);
|
|
37
|
+
|
|
38
|
+
-- Dedup check: same code_hash in the same scope is a no-op on insert.
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_exemplars_code_hash
|
|
40
|
+
ON code_exemplars(install_scope, code_hash);
|
|
41
|
+
|
|
42
|
+
-- Vector lane for semantic code search. 768 dims matches CodeRankEmbed-137M
|
|
43
|
+
-- (same width as nomic-embed-text, different space — lanes never share).
|
|
44
|
+
-- Graceful degradation: if no code embedder is configured, exemplars still
|
|
45
|
+
-- land in code_exemplars; only the semantic search path is unavailable.
|
|
46
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS code_exemplars_vec USING vec0(
|
|
47
|
+
exemplar_id TEXT PRIMARY KEY,
|
|
48
|
+
embedding float[768]
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
INSERT OR IGNORE INTO schema_migrations (version, name) VALUES (21, '021_code_exemplars');
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-- Migration 022: facts.retired_at — operator retirement of incorrect facts.
|
|
2
|
+
--
|
|
3
|
+
-- Before this, `supersede_fact` / `mark_superseded` (MCP) called
|
|
4
|
+
-- markSuperseded(id, null), which set superseded_by = NULL — a no-op, since
|
|
5
|
+
-- active facts already have superseded_by IS NULL. Retired facts kept serving
|
|
6
|
+
-- in recall (NLM #326). Retirement-without-a-successor was structurally
|
|
7
|
+
-- impossible because supersededness is encoded ONLY by a non-null successor
|
|
8
|
+
-- id (and invariant I5b requires that id to reference a real fact).
|
|
9
|
+
--
|
|
10
|
+
-- retired_at is a distinct nullable marker: a non-null timestamp means an
|
|
11
|
+
-- operator declared the fact wrong/noise. Recall excludes retired facts the
|
|
12
|
+
-- same way it excludes superseded ones; getHistory and includeSuperseded
|
|
13
|
+
-- still surface them so the audit trail survives.
|
|
14
|
+
|
|
15
|
+
ALTER TABLE facts ADD COLUMN retired_at TEXT;
|
|
16
|
+
|
|
17
|
+
INSERT OR IGNORE INTO schema_migrations (version, name) VALUES (22, '022_facts_retired_at');
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
-- PG parity for SQLite migration 021: code_exemplars lane.
|
|
2
|
+
--
|
|
3
|
+
-- Mirrors migrations/021_code_exemplars.sql. Uses pgvector `vector(768)`
|
|
4
|
+
-- instead of sqlite-vec `vec0`. Applied manually by an operator.
|
|
5
|
+
|
|
6
|
+
BEGIN;
|
|
7
|
+
|
|
8
|
+
CREATE TABLE IF NOT EXISTS code_exemplars (
|
|
9
|
+
id TEXT PRIMARY KEY,
|
|
10
|
+
install_scope TEXT NOT NULL,
|
|
11
|
+
signal_id TEXT,
|
|
12
|
+
session_id TEXT,
|
|
13
|
+
repo TEXT NOT NULL,
|
|
14
|
+
model TEXT NOT NULL,
|
|
15
|
+
lang TEXT,
|
|
16
|
+
task_context TEXT NOT NULL,
|
|
17
|
+
code TEXT NOT NULL,
|
|
18
|
+
code_hash TEXT NOT NULL,
|
|
19
|
+
outcome TEXT NOT NULL CHECK (outcome IN ('pass','fail','fix','exhausted')),
|
|
20
|
+
git_sha TEXT,
|
|
21
|
+
survived SMALLINT,
|
|
22
|
+
ts TEXT NOT NULL,
|
|
23
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
CREATE INDEX IF NOT EXISTS idx_exemplars_scope_repo
|
|
27
|
+
ON code_exemplars(install_scope, repo, outcome);
|
|
28
|
+
|
|
29
|
+
CREATE INDEX IF NOT EXISTS idx_exemplars_ts
|
|
30
|
+
ON code_exemplars(ts);
|
|
31
|
+
|
|
32
|
+
CREATE INDEX IF NOT EXISTS idx_exemplars_code_hash
|
|
33
|
+
ON code_exemplars(install_scope, code_hash);
|
|
34
|
+
|
|
35
|
+
-- Vector lane. 768 dims matches CodeRankEmbed-137M output.
|
|
36
|
+
CREATE TABLE IF NOT EXISTS code_exemplars_vec (
|
|
37
|
+
exemplar_id TEXT PRIMARY KEY,
|
|
38
|
+
embedding vector(768) NOT NULL
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CREATE INDEX IF NOT EXISTS code_exemplars_vec_embedding_idx
|
|
42
|
+
ON code_exemplars_vec USING ivfflat (embedding vector_l2_ops)
|
|
43
|
+
WITH (lists = 10);
|
|
44
|
+
|
|
45
|
+
COMMIT;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- PG parity for SQLite migration 022: facts.retired_at.
|
|
2
|
+
--
|
|
3
|
+
-- Mirrors migrations/022_facts_retired_at.sql. Distinct nullable marker for
|
|
4
|
+
-- operator retirement of incorrect facts (NLM #326). Recall excludes retired
|
|
5
|
+
-- facts; getHistory / includeSuperseded still surface them. Applied manually
|
|
6
|
+
-- by an operator.
|
|
7
|
+
|
|
8
|
+
BEGIN;
|
|
9
|
+
|
|
10
|
+
ALTER TABLE facts ADD COLUMN IF NOT EXISTS retired_at TEXT;
|
|
11
|
+
|
|
12
|
+
COMMIT;
|
package/nlm/index.js
CHANGED
|
@@ -339,6 +339,10 @@ var SCORE_THRESHOLD = 0;
|
|
|
339
339
|
var PER_FIRE_CAP = 3;
|
|
340
340
|
var PER_CONVERSATION_CAP = 10;
|
|
341
341
|
var PROMPT_PREVIEW_CHARS = 200;
|
|
342
|
+
function hookRuntimeFromEnv(env = process.env) {
|
|
343
|
+
const raw = env["NLM_HOOK_RUNTIME"]?.trim();
|
|
344
|
+
return raw ? raw : "claude-code";
|
|
345
|
+
}
|
|
342
346
|
function normalizeRecall(raw) {
|
|
343
347
|
if (Array.isArray(raw)) return { hits: raw, facts: [] };
|
|
344
348
|
return raw;
|
|
@@ -410,9 +414,10 @@ async function main() {
|
|
|
410
414
|
const conversationId = typeof payload.session_id === "string" ? payload.session_id : "unknown";
|
|
411
415
|
if (!prompt) return;
|
|
412
416
|
const mode = process.env["NLM_HOOK_MODE"] === "live" ? "live" : "shadow";
|
|
417
|
+
const runtime = hookRuntimeFromEnv();
|
|
413
418
|
const out = await runHook(
|
|
414
419
|
{ prompt, conversationId },
|
|
415
|
-
{ mode, recall: (q) => recallOverHttp(q,
|
|
420
|
+
{ mode, recall: (q) => recallOverHttp(q, runtime, conversationId === "unknown" ? void 0 : conversationId) }
|
|
416
421
|
);
|
|
417
422
|
if (out) process.stdout.write(out);
|
|
418
423
|
} catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nlm-memory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Local-first non-linear memory operating system for AI operators.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
"bench:longmemeval": "tsx scripts/longmemeval/run-harness.ts",
|
|
57
57
|
"bench:classifier": "tsx scripts/longmemeval/run-harness.ts --classifier",
|
|
58
58
|
"bench:compare": "tsx scripts/longmemeval/compare-classifiers.ts",
|
|
59
|
-
"eval:signals": "tsx scripts/eval/signals-eval.ts"
|
|
59
|
+
"eval:signals": "tsx scripts/eval/signals-eval.ts",
|
|
60
|
+
"eval:classifier": "tsx scripts/eval/classifier-eval.ts"
|
|
60
61
|
},
|
|
61
62
|
"dependencies": {
|
|
62
63
|
"@clack/prompts": "^1.4.0",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nlm-memory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Local-first persistent memory for AI coding agents. Recalls relevant prior sessions on every prompt; learns which sessions actually get cited. Owner-edited timeline beats append-only memory layers.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Edward Chalupa",
|
|
7
7
|
"url": "https://github.com/pbmagnet4"
|
|
8
8
|
},
|
|
9
|
-
"license": "
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
10
|
"homepage": "https://github.com/pbmagnet4/nlm-memory",
|
|
11
11
|
"repository": "https://github.com/pbmagnet4/nlm-memory",
|
|
12
12
|
"keywords": [
|
package/plugin/hooks/hooks.json
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "NLM_HOOK_RUNTIME=codex node \"${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/scripts/session-start-hook.mjs\"",
|
|
9
|
+
"statusMessage": "nlm-memory: cold-start recall"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
],
|
|
3
14
|
"UserPromptSubmit": [
|
|
4
15
|
{
|
|
5
16
|
"hooks": [
|
|
6
17
|
{
|
|
7
18
|
"type": "command",
|
|
8
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/prompt-recall-hook.mjs\"",
|
|
19
|
+
"command": "NLM_HOOK_RUNTIME=codex node \"${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/scripts/prompt-recall-hook.mjs\"",
|
|
9
20
|
"statusMessage": "nlm-memory: recalling prior sessions"
|
|
10
21
|
}
|
|
11
22
|
]
|
|
@@ -16,7 +27,7 @@
|
|
|
16
27
|
"hooks": [
|
|
17
28
|
{
|
|
18
29
|
"type": "command",
|
|
19
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/stop-hook.mjs\""
|
|
30
|
+
"command": "NLM_HOOK_RUNTIME=codex node \"${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/scripts/stop-hook.mjs\""
|
|
20
31
|
}
|
|
21
32
|
]
|
|
22
33
|
}
|
|
@@ -341,6 +341,10 @@ var SCORE_THRESHOLD = 0;
|
|
|
341
341
|
var PER_FIRE_CAP = 3;
|
|
342
342
|
var PER_CONVERSATION_CAP = 10;
|
|
343
343
|
var PROMPT_PREVIEW_CHARS = 200;
|
|
344
|
+
function hookRuntimeFromEnv(env = process.env) {
|
|
345
|
+
const raw = env["NLM_HOOK_RUNTIME"]?.trim();
|
|
346
|
+
return raw ? raw : "claude-code";
|
|
347
|
+
}
|
|
344
348
|
function normalizeRecall(raw) {
|
|
345
349
|
if (Array.isArray(raw)) return { hits: raw, facts: [] };
|
|
346
350
|
return raw;
|
|
@@ -412,9 +416,10 @@ async function main() {
|
|
|
412
416
|
const conversationId = typeof payload.session_id === "string" ? payload.session_id : "unknown";
|
|
413
417
|
if (!prompt) return;
|
|
414
418
|
const mode = process.env["NLM_HOOK_MODE"] === "live" ? "live" : "shadow";
|
|
419
|
+
const runtime = hookRuntimeFromEnv();
|
|
415
420
|
const out = await runHook(
|
|
416
421
|
{ prompt, conversationId },
|
|
417
|
-
{ mode, recall: (q) => recallOverHttp(q,
|
|
422
|
+
{ mode, recall: (q) => recallOverHttp(q, runtime, conversationId === "unknown" ? void 0 : conversationId) }
|
|
418
423
|
);
|
|
419
424
|
if (out) process.stdout.write(out);
|
|
420
425
|
} catch {
|
|
@@ -424,5 +429,6 @@ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href)
|
|
|
424
429
|
void main();
|
|
425
430
|
}
|
|
426
431
|
export {
|
|
432
|
+
hookRuntimeFromEnv,
|
|
427
433
|
runHook
|
|
428
434
|
};
|