@shahmilsaari/memory-core 1.0.31 → 1.0.33
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/dist/{chunk-KNZ3JNHE.js → chunk-23GUWJ6F.js} +1 -1
- package/dist/{chunk-4ZSVQMI7.js → chunk-GIPKVQSA.js} +61 -1
- package/dist/cli.js +95 -6
- package/dist/dashboard/assets/index-DqbNcMwV.js +2 -0
- package/dist/dashboard/assets/index-y7eHWJtq.css +1 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/{dashboard-server-FMKL4KZG.js → dashboard-server-LWMXEJHE.js} +179 -2
- package/dist/{db-Y6BXHLRN.js → db-FLFZZXG3.js} +15 -1
- package/package.json +5 -1
- package/dist/dashboard/assets/index-B5TFTqLb.js +0 -2
- package/dist/dashboard/assets/index-Cfkgvz08.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{color-scheme:light dark;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased}body{margin:0;min-width:320px;min-height:100vh}button,input,select,textarea{font:inherit}button{border:0}:root{--primary: #0040e0;--primary-dim: #2e5bff;--primary-container: #efefff;--on-primary: #ffffff;--surface: #f8f9fb;--surface-low: #f3f4f6;--surface-mid: #edeef0;--surface-high: #e7e8ea;--surface-highest: #e1e2e4;--on-surface: #191c1e;--on-surface-var: #434656;--outline: #747688;--outline-var: #c4c5d9;--error: #ba1a1a;--error-bg: #ffdad6;--tertiary: #993100;--green: #10b981;--green-bg: rgba(16,185,129,.1);--green-border: rgba(16,185,129,.3);--mono: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;--sans: "Hanken Grotesk", Inter, ui-sans-serif, system-ui, sans-serif;--sidebar-bg: #f0f1f5;--sidebar-border: #e0e1e9;--sidebar-text: #191c1e;--sidebar-muted: #747688;--sidebar-hover: rgba(0,0,0,.05);--sidebar-active-bg: #e4e8ff}body{margin:0;background:var(--surface);color:var(--on-surface);font-family:var(--sans);font-size:14px;overflow:hidden;height:100vh}*{box-sizing:border-box}::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-track{background:var(--surface-low)}::-webkit-scrollbar-thumb{background:var(--outline-var);border-radius:4px}.shell.svelte-d3ct2b{display:flex;flex-direction:column;height:100vh;overflow:hidden}.topbar.svelte-d3ct2b{display:flex;align-items:center;gap:12px;height:48px;padding:0 20px;background:var(--surface);border-bottom:1px solid var(--outline-var);flex-shrink:0;z-index:30}.topbar-brand.svelte-d3ct2b{display:flex;align-items:center;gap:10px;flex-shrink:0}.topbar-project.svelte-d3ct2b{font-family:var(--mono);font-size:12px;font-weight:700;color:var(--on-surface);letter-spacing:.02em;text-transform:uppercase}.topbar-arch-pill.svelte-d3ct2b{font-family:var(--mono);font-size:10px;font-weight:600;color:var(--primary);background:var(--primary-container);border:1px solid var(--primary-dim);border-radius:4px;padding:2px 7px;letter-spacing:.04em;text-transform:uppercase}.topbar-search.svelte-d3ct2b{flex:1;max-width:480px;margin:0 auto;position:relative}.search-icon.svelte-d3ct2b{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--on-surface-var);font-size:18px;pointer-events:none;line-height:1}.search-input.svelte-d3ct2b{width:100%;height:36px;padding:0 12px 0 36px;background:var(--surface-mid);border:1px solid var(--outline-var);border-radius:8px;color:var(--on-surface);font-family:var(--sans);font-size:13px;outline:none;transition:border-color .15s}.search-input.svelte-d3ct2b:focus{border-color:var(--primary-dim)}.topbar-actions.svelte-d3ct2b{display:flex;align-items:center;gap:4px;flex-shrink:0}.icon-btn.svelte-d3ct2b{width:34px;height:34px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:8px;color:var(--on-surface-var);cursor:pointer;transition:background .15s,color .15s}.icon-btn.svelte-d3ct2b:hover{background:var(--surface-low);color:var(--primary)}.icon-btn-active.svelte-d3ct2b{color:var(--primary)!important;background:var(--primary-container)!important}.avatar.svelte-d3ct2b{width:32px;height:32px;border-radius:50%;background:var(--primary-dim);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;margin-left:8px;border:1px solid var(--outline-var);flex-shrink:0;cursor:default}.body.svelte-d3ct2b{display:flex;flex:1;min-height:0;overflow:hidden}.sidebar.svelte-d3ct2b{width:188px;flex-shrink:0;display:flex;flex-direction:column;padding:0;background:var(--sidebar-bg);border-right:1px solid var(--sidebar-border);z-index:20}.sidebar-logo.svelte-d3ct2b{display:flex;align-items:center;gap:10px;padding:0 16px;height:48px;border-bottom:1px solid var(--sidebar-border);color:var(--sidebar-text);flex-shrink:0}.sidebar-brand-label.svelte-d3ct2b{font-family:var(--mono);font-size:12px;font-weight:700;letter-spacing:.04em;color:var(--sidebar-text, #e2e2e8);text-transform:uppercase}.sidebar-nav.svelte-d3ct2b{display:flex;flex-direction:column;gap:2px;padding:12px 8px;flex:1}.side-btn.svelte-d3ct2b{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;background:transparent;border:none;border-left:2px solid transparent;border-radius:0 6px 6px 0;color:var(--sidebar-muted);font-family:var(--sans);font-size:13px;font-weight:500;cursor:pointer;text-align:left;transition:color .12s,background .12s,border-color .12s;margin-left:-8px}.side-btn.svelte-d3ct2b:hover{color:var(--sidebar-text);background:var(--sidebar-hover)}.side-btn-active.svelte-d3ct2b{color:var(--sidebar-text)!important;background:var(--sidebar-active-bg)!important;border-left-color:var(--primary)!important}.side-badge.svelte-d3ct2b{display:inline-flex;align-items:center;justify-content:center;min-width:16px;height:16px;padding:0 4px;border-radius:8px;background:var(--error);color:#fff;font-size:9px;font-weight:700;margin-left:2px}.sidebar-footer.svelte-d3ct2b{display:flex;align-items:center;gap:8px;padding:12px 16px;border-top:1px solid var(--sidebar-border)}.sidebar-conn-dot.svelte-d3ct2b{width:7px;height:7px;border-radius:50%;background:var(--outline);flex-shrink:0}.sidebar-conn-label.svelte-d3ct2b{font-family:var(--mono);font-size:10px;font-weight:600;color:var(--sidebar-muted);text-transform:uppercase;letter-spacing:.06em}.dot-live.svelte-d3ct2b{background:var(--green)!important;box-shadow:0 0 6px var(--green)}.sidebar-user.svelte-d3ct2b{display:flex;align-items:center;gap:6px;flex:1;min-width:0;overflow:hidden}.sidebar-avatar.svelte-d3ct2b{width:22px;height:22px;border-radius:50%;background:var(--primary);color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}.sidebar-username.svelte-d3ct2b{font-size:12px;color:var(--sidebar-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.sidebar-logout.svelte-d3ct2b{background:none;border:none;cursor:pointer;padding:3px;color:var(--sidebar-muted);display:flex;align-items:center;border-radius:4px;flex-shrink:0}.sidebar-logout.svelte-d3ct2b:hover{color:var(--error)}.login-screen.svelte-d3ct2b{min-height:100vh;display:flex;align-items:center;justify-content:center;background:var(--surface)}.login-card.svelte-d3ct2b{width:360px;background:var(--surface-low);border:1px solid var(--outline-var);border-radius:12px;padding:40px 36px 32px;display:flex;flex-direction:column;align-items:center;gap:8px;box-shadow:0 4px 24px #00000014}.login-logo.svelte-d3ct2b{margin-bottom:4px}.login-title.svelte-d3ct2b{font-family:var(--sans);font-size:22px;font-weight:700;color:var(--on-surface);margin:0}.login-sub.svelte-d3ct2b{font-size:13px;color:var(--on-surface-var);margin:0 0 8px}.login-error.svelte-d3ct2b{width:100%;background:var(--error-bg);color:var(--error);border-radius:6px;padding:8px 12px;font-size:13px;margin:0}.login-form.svelte-d3ct2b{width:100%;display:flex;flex-direction:column;gap:6px}.login-label.svelte-d3ct2b{font-size:12px;font-weight:600;color:var(--on-surface-var);margin-top:4px}.login-input.svelte-d3ct2b{width:100%;padding:9px 12px;border:1px solid var(--outline-var);border-radius:7px;background:var(--surface);color:var(--on-surface);font-size:14px;box-sizing:border-box;transition:border-color .15s}.login-input.svelte-d3ct2b:focus{outline:none;border-color:var(--primary)}.login-btn.svelte-d3ct2b{margin-top:10px;padding:10px;background:var(--primary);color:var(--on-primary);border:none;border-radius:7px;font-size:14px;font-weight:600;cursor:pointer;transition:opacity .15s}.login-btn.svelte-d3ct2b:disabled{opacity:.6;cursor:not-allowed}.login-btn.svelte-d3ct2b:not(:disabled):hover{opacity:.88}.login-hint.svelte-d3ct2b{font-size:12px;color:var(--on-surface-var);margin:8px 0 0;text-align:center}.login-hint.svelte-d3ct2b code:where(.svelte-d3ct2b){font-family:var(--mono);font-size:11px;background:var(--surface-mid);padding:1px 5px;border-radius:4px}.content.svelte-d3ct2b{flex:1;min-width:0;display:flex;flex-direction:column;overflow:hidden;background:var(--surface)}.health-bar.svelte-d3ct2b{display:flex;align-items:center;gap:8px;padding:6px 24px;border-bottom:1px solid var(--outline-var);background:#fff;flex-shrink:0;flex-wrap:wrap}.health-label.svelte-d3ct2b{font-family:var(--mono);font-size:10px;font-weight:700;color:var(--outline);text-transform:uppercase;letter-spacing:.06em;margin-right:4px}.health-badge.svelte-d3ct2b{display:flex;align-items:center;gap:4px;padding:2px 8px;border-radius:4px;font-family:var(--mono);font-size:10px;font-weight:700}.health-green.svelte-d3ct2b{background:var(--green-bg);color:var(--green);border:1px solid var(--green-border)}.health-blue.svelte-d3ct2b{background:#0040e014;color:var(--primary);border:1px solid rgba(0,64,224,.2)}.health-warn.svelte-d3ct2b{background:#ba1a1a14;color:var(--error);border:1px solid rgba(186,26,26,.25)}.health-error.svelte-d3ct2b{font-family:var(--mono);font-size:10px;color:var(--error);font-weight:700}.dot.svelte-d3ct2b{width:6px;height:6px;border-radius:50%;flex-shrink:0}.dot-green.svelte-d3ct2b{background:var(--green)}.dot-blue.svelte-d3ct2b{background:var(--primary)}.dot-warn.svelte-d3ct2b{background:var(--error)}.dot-pulse.svelte-d3ct2b{animation:svelte-d3ct2b-pulse 1.4s ease-in-out infinite}@keyframes svelte-d3ct2b-pulse{0%,to{opacity:1}50%{opacity:.35}}.filter-bar.svelte-d3ct2b{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 24px;background:var(--surface-low);border-bottom:1px solid var(--outline-var);flex-shrink:0}.filter-left.svelte-d3ct2b,.filter-right.svelte-d3ct2b{display:flex;align-items:center;gap:8px}.chip.svelte-d3ct2b{display:flex;align-items:center;gap:4px;padding:4px 10px;border-radius:8px;font-family:var(--mono);font-size:11px;font-weight:600;cursor:pointer;white-space:nowrap;border:none}.chip-primary.svelte-d3ct2b{background:var(--primary-dim);color:#fff}.chip-close.svelte-d3ct2b{background:transparent;border:none;color:#fffc;cursor:pointer;padding:0;font-size:10px;line-height:1}.chip-outline.svelte-d3ct2b{background:var(--surface);color:var(--on-surface-var);border:1px solid var(--outline-var);transition:border-color .15s}.chip-outline.svelte-d3ct2b:hover{border-color:var(--primary-dim)}.chevron.svelte-d3ct2b{transition:transform .2s}.chevron-open.svelte-d3ct2b{transform:rotate(180deg)}.service-dropdown-wrap.svelte-d3ct2b{position:relative}.dropdown.svelte-d3ct2b{position:absolute;top:calc(100% + 4px);left:0;min-width:180px;background:#fff;border:1px solid var(--outline-var);border-radius:8px;box-shadow:0 8px 24px #0000001f;z-index:100;overflow:hidden;animation:svelte-d3ct2b-dropIn .12s ease}@keyframes svelte-d3ct2b-dropIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.dropdown-item.svelte-d3ct2b{display:flex;align-items:center;gap:8px;width:100%;padding:10px 14px;background:transparent;border:none;color:var(--on-surface-var);font-family:var(--sans);font-size:13px;font-weight:500;cursor:pointer;transition:background .12s;text-align:left}.dropdown-item.svelte-d3ct2b:hover{background:var(--surface-low)}.dropdown-item-active.svelte-d3ct2b{color:var(--primary);background:var(--primary-container)}.dropdown-item-active.svelte-d3ct2b:hover{background:var(--primary-container)}.dropdown-badge.svelte-d3ct2b{margin-left:auto;background:var(--error);color:#fff;border-radius:999px;padding:1px 6px;font-size:10px;font-weight:700}.divider-v.svelte-d3ct2b{width:1px;height:28px;background:var(--outline-var);margin:0 4px}.metrics-strip.svelte-d3ct2b{display:flex;align-items:center;gap:24px}.metric-item.svelte-d3ct2b{display:flex;flex-direction:column;align-items:center}.metric-label.svelte-d3ct2b{font-family:var(--mono);font-size:9px;font-weight:700;color:var(--outline);text-transform:uppercase;letter-spacing:.05em;line-height:1}.metric-value.svelte-d3ct2b{font-family:var(--mono);font-size:14px;font-weight:700;color:var(--on-surface);line-height:1.4}.metric-value-warn.svelte-d3ct2b{color:var(--error)}.live-badge.svelte-d3ct2b{display:flex;align-items:center;gap:6px;padding:4px 10px;border:1px solid var(--outline-var);border-radius:8px;background:#fff;font-family:var(--mono);font-size:11px;font-weight:600;color:var(--on-surface);white-space:nowrap}.feed-area.svelte-d3ct2b{flex:1;min-height:0;overflow-y:auto;padding:12px 24px;background:#fff;font-family:var(--mono);font-size:12px}.log-row.svelte-d3ct2b{display:flex;align-items:baseline;gap:12px;padding:3px 8px;border-radius:4px;transition:background .1s;min-height:22px}.log-row.svelte-d3ct2b:hover{background:var(--surface-low)}.log-row-warn.svelte-d3ct2b{background:#ba1a1a0a}.log-row-fail.svelte-d3ct2b{background:#9931000a}.log-time.svelte-d3ct2b{width:80px;flex-shrink:0;color:var(--outline)}.log-label.svelte-d3ct2b{width:56px;flex-shrink:0;font-weight:700}.label-sys.svelte-d3ct2b{color:var(--primary)}.label-ok.svelte-d3ct2b{color:var(--green)}.label-warn.svelte-d3ct2b{color:var(--tertiary)}.label-info.svelte-d3ct2b{color:var(--on-surface-var)}.label-hook.svelte-d3ct2b{color:var(--error)}.label-chck.svelte-d3ct2b{color:var(--outline)}.log-msg.svelte-d3ct2b{flex:1;min-width:0;color:var(--on-surface-var);word-break:break-all;line-height:1.5}.log-msg.svelte-d3ct2b strong:where(.svelte-d3ct2b){color:var(--on-surface);font-weight:600}.copy-btn.svelte-d3ct2b{opacity:0;background:transparent;border:none;color:var(--outline);cursor:pointer;font-size:14px;padding:0 4px;transition:opacity .15s,color .15s;flex-shrink:0}.log-row.svelte-d3ct2b:hover .copy-btn:where(.svelte-d3ct2b){opacity:1}.copy-btn.svelte-d3ct2b:hover{color:var(--primary)}.log-detail.svelte-d3ct2b{display:flex;gap:8px;padding:3px 8px 3px 148px;font-size:11px;border-left:2px solid rgba(153,49,0,.3);margin-left:8px;margin-bottom:2px}.detail-index.svelte-d3ct2b{color:var(--outline);flex-shrink:0;width:24px}.detail-body.svelte-d3ct2b{color:var(--on-surface-var);flex:1;min-width:0;line-height:1.5}.detail-fix.svelte-d3ct2b{color:var(--primary)}.cursor-blink.svelte-d3ct2b{animation:svelte-d3ct2b-blink 1s step-start infinite}@keyframes svelte-d3ct2b-blink{0%,to{opacity:1}50%{opacity:0}}.section-header.svelte-d3ct2b{display:flex;align-items:baseline;gap:12px;padding:8px 8px 10px;border-bottom:1px solid var(--outline-var);margin-bottom:8px}.section-title.svelte-d3ct2b{font-family:var(--sans);font-size:14px;font-weight:700;color:var(--on-surface)}.section-meta.svelte-d3ct2b{font-size:11px;color:var(--outline);font-family:var(--mono)}.rules-toolbar.svelte-d3ct2b{display:flex;gap:8px;padding:8px;margin-bottom:4px}.rules-select.svelte-d3ct2b,.rules-input.svelte-d3ct2b,.rules-textarea.svelte-d3ct2b{padding:6px 10px;background:var(--surface-low);border:1px solid var(--outline-var);border-radius:6px;color:var(--on-surface);font-family:var(--sans);font-size:13px;outline:none;transition:border-color .15s}.rules-select.svelte-d3ct2b:focus,.rules-input.svelte-d3ct2b:focus,.rules-textarea.svelte-d3ct2b:focus{border-color:var(--primary-dim)}.rules-textarea.svelte-d3ct2b{resize:vertical;flex:1;min-width:0}.rule-form-wrap.svelte-d3ct2b{padding:0 8px 8px;border-bottom:1px solid var(--outline-var);margin-bottom:8px}.rule-form.svelte-d3ct2b{display:flex;flex-direction:column;gap:8px}.rule-form-row.svelte-d3ct2b{display:flex;gap:8px;align-items:flex-start}.add-btn.svelte-d3ct2b{padding:8px 16px;background:var(--primary);color:var(--on-primary);border:none;border-radius:6px;font-family:var(--mono);font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap;transition:background .15s;align-self:flex-end}.add-btn.svelte-d3ct2b:hover:not(:disabled){background:var(--primary-dim)}.add-btn.svelte-d3ct2b:disabled{opacity:.5;cursor:not-allowed}.rule-list.svelte-d3ct2b{display:flex;flex-direction:column;gap:4px;overflow-y:auto;max-height:400px;padding:0 8px}.rule-row.svelte-d3ct2b{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--outline-var);border-radius:6px;background:var(--surface-low);font-size:12px;min-width:0;transition:background .1s}.rule-row.svelte-d3ct2b:hover{background:var(--surface-mid)}.rule-badge.svelte-d3ct2b{padding:2px 7px;background:var(--primary-container);color:var(--primary);border-radius:4px;font-family:var(--mono);font-size:10px;font-weight:700;text-transform:uppercase;flex-shrink:0}.rule-scope.svelte-d3ct2b{color:var(--outline);font-family:var(--mono);font-size:10px;font-weight:600;flex-shrink:0}.rule-content.svelte-d3ct2b{flex:1;min-width:0;color:var(--on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rule-reason.svelte-d3ct2b{color:var(--on-surface-var);font-size:11px;flex-shrink:0;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.del-btn.svelte-d3ct2b{background:transparent;border:none;color:var(--outline);cursor:pointer;font-size:12px;padding:2px 6px;border-radius:4px;flex-shrink:0;transition:background .1s,color .1s}.del-btn.svelte-d3ct2b:hover{background:var(--error-bg);color:var(--error)}.metrics-footer.svelte-d3ct2b{display:flex;align-items:center;justify-content:space-between;height:48px;padding:0 24px;border-top:1px solid var(--outline-var);background:var(--surface);flex-shrink:0}.footer-left.svelte-d3ct2b,.footer-right.svelte-d3ct2b{display:flex;align-items:center;gap:24px}.footer-metric.svelte-d3ct2b{display:flex;align-items:center;gap:6px}.footer-label.svelte-d3ct2b{font-family:var(--mono);font-size:10px;font-weight:700;color:var(--outline);text-transform:uppercase;letter-spacing:.04em}.footer-val.svelte-d3ct2b{font-family:var(--mono);font-size:14px;font-weight:700;color:var(--on-surface)}.footer-val-error.svelte-d3ct2b{color:var(--error)}.footer-unit.svelte-d3ct2b{font-family:var(--mono);font-size:9px;color:var(--outline);text-transform:uppercase}.storage-bar-wrap.svelte-d3ct2b{display:flex;align-items:center;gap:8px}.storage-bar.svelte-d3ct2b{width:96px;height:6px;background:var(--surface-mid);border-radius:999px;overflow:hidden}.storage-fill.svelte-d3ct2b{height:100%;background:var(--primary-dim);border-radius:999px;transition:width .6s ease}.cli-btn.svelte-d3ct2b{display:flex;align-items:center;gap:6px;padding:5px 12px;background:var(--surface-high);border:none;border-radius:4px;color:var(--on-surface);font-family:var(--mono);font-size:11px;font-weight:700;cursor:pointer;transition:background .15s}.cli-btn.svelte-d3ct2b:hover{background:var(--outline-var)}:root[data-theme=dark]{--primary: #4f9eff;--primary-dim: #3b82f6;--primary-container: #172036;--on-primary: #001b3e;--surface: #111318;--surface-low: #0c0e12;--surface-mid: #1e2128;--surface-high: #252930;--surface-highest: #2e3138;--on-surface: #e6edf3;--on-surface-var: #8b949e;--outline: #484f58;--outline-var: #30363d;--error: #f85149;--error-bg: rgba(248,81,73,.15);--tertiary: #f0883e;--green: #3fb950;--green-bg: rgba(63,185,80,.12);--green-border: rgba(63,185,80,.3);--sidebar-bg: #0d1117;--sidebar-border: #21262d;--sidebar-text: #e6edf3;--sidebar-muted: #6e7681;--sidebar-hover: rgba(255,255,255,.04);--sidebar-active-bg: rgba(79,158,255,.1)}html[data-theme=dark] .topbar.svelte-d3ct2b{background:#161b22;border-bottom-color:var(--outline-var)}html[data-theme=dark] .health-bar.svelte-d3ct2b{background:#1a1c20;border-bottom-color:var(--outline-var)}html[data-theme=dark] .filter-bar.svelte-d3ct2b{background:#111318;border-bottom-color:var(--outline-var)}html[data-theme=dark] .feed-area.svelte-d3ct2b{background:#0c0e12}html[data-theme=dark] .metrics-footer.svelte-d3ct2b{background:#111318;border-top-color:var(--outline-var)}html[data-theme=dark] .search-input.svelte-d3ct2b{background:#1e2024;border-color:var(--outline-var);color:var(--on-surface)}html[data-theme=dark] .dropdown.svelte-d3ct2b{background:#1e2024;border-color:var(--outline-var);box-shadow:0 8px 24px #00000073}html[data-theme=dark] .dropdown-item.svelte-d3ct2b:hover{background:#282a2e}html[data-theme=dark] .dropdown-item-active.svelte-d3ct2b{background:var(--primary-container);color:var(--primary)}html[data-theme=dark] .chip-outline.svelte-d3ct2b,html[data-theme=dark] .live-badge.svelte-d3ct2b{background:#1e2024}html[data-theme=dark] .rule-row.svelte-d3ct2b{background:#1e2024;border-color:var(--outline-var)}html[data-theme=dark] .rule-row.svelte-d3ct2b:hover{background:#282a2e}html[data-theme=dark] .rules-select.svelte-d3ct2b,html[data-theme=dark] .rules-input.svelte-d3ct2b,html[data-theme=dark] .rules-textarea.svelte-d3ct2b{background:#1e2024;border-color:var(--outline-var);color:var(--on-surface)}html[data-theme=dark] .log-row.svelte-d3ct2b:hover{background:#1e2024}html[data-theme=dark] .log-row-warn.svelte-d3ct2b{background:#ffb4ab0d}html[data-theme=dark] .log-row-fail.svelte-d3ct2b{background:#ffba200a}html[data-theme=dark] .section-header.svelte-d3ct2b{border-bottom-color:var(--outline-var)}html[data-theme=dark] .storage-bar.svelte-d3ct2b{background:#282a2e}html[data-theme=dark] .badge-warn.svelte-d3ct2b{background:#422006;color:#fbbf24}html[data-theme=dark] .log-detail.svelte-d3ct2b{border-left-color:#ffba204d}html[data-theme=dark] .history-entry.svelte-d3ct2b{border-color:var(--outline-var);background:#1a1c20}html[data-theme=dark] .history-header.svelte-d3ct2b{background:#1e2024;border-bottom-color:var(--outline-var)}html[data-theme=dark] .history-violation.svelte-d3ct2b{border-bottom-color:var(--outline-var)}html[data-theme=dark] .arch-node-panel.svelte-d3ct2b{background:#1a1c20;border-color:var(--outline-var)}html[data-theme=dark] .arch-node-panel-path.svelte-d3ct2b{background:#1e2024}html[data-theme=dark] .arch-rule-row.svelte-d3ct2b{background:#1a1c20;border-color:var(--outline-var)}html[data-theme=dark] .arch-svg.svelte-d3ct2b{background:#0c0e12;border-color:var(--outline-var)}html[data-theme=dark] .footer-actions.svelte-d3ct2b .action-btn:where(.svelte-d3ct2b){background:#1e2024}html[data-theme=dark] .cli-btn.svelte-d3ct2b{background:#1e2024}html[data-theme=dark] .modal-status-row.svelte-d3ct2b{border-bottom-color:var(--outline-var)}html[data-theme=dark] .modal-input.svelte-d3ct2b{background:#1e2024;border-color:var(--outline-var);color:var(--on-surface)}html[data-theme=dark] .modal-btn.svelte-d3ct2b{background:#1e2024;border-color:var(--outline-var);color:var(--on-surface-var)}html[data-theme=dark] .modal-btn.svelte-d3ct2b:hover:not(:disabled){background:#282a2e}html[data-theme=dark] .rule-form-wrap.svelte-d3ct2b{border-bottom-color:var(--outline-var)}@media (max-width: 768px){.sidebar.svelte-d3ct2b{width:48px}.sidebar-brand-label.svelte-d3ct2b{display:none}.side-btn.svelte-d3ct2b span:where(.svelte-d3ct2b){display:none}.sidebar-conn-label.svelte-d3ct2b,.metrics-strip.svelte-d3ct2b{display:none}.filter-bar.svelte-d3ct2b,.feed-area.svelte-d3ct2b{padding:8px 12px}.metrics-footer.svelte-d3ct2b{padding:0 12px;gap:12px}.footer-metric.svelte-d3ct2b:nth-child(n+2){display:none}}.footer-actions.svelte-d3ct2b{display:flex;gap:6px;align-items:center;margin-right:12px}.action-btn.svelte-d3ct2b{font-size:11px;font-family:var(--mono);padding:4px 10px;border-radius:6px;border:1px solid var(--outline-var);background:var(--surface-low);color:var(--on-surface-var);cursor:pointer;transition:background .15s,border-color .15s}.action-btn.svelte-d3ct2b:hover:not(:disabled){background:var(--primary-container);border-color:var(--primary);color:var(--primary)}.action-btn.svelte-d3ct2b:disabled{opacity:.5;cursor:not-allowed}.action-btn-warn.svelte-d3ct2b:hover:not(:disabled){background:#fff3e0;border-color:#f59e0b;color:#b45309}.modal-backdrop.svelte-d3ct2b{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000073;display:flex;align-items:center;justify-content:center;z-index:200}.modal.svelte-d3ct2b{background:var(--surface);border:1px solid var(--outline-var);border-radius:12px;width:480px;max-width:calc(100vw - 32px);box-shadow:0 8px 32px #0000002e;overflow:hidden}.modal-header.svelte-d3ct2b{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid var(--outline-var)}.modal-title.svelte-d3ct2b{font-size:14px;font-weight:600;color:var(--on-surface)}.modal-close.svelte-d3ct2b{background:none;border:none;cursor:pointer;color:var(--outline);font-size:16px;line-height:1}.modal-section.svelte-d3ct2b{padding:16px 20px;border-bottom:1px solid var(--outline-var)}.modal-section.svelte-d3ct2b:last-child{border-bottom:none}.modal-section-title.svelte-d3ct2b{font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--outline);text-transform:uppercase;margin-bottom:12px}.modal-row.svelte-d3ct2b{display:grid;grid-template-columns:100px 1fr;gap:8px;align-items:center;margin-bottom:10px}.modal-label.svelte-d3ct2b{font-size:12px;color:var(--on-surface-var)}.modal-input.svelte-d3ct2b{font-size:12px;font-family:var(--mono);padding:6px 10px;border:1px solid var(--outline-var);border-radius:6px;background:var(--surface-low);color:var(--on-surface);outline:none;width:100%}.modal-input.svelte-d3ct2b:focus{border-color:var(--primary)}.modal-row-actions.svelte-d3ct2b{display:flex;gap:8px}.modal-btn.svelte-d3ct2b{font-size:12px;padding:6px 14px;border:1px solid var(--outline-var);border-radius:6px;background:var(--surface-low);color:var(--on-surface-var);cursor:pointer}.modal-btn.svelte-d3ct2b:hover:not(:disabled){background:var(--surface-mid)}.modal-btn.svelte-d3ct2b:disabled{opacity:.5;cursor:not-allowed}.modal-btn-primary.svelte-d3ct2b{background:var(--primary);color:var(--on-primary);border-color:var(--primary)}.modal-btn-primary.svelte-d3ct2b:hover:not(:disabled){background:var(--primary-dim)}.modal-msg.svelte-d3ct2b{font-size:12px;margin-top:8px;padding:6px 10px;border-radius:6px}.modal-msg-ok.svelte-d3ct2b{background:var(--green-bg);color:var(--green);border:1px solid var(--green-border)}.modal-msg-err.svelte-d3ct2b{background:var(--error-bg);color:var(--error);border:1px solid var(--error)}.modal-status-row.svelte-d3ct2b{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--surface-mid)}.modal-status-row.svelte-d3ct2b:last-child{border-bottom:none}.modal-status-label.svelte-d3ct2b{font-size:11px;color:var(--outline)}.modal-status-val.svelte-d3ct2b{font-size:11px;font-family:var(--mono);color:var(--on-surface)}html[data-theme=dark] .modal.svelte-d3ct2b{background:var(--surface);border-color:var(--outline-var)}.arch-graph-wrap.svelte-d3ct2b{display:flex;flex-direction:column;gap:16px;padding:16px}.arch-svg.svelte-d3ct2b{display:block;border:1px solid var(--outline-var);border-radius:8px;background:var(--surface-low);width:100%;max-width:640px}.arch-node-rect.svelte-d3ct2b{fill:var(--surface-mid);stroke:var(--outline-var);stroke-width:1.5}.arch-node-domain.arch-node-rect.svelte-d3ct2b{fill:#eff6ff;stroke:#3b82f6}.arch-node-application.arch-node-rect.svelte-d3ct2b{fill:#f0fdf4;stroke:#22c55e}.arch-node-infrastructure.arch-node-rect.svelte-d3ct2b{fill:#fff7ed;stroke:#f97316}.arch-node-api.arch-node-rect.svelte-d3ct2b{fill:#faf5ff;stroke:#a855f7}.arch-node-shared.arch-node-rect.svelte-d3ct2b{fill:#f8fafc;stroke:#94a3b8}.arch-node-controllers.arch-node-rect.svelte-d3ct2b{fill:#eff6ff;stroke:#3b82f6}.arch-node-handlers.arch-node-rect.svelte-d3ct2b{fill:#faf5ff;stroke:#a855f7}.arch-node-services.arch-node-rect.svelte-d3ct2b{fill:#f0fdf4;stroke:#22c55e}.arch-node-repositories.arch-node-rect.svelte-d3ct2b{fill:#fff7ed;stroke:#f97316}.arch-node-modules.arch-node-rect.svelte-d3ct2b{fill:#eef2ff;stroke:#6366f1}.arch-node-common.arch-node-rect.svelte-d3ct2b{fill:#f8fafc;stroke:#94a3b8}.arch-node-models.arch-node-rect.svelte-d3ct2b{fill:#f0fdfa;stroke:#14b8a6}.arch-node-views.arch-node-rect.svelte-d3ct2b{fill:#fefce8;stroke:#eab308}.arch-node-pages.arch-node-rect.svelte-d3ct2b,.arch-node-screens.arch-node-rect.svelte-d3ct2b,.arch-node-routes.arch-node-rect.svelte-d3ct2b{fill:#eff6ff;stroke:#3b82f6}.arch-node-components.arch-node-rect.svelte-d3ct2b{fill:#fdf2f8;stroke:#ec4899}.arch-node-hooks.arch-node-rect.svelte-d3ct2b{fill:#f5f3ff;stroke:#8b5cf6}.arch-node-composables.arch-node-rect.svelte-d3ct2b{fill:#ecfeff;stroke:#06b6d4}.arch-node-store.arch-node-rect.svelte-d3ct2b,.arch-node-stores.arch-node-rect.svelte-d3ct2b{fill:#fffbeb;stroke:#f59e0b}.arch-node-lib.arch-node-rect.svelte-d3ct2b{fill:#f0fdfa;stroke:#14b8a6}.arch-node-utils.arch-node-rect.svelte-d3ct2b{fill:#f8fafc;stroke:#94a3b8}.arch-node-guards.arch-node-rect.svelte-d3ct2b{fill:#fff1f2;stroke:#f43f5e}.arch-node-server.arch-node-rect.svelte-d3ct2b{fill:#fff7ed;stroke:#f97316}.arch-node-ports.arch-node-rect.svelte-d3ct2b{fill:#ecfeff;stroke:#06b6d4}.arch-node-adapters.arch-node-rect.svelte-d3ct2b{fill:#f0fdfa;stroke:#14b8a6}html[data-theme=dark] .arch-node-domain.arch-node-rect.svelte-d3ct2b{fill:#1e3a5f;stroke:#3b82f6}html[data-theme=dark] .arch-node-application.arch-node-rect.svelte-d3ct2b{fill:#14352a;stroke:#22c55e}html[data-theme=dark] .arch-node-infrastructure.arch-node-rect.svelte-d3ct2b{fill:#3d2006;stroke:#f97316}html[data-theme=dark] .arch-node-api.arch-node-rect.svelte-d3ct2b{fill:#2e1a47;stroke:#a855f7}html[data-theme=dark] .arch-node-shared.arch-node-rect.svelte-d3ct2b{fill:#1e2535;stroke:#94a3b8}html[data-theme=dark] .arch-node-controllers.arch-node-rect.svelte-d3ct2b{fill:#1e3a5f;stroke:#3b82f6}html[data-theme=dark] .arch-node-handlers.arch-node-rect.svelte-d3ct2b{fill:#2e1a47;stroke:#a855f7}html[data-theme=dark] .arch-node-services.arch-node-rect.svelte-d3ct2b{fill:#14352a;stroke:#22c55e}html[data-theme=dark] .arch-node-repositories.arch-node-rect.svelte-d3ct2b{fill:#3d2006;stroke:#f97316}html[data-theme=dark] .arch-node-modules.arch-node-rect.svelte-d3ct2b{fill:#1e1b4b;stroke:#6366f1}html[data-theme=dark] .arch-node-common.arch-node-rect.svelte-d3ct2b{fill:#1e2535;stroke:#94a3b8}html[data-theme=dark] .arch-node-models.arch-node-rect.svelte-d3ct2b{fill:#0f2922;stroke:#14b8a6}html[data-theme=dark] .arch-node-views.arch-node-rect.svelte-d3ct2b{fill:#29240a;stroke:#eab308}html[data-theme=dark] .arch-node-pages.arch-node-rect.svelte-d3ct2b,html[data-theme=dark] .arch-node-screens.arch-node-rect.svelte-d3ct2b,html[data-theme=dark] .arch-node-routes.arch-node-rect.svelte-d3ct2b{fill:#1e3a5f;stroke:#3b82f6}html[data-theme=dark] .arch-node-components.arch-node-rect.svelte-d3ct2b{fill:#3d0e2e;stroke:#ec4899}html[data-theme=dark] .arch-node-hooks.arch-node-rect.svelte-d3ct2b{fill:#1e1547;stroke:#8b5cf6}html[data-theme=dark] .arch-node-composables.arch-node-rect.svelte-d3ct2b{fill:#042934;stroke:#06b6d4}html[data-theme=dark] .arch-node-store.arch-node-rect.svelte-d3ct2b,html[data-theme=dark] .arch-node-stores.arch-node-rect.svelte-d3ct2b{fill:#2d200a;stroke:#f59e0b}html[data-theme=dark] .arch-node-lib.arch-node-rect.svelte-d3ct2b{fill:#0f2922;stroke:#14b8a6}html[data-theme=dark] .arch-node-utils.arch-node-rect.svelte-d3ct2b{fill:#1e2535;stroke:#94a3b8}html[data-theme=dark] .arch-node-guards.arch-node-rect.svelte-d3ct2b{fill:#3d0a14;stroke:#f43f5e}html[data-theme=dark] .arch-node-server.arch-node-rect.svelte-d3ct2b{fill:#3d2006;stroke:#f97316}html[data-theme=dark] .arch-node-ports.arch-node-rect.svelte-d3ct2b{fill:#042934;stroke:#06b6d4}html[data-theme=dark] .arch-node-adapters.arch-node-rect.svelte-d3ct2b{fill:#0f2922;stroke:#14b8a6}.arch-node-label.svelte-d3ct2b{font-family:var(--mono);font-size:11px;font-weight:600;fill:var(--on-surface)}.arch-node-desc.svelte-d3ct2b{font-family:var(--sans);font-size:9px;fill:var(--outline)}.arch-node-clickable.svelte-d3ct2b{cursor:pointer}.arch-node-clickable.svelte-d3ct2b:hover .arch-node-rect:where(.svelte-d3ct2b){filter:brightness(.95)}html[data-theme=dark] .arch-node-clickable.svelte-d3ct2b:hover .arch-node-rect:where(.svelte-d3ct2b){filter:brightness(1.15)}.arch-node-panel.svelte-d3ct2b{border:1px solid var(--outline-var);border-radius:8px;background:var(--surface-low);padding:12px 16px;max-width:640px;display:flex;flex-direction:column;gap:10px}.arch-node-panel-header.svelte-d3ct2b{display:flex;align-items:center;gap:10px}.arch-node-panel-name.svelte-d3ct2b{font-family:var(--mono);font-weight:700;font-size:13px;color:var(--on-surface)}.arch-node-panel-meta.svelte-d3ct2b{font-size:12px;color:var(--outline);flex:1}.arch-node-panel-close.svelte-d3ct2b{background:none;border:none;cursor:pointer;color:var(--outline);font-size:14px;padding:0;line-height:1}.arch-node-panel-close.svelte-d3ct2b:hover{color:var(--on-surface)}.arch-node-panel-paths.svelte-d3ct2b{display:flex;flex-direction:column;gap:4px}.arch-node-panel-section.svelte-d3ct2b{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--outline);margin-bottom:2px}.arch-node-panel-path.svelte-d3ct2b{font-family:var(--mono);font-size:11px;color:var(--cyan, #22d3ee);background:var(--surface-mid);padding:3px 8px;border-radius:4px}.arch-node-panel-rule.svelte-d3ct2b{display:flex;align-items:center;gap:8px;font-size:12px}.arch-legend.svelte-d3ct2b{display:flex;gap:16px;align-items:center;font-size:11px;color:var(--outline)}.legend-item.svelte-d3ct2b{display:flex;align-items:center;gap:6px}.arch-rule-list.svelte-d3ct2b{display:flex;flex-direction:column;gap:4px;max-width:640px}.arch-rule-row.svelte-d3ct2b{display:flex;align-items:center;gap:8px;padding:6px 10px;background:var(--surface-low);border-radius:4px;border:1px solid var(--outline-var)}.tab-badge.svelte-d3ct2b{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:16px;padding:0 5px;border-radius:8px;background:var(--error);color:#fff;font-size:10px;font-weight:700;margin-left:4px;vertical-align:middle}.history-list.svelte-d3ct2b{display:flex;flex-direction:column;gap:8px;max-width:760px}.history-entry.svelte-d3ct2b{border:1px solid var(--outline-var);border-radius:6px;background:var(--surface-low);overflow:hidden}.history-header.svelte-d3ct2b{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-bottom:1px solid var(--outline-var);background:var(--surface-mid)}.history-file.svelte-d3ct2b{font-family:var(--mono);font-size:12px;font-weight:600;color:var(--cyan, #22d3ee)}.history-time.svelte-d3ct2b{font-size:11px;color:var(--outline)}.history-violation.svelte-d3ct2b{display:flex;align-items:center;gap:8px;padding:6px 12px;border-bottom:1px solid var(--outline-var);flex-wrap:wrap}.history-violation.svelte-d3ct2b:last-child{border-bottom:none}.history-badge.svelte-d3ct2b{flex-shrink:0;font-family:var(--mono);font-size:10px;font-weight:700;padding:2px 6px;border-radius:3px;background:var(--error-bg);color:var(--error);white-space:nowrap}.history-rule.svelte-d3ct2b{font-size:12px;font-weight:600;color:var(--on-surface)}.history-issue.svelte-d3ct2b{font-size:12px;color:var(--outline)}.history-entry-resolved.svelte-d3ct2b{opacity:.5}.history-entry-resolved.svelte-d3ct2b .history-file:where(.svelte-d3ct2b){text-decoration:line-through}.history-resolved-badge.svelte-d3ct2b{font-family:var(--mono);font-size:10px;font-weight:700;color:var(--green);letter-spacing:.04em}.history-resolve-btn.svelte-d3ct2b{margin-left:auto;padding:2px 8px;font-family:var(--mono);font-size:10px;font-weight:700;background:var(--surface-mid);border:1px solid var(--outline-var);border-radius:4px;color:var(--outline);cursor:pointer;transition:color .12s,border-color .12s,background .12s;white-space:nowrap}.history-resolve-btn.svelte-d3ct2b:hover{color:var(--green);border-color:var(--green);background:var(--green-bg)}.history-resolve-btn-active.svelte-d3ct2b{color:var(--green)!important;border-color:var(--green-border)!important;background:var(--green-bg)!important}.history-toggle-label.svelte-d3ct2b{display:flex;align-items:center;gap:5px;font-family:var(--mono);font-size:10px;color:var(--outline);cursor:pointer;-webkit-user-select:none;user-select:none}.arch-rule-badge.svelte-d3ct2b{font-size:10px;font-family:var(--mono);font-weight:700;padding:2px 6px;border-radius:3px}.badge-block.svelte-d3ct2b{background:var(--error-bg);color:var(--error)}.badge-warn.svelte-d3ct2b{background:#fef3c7;color:#92400e}.badge-allow.svelte-d3ct2b{background:var(--green-bg);color:var(--green)}.arch-rule-layers.svelte-d3ct2b{font-family:var(--mono);font-size:11px;color:var(--on-surface);white-space:nowrap}.arch-rule-name.svelte-d3ct2b{font-size:11px;color:var(--outline);flex:1}.arch-edit-btn.svelte-d3ct2b{padding:4px 10px;font-family:var(--mono);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;background:var(--surface-mid);border:1px solid var(--outline-var);border-radius:4px;color:var(--on-surface-var);cursor:pointer;transition:background .15s,color .15s}.arch-edit-btn.svelte-d3ct2b:hover{background:var(--primary-container);color:var(--primary);border-color:var(--primary-dim)}.arch-edit-btn-active.svelte-d3ct2b{background:var(--primary-container)!important;color:var(--primary)!important;border-color:var(--primary-dim)!important}.arch-reset-btn.svelte-d3ct2b{color:var(--tertiary)!important;border-color:var(--tertiary)!important}.arch-reset-btn.svelte-d3ct2b:hover{background:#fff3eb!important}html[data-theme=dark] .arch-reset-btn.svelte-d3ct2b:hover{background:#3d1a00!important}.arch-rule-del.svelte-d3ct2b{background:none;border:none;color:var(--outline);cursor:pointer;font-size:12px;padding:0 4px;line-height:1;transition:color .15s}.arch-rule-del.svelte-d3ct2b:hover{color:var(--error)}.arch-add-form.svelte-d3ct2b{display:flex;flex-direction:column;gap:8px;background:var(--surface-low);border:1px solid var(--outline-var);border-radius:6px;padding:12px;max-width:640px}.arch-add-form-title.svelte-d3ct2b{font-family:var(--mono);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--outline)}.arch-add-row.svelte-d3ct2b{display:flex;gap:8px;flex-wrap:wrap;align-items:flex-end}.arch-add-input.svelte-d3ct2b{height:30px;padding:0 8px;background:var(--surface);border:1px solid var(--outline-var);border-radius:4px;color:var(--on-surface);font-family:var(--mono);font-size:11px;outline:none;min-width:80px}.arch-add-input.svelte-d3ct2b:focus{border-color:var(--primary-dim)}.arch-add-select.svelte-d3ct2b{height:30px;padding:0 6px;background:var(--surface);border:1px solid var(--outline-var);border-radius:4px;color:var(--on-surface);font-family:var(--mono);font-size:11px;outline:none}.arch-add-submit.svelte-d3ct2b{height:30px;padding:0 12px;background:var(--primary);border:none;border-radius:4px;color:#fff;font-family:var(--mono);font-size:11px;font-weight:700;cursor:pointer;transition:background .15s}.arch-add-submit.svelte-d3ct2b:hover{background:var(--primary-dim)}.arch-add-submit.svelte-d3ct2b:disabled{opacity:.5;cursor:default}.arch-add-label.svelte-d3ct2b{font-size:10px;color:var(--outline);font-family:var(--mono)}.arch-add-field.svelte-d3ct2b{display:flex;flex-direction:column;gap:2px}.an-summary.svelte-d3ct2b{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:16px}.an-card.svelte-d3ct2b{display:flex;flex-direction:column;align-items:center;padding:12px 20px;background:var(--surface-low);border:1px solid var(--outline-var);border-radius:8px;min-width:100px}.an-card-val.svelte-d3ct2b{font-family:var(--mono);font-size:24px;font-weight:700;color:var(--on-surface);line-height:1}.an-card-label.svelte-d3ct2b{font-family:var(--mono);font-size:10px;color:var(--outline);text-transform:uppercase;letter-spacing:.06em;margin-top:4px}.an-card-warn.svelte-d3ct2b .an-card-val:where(.svelte-d3ct2b){color:var(--error)}.an-card-green.svelte-d3ct2b .an-card-val:where(.svelte-d3ct2b){color:var(--green)}.an-tabs.svelte-d3ct2b{display:flex;gap:2px;margin-bottom:14px;border-bottom:1px solid var(--outline-var)}.an-tab.svelte-d3ct2b{padding:6px 14px;background:transparent;border:none;border-bottom:2px solid transparent;color:var(--outline);font-family:var(--mono);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;transition:color .12s,border-color .12s;margin-bottom:-1px}.an-tab.svelte-d3ct2b:hover{color:var(--on-surface)}.an-tab-active.svelte-d3ct2b{color:var(--primary)!important;border-bottom-color:var(--primary)!important}.an-chart-wrap.svelte-d3ct2b{background:var(--surface-low);border:1px solid var(--outline-var);border-radius:8px;padding:16px;max-width:760px}.an-chart-svg.svelte-d3ct2b{display:block;width:100%;height:160px}.an-chart-legend.svelte-d3ct2b{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:11px;color:var(--outline)}.an-legend-dot.svelte-d3ct2b{width:10px;height:10px;border-radius:50%;display:inline-block}.an-heat-table.svelte-d3ct2b,.an-rule-table.svelte-d3ct2b{display:flex;flex-direction:column;gap:3px;max-width:760px}.an-heat-header.svelte-d3ct2b{display:grid;grid-template-columns:2fr 2fr 80px 100px;gap:8px;padding:4px 10px;font-family:var(--mono);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--outline)}.an-rule-table.svelte-d3ct2b .an-heat-header:where(.svelte-d3ct2b){grid-template-columns:2fr 1.5fr 2fr 100px}.an-heat-row.svelte-d3ct2b{display:grid;grid-template-columns:2fr 2fr 80px 100px;gap:8px;align-items:center;padding:6px 10px;background:var(--surface-low);border-radius:4px;border:1px solid var(--outline-var)}.an-rule-table.svelte-d3ct2b .an-heat-row:where(.svelte-d3ct2b){grid-template-columns:2fr 1.5fr 2fr 100px}.an-heat-file.svelte-d3ct2b{font-family:var(--mono);font-size:11px;color:var(--on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.an-heat-bar-wrap.svelte-d3ct2b{display:flex;align-items:center;gap:6px}.an-heat-bar.svelte-d3ct2b{height:8px;border-radius:4px;min-width:2px;flex-shrink:0}.an-heat-count.svelte-d3ct2b{font-family:var(--mono);font-size:11px;font-weight:700;color:var(--on-surface);white-space:nowrap}.an-heat-resolved.svelte-d3ct2b{font-family:var(--mono);font-size:11px;color:var(--green)}.an-heat-time.svelte-d3ct2b{font-size:11px;color:var(--outline);white-space:nowrap}.an-rule-name.svelte-d3ct2b{font-family:var(--mono);font-size:11px;color:var(--on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.an-rule-layers.svelte-d3ct2b{font-family:var(--mono);font-size:10px;color:var(--outline)}.an-row-dead.svelte-d3ct2b{opacity:.45}.an-dead-count.svelte-d3ct2b{color:var(--outline)!important;font-weight:400!important}.profile-panel.svelte-d3ct2b{background:var(--surface-low);border:1px solid var(--outline-var);border-radius:6px;padding:12px;display:flex;flex-direction:column;gap:10px;max-width:760px}.profile-save-row.svelte-d3ct2b{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.profile-name-input.svelte-d3ct2b{height:30px;padding:0 8px;background:var(--surface);border:1px solid var(--outline-var);border-radius:4px;color:var(--on-surface);font-family:var(--mono);font-size:11px;outline:none;min-width:160px;flex:1}.profile-name-input.svelte-d3ct2b:focus{border-color:var(--primary-dim)}.profile-scope-label.svelte-d3ct2b{display:flex;align-items:center;gap:4px;font-family:var(--mono);font-size:10px;color:var(--outline);white-space:nowrap;cursor:pointer}.profile-msg.svelte-d3ct2b{font-family:var(--mono);font-size:10px;color:var(--green)}.profile-empty.svelte-d3ct2b{font-size:12px;color:var(--outline);font-style:italic}.profile-list.svelte-d3ct2b{display:flex;flex-direction:column;gap:4px}.profile-row.svelte-d3ct2b{display:flex;align-items:center;gap:8px;padding:6px 10px;background:var(--surface-mid);border:1px solid var(--outline-var);border-radius:4px}.profile-name.svelte-d3ct2b{font-family:var(--mono);font-size:12px;font-weight:700;color:var(--on-surface)}.profile-meta.svelte-d3ct2b{font-size:11px;color:var(--outline);flex:1}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-DqbNcMwV.js"></script>
|
|
11
|
+
<link rel="stylesheet" crossorigin href="/assets/index-y7eHWJtq.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="app"></div>
|
|
@@ -6,23 +6,29 @@ import {
|
|
|
6
6
|
embed,
|
|
7
7
|
inferProjectArchitectures,
|
|
8
8
|
startWatch
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-23GUWJ6F.js";
|
|
10
10
|
import {
|
|
11
11
|
getChatProviderLabel
|
|
12
12
|
} from "./chunk-PQBWHAZN.js";
|
|
13
13
|
import {
|
|
14
14
|
Config,
|
|
15
15
|
closePool,
|
|
16
|
+
countUsers,
|
|
17
|
+
createUser,
|
|
16
18
|
deleteArchProfile,
|
|
17
19
|
deleteMemory,
|
|
20
|
+
deleteUser,
|
|
18
21
|
getArchProfile,
|
|
19
22
|
getPool,
|
|
23
|
+
getUserByEmail,
|
|
20
24
|
listArchProfiles,
|
|
21
25
|
listMemories,
|
|
26
|
+
listUsers,
|
|
22
27
|
saveArchProfile,
|
|
23
28
|
saveMemory,
|
|
29
|
+
updateLastLogin,
|
|
24
30
|
updateMemory
|
|
25
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-GIPKVQSA.js";
|
|
26
32
|
import "./chunk-ZZBQEXEO.js";
|
|
27
33
|
|
|
28
34
|
// src/dashboard-server.ts
|
|
@@ -33,6 +39,46 @@ import { createServer } from "http";
|
|
|
33
39
|
import { basename, dirname, extname, join, normalize, relative, resolve } from "path";
|
|
34
40
|
import { fileURLToPath } from "url";
|
|
35
41
|
import chalk from "chalk";
|
|
42
|
+
|
|
43
|
+
// src/auth.ts
|
|
44
|
+
import jwt from "jsonwebtoken";
|
|
45
|
+
import bcrypt from "bcryptjs";
|
|
46
|
+
var BCRYPT_ROUNDS = 12;
|
|
47
|
+
var JWT_EXPIRY = "30d";
|
|
48
|
+
function getJwtSecret() {
|
|
49
|
+
const secret = process.env.MC_JWT_SECRET;
|
|
50
|
+
if (!secret) throw new Error("MC_JWT_SECRET not set. Add it to .memory-core.env.");
|
|
51
|
+
return secret;
|
|
52
|
+
}
|
|
53
|
+
function signToken(payload) {
|
|
54
|
+
return jwt.sign(payload, getJwtSecret(), { expiresIn: JWT_EXPIRY });
|
|
55
|
+
}
|
|
56
|
+
function verifyToken(token) {
|
|
57
|
+
return jwt.verify(token, getJwtSecret());
|
|
58
|
+
}
|
|
59
|
+
async function hashPassword(password) {
|
|
60
|
+
return bcrypt.hash(password, BCRYPT_ROUNDS);
|
|
61
|
+
}
|
|
62
|
+
async function comparePassword(password, hash) {
|
|
63
|
+
return bcrypt.compare(password, hash);
|
|
64
|
+
}
|
|
65
|
+
function extractBearerToken(authHeader) {
|
|
66
|
+
if (!authHeader?.startsWith("Bearer ")) return null;
|
|
67
|
+
return authHeader.slice(7).trim() || null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/dashboard-server.ts
|
|
71
|
+
var authEnabled = false;
|
|
72
|
+
function requireAuth(req) {
|
|
73
|
+
if (!authEnabled) return { userId: 0, email: "local", username: "local", role: "admin", teamName: null };
|
|
74
|
+
const token = extractBearerToken(req.headers["authorization"]);
|
|
75
|
+
if (!token) return null;
|
|
76
|
+
try {
|
|
77
|
+
return verifyToken(token);
|
|
78
|
+
} catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
36
82
|
var clients = /* @__PURE__ */ new Set();
|
|
37
83
|
var fileStatuses = /* @__PURE__ */ new Map();
|
|
38
84
|
var recentEvents = [];
|
|
@@ -969,6 +1015,136 @@ async function handleApi(req, res, url) {
|
|
|
969
1015
|
}
|
|
970
1016
|
return;
|
|
971
1017
|
}
|
|
1018
|
+
if (req.method === "POST" && url.pathname === "/api/auth/setup") {
|
|
1019
|
+
if (!authEnabled) {
|
|
1020
|
+
sendJson(res, 403, { error: "Auth not enabled. Start dashboard with --auth flag." });
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
const count = await countUsers();
|
|
1024
|
+
if (count > 0) {
|
|
1025
|
+
sendJson(res, 409, { error: "Admin already exists. Use /api/auth/login." });
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
const body = await readBody(req);
|
|
1029
|
+
const email = typeof body.email === "string" ? body.email.trim() : "";
|
|
1030
|
+
const username = typeof body.username === "string" ? body.username.trim() : "";
|
|
1031
|
+
const password = typeof body.password === "string" ? body.password : "";
|
|
1032
|
+
const teamName = typeof body.teamName === "string" ? body.teamName.trim() : void 0;
|
|
1033
|
+
if (!email || !username || password.length < 8) {
|
|
1034
|
+
sendJson(res, 400, { error: "email, username, and password (min 8 chars) required" });
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
const passwordHash = await hashPassword(password);
|
|
1038
|
+
const user = await createUser({ email, username, passwordHash, role: "admin", teamName });
|
|
1039
|
+
await updateLastLogin(user.id);
|
|
1040
|
+
const token = signToken({ userId: user.id, email: user.email, username: user.username, role: user.role, teamName: user.team_name });
|
|
1041
|
+
sendJson(res, 201, { token, user: { id: user.id, email: user.email, username: user.username, role: user.role, teamName: user.team_name } });
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
if (req.method === "POST" && url.pathname === "/api/auth/login") {
|
|
1045
|
+
if (!authEnabled) {
|
|
1046
|
+
sendJson(res, 403, { error: "Auth not enabled." });
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
const body = await readBody(req);
|
|
1050
|
+
const email = typeof body.email === "string" ? body.email.trim() : "";
|
|
1051
|
+
const password = typeof body.password === "string" ? body.password : "";
|
|
1052
|
+
if (!email || !password) {
|
|
1053
|
+
sendJson(res, 400, { error: "email and password required" });
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
const user = await getUserByEmail(email);
|
|
1057
|
+
if (!user) {
|
|
1058
|
+
sendJson(res, 401, { error: "Invalid credentials" });
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
const ok = await comparePassword(password, user.password_hash);
|
|
1062
|
+
if (!ok) {
|
|
1063
|
+
sendJson(res, 401, { error: "Invalid credentials" });
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1066
|
+
await updateLastLogin(user.id);
|
|
1067
|
+
const token = signToken({ userId: user.id, email: user.email, username: user.username, role: user.role, teamName: user.team_name });
|
|
1068
|
+
sendJson(res, 200, { token, user: { id: user.id, email: user.email, username: user.username, role: user.role, teamName: user.team_name } });
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
if (req.method === "GET" && url.pathname === "/api/auth/me") {
|
|
1072
|
+
const payload = requireAuth(req);
|
|
1073
|
+
if (!payload) {
|
|
1074
|
+
sendJson(res, 401, { error: "Unauthorized", authEnabled });
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
sendJson(res, 200, { user: { userId: payload.userId, email: payload.email, username: payload.username, role: payload.role, teamName: payload.teamName }, authEnabled });
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
if (req.method === "POST" && url.pathname === "/api/auth/logout") {
|
|
1081
|
+
sendJson(res, 200, { ok: true });
|
|
1082
|
+
return;
|
|
1083
|
+
}
|
|
1084
|
+
if (req.method === "GET" && url.pathname === "/api/users") {
|
|
1085
|
+
const payload = requireAuth(req);
|
|
1086
|
+
if (!payload) {
|
|
1087
|
+
sendJson(res, 401, { error: "Unauthorized" });
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
if (payload.role !== "admin") {
|
|
1091
|
+
sendJson(res, 403, { error: "Admin only" });
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
const users = await listUsers();
|
|
1095
|
+
sendJson(res, 200, { users });
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
if (req.method === "POST" && url.pathname === "/api/users") {
|
|
1099
|
+
const payload = requireAuth(req);
|
|
1100
|
+
if (!payload) {
|
|
1101
|
+
sendJson(res, 401, { error: "Unauthorized" });
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1104
|
+
if (payload.role !== "admin") {
|
|
1105
|
+
sendJson(res, 403, { error: "Admin only" });
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
const body = await readBody(req);
|
|
1109
|
+
const email = typeof body.email === "string" ? body.email.trim() : "";
|
|
1110
|
+
const username = typeof body.username === "string" ? body.username.trim() : "";
|
|
1111
|
+
const password = typeof body.password === "string" ? body.password : "";
|
|
1112
|
+
const role = body.role === "admin" ? "admin" : "viewer";
|
|
1113
|
+
const teamName = typeof body.teamName === "string" ? body.teamName.trim() : void 0;
|
|
1114
|
+
if (!email || !username || password.length < 8) {
|
|
1115
|
+
sendJson(res, 400, { error: "email, username, and password (min 8 chars) required" });
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1118
|
+
const passwordHash = await hashPassword(password);
|
|
1119
|
+
try {
|
|
1120
|
+
const user = await createUser({ email, username, passwordHash, role, teamName });
|
|
1121
|
+
sendJson(res, 201, { user: { id: user.id, email: user.email, username: user.username, role: user.role, teamName: user.team_name } });
|
|
1122
|
+
} catch (err) {
|
|
1123
|
+
const msg = err.message;
|
|
1124
|
+
sendJson(res, 409, { error: msg.includes("unique") ? "Email or username already exists" : msg });
|
|
1125
|
+
}
|
|
1126
|
+
return;
|
|
1127
|
+
}
|
|
1128
|
+
const userMatch = url.pathname.match(/^\/api\/users\/(\d+)$/);
|
|
1129
|
+
if (userMatch && req.method === "DELETE") {
|
|
1130
|
+
const payload = requireAuth(req);
|
|
1131
|
+
if (!payload) {
|
|
1132
|
+
sendJson(res, 401, { error: "Unauthorized" });
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
if (payload.role !== "admin") {
|
|
1136
|
+
sendJson(res, 403, { error: "Admin only" });
|
|
1137
|
+
return;
|
|
1138
|
+
}
|
|
1139
|
+
const uid = parseInt(userMatch[1], 10);
|
|
1140
|
+
if (uid === payload.userId) {
|
|
1141
|
+
sendJson(res, 400, { error: "Cannot delete yourself" });
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
const deleted = await deleteUser(uid);
|
|
1145
|
+
sendJson(res, deleted ? 200 : 404, deleted ? { ok: true } : { error: "User not found" });
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
972
1148
|
sendJson(res, 404, { error: "Not found" });
|
|
973
1149
|
} catch (err) {
|
|
974
1150
|
sendJson(res, 500, { error: err.message });
|
|
@@ -1231,6 +1407,7 @@ function startConfigWatch() {
|
|
|
1231
1407
|
}
|
|
1232
1408
|
async function startDashboard(options = {}) {
|
|
1233
1409
|
projectRoot = resolveDashboardProjectRoot(options.path);
|
|
1410
|
+
authEnabled = options.auth ?? false;
|
|
1234
1411
|
reloadRuntimeEnv();
|
|
1235
1412
|
const port = options.port ?? 5178;
|
|
1236
1413
|
const stopConfigWatch = startConfigWatch();
|
|
@@ -1,37 +1,51 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
closePool,
|
|
4
|
+
countUsers,
|
|
5
|
+
createUser,
|
|
4
6
|
deleteArchProfile,
|
|
5
7
|
deleteMemories,
|
|
6
8
|
deleteMemory,
|
|
9
|
+
deleteUser,
|
|
7
10
|
getArchProfile,
|
|
8
11
|
getMemory,
|
|
9
12
|
getPool,
|
|
13
|
+
getUserByEmail,
|
|
14
|
+
getUserById,
|
|
10
15
|
hashMemoryContent,
|
|
11
16
|
listArchProfiles,
|
|
12
17
|
listMemories,
|
|
18
|
+
listUsers,
|
|
13
19
|
runMigrations,
|
|
14
20
|
saveArchProfile,
|
|
15
21
|
saveMemory,
|
|
16
22
|
searchMemories,
|
|
23
|
+
updateLastLogin,
|
|
17
24
|
updateMemory,
|
|
18
25
|
upsertMemory
|
|
19
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-GIPKVQSA.js";
|
|
20
27
|
export {
|
|
21
28
|
closePool,
|
|
29
|
+
countUsers,
|
|
30
|
+
createUser,
|
|
22
31
|
deleteArchProfile,
|
|
23
32
|
deleteMemories,
|
|
24
33
|
deleteMemory,
|
|
34
|
+
deleteUser,
|
|
25
35
|
getArchProfile,
|
|
26
36
|
getMemory,
|
|
27
37
|
getPool,
|
|
38
|
+
getUserByEmail,
|
|
39
|
+
getUserById,
|
|
28
40
|
hashMemoryContent,
|
|
29
41
|
listArchProfiles,
|
|
30
42
|
listMemories,
|
|
43
|
+
listUsers,
|
|
31
44
|
runMigrations,
|
|
32
45
|
saveArchProfile,
|
|
33
46
|
saveMemory,
|
|
34
47
|
searchMemories,
|
|
48
|
+
updateLastLogin,
|
|
35
49
|
updateMemory,
|
|
36
50
|
upsertMemory
|
|
37
51
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shahmilsaari/memory-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.33",
|
|
4
4
|
"description": "Universal AI memory core — generate AI context files from architecture profiles with RAG support",
|
|
5
5
|
"homepage": "https://memory-core.shahmilsaari.my/",
|
|
6
6
|
"type": "module",
|
|
@@ -33,18 +33,22 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@inquirer/prompts": "^5.0.0",
|
|
36
|
+
"bcryptjs": "^3.0.3",
|
|
36
37
|
"chalk": "^5.3.0",
|
|
37
38
|
"chokidar": "^5.0.0",
|
|
38
39
|
"commander": "^12.0.0",
|
|
39
40
|
"dotenv": "^16.4.0",
|
|
40
41
|
"handlebars": "^4.7.8",
|
|
41
42
|
"js-yaml": "^4.1.0",
|
|
43
|
+
"jsonwebtoken": "^9.0.3",
|
|
42
44
|
"ora": "^8.0.0",
|
|
43
45
|
"pg": "^8.11.0"
|
|
44
46
|
},
|
|
45
47
|
"devDependencies": {
|
|
46
48
|
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
|
49
|
+
"@types/bcryptjs": "^2.4.6",
|
|
47
50
|
"@types/js-yaml": "^4.0.9",
|
|
51
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
48
52
|
"@types/node": "^20.0.0",
|
|
49
53
|
"@types/pg": "^8.11.0",
|
|
50
54
|
"svelte": "^5.55.5",
|