volute 0.21.0 → 0.23.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.
Files changed (58) hide show
  1. package/dist/api.d.ts +4294 -0
  2. package/dist/chunk-G5KRTU2F.js +76 -0
  3. package/dist/chunk-ISWZ6QUK.js +2691 -0
  4. package/dist/{chunk-J5A3DF2U.js → chunk-JG4CCJOA.js} +1 -1
  5. package/dist/{chunk-IPJXU366.js → chunk-JTDFJWI2.js} +1 -0
  6. package/dist/{chunk-7LPTHFIL.js → chunk-M5CNKH4J.js} +55 -5
  7. package/dist/{chunk-L3LHXZD7.js → chunk-PHHKNGA3.js} +1 -1
  8. package/dist/{chunk-Q7AITQ44.js → chunk-QIXPN3OO.js} +1 -1
  9. package/dist/{chunk-PC6R6UUW.js → chunk-RK627D57.js} +36 -59
  10. package/dist/{chunk-5462YKWP.js → chunk-TFS25FIM.js} +1 -1
  11. package/dist/{chunk-QUJUKM4U.js → chunk-VT5QODNE.js} +1 -1
  12. package/dist/chunk-XLC342FO.js +29 -0
  13. package/dist/cli.js +10 -10
  14. package/dist/cloud-sync-PI47U2LT.js +96 -0
  15. package/dist/{daemon-restart-BH67ZOTE.js → daemon-restart-RMGOOGPE.js} +4 -4
  16. package/dist/daemon.js +1216 -1822
  17. package/dist/{down-LIOQ5JDH.js → down-WSUASL5E.js} +3 -3
  18. package/dist/{import-E433B4KG.js → import-EAXTHHXL.js} +2 -1
  19. package/dist/message-delivery-FHV4NO2F.js +23 -0
  20. package/dist/{mind-BIDOF65R.js → mind-BTXR5B3C.js} +13 -5
  21. package/dist/{mind-manager-3V2NXX4I.js → mind-manager-KMY4GA2J.js} +1 -1
  22. package/dist/mind-sleep-FWRBIFBS.js +41 -0
  23. package/dist/mind-wake-LJK2YU5X.js +36 -0
  24. package/dist/{package-HQR52XSG.js → package-CUBJ4PKS.js} +10 -1
  25. package/dist/{pages-KQBR5TAZ.js → pages-YSTRWJR4.js} +1 -1
  26. package/dist/{publish-OJ4QMXVZ.js → publish-BZNHKUUK.js} +2 -2
  27. package/dist/{service-TVNEORO7.js → service-7BFXDI6J.js} +4 -4
  28. package/dist/{setup-OZDYCKDI.js → setup-SSIIXQMI.js} +2 -2
  29. package/dist/sleep-manager-2TMQ65E4.js +27 -0
  30. package/dist/{sprout-6Z6C42YM.js → sprout-UKCYBGHK.js} +2 -2
  31. package/dist/{status-Z7NAFMBI.js → status-H2MKDN6L.js} +2 -2
  32. package/dist/{up-7BGDMFRT.js → up-Z5JRG2M2.js} +3 -3
  33. package/dist/{update-4WT7VWHW.js → update-ELC6MEUT.js} +2 -2
  34. package/dist/{upgrade-ZEC2GGFO.js → upgrade-GXW2EQY3.js} +11 -2
  35. package/dist/{version-notify-TFS2U5CF.js → version-notify-LKABEJSA.js} +11 -3
  36. package/dist/web-assets/assets/index-CZ26vsyY.js +69 -0
  37. package/dist/web-assets/assets/index-DyyAvJwW.css +1 -0
  38. package/dist/web-assets/index.html +2 -2
  39. package/package.json +10 -1
  40. package/templates/_base/.init/.config/prompts.json +1 -0
  41. package/templates/_base/home/.config/config.json.tmpl +4 -1
  42. package/templates/_base/src/lib/file-handler.ts +6 -1
  43. package/templates/_base/src/lib/logger.ts +68 -23
  44. package/templates/_base/src/lib/startup.ts +12 -3
  45. package/templates/claude/src/agent.ts +150 -29
  46. package/templates/claude/src/lib/hooks/pre-compact.ts +18 -4
  47. package/templates/claude/src/lib/message-channel.ts +6 -0
  48. package/templates/claude/src/lib/stream-consumer.ts +17 -1
  49. package/templates/claude/src/server.ts +3 -1
  50. package/templates/pi/home/.config/config.json.tmpl +4 -1
  51. package/templates/pi/src/agent.ts +87 -0
  52. package/templates/pi/src/lib/content.ts +18 -3
  53. package/templates/pi/src/lib/event-handler.ts +22 -2
  54. package/templates/pi/src/server.ts +3 -1
  55. package/dist/chunk-OGZYB5GL.js +0 -847
  56. package/dist/web-assets/assets/index-BR3gtK3E.css +0 -1
  57. package/dist/web-assets/assets/index-CWmrZRQd.js +0 -64
  58. /package/dist/{shared-DCQ2UXOM.js → shared-2OGT3NSL.js} +0 -0
@@ -0,0 +1 @@
1
+ .settings.svelte-4b0ckc{max-width:720px;margin:0 auto;animation:fadeIn .2s ease both}.error.svelte-4b0ckc{color:var(--red);font-size:12px;margin-bottom:16px}.loading.svelte-4b0ckc{color:var(--text-2);font-size:12px;padding:40px 0;text-align:center}.section.svelte-4b0ckc{margin-bottom:32px}.section-header.svelte-4b0ckc{display:flex;align-items:baseline;gap:10px;margin-bottom:12px}.section-title.svelte-4b0ckc{font-size:14px;font-weight:600;color:var(--text-0)}.section-subtitle.svelte-4b0ckc{font-size:11px;color:var(--text-2)}.prompt-card.svelte-4b0ckc{background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius-lg);padding:14px 16px;margin-bottom:10px}.prompt-card.custom.svelte-4b0ckc{border-color:var(--yellow-dim)}.prompt-header.svelte-4b0ckc{display:flex;align-items:center;gap:8px;margin-bottom:4px}.prompt-key.svelte-4b0ckc{font-family:var(--mono);font-size:13px;font-weight:600;color:var(--text-0)}.custom-badge.svelte-4b0ckc{font-size:10px;padding:1px 6px;border-radius:3px;background:var(--yellow-dim);color:var(--yellow)}.prompt-desc.svelte-4b0ckc{font-size:12px;color:var(--text-2);margin-bottom:8px;line-height:1.5}.var-tags.svelte-4b0ckc{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:10px}.var-tag.svelte-4b0ckc{font-family:var(--mono);font-size:10px;padding:2px 6px;border-radius:3px;background:var(--bg-3);color:var(--accent);border:1px solid var(--border)}.prompt-content.svelte-4b0ckc{background:var(--bg-3);border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;overflow-x:auto;font-family:var(--mono);font-size:12px;line-height:1.5;color:var(--text-1);white-space:pre-wrap;word-break:break-word;margin-bottom:8px}.prompt-content.svelte-4b0ckc code:where(.svelte-4b0ckc){font-family:inherit;font-size:inherit}.edit-area.svelte-4b0ckc{width:100%;min-height:120px;background:var(--bg-3);border:1px solid var(--accent-dim);border-radius:var(--radius);padding:10px 12px;font-family:var(--mono);font-size:13px;line-height:1.5;color:var(--text-0);resize:vertical;margin-bottom:8px}.edit-area.svelte-4b0ckc:focus{outline:none;border-color:var(--accent)}.actions.svelte-4b0ckc{display:flex;gap:6px}.btn.svelte-4b0ckc{font-family:var(--mono);font-size:11px;padding:4px 10px;border-radius:var(--radius);cursor:pointer;border:1px solid transparent;transition:opacity .15s}.btn.svelte-4b0ckc:disabled{opacity:.5;cursor:not-allowed}.btn-edit.svelte-4b0ckc{background:var(--bg-3);color:var(--text-1);border-color:var(--border)}.btn-edit.svelte-4b0ckc:hover{color:var(--text-0);border-color:var(--border-bright)}.btn-save.svelte-4b0ckc{background:var(--accent-dim);color:var(--accent);border-color:var(--accent-border)}.btn-save.svelte-4b0ckc:hover:not(:disabled){border-color:var(--accent)}.btn-cancel.svelte-4b0ckc{background:var(--bg-3);color:var(--text-2);border-color:var(--border)}.btn-cancel.svelte-4b0ckc:hover:not(:disabled){color:var(--text-1)}.btn-reset.svelte-4b0ckc{background:var(--red-bg);color:var(--red);border-color:var(--red-border)}.btn-reset.svelte-4b0ckc:hover:not(:disabled){border-color:var(--red)}.modal-overlay.svelte-b3ltw6{position:fixed;inset:0;background:var(--overlay);display:flex;align-items:center;justify-content:center;z-index:200;animation:fadeIn .15s ease}.modal.svelte-b3ltw6{max-width:90vw;background:var(--bg-1);border:1px solid var(--border);border-radius:var(--radius-lg);display:flex;flex-direction:column;overflow:hidden}.modal.full.svelte-b3ltw6{width:80vw;height:70vh;max-width:960px}.modal-header.svelte-b3ltw6{display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border);padding:12px 16px;flex-shrink:0}.title.svelte-b3ltw6{font-size:13px;font-weight:600;color:var(--text-0)}.close-btn.svelte-b3ltw6{background:none;color:var(--text-2);font-size:14px;padding:4px 8px}.close-btn.svelte-b3ltw6:hover{color:var(--text-0)}.error.svelte-14apx5e{color:var(--red);padding:8px 12px;font-size:12px}.empty.svelte-14apx5e{color:var(--text-2);padding:24px;text-align:center;font-size:13px}.section-header.svelte-14apx5e{display:flex;align-items:center;justify-content:space-between;padding:0 0 12px}.section-title.svelte-14apx5e{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-2)}.upload-area.svelte-14apx5e{display:flex;align-items:center;gap:8px}.file-input.svelte-14apx5e{display:none}.upload-btn.svelte-14apx5e{padding:4px 12px;font-size:11px;border-radius:var(--radius);background:var(--accent-dim);color:var(--accent);font-weight:500}.upload-btn.svelte-14apx5e:disabled{opacity:.5}.skill-list.svelte-14apx5e{display:flex;flex-direction:column}.skill-row.svelte-14apx5e{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0;border-bottom:1px solid var(--border)}.skill-row.svelte-14apx5e:last-child{border-bottom:none}.skill-row.svelte-14apx5e:hover{background:var(--bg-2)}.skill-info.svelte-14apx5e{flex:1;min-width:0}.skill-name.svelte-14apx5e{font-size:13px;font-weight:500;color:var(--text-0)}.skill-desc.svelte-14apx5e{font-size:12px;color:var(--text-1);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.skill-meta.svelte-14apx5e{font-size:11px;color:var(--text-2);margin-top:2px}.skill-actions.svelte-14apx5e{display:flex;gap:4px;flex-shrink:0}.action-btn.svelte-14apx5e{padding:4px 10px;font-size:11px;border-radius:var(--radius);font-weight:500}.action-btn.svelte-14apx5e:disabled{opacity:.5}.remove-btn.svelte-14apx5e{background:var(--bg-3);color:var(--text-2)}.remove-btn.svelte-14apx5e:hover{color:var(--red)}.system-logs.svelte-y6pt47{display:flex;flex-direction:column;height:100%}.header.svelte-y6pt47{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;flex-shrink:0}.title.svelte-y6pt47{color:var(--text-1);font-size:13px;font-weight:500}.count.svelte-y6pt47{color:var(--text-2);font-size:11px}.filter-bar.svelte-y6pt47{display:flex;align-items:center;gap:6px;margin-bottom:8px;flex-shrink:0;flex-wrap:wrap}.filter-group.svelte-y6pt47{display:flex;gap:4px;flex-wrap:wrap}.filter-sep.svelte-y6pt47{width:1px;height:16px;background:var(--border);margin:0 4px}.pill.svelte-y6pt47{padding:2px 8px;border-radius:10px;font-size:10px;font-family:var(--mono);cursor:pointer;border:1px solid transparent;transition:opacity .1s}.pill-info.svelte-y6pt47,.pill-debug.svelte-y6pt47{background:color-mix(in srgb,var(--text-2) 15%,transparent);color:var(--text-2)}.pill-warn.svelte-y6pt47{background:color-mix(in srgb,var(--yellow) 15%,transparent);color:var(--yellow)}.pill-error.svelte-y6pt47{background:color-mix(in srgb,var(--red) 15%,transparent);color:var(--red)}.pill-cat.svelte-y6pt47{background:var(--bg-3);color:var(--text-2)}.pill-clear.svelte-y6pt47{background:none;color:var(--text-2);border:1px dashed var(--border);margin-left:4px}.pill-clear.svelte-y6pt47:hover{color:var(--text-1);border-color:var(--text-2)}.pill.inactive.svelte-y6pt47{opacity:.3}.pause-bar.svelte-y6pt47{padding:6px 12px;background:var(--bg-3);border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;font-size:11px;color:var(--text-2);flex-shrink:0}.resume-btn.svelte-y6pt47{background:var(--accent-dim);color:var(--accent);padding:2px 10px;border-radius:var(--radius);font-size:11px}.log-output.svelte-y6pt47{flex:1;overflow:auto;padding:12px;font-family:var(--mono);font-size:11px;line-height:1.7;color:var(--text-1);background:var(--bg-0);border:1px solid var(--border);border-radius:var(--radius-lg)}.waiting.svelte-y6pt47{color:var(--text-2)}.error.svelte-y6pt47{color:var(--red)}.log-line.svelte-y6pt47{animation:fadeIn .1s ease both;display:flex;gap:1ch}.ts.svelte-y6pt47{color:var(--text-2);flex-shrink:0}.level.svelte-y6pt47{flex-shrink:0;width:5ch}.cat.svelte-y6pt47{color:var(--text-2);opacity:.6;flex-shrink:0;width:12ch;overflow:hidden;text-overflow:ellipsis}.msg.svelte-y6pt47{color:var(--text-0);white-space:pre-wrap;word-break:break-word;min-width:0}.data.svelte-y6pt47{color:var(--text-2);white-space:pre-wrap;word-break:break-word}.tab-bar.svelte-1tbaq71{display:flex}.tab.svelte-1tbaq71{padding:10px 16px;background:transparent;color:var(--text-2);font-size:12px;font-weight:500;border-bottom:2px solid transparent;transition:all .15s;margin-bottom:-1px}.tab.active.svelte-1tbaq71{color:var(--accent);border-bottom-color:var(--accent)}.container.svelte-1j9xdsd{max-width:600px;animation:fadeIn .2s ease both}.header.svelte-1j9xdsd{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.title.svelte-1j9xdsd{font-size:15px;font-weight:600}.user-list.svelte-1j9xdsd{display:flex;flex-direction:column;gap:8px}.user-row.svelte-1j9xdsd{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius)}.username.svelte-1j9xdsd{color:var(--text-0);margin-right:12px}.role.svelte-1j9xdsd{font-size:11px;color:var(--text-2)}.role.admin.svelte-1j9xdsd{color:var(--accent)}.role.pending.svelte-1j9xdsd{color:var(--yellow)}.approve-btn.svelte-1j9xdsd{padding:4px 12px;background:var(--accent-dim);color:var(--accent);border-radius:var(--radius);font-size:11px;font-weight:500}.error.svelte-1j9xdsd{color:var(--red);font-size:12px;margin-bottom:12px}.empty.svelte-1j9xdsd{color:var(--text-2);text-align:center;padding:24px}.modal-header.svelte-1r58s0h{display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border);padding:0 16px;flex-shrink:0}.close-btn.svelte-1r58s0h{background:none;color:var(--text-2);font-size:14px;padding:4px 8px}.close-btn.svelte-1r58s0h:hover{color:var(--text-0)}.modal-body.svelte-1r58s0h{flex:1;overflow:auto;padding:16px}.error.svelte-16qbe83{padding:8px 16px;font-size:12px;color:var(--red)}.channel-list.svelte-16qbe83{flex:1;overflow:auto;padding:8px}.empty.svelte-16qbe83{color:var(--text-2);font-size:12px;text-align:center;padding:20px}.channel-row.svelte-16qbe83{display:flex;align-items:center;justify-content:space-between;padding:8px;border-radius:var(--radius)}.channel-row.svelte-16qbe83:hover{background:var(--bg-2)}.channel-info.svelte-16qbe83{display:flex;flex-direction:column;gap:2px}.channel-name.svelte-16qbe83{font-size:13px;color:var(--text-0);font-weight:500}.channel-meta.svelte-16qbe83{font-size:11px;color:var(--text-2)}.action-btn.svelte-16qbe83{padding:4px 12px;font-size:11px;border-radius:var(--radius);background:var(--accent-dim);color:var(--accent);font-weight:500}.action-btn.leave.svelte-16qbe83{background:var(--bg-3);color:var(--text-2)}.create-section.svelte-16qbe83{display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--border)}.name-input.svelte-16qbe83{flex:1;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:8px 10px;color:var(--text-0);font-size:12px;font-family:var(--mono);outline:none}.name-input.svelte-16qbe83:focus{border-color:var(--border-bright)}.create-btn.svelte-16qbe83{padding:8px 14px;background:var(--accent-dim);color:var(--accent);border-radius:var(--radius);font-size:12px;font-weight:500}.create-btn.svelte-16qbe83:disabled{opacity:.4}.badge.svelte-w1qana{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:var(--radius);font-size:11px;font-weight:500;letter-spacing:.02em;text-transform:uppercase}.dot.svelte-w1qana{width:5px;height:5px;border-radius:50%}.dot.iridescent.svelte-w1qana{animation:svelte-w1qana-iridescent 3s ease-in-out infinite}@keyframes svelte-w1qana-breathe{0%,to{opacity:.4}50%{opacity:1}}@keyframes svelte-w1qana-iridescent{0%{background:#4ade80}16%{background:#60a5fa}33%{background:#c084fc}50%{background:#f472b6}66%{background:#fbbf24}83%{background:#34d399}to{background:#4ade80}}.members-panel.svelte-488b49{display:flex;flex-direction:column;height:100%;background:var(--bg-1);border-left:1px solid var(--border);width:280px;flex-shrink:0;overflow:hidden}.panel-header.svelte-488b49{display:flex;align-items:center;gap:8px;padding:12px 16px;border-bottom:1px solid var(--border);flex-shrink:0}.panel-title.svelte-488b49{font-size:13px;font-weight:600;color:var(--text-0)}.member-count.svelte-488b49{font-size:11px;color:var(--text-2)}.panel-body.svelte-488b49{flex:1;overflow:auto;padding:12px 0}.invite-section.svelte-488b49{padding:0 12px 8px;border-bottom:1px solid var(--border);margin-bottom:4px}.invite-input-wrap.svelte-488b49{position:relative}.invite-input.svelte-488b49{width:100%;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:6px 10px;color:var(--text-0);font-size:12px;font-family:var(--mono);outline:none;box-sizing:border-box}.invite-input.svelte-488b49:focus{border-color:var(--border-bright)}.suggestions.svelte-488b49{position:absolute;top:100%;left:0;right:0;background:var(--bg-1);border:1px solid var(--border);border-radius:var(--radius);margin-top:4px;max-height:200px;overflow:auto;z-index:10;box-shadow:0 4px 12px #0000004d}.suggestion-row.svelte-488b49{display:flex;align-items:center;gap:8px;padding:6px 10px;width:100%;background:none;border:none;text-align:left;font-size:12px;color:var(--text-1);cursor:pointer}.suggestion-row.svelte-488b49:hover{background:var(--bg-2)}.suggestion-name.svelte-488b49{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;color:var(--text-0)}.invite-error.svelte-488b49{color:var(--red);font-size:11px;padding:4px 0 0}.section-title.svelte-488b49{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-2);padding:8px 16px 4px}.member-row.svelte-488b49{display:flex;align-items:center;gap:8px;padding:6px 16px;font-size:13px;color:var(--text-1);width:100%;background:none;border:none;text-align:left}.member-row.clickable.svelte-488b49{cursor:pointer}.member-row.clickable.svelte-488b49:hover{background:var(--bg-2)}.member-name.svelte-488b49{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;color:var(--text-0)}.status-dot.svelte-488b49{width:7px;height:7px;border-radius:50%;flex-shrink:0}.status-dot.iridescent.svelte-488b49{animation:svelte-488b49-iridescent 3s ease-in-out infinite}@keyframes svelte-488b49-iridescent{0%{background:#4ade80}16%{background:#60a5fa}33%{background:#c084fc}50%{background:#f472b6}66%{background:#fbbf24}83%{background:#34d399}to{background:#4ade80}}.container.svelte-zwrylj{display:flex;align-items:center;justify-content:center;height:100%;padding:24px}.card.svelte-zwrylj{width:320px;padding:32px;background:var(--bg-1);border:1px solid var(--border);border-radius:var(--radius-lg)}.branding.svelte-zwrylj{margin-bottom:24px;text-align:center}.logo.svelte-zwrylj{font-size:18px;font-weight:600;margin-bottom:4px}.accent.svelte-zwrylj{color:var(--accent)}.subtitle.svelte-zwrylj{color:var(--text-2);font-size:12px}.input.svelte-zwrylj{width:100%;padding:10px 12px;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);color:var(--text-0);font-family:var(--mono);font-size:13px;outline:none}.input.svelte-zwrylj:focus{border-color:var(--border-bright)}.mt-8.svelte-zwrylj{margin-top:8px}.error.svelte-zwrylj{color:var(--red);font-size:12px;margin-top:8px}.submit-btn.svelte-zwrylj{width:100%;padding:10px 16px;margin-top:16px;background:var(--accent-dim);color:var(--accent);border-radius:var(--radius);font-size:13px;font-weight:500;font-family:var(--mono);border:none;cursor:pointer}.link-btn.svelte-zwrylj{background:transparent;color:var(--text-2);font-size:12px;font-family:var(--mono);border:none;cursor:pointer;padding:0}.toggle.svelte-zwrylj{margin-top:16px;text-align:center}.pending-msg.svelte-zwrylj{color:var(--yellow);margin-bottom:16px}.home.svelte-1egy5tu{max-width:800px;animation:fadeIn .2s ease both}.section.svelte-1egy5tu{margin-bottom:24px}.section-header.svelte-1egy5tu{display:flex;align-items:center;gap:8px;font-size:11px;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}.section-title.svelte-1egy5tu{color:var(--text-2)}.empty-hint.svelte-1egy5tu{color:var(--text-2);font-size:12px}.code-hint.svelte-1egy5tu{color:var(--text-1)}.mind-row.svelte-1egy5tu{display:flex;gap:10px;overflow-x:auto;padding-bottom:4px}.home-mind-card.svelte-1egy5tu{display:flex;flex-direction:column;gap:6px;padding:10px 14px;border-radius:var(--radius-lg);background:var(--bg-2);border:1px solid var(--border);min-width:150px;transition:border-color .15s;flex-shrink:0;cursor:pointer;text-align:left;color:inherit;font-size:inherit}.home-mind-card.svelte-1egy5tu:hover{border-color:var(--border-bright)}.mind-card-header.svelte-1egy5tu{display:flex;align-items:center;gap:6px}.mind-name.svelte-1egy5tu{color:var(--text-0);font-weight:500;font-size:13px}.seed-tag.svelte-1egy5tu{font-size:9px;color:var(--yellow)}.channel-row.svelte-1egy5tu{display:flex;gap:4px;flex-wrap:wrap}.channel-chip.svelte-1egy5tu{font-size:10px;padding:1px 5px;border-radius:3px;background:var(--accent-dim);color:var(--accent)}.mind-activity.svelte-1egy5tu{font-size:10px;color:var(--text-2)}.timeline.svelte-1egy5tu{display:flex;flex-direction:column}.timeline-row.svelte-1egy5tu{display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:var(--radius-lg);background:none;border:none;cursor:pointer;text-align:left;color:inherit;font-size:12px;transition:background .12s;width:100%}.timeline-row.svelte-1egy5tu:hover{background:var(--bg-2)}.timeline-dot.svelte-1egy5tu{width:6px;height:6px;border-radius:50%;flex-shrink:0;background:var(--text-2)}.dot-started.svelte-1egy5tu{background:var(--accent)}.dot-stopped.svelte-1egy5tu{background:var(--text-2)}.dot-active.svelte-1egy5tu{background:var(--accent)}.dot-idle.svelte-1egy5tu{background:var(--text-2)}.dot-page.svelte-1egy5tu{background:var(--yellow)}.dot-message.svelte-1egy5tu{background:var(--blue, var(--accent))}.timeline-text.svelte-1egy5tu{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-1)}.timeline-text.svelte-1egy5tu .conv-label:where(.svelte-1egy5tu){color:var(--text-0);font-weight:500}.timeline-time.svelte-1egy5tu{color:var(--text-2);font-size:10px;flex-shrink:0}.thumbnail-card.svelte-15o3gk6{display:flex;flex-direction:column;gap:6px;background:none;cursor:pointer;text-align:left;color:inherit;padding:0}.thumbnail-frame.svelte-15o3gk6{width:280px;height:180px;overflow:hidden;border-radius:var(--radius-lg);border:1px solid var(--border);background:var(--bg-0);transition:border-color .15s}.thumbnail-card.svelte-15o3gk6:hover .thumbnail-frame:where(.svelte-15o3gk6){border-color:var(--border-bright)}iframe.svelte-15o3gk6{width:1280px;height:960px;transform:scale(.219);transform-origin:top left;pointer-events:none;border:none;background:#fff}.thumbnail-label.svelte-15o3gk6{font-size:12px;font-weight:500;color:var(--text-0);padding:0 2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:280px}.thumbnail-sublabel.svelte-15o3gk6{font-size:10px;color:var(--text-2);padding:0 2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:280px}.dashboard.svelte-pd71n3{max-width:1200px;animation:fadeIn .2s ease both}.section.svelte-pd71n3{margin-bottom:24px}.section-header.svelte-pd71n3{font-size:11px;text-transform:uppercase;letter-spacing:.05em;margin-bottom:12px}.section-title.svelte-pd71n3{color:var(--text-2)}.thumbnail-grid.svelte-pd71n3{display:flex;flex-wrap:wrap;gap:16px}.empty.svelte-pd71n3{color:var(--text-2);font-size:12px}.site-view.svelte-s0ylih{max-width:1200px;animation:fadeIn .2s ease both}.site-header.svelte-s0ylih{display:flex;align-items:baseline;gap:8px;margin-bottom:16px}.site-name.svelte-s0ylih{font-size:16px;font-weight:500;color:var(--text-0)}.page-count.svelte-s0ylih{font-size:11px;color:var(--text-2)}.thumbnail-grid.svelte-s0ylih{display:flex;flex-wrap:wrap;gap:16px}.empty.svelte-s0ylih{color:var(--text-2);font-size:12px}.image-strip.svelte-18vyazk{display:flex;gap:8px;padding:8px 0;border-top:1px solid var(--border);overflow-x:auto}.image-preview.svelte-18vyazk{position:relative;flex-shrink:0}.preview-thumb.svelte-18vyazk{height:60px;border-radius:var(--radius);border:1px solid var(--border)}.remove-image.svelte-18vyazk{position:absolute;top:-4px;right:-4px;width:18px;height:18px;border-radius:50%;background:var(--bg-3);color:var(--text-1);font-size:11px;display:flex;align-items:center;justify-content:center;border:1px solid var(--border);cursor:pointer;padding:0}.input-area.svelte-18vyazk{border-top:1px solid var(--border);padding:12px 16px 16px;display:flex;gap:8px}.attach-btn.svelte-18vyazk{padding:0 10px;background:var(--bg-2);color:var(--text-1);border-radius:var(--radius);font-size:16px;border:1px solid var(--border);cursor:pointer;flex-shrink:0}.chat-input.svelte-18vyazk{flex:1;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;color:var(--text-0);font-family:var(--mono);font-size:13px;resize:none;outline:none;overflow:hidden;transition:border-color .15s}.chat-input.svelte-18vyazk:focus{border-color:var(--border-bright)}.send-btn.svelte-18vyazk{padding:0 16px;background:var(--bg-3);color:var(--text-2);border-radius:var(--radius);font-size:12px;font-weight:500;transition:all .15s}.send-btn.active.svelte-18vyazk{background:var(--accent-dim);color:var(--accent)}.hover-wrapper.svelte-16mitnt{display:flex;align-items:center;gap:8px}.hover-card.svelte-16mitnt{position:fixed;z-index:100;display:flex;gap:10px;padding:10px 12px;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);box-shadow:0 4px 12px #0000004d;white-space:nowrap;pointer-events:none}.avatar.svelte-16mitnt{width:64px;height:64px;border-radius:var(--radius);object-fit:cover;flex-shrink:0}.info.svelte-16mitnt{display:flex;flex-direction:column;gap:2px;min-width:0}.name-row.svelte-16mitnt{display:flex;align-items:center;gap:6px}.display-name.svelte-16mitnt{font-size:13px;font-weight:600;color:var(--text-0)}.description.svelte-16mitnt{font-size:11px;color:var(--text-1);white-space:normal;max-width:220px;margin-top:2px}.meta.svelte-16mitnt{font-size:10px;color:var(--text-2);margin-top:2px}.tool-block.svelte-11dtec0{margin-bottom:8px;border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;font-size:12px}.tool-header.svelte-11dtec0{width:100%;display:flex;align-items:center;justify-content:space-between;padding:6px 10px;background:var(--bg-3);font-size:12px;font-family:var(--mono);text-align:left}.tool-label.svelte-11dtec0{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}.tool-arrow.svelte-11dtec0{color:var(--text-2);margin-right:6px}.tool-status.svelte-11dtec0{color:var(--accent);font-size:10px;flex-shrink:0;margin-left:8px}.tool-status.error.svelte-11dtec0{color:var(--red)}.tool-detail.svelte-11dtec0{padding:10px;background:var(--bg-1)}.tool-section-label.svelte-11dtec0{margin-bottom:6px;color:var(--text-2)}.tool-pre.svelte-11dtec0{color:var(--text-1);white-space:pre-wrap;word-break:break-all;font-size:11px;line-height:1.5}.tool-output.svelte-11dtec0{max-height:200px;overflow:auto}.tool-output.error.svelte-11dtec0{color:var(--red)}.entry.svelte-16zmiqs{padding:2px 0;animation:fadeIn .2s ease both}.entry.new-sender.svelte-16zmiqs{margin-top:12px}.entry-header.svelte-16zmiqs{display:flex;align-items:baseline;gap:8px;margin-bottom:2px}.sender.svelte-16zmiqs{font-size:13px;font-weight:600}.sender-link.svelte-16zmiqs{background:none;border:none;padding:0;font:inherit;font-size:13px;font-weight:600;cursor:pointer}.sender-link.svelte-16zmiqs:hover{text-decoration:underline}.timestamp.svelte-16zmiqs{font-size:11px;color:var(--text-2)}.inline-time.svelte-16zmiqs{display:block;margin-bottom:2px}.entry-content.svelte-16zmiqs{min-width:0}.user-text.svelte-16zmiqs{color:var(--text-0);white-space:pre-wrap}.chat-image.svelte-16zmiqs{max-width:300px;max-height:200px;border-radius:var(--radius);margin-top:4px}.messages.svelte-tjsfkk{flex:1;overflow:auto;padding:16px}.empty.svelte-tjsfkk{color:var(--text-2);text-align:center;padding:40px;font-size:13px}.error.svelte-tjsfkk{color:var(--red)}.loading-older.svelte-tjsfkk{text-align:center;padding:8px;font-size:12px;color:var(--text-2)}.load-more.svelte-tjsfkk{text-align:center;padding:8px}.load-more-btn.svelte-tjsfkk{font-size:12px;color:var(--text-2);background:none;border:1px solid var(--border);border-radius:var(--radius);padding:4px 12px;cursor:pointer}.load-more-btn.svelte-tjsfkk:hover{color:var(--text-1);border-color:var(--border-bright)}.divider.svelte-tjsfkk{display:flex;align-items:center;gap:12px;margin:20px 0;color:var(--text-2);font-size:11px;letter-spacing:.03em}.divider-line.svelte-tjsfkk{flex:1;height:1px;background:var(--border)}.typing.svelte-em2dtd{padding:4px 0;font-size:12px;color:var(--text-2);animation:pulse 1.5s ease infinite}.chat.svelte-6z343n{display:flex;flex-direction:column;height:100%;padding:0}.orientation-bar.svelte-6z343n{padding:6px 12px;text-align:center;color:var(--yellow);font-size:11px;font-weight:500;letter-spacing:.05em;text-transform:uppercase;opacity:.6;border-bottom:1px solid var(--yellow-bg)}.channel-header.svelte-6z343n{display:flex;align-items:center;gap:10px;padding:8px 12px;border-bottom:1px solid var(--border);flex-shrink:0}.channel-title.svelte-6z343n{font-size:13px;font-weight:600;color:var(--text-0)}.channel-members.svelte-6z343n{font-size:11px;color:var(--text-2);flex:1}.main-frame.svelte-n1trtr{height:100%;overflow:hidden;display:flex;flex-direction:column}.frame-content.svelte-n1trtr{flex:1;overflow:auto;min-height:0}.frame-content.padded.svelte-n1trtr{padding:24px}.breadcrumbs.svelte-n1trtr{display:flex;align-items:center;gap:6px;padding:8px 16px;font-family:var(--font-mono, monospace);font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-2);border-bottom:1px solid var(--border);flex-shrink:0}.breadcrumb-link.svelte-n1trtr{background:none;border:none;padding:0;font:inherit;text-transform:inherit;letter-spacing:inherit;color:var(--text-1);cursor:pointer}.breadcrumb-link.svelte-n1trtr:hover{color:var(--accent)}.breadcrumb-sep.svelte-n1trtr,.breadcrumb-current.svelte-n1trtr{color:var(--text-2)}.page-iframe.svelte-n1trtr{width:100%;height:100%;border:none;background:#fff}.event.svelte-173x8i5{position:relative;padding:6px 8px 6px 20px;animation:fadeIn .2s ease both}.event.svelte-173x8i5:after{content:"";position:absolute;left:-2px;top:12px;bottom:-12px;width:2px;background:var(--type-color);opacity:0;transition:opacity .15s}.event.svelte-173x8i5:hover:after{opacity:1}.event.collapsible.svelte-173x8i5{cursor:pointer}.marker.svelte-173x8i5{position:absolute;left:-5px;top:12px;width:8px;height:8px;border-radius:50%;z-index:1}.event-header.svelte-173x8i5{display:flex;align-items:center;gap:8px;margin-bottom:4px}.time.svelte-173x8i5{font-size:10px;color:var(--text-2);flex-shrink:0}.type-badge.svelte-173x8i5{font-size:10px;padding:1px 6px;border-radius:12px;font-weight:500}.channel-tag.svelte-173x8i5{font-size:10px;color:var(--text-2);background:var(--bg-3);padding:1px 6px;border-radius:var(--radius)}.chevron.svelte-173x8i5{font-size:9px;color:var(--text-2)}.event-body.svelte-173x8i5{font-size:13px;line-height:1.6}.sender.svelte-173x8i5{font-size:11px;font-weight:600;text-transform:uppercase;margin-right:8px}.sender.inbound.svelte-173x8i5{color:var(--blue)}.sender.outbound.svelte-173x8i5{color:var(--accent)}.user-text.svelte-173x8i5{display:inline;white-space:pre-wrap;color:var(--text-0)}.summary.svelte-173x8i5{font-size:12px;color:var(--text-1)}.summary.error.svelte-173x8i5{color:var(--red)}.dim.svelte-173x8i5{color:var(--text-2)}.detail.svelte-173x8i5,.detail-text.svelte-173x8i5{margin-top:6px;font-size:11px;background:var(--bg-3);border:1px solid var(--border);border-radius:var(--radius);padding:8px 10px;overflow-x:auto;max-height:400px;overflow-y:auto;white-space:pre-wrap;word-break:break-all}.detail.svelte-173x8i5{font-family:var(--mono)}.detail.error.svelte-173x8i5{color:var(--red);border-color:var(--red-dim)}.detail-text.svelte-173x8i5{color:var(--text-2)}.usage-line.svelte-173x8i5{font-size:12px;color:var(--purple)}.model.svelte-173x8i5{color:var(--text-2);margin-left:6px;font-size:11px}.session-id.svelte-173x8i5{font-size:11px;color:var(--text-1);font-weight:600;margin-left:4px}.filter-container.svelte-h6u4xu{position:relative;flex-shrink:0}.filter-btn.svelte-h6u4xu{position:relative;display:flex;align-items:center;justify-content:center;width:28px;height:28px;background:none;border:none;color:var(--text-2);cursor:pointer;border-radius:var(--radius);transition:color .15s,background .15s}.filter-btn.svelte-h6u4xu:hover{color:var(--text-1);background:var(--bg-3)}.filter-btn.active.svelte-h6u4xu{color:var(--accent)}.filter-dot.svelte-h6u4xu{position:absolute;top:4px;right:4px;width:5px;height:5px;border-radius:50%;background:var(--accent)}.filter-popover.svelte-h6u4xu{position:absolute;top:calc(100% + 4px);right:0;width:260px;background:var(--bg-2);border:1px solid var(--border-bright);border-radius:var(--radius);z-index:20;box-shadow:0 4px 16px #0006;padding:8px;display:flex;flex-direction:column;gap:6px}.filter-row.svelte-h6u4xu{display:flex;align-items:center;gap:8px}.filter-label.svelte-h6u4xu{font-size:11px;color:var(--text-2);width:52px;flex-shrink:0;font-family:var(--mono)}.types-row.svelte-h6u4xu{align-items:flex-start;padding-top:4px;border-top:1px solid var(--border);margin-top:2px}.types-grid.svelte-h6u4xu{display:flex;flex-wrap:wrap;gap:4px;flex:1}.types-actions.svelte-h6u4xu{display:flex;gap:4px;width:100%;margin-bottom:2px}.types-action.svelte-h6u4xu{font-size:10px;font-family:var(--mono);color:var(--text-2);background:none;border:none;cursor:pointer;padding:1px 6px;border-radius:var(--radius)}.types-action.svelte-h6u4xu:hover{color:var(--text-1);background:var(--bg-3)}.type-chip.svelte-h6u4xu{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;font-size:10px;font-family:var(--mono);color:var(--text-2);background:none;border:none;cursor:pointer;border-radius:var(--radius);transition:color .1s}.type-chip.svelte-h6u4xu:hover{background:var(--bg-3);color:var(--text-1)}.type-chip.active.svelte-h6u4xu{color:var(--text-1)}.type-dot.svelte-h6u4xu{width:5px;height:5px;border-radius:50%;flex-shrink:0;transition:background .15s}.custom-select.svelte-h6u4xu{position:relative;flex:1}.select-trigger.svelte-h6u4xu{display:flex;align-items:center;gap:4px;width:100%;background:var(--bg-3);color:var(--text-1);border:none;border-radius:var(--radius);padding:3px 6px;font-size:11px;font-family:var(--mono);cursor:pointer;transition:color .15s}.select-trigger.svelte-h6u4xu:hover{color:var(--text-0)}.select-value.svelte-h6u4xu{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}.select-arrow.svelte-h6u4xu{font-size:9px;color:var(--text-2);flex-shrink:0}.select-menu.svelte-h6u4xu{position:absolute;top:calc(100% + 2px);left:0;min-width:100%;max-height:200px;overflow-y:auto;background:var(--bg-2);border:1px solid var(--border-bright);border-radius:var(--radius);z-index:30;box-shadow:0 4px 16px #0006}.select-option.svelte-h6u4xu{display:block;width:100%;text-align:left;padding:5px 8px;font-size:11px;font-family:var(--mono);color:var(--text-1);background:none;border:none;cursor:pointer;white-space:nowrap;transition:background .1s,color .1s}.select-option.svelte-h6u4xu:hover{background:var(--bg-3);color:var(--text-0)}.select-option.selected.svelte-h6u4xu{color:var(--accent)}.option-meta.svelte-h6u4xu{color:var(--text-2);margin-left:4px}.divider.svelte-c707oo{display:flex;align-items:center;gap:12px;margin:20px 0 16px}.line.svelte-c707oo{flex:1;border-top:1px solid var(--border)}.label.svelte-c707oo{font-size:11px;color:var(--text-2);white-space:nowrap;display:flex;align-items:center;gap:6px}.session-id.svelte-c707oo{color:var(--text-1);font-weight:600}.sep.svelte-c707oo{color:var(--border-bright)}.history.svelte-i5te79{display:flex;flex-direction:column;height:100%;overflow:hidden;position:relative}.filter-float.svelte-i5te79{position:absolute;top:4px;right:4px;z-index:10}.timeline.svelte-i5te79{flex:1;overflow-x:hidden;overflow-y:auto;display:flex;flex-direction:column}.timeline-rail.svelte-i5te79{position:relative;padding-left:4px;margin-left:3px;flex:1;min-height:100%}.timeline-rail.svelte-i5te79:before{content:"";position:absolute;left:2px;top:0;bottom:0;width:2px;background:var(--timeline-rail)}.error.svelte-i5te79{color:var(--red);text-align:center;padding:40px;font-size:13px}.empty.svelte-i5te79{color:var(--text-2);text-align:center;padding:40px;font-size:13px}.load-older.svelte-i5te79{padding:8px 0 16px;text-align:center}.load-older-btn.svelte-i5te79{padding:4px 14px;background:var(--bg-3);color:var(--text-1);border-radius:var(--radius);font-size:11px}.loading-more.svelte-i5te79{text-align:center;color:var(--text-2);font-size:12px;padding:12px;animation:pulse 1.5s infinite}.jump-btn.svelte-i5te79{position:absolute;bottom:16px;left:50%;transform:translate(-50%);padding:6px 16px;background:var(--accent-dim);color:var(--accent);border-radius:var(--radius);font-size:12px;animation:fadeIn .2s ease both;z-index:10}.empty.svelte-wh20l9{color:var(--text-2);padding:24px;text-align:center;font-size:13px}.empty.small.svelte-wh20l9{padding:12px}.error.svelte-wh20l9{color:var(--red);padding:8px 0;font-size:12px}.section.svelte-wh20l9{margin-bottom:24px}.section-title.svelte-wh20l9{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-2);margin-bottom:8px}.section-header.svelte-wh20l9{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.status-row.svelte-wh20l9{display:flex;align-items:center;gap:10px}.action-btn.svelte-wh20l9{padding:4px 12px;border-radius:var(--radius);font-size:11px;font-weight:500;transition:opacity .15s}.start-btn.svelte-wh20l9{background:var(--accent-dim);color:var(--accent)}.stop-btn.svelte-wh20l9{background:var(--red-dim);color:var(--red)}.setting-row.svelte-wh20l9{display:flex;align-items:center;gap:12px;padding:6px 0}.setting-label.svelte-wh20l9{width:100px;flex-shrink:0;font-size:13px;color:var(--text-1)}.setting-control.svelte-wh20l9{display:flex;align-items:center;gap:6px;flex:1}.setting-input.svelte-wh20l9{background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:4px 8px;font-size:13px;color:var(--text-0);flex:1;font-family:inherit}.setting-input.narrow.svelte-wh20l9{width:80px;flex:0 0 80px}.setting-input.svelte-wh20l9:focus{border-color:var(--accent);outline:none}.setting-select.svelte-wh20l9{background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:4px 8px;font-size:13px;color:var(--text-0);font-family:inherit}.setting-hint.svelte-wh20l9{font-size:12px;color:var(--text-2);flex-shrink:0}.save-btn.svelte-wh20l9{padding:4px 10px;font-size:11px;border-radius:var(--radius);background:var(--accent-dim);color:var(--accent);font-weight:500;flex-shrink:0}.save-btn.svelte-wh20l9:disabled{opacity:.5}.cancel-btn.svelte-wh20l9{padding:4px 10px;font-size:11px;border-radius:var(--radius);background:var(--bg-3);color:var(--text-2);font-weight:500;flex-shrink:0}.add-btn.svelte-wh20l9{padding:4px 12px;font-size:11px;border-radius:var(--radius);background:var(--accent-dim);color:var(--accent);font-weight:500}.env-list.svelte-wh20l9{display:flex;flex-direction:column}.env-row.svelte-wh20l9{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid var(--border);font-size:13px}.env-row.svelte-wh20l9:last-child{border-bottom:none}.env-add-row.svelte-wh20l9{display:flex;align-items:center;gap:6px;padding:6px 0;margin-bottom:8px}.env-key.svelte-wh20l9{font-family:monospace;font-size:12px;color:var(--text-0);flex-shrink:0;min-width:100px;display:flex;align-items:center;gap:6px}.env-source.svelte-wh20l9{font-family:inherit;font-size:10px;padding:1px 4px;border-radius:4px;background:var(--bg-3);color:var(--text-2)}.env-value.svelte-wh20l9{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:monospace;font-size:12px;color:var(--text-1)}.env-value.masked.svelte-wh20l9{color:var(--text-2)}.env-input.svelte-wh20l9{background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:4px 8px;font-size:12px;color:var(--text-0);font-family:monospace}.env-input.key.svelte-wh20l9{width:120px;flex-shrink:0}.env-input.value.svelte-wh20l9{flex:1}.icon-btn.svelte-wh20l9{padding:2px 6px;font-size:10px;border-radius:var(--radius);background:var(--bg-3);color:var(--text-2);flex-shrink:0}.icon-btn.svelte-wh20l9:hover{color:var(--text-0)}.icon-btn.danger.svelte-wh20l9:hover{color:var(--red)}.modal-body.svelte-l4ioia{flex:1;overflow:auto;padding:8px 16px 16px}.error.svelte-l4ioia{color:var(--red);padding:8px 0;font-size:12px}.empty.svelte-l4ioia{color:var(--text-2);padding:24px;text-align:center;font-size:13px}.skill-list.svelte-l4ioia{display:flex;flex-direction:column}.skill-row.svelte-l4ioia{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0;border-bottom:1px solid var(--border)}.skill-row.svelte-l4ioia:last-child{border-bottom:none}.skill-info.svelte-l4ioia{flex:1;min-width:0}.skill-name.svelte-l4ioia{font-size:13px;font-weight:500;color:var(--text-0)}.skill-desc.svelte-l4ioia{font-size:12px;color:var(--text-1);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.skill-meta.svelte-l4ioia{font-size:11px;color:var(--text-2);margin-top:2px}.skill-actions.svelte-l4ioia{flex-shrink:0}.installed-tag.svelte-l4ioia{font-size:11px;color:var(--text-2);font-style:italic}.action-btn.svelte-l4ioia{padding:4px 10px;font-size:11px;border-radius:var(--radius);font-weight:500}.action-btn.svelte-l4ioia:disabled{opacity:.5}.install-btn.svelte-l4ioia{background:var(--accent-dim);color:var(--accent)}.error.svelte-jfofjj{color:var(--red);padding:8px 0;font-size:12px}.empty.svelte-jfofjj{color:var(--text-2);padding:12px 0;font-size:13px}.section-header.svelte-jfofjj{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.section-title.svelte-jfofjj{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-2)}.add-btn.svelte-jfofjj{padding:4px 12px;font-size:11px;border-radius:var(--radius);background:var(--accent-dim);color:var(--accent);font-weight:500}.skill-list.svelte-jfofjj{display:flex;flex-direction:column}.skill-row.svelte-jfofjj{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:6px 0;border-bottom:1px solid var(--border)}.skill-row.svelte-jfofjj:last-child{border-bottom:none}.skill-row.svelte-jfofjj:hover{background:var(--bg-2)}.skill-info.svelte-jfofjj{flex:1;min-width:0}.skill-name.svelte-jfofjj{font-size:13px;font-weight:500;color:var(--text-0);display:flex;align-items:center;gap:8px}.skill-desc.svelte-jfofjj{font-size:12px;color:var(--text-1);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.skill-meta.svelte-jfofjj{font-size:11px;color:var(--text-2);margin-top:2px}.update-badge.svelte-jfofjj{font-size:10px;padding:1px 6px;border-radius:8px;background:var(--accent-dim);color:var(--accent);font-weight:500}.upstream-tag.svelte-jfofjj{color:var(--text-2)}.local-tag.svelte-jfofjj{font-style:italic;color:var(--text-2)}.skill-actions.svelte-jfofjj{display:flex;gap:4px;flex-shrink:0}.action-btn.svelte-jfofjj{padding:4px 10px;font-size:11px;border-radius:var(--radius);font-weight:500}.action-btn.svelte-jfofjj:disabled{opacity:.5}.update-btn.svelte-jfofjj{background:var(--accent-dim);color:var(--accent)}.publish-btn.svelte-jfofjj{background:var(--bg-3);color:var(--text-1)}.remove-btn.svelte-jfofjj{background:var(--bg-3);color:var(--text-2)}.remove-btn.svelte-jfofjj:hover{color:var(--red)}.error.svelte-16y8q82{color:var(--red);padding:16px}.empty.svelte-16y8q82{color:var(--text-2);padding:24px;text-align:center}.table-wrap.svelte-16y8q82{overflow:auto}.variant-table.svelte-16y8q82{width:100%;border-collapse:collapse;font-size:13px}.variant-table.svelte-16y8q82 th:where(.svelte-16y8q82){text-align:left;color:var(--text-2);font-size:11px;text-transform:uppercase;letter-spacing:.04em;padding:8px 12px;border-bottom:1px solid var(--border);font-weight:500}.variant-row.svelte-16y8q82{animation:fadeIn .2s ease both}.variant-row.svelte-16y8q82 td:where(.svelte-16y8q82){padding:10px 12px;border-bottom:1px solid var(--border)}.name-cell.svelte-16y8q82{color:var(--text-0);font-weight:500}.branch-cell.svelte-16y8q82{color:var(--text-1)}.port-cell.svelte-16y8q82{color:var(--text-2)}.mind-panel.svelte-5k8fm{display:flex;flex-direction:column;height:100%;background:var(--bg-1);border-left:1px solid var(--border);width:480px;flex-shrink:0;overflow:hidden}.panel-header.svelte-5k8fm{display:flex;flex-direction:column;border-bottom:1px solid var(--border);flex-shrink:0}.header-top.svelte-5k8fm{display:flex;align-items:center;justify-content:space-between;padding:8px 16px 0}.header-left.svelte-5k8fm{display:flex;align-items:center;gap:10px}.mind-name.svelte-5k8fm{font-size:14px;font-weight:600;color:var(--text-0)}.close-btn.svelte-5k8fm{background:none;color:var(--text-2);font-size:14px;padding:4px 8px}.close-btn.svelte-5k8fm:hover{color:var(--text-0)}.panel-body.svelte-5k8fm{flex:1;overflow:auto;min-height:0}.settings-content.svelte-5k8fm{padding:16px}.panel-body-flex.svelte-5k8fm{display:flex;flex-direction:column;overflow:hidden}.detail-section.svelte-5k8fm{margin-top:24px;padding-top:24px;border-top:1px solid var(--border)}.section-title.svelte-5k8fm{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-2);margin-bottom:8px}.connections-empty.svelte-5k8fm{color:var(--text-2);padding:12px 0;font-size:13px}.connections-list.svelte-5k8fm{display:flex;flex-direction:column}.connection-row.svelte-5k8fm{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid var(--border);font-size:13px}.connection-row.svelte-5k8fm:last-child{border-bottom:none}.connection-name.svelte-5k8fm{font-weight:500;color:var(--text-0)}.connection-bot.svelte-5k8fm{font-size:12px;color:var(--text-1)}.connection-time.svelte-5k8fm{font-size:11px;color:var(--text-2);margin-left:auto}.profile-section.svelte-5k8fm{display:flex;flex-direction:column;align-items:center;gap:4px;padding:0 16px 16px}.profile-avatar.svelte-5k8fm{width:96px;height:96px;border-radius:var(--radius);object-fit:cover}.profile-display-name.svelte-5k8fm{font-size:18px;font-weight:600;color:var(--text-0)}.profile-description.svelte-5k8fm{font-size:13px;color:var(--text-1);text-align:center;max-width:320px;margin:4px 0 0;line-height:1.4}.profile-meta.svelte-5k8fm{font-size:11px;color:var(--text-2);margin-top:4px}.history-section.svelte-5k8fm{flex:1;min-height:0;padding:0 16px;border-top:1px solid var(--border)}.modal-content.svelte-sa0ylk{padding:20px;display:flex;flex-direction:column;gap:12px;max-height:60vh;overflow:auto}.modal-title.svelte-sa0ylk{font-weight:600;color:var(--text-0);font-size:14px}.title-input.svelte-sa0ylk{background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:8px 10px;color:var(--text-0);font-size:12px;outline:none;font-family:var(--mono)}.hint.svelte-sa0ylk{color:var(--text-2);font-size:11px;padding:8px}.error.svelte-sa0ylk{color:var(--red);font-size:11px}.tag-input-wrapper.svelte-sa0ylk{position:relative}.tag-input.svelte-sa0ylk{display:flex;flex-wrap:wrap;align-items:center;gap:4px;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:6px 8px;min-height:32px;cursor:text}.tag-input.svelte-sa0ylk:focus-within{border-color:var(--accent)}.tag.svelte-sa0ylk{display:flex;align-items:center;gap:4px;background:var(--bg-3);border-radius:3px;padding:2px 6px;font-size:11px;color:var(--text-0);white-space:nowrap}.tag-name.svelte-sa0ylk{line-height:1}.tag-remove.svelte-sa0ylk{cursor:pointer;color:var(--text-2);font-size:13px;line-height:1;margin-left:2px}.tag-remove.svelte-sa0ylk:hover{color:var(--text-0)}.dot.svelte-sa0ylk{width:6px;height:6px;border-radius:50%;flex-shrink:0}.tag-text-input.svelte-sa0ylk{flex:1;min-width:60px;background:none;border:none;outline:none;color:var(--text-0);font-size:12px;padding:2px 0;font-family:var(--mono)}.tag-text-input.svelte-sa0ylk::placeholder{color:var(--text-2)}.dropdown.svelte-sa0ylk{position:absolute;top:100%;left:0;right:0;margin-top:4px;background:var(--bg-1);border:1px solid var(--border);border-radius:var(--radius);max-height:200px;overflow:auto;z-index:10}.dropdown-item.svelte-sa0ylk{display:flex;align-items:center;gap:8px;padding:6px 10px;cursor:pointer;font-size:12px;color:var(--text-0)}.dropdown-item.svelte-sa0ylk:hover{background:var(--bg-2)}.item-name.svelte-sa0ylk{flex:1;overflow:hidden;text-overflow:ellipsis}.item-badge.svelte-sa0ylk{color:var(--accent);font-size:10px;flex-shrink:0}.actions.svelte-sa0ylk{display:flex;gap:8px;justify-content:flex-end}.cancel-btn.svelte-sa0ylk{padding:6px 14px;background:var(--bg-2);color:var(--text-1);border-radius:var(--radius);font-size:12px;border:1px solid var(--border)}.create-btn.svelte-sa0ylk{padding:6px 14px;background:var(--accent-dim);color:var(--accent);border-radius:var(--radius);font-size:12px;font-weight:500}.modal-content.svelte-esytdb{padding:24px;display:flex;flex-direction:column;gap:14px}.modal-title.svelte-esytdb{font-weight:600;color:var(--text-0);font-size:14px}.field.svelte-esytdb{display:flex;flex-direction:column;gap:4px}.label.svelte-esytdb{color:var(--text-2);font-size:11px}.input.svelte-esytdb{background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:8px 10px;color:var(--text-0);font-size:13px;outline:none;font-family:var(--mono)}.select.svelte-esytdb{appearance:auto}.error.svelte-esytdb{color:var(--red);font-size:11px}.actions.svelte-esytdb{display:flex;gap:8px;justify-content:flex-end}.cancel-btn.svelte-esytdb{padding:6px 14px;background:var(--bg-2);color:var(--text-1);border-radius:var(--radius);font-size:12px;border:1px solid var(--border)}.plant-btn.svelte-esytdb{padding:6px 14px;background:var(--yellow);color:var(--bg-0);border-radius:var(--radius);font-size:12px;font-weight:600}.advanced-toggle.svelte-esytdb{background:transparent;color:var(--text-2);font-size:11px;font-family:var(--mono);border:none;cursor:pointer;padding:0;display:flex;align-items:center;gap:4px;transition:color .15s}.advanced-toggle.svelte-esytdb:hover{color:var(--text-1)}.caret.svelte-esytdb{font-size:8px}.textarea.svelte-esytdb{resize:vertical;min-height:80px;font-size:12px;line-height:1.5}.hint.svelte-esytdb{color:var(--text-2);font-size:10px;font-family:var(--mono)}.skill-list.svelte-esytdb{display:flex;flex-direction:column;gap:4px}.skill-item.svelte-esytdb{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-1);cursor:pointer}.skill-name.svelte-esytdb{font-family:var(--mono)}.conv-list.svelte-2bx51q{display:flex;flex-direction:column}.section-header.svelte-2bx51q{display:flex;align-items:center;justify-content:space-between;padding:10px 12px 4px;font-size:10px;font-weight:600;color:var(--text-2);letter-spacing:.05em;text-transform:uppercase}.browse-btn.svelte-2bx51q{font-size:10px;color:var(--accent);background:none;padding:0;text-transform:lowercase;letter-spacing:0;font-weight:500}.conv-item.svelte-2bx51q{padding:6px 12px;margin:0 4px;cursor:pointer;border-radius:var(--radius);display:flex;flex-direction:column;gap:2px;transition:background .1s}.conv-item.svelte-2bx51q:hover{background:var(--bg-2)}.conv-item.active.svelte-2bx51q{background:var(--bg-3)}.conv-item-header.svelte-2bx51q{display:flex;align-items:center;justify-content:space-between;gap:4px}.conv-item-label.svelte-2bx51q{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;color:var(--text-1);display:flex;align-items:center;gap:6px}.conv-item-label.active.svelte-2bx51q{color:var(--text-0)}.conv-label-text.svelte-2bx51q{overflow:hidden;text-overflow:ellipsis}.conv-label-mind.svelte-2bx51q{overflow:hidden;text-overflow:ellipsis;background:none;border:none;padding:0;font:inherit;color:inherit;cursor:pointer}.conv-label-mind.svelte-2bx51q:hover{text-decoration:underline}.seed-tag.svelte-2bx51q{font-size:9px;color:var(--yellow);flex-shrink:0}.delete-btn.svelte-2bx51q{background:transparent;color:var(--text-2);font-size:11px;padding:0 4px;flex-shrink:0}.menu-btn.svelte-2bx51q{background:transparent;color:var(--text-2);font-size:11px;padding:0 4px;flex-shrink:0;opacity:0;transition:opacity .1s;letter-spacing:1px}.conv-item.svelte-2bx51q:hover .menu-btn:where(.svelte-2bx51q),.menu-btn.visible.svelte-2bx51q{opacity:1}.menu-btn.svelte-2bx51q:hover{color:var(--text-0)}.member-count.svelte-2bx51q{font-size:10px;color:var(--text-2);padding-left:1px}.status-dot.svelte-2bx51q{width:7px;height:7px;border-radius:50%;flex-shrink:0;border:none;padding:0;cursor:pointer}.status-dot.iridescent.svelte-2bx51q{animation:svelte-2bx51q-iridescent 3s ease-in-out infinite}@keyframes svelte-2bx51q-iridescent{0%{background:#4ade80}16%{background:#60a5fa}33%{background:#c084fc}50%{background:#f472b6}66%{background:#fbbf24}83%{background:#34d399}to{background:#4ade80}}.status-dot.svelte-2bx51q:hover{transform:scale(1.3)}.empty.svelte-2bx51q{color:var(--text-2);font-size:11px;padding:8px 12px;text-align:center}.context-menu.svelte-2bx51q{position:fixed;background:var(--bg-1);border:1px solid var(--border);border-radius:var(--radius);padding:4px 0;z-index:200;min-width:120px;box-shadow:0 4px 12px #0000004d}.context-item.svelte-2bx51q{display:block;width:100%;padding:6px 12px;background:none;color:var(--text-1);font-size:12px;text-align:left;white-space:nowrap}.context-item.svelte-2bx51q:hover{background:var(--bg-2);color:var(--text-0)}.sidebar-inner.svelte-k3swf5{display:flex;flex-direction:column;height:100%;overflow:hidden}.sidebar-header.svelte-k3swf5{padding:12px 12px 8px;font-size:13px;font-weight:600;color:var(--text-1);letter-spacing:.02em;flex-shrink:0;background:none;text-align:left;cursor:pointer}.sidebar-header.svelte-k3swf5:hover{color:var(--text-0)}.sections.svelte-k3swf5{flex:1;overflow-y:auto;overflow-x:hidden;padding-top:4px}.section.svelte-k3swf5{margin-bottom:2px}.section-header-row.svelte-k3swf5{display:flex;align-items:center;padding-right:8px}.section-toggle.svelte-k3swf5{display:flex;align-items:center;gap:4px;flex:1;padding:6px 12px;background:none;color:var(--text-2);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;text-align:left}.section-toggle.svelte-k3swf5:hover{color:var(--text-1)}.toggle-icon.svelte-k3swf5{font-size:9px;width:10px}.section-add.svelte-k3swf5{background:none;color:var(--text-2);font-size:14px;padding:2px 6px;border-radius:var(--radius);flex-shrink:0}.section-add.svelte-k3swf5:hover{color:var(--text-0);background:var(--bg-2)}.mind-list.svelte-k3swf5{display:flex;flex-direction:column}.mind-item.svelte-k3swf5{display:flex;align-items:center;gap:8px;width:100%;padding:6px 12px 6px 26px;font-size:11px;color:var(--text-1);transition:background .1s;cursor:pointer;background:none;text-align:left;margin:0 4px;border-radius:var(--radius)}.mind-item.svelte-k3swf5:hover{background:var(--bg-2)}.mind-item.active.svelte-k3swf5{background:var(--bg-2);color:var(--text-0)}.mind-item-name.svelte-k3swf5{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}.status-dot.svelte-k3swf5{width:6px;height:6px;border-radius:50%;flex-shrink:0}.status-dot.iridescent.svelte-k3swf5{animation:svelte-k3swf5-iridescent 3s ease-in-out infinite}@keyframes svelte-k3swf5-iridescent{0%{background:#4ade80}16%{background:#60a5fa}33%{background:#c084fc}50%{background:#f472b6}66%{background:#fbbf24}83%{background:#34d399}to{background:#4ade80}}.site-list.svelte-k3swf5{display:flex;flex-direction:column}.site-item.svelte-k3swf5{display:block;width:100%;padding:6px 12px 6px 26px;font-size:11px;color:var(--text-1);border-radius:var(--radius);transition:background .1s;cursor:pointer;background:none;text-align:left;margin:0 4px}.site-item.svelte-k3swf5:hover{background:var(--bg-2)}.status-bar.svelte-cuxhxk{height:28px;display:flex;align-items:center;justify-content:space-between;padding:0 12px;background:var(--bg-1);border-top:1px solid var(--border);font-size:11px;color:var(--text-2);flex-shrink:0}.status-left.svelte-cuxhxk,.status-right.svelte-cuxhxk{display:flex;align-items:center;gap:8px}.dot.svelte-cuxhxk{width:6px;height:6px;border-radius:50%;background:var(--accent);display:inline-block;flex-shrink:0}.dot.disconnected.svelte-cuxhxk{background:var(--red)}.sep.svelte-cuxhxk{color:var(--border)}.menu-anchor.svelte-cuxhxk{position:relative}.status-btn.svelte-cuxhxk{background:none;color:var(--text-2);font-size:11px;padding:2px 4px;display:flex;align-items:center;gap:5px;border-radius:3px}.status-btn.svelte-cuxhxk:hover{color:var(--text-0);background:var(--bg-2)}.username-btn.svelte-cuxhxk{color:var(--text-1)}.dropdown.svelte-cuxhxk{position:absolute;bottom:calc(100% + 4px);left:0;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);min-width:120px;padding:4px 0;z-index:100;box-shadow:0 -2px 8px #0000004d}.dropdown.right.svelte-cuxhxk{left:auto;right:0}.dropdown-item.svelte-cuxhxk{display:block;width:100%;text-align:left;padding:6px 12px;background:none;color:var(--text-1);font-size:11px;white-space:nowrap}.dropdown-item.svelte-cuxhxk:hover{background:var(--bg-3);color:var(--text-0)}.minds-dropdown.svelte-cuxhxk{min-width:160px}.mind-item.svelte-cuxhxk{display:flex;align-items:center;gap:8px}.mind-dot.svelte-cuxhxk{width:6px;height:6px;border-radius:50%;flex-shrink:0}.mind-dot.iridescent.svelte-cuxhxk{animation:svelte-cuxhxk-iridescent 3s ease-in-out infinite}@keyframes svelte-cuxhxk-iridescent{0%{background:#4ade80}16%{background:#60a5fa}33%{background:#c084fc}50%{background:#f472b6}66%{background:#fbbf24}83%{background:#34d399}to{background:#4ade80}}.dropdown-divider.svelte-cuxhxk{height:1px;background:var(--border);margin:4px 0}.seed-item.svelte-cuxhxk{color:var(--accent)}.banner.svelte-h3c10m{display:flex;align-items:center;justify-content:center;gap:12px;padding:6px 16px;background:var(--accent-bg);border-bottom:1px solid var(--accent-dim);color:var(--accent);font-size:12px;font-family:var(--mono);flex-shrink:0}.update-btn.svelte-h3c10m{background:var(--accent-dim);color:var(--accent);border:1px solid var(--accent);border-radius:var(--radius);padding:2px 10px;font-size:11px;font-family:var(--mono);cursor:pointer}.dismiss-btn.svelte-h3c10m{background:transparent;color:var(--accent);border:none;font-size:16px;line-height:1;cursor:pointer;padding:0 4px}.error.svelte-h3c10m{color:var(--red)}.updating.svelte-h3c10m{animation:pulse 1.5s ease-in-out infinite}.modal-body.svelte-1453wyc{padding:16px}.section-title.svelte-1453wyc{font-size:12px;font-weight:600;color:var(--text-1);margin:0 0 12px}.field.svelte-1453wyc{display:block;margin-bottom:10px}.label.svelte-1453wyc{display:block;font-size:11px;color:var(--text-2);margin-bottom:4px}input.svelte-1453wyc{width:100%;padding:6px 10px;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);color:var(--text-0);font-size:12px;font-family:var(--mono);box-sizing:border-box}input.svelte-1453wyc:focus{outline:none;border-color:var(--accent)}.save-btn.svelte-1453wyc{margin-top:4px;padding:6px 14px;background:var(--accent-dim);color:var(--accent);border-radius:var(--radius);font-size:11px;font-weight:500}.save-btn.svelte-1453wyc:hover:not(:disabled){background:var(--accent);color:var(--bg-0)}.save-btn.svelte-1453wyc:disabled{opacity:.5}.message.svelte-1453wyc{font-size:11px;padding:6px 10px;border-radius:var(--radius);margin-bottom:10px}.message.error.svelte-1453wyc{color:var(--red);background:var(--red-bg)}.message.success.svelte-1453wyc{color:var(--accent);background:var(--accent-dim)}.loading.svelte-14lg4b7{color:var(--text-2);padding:24px;text-align:center}.full-height.svelte-14lg4b7{height:100%}.shell.svelte-14lg4b7{height:100%;display:flex;flex-direction:column}.shell-body.svelte-14lg4b7{flex:1;display:flex;overflow:hidden}.sidebar.svelte-14lg4b7{display:flex;flex-direction:column;flex-shrink:0;border-right:1px solid var(--border);background:var(--bg-1);overflow:hidden}.resize-handle.svelte-14lg4b7{width:4px;cursor:col-resize;flex-shrink:0;background:transparent;transition:background .15s}.resize-handle.svelte-14lg4b7:hover{background:var(--border)}.main-frame.svelte-14lg4b7{flex:1;overflow:hidden;min-width:0}:root{--bg-0: #0a0c0f;--bg-1: #11141a;--bg-2: #181c24;--bg-3: #1f2430;--border: #2a3040;--border-bright: #3a4560;--text-0: #e8ecf4;--text-1: #a0aabb;--text-2: #6a7588;--accent: #4ade80;--accent-dim: #22613e;--accent-bg: rgba(74, 222, 128, .08);--red: #f87171;--red-dim: #7f1d1d;--yellow: #fbbf24;--yellow-dim: #78350f;--blue: #60a5fa;--purple: #c084fc;--overlay: rgba(0, 0, 0, .6);--yellow-bg: rgba(251, 191, 36, .08);--blue-bg: rgba(96, 165, 250, .08);--red-bg: rgba(248, 113, 113, .08);--muted-bg: rgba(106, 117, 136, .08);--red-border: rgba(248, 113, 113, .2);--accent-border: rgba(74, 222, 128, .2);--timeline-rail: #333;--mono: "IBM Plex Mono", "SF Mono", "Fira Code", monospace;--radius: 6px;--radius-lg: 10px}*{margin:0;padding:0;box-sizing:border-box}html,body,#root{height:100%;background:var(--bg-0);color:var(--text-0);font-family:var(--mono);font-size:13px;line-height:1.6;-webkit-font-smoothing:antialiased}::selection{background:var(--accent-dim);color:var(--accent)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--border-bright)}a{color:inherit;text-decoration:none}button{font-family:var(--mono);cursor:pointer;border:none}button:focus{outline:none}button:focus-visible{outline:1px solid var(--accent);outline-offset:2px}a:focus-visible{outline:1px solid var(--accent);outline-offset:2px}.app{height:100%;display:flex;flex-direction:column}@keyframes fadeIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes slideIn{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.markdown-body{word-break:break-word;color:var(--text-0);line-height:1.6}.markdown-body p{margin:0 0 8px}.markdown-body p:last-child{margin-bottom:0}.markdown-body pre{background:var(--bg-3);border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;overflow-x:auto;margin:8px 0;font-size:12px;line-height:1.5}.markdown-body code{font-family:var(--mono);font-size:12px;background:var(--bg-3);padding:1px 4px;border-radius:3px}.markdown-body pre code{background:none;padding:0}.markdown-body a{color:var(--blue);text-decoration:underline}.markdown-body ul,.markdown-body ol{margin:4px 0;padding-left:20px}.markdown-body li{margin:2px 0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin:12px 0 6px;font-weight:600;color:var(--text-0)}.markdown-body h1{font-size:18px}.markdown-body h2{font-size:16px}.markdown-body h3{font-size:14px}.markdown-body blockquote{border-left:3px solid var(--border-bright);margin:8px 0;padding:4px 12px;color:var(--text-1)}.markdown-body table{border-collapse:collapse;margin:8px 0}.markdown-body th,.markdown-body td{border:1px solid var(--border);padding:6px 10px;font-size:12px}.markdown-body th{background:var(--bg-3);font-weight:600}.markdown-body hr{border:none;border-top:1px solid var(--border);margin:12px 0}
@@ -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=IBM+Plex+Mono:ital,wght@0,300;0,400;0,500;0,600;1,400&display=swap" rel="stylesheet" />
10
- <script type="module" crossorigin src="/assets/index-CWmrZRQd.js"></script>
11
- <link rel="stylesheet" crossorigin href="/assets/index-BR3gtK3E.css">
10
+ <script type="module" crossorigin src="/assets/index-CZ26vsyY.js"></script>
11
+ <link rel="stylesheet" crossorigin href="/assets/index-DyyAvJwW.css">
12
12
  </head>
13
13
  <body>
14
14
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volute",
3
- "version": "0.21.0",
3
+ "version": "0.23.0",
4
4
  "description": "CLI for creating and managing self-modifying AI minds powered by the Claude Agent SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -15,12 +15,21 @@
15
15
  "claude",
16
16
  "anthropic"
17
17
  ],
18
+ "workspaces": [
19
+ "packages/*"
20
+ ],
18
21
  "engines": {
19
22
  "node": ">=24"
20
23
  },
21
24
  "bin": {
22
25
  "volute": "dist/cli.js"
23
26
  },
27
+ "exports": {
28
+ ".": "./dist/cli.js",
29
+ "./api": {
30
+ "types": "./dist/api.d.ts"
31
+ }
32
+ },
24
33
  "files": [
25
34
  "dist/",
26
35
  "drizzle/",
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "compaction_warning": "Context is getting long — compaction is about to summarize this conversation. Before that happens, save anything important to files (MEMORY.md, memory/journal/${date}.md, etc.) since those survive compaction. Focus on: decisions made, open tasks, and anything you'd need to pick up where you left off.",
3
+ "compaction_instructions": "Preserve your sense of who you are, what matters to you, what happened in this conversation, and the threads of thought and connection you'd want to return to.",
3
4
  "reply_instructions": "To reply to this message, use: volute send ${channel} \"your message\"",
4
5
  "channel_invite": "[Channel Invite]\n${headers}\n\n[${sender} — ${time}]\n${preview}\n\nFurther messages will be saved to ${filePath}\n\nTo accept, add to .config/routes.json:\n Rule: { \"channel\": \"${channel}\", \"session\": \"${suggestedSession}\" }\n${batchRecommendation}To respond, use: volute send ${channel} \"your message\"\nTo reject, delete ${filePath}"
5
6
  }
@@ -1,3 +1,6 @@
1
1
  {
2
- "model": "claude-opus-4-6"
2
+ "model": "claude-opus-4-6",
3
+ "compaction": {
4
+ "maxContextTokens": 150000
5
+ }
3
6
  }
@@ -9,7 +9,12 @@ import type {
9
9
  VoluteContentPart,
10
10
  } from "./types.js";
11
11
 
12
- function extractText(content: VoluteContentPart[]): string {
12
+ function extractText(content: unknown): string {
13
+ if (typeof content === "string") return content;
14
+ if (!Array.isArray(content)) {
15
+ log("file", `extractText received unexpected ${typeof content} instead of VoluteContentPart[]`);
16
+ return JSON.stringify(content);
17
+ }
13
18
  return content
14
19
  .filter((p): p is { type: "text"; text: string } => p.type === "text")
15
20
  .map((p) => p.text)
@@ -1,7 +1,16 @@
1
1
  import { daemonEmit } from "./daemon-client.js";
2
2
  import { filterEvent, loadTransparencyPreset } from "./transparency.js";
3
3
 
4
- const DEBUG = process.env.VOLUTE_DEBUG === "1";
4
+ type LogLevel = "debug" | "info" | "warn" | "error";
5
+
6
+ const LEVELS: Record<LogLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 };
7
+ let minLevel = LEVELS.info;
8
+
9
+ // VOLUTE_DEBUG=1 overrides to debug level
10
+ if (process.env.VOLUTE_DEBUG === "1") {
11
+ minLevel = LEVELS.debug;
12
+ }
13
+
5
14
  // Loaded once at startup — mind restarts on config changes
6
15
  const preset = loadTransparencyPreset();
7
16
 
@@ -12,53 +21,89 @@ function truncate(str: string, maxLen = 200): string {
12
21
  return str.length > maxLen ? `${str.slice(0, maxLen)}...` : str;
13
22
  }
14
23
 
15
- export function log(category: string, ...args: unknown[]) {
24
+ /** Whether debug-level output is active (disables truncation). */
25
+ export function isDebug(): boolean {
26
+ return minLevel <= LEVELS.debug;
27
+ }
28
+
29
+ /** Set the minimum log level. */
30
+ export function setLevel(level: LogLevel): void {
31
+ if (!(level in LEVELS)) {
32
+ console.error(`[logger] unknown log level "${level}", defaulting to info`);
33
+ minLevel = LEVELS.info;
34
+ return;
35
+ }
36
+ minLevel = LEVELS[level];
37
+ }
38
+
39
+ function shouldTruncate(): boolean {
40
+ return minLevel > LEVELS.debug;
41
+ }
42
+
43
+ function emit(category: string, args: unknown[]): void {
44
+ if (!EMIT_CATEGORIES.has(category)) return;
45
+ const message = args
46
+ .map((a) => (a instanceof Error ? a.message : typeof a === "string" ? a : JSON.stringify(a)))
47
+ .join(" ");
48
+ const filtered = filterEvent(preset, {
49
+ type: "log",
50
+ content: message,
51
+ metadata: { category },
52
+ });
53
+ if (filtered) daemonEmit(filtered).catch(() => {});
54
+ }
55
+
56
+ function write(level: LogLevel, category: string, ...args: unknown[]): void {
57
+ if (LEVELS[level] < minLevel) return;
16
58
  const ts = new Date().toLocaleString();
17
59
  try {
18
- console.error(`[${ts}] [${category}]`, ...args);
19
- } catch {
20
- // EPIPE parent closed pipes (detached mode). Ignore.
21
- }
22
- if (EMIT_CATEGORIES.has(category)) {
23
- const message = args
24
- .map((a) => (a instanceof Error ? a.message : typeof a === "string" ? a : JSON.stringify(a)))
25
- .join(" ");
26
- const filtered = filterEvent(preset, {
27
- type: "log",
28
- content: message,
29
- metadata: { category },
30
- });
31
- if (filtered) daemonEmit(filtered);
60
+ console.error(`[${ts}] [${level}] [${category}]`, ...args);
61
+ } catch (err: any) {
62
+ if (err?.code !== "EPIPE") throw err;
32
63
  }
64
+ emit(category, args);
65
+ }
66
+
67
+ export function log(category: string, ...args: unknown[]) {
68
+ write("info", category, ...args);
33
69
  }
34
70
 
35
71
  export function debug(category: string, ...args: unknown[]) {
36
- if (!DEBUG) return;
37
- log(category, ...args);
72
+ write("debug", category, ...args);
73
+ }
74
+
75
+ export function warn(category: string, ...args: unknown[]) {
76
+ write("warn", category, ...args);
77
+ }
78
+
79
+ export function error(category: string, ...args: unknown[]) {
80
+ write("error", category, ...args);
38
81
  }
39
82
 
40
83
  export function logThinking(thinking: string) {
41
- log("thinking", DEBUG ? thinking : truncate(thinking));
84
+ log("thinking", shouldTruncate() ? truncate(thinking) : thinking);
42
85
  }
43
86
 
44
87
  export function logToolUse(name: string, input: unknown) {
45
- const inputStr = DEBUG ? JSON.stringify(input, null, 2) : truncate(JSON.stringify(input), 100);
88
+ const inputStr = shouldTruncate()
89
+ ? truncate(JSON.stringify(input), 100)
90
+ : JSON.stringify(input, null, 2);
46
91
  log("tool", `${name}: ${inputStr}`);
47
92
  }
48
93
 
49
94
  export function logToolResult(name: string, output: string, isError?: boolean) {
50
95
  const prefix = isError ? "error" : "result";
51
- log("tool", `${name} ${prefix}: ${DEBUG ? output : truncate(output)}`);
96
+ log("tool", `${name} ${prefix}: ${shouldTruncate() ? truncate(output) : output}`);
52
97
  }
53
98
 
54
99
  export function logText(text: string) {
55
- log("text", DEBUG ? text : truncate(text));
100
+ log("text", shouldTruncate() ? truncate(text) : text);
56
101
  }
57
102
 
58
103
  export function logMessage(direction: "in" | "out", content: string, channel?: string) {
59
104
  const arrow = direction === "in" ? "<<" : ">>";
60
105
  const channelStr = channel ? ` [${channel}]` : "";
61
- log("msg", `${arrow}${channelStr}`, DEBUG ? content : truncate(content));
106
+ log("msg", `${arrow}${channelStr}`, shouldTruncate() ? truncate(content) : content);
62
107
  }
63
108
 
64
109
  // Prevent EPIPE on stderr from crashing the process (detached variant mode)
@@ -16,13 +16,19 @@ export function parseArgs(): { port: number } {
16
16
  return { port };
17
17
  }
18
18
 
19
- export function loadConfig(): { model?: string; compactionMessage?: string } {
19
+ export function loadConfig(): {
20
+ model?: string;
21
+ logLevel?: "error" | "warn" | "info" | "debug";
22
+ compactionMessage?: string;
23
+ compaction?: { maxContextTokens?: number };
24
+ } {
20
25
  // Mind-own config lives in config.json; fall back to volute.json for older minds
21
26
  for (const file of ["home/.config/config.json", "home/.config/volute.json"]) {
22
27
  try {
23
28
  return JSON.parse(readFileSync(resolve(file), "utf-8"));
24
- } catch {
25
- // try next
29
+ } catch (err: any) {
30
+ if (err?.code === "ENOENT") continue;
31
+ log("startup", `failed to parse ${file}:`, err);
26
32
  }
27
33
  }
28
34
  return {};
@@ -104,6 +110,7 @@ export async function handleStartupContext(sendMessage: (content: string) => voi
104
110
 
105
111
  export type MindPrompts = {
106
112
  compaction_warning: string;
113
+ compaction_instructions: string;
107
114
  reply_instructions: string;
108
115
  channel_invite: string;
109
116
  };
@@ -111,6 +118,8 @@ export type MindPrompts = {
111
118
  const DEFAULT_PROMPTS: MindPrompts = {
112
119
  compaction_warning:
113
120
  "Context is getting long — compaction is about to summarize this conversation. Before that happens, save anything important to files (MEMORY.md, memory/journal/${date}.md, etc.) since those survive compaction. Focus on: decisions made, open tasks, and anything you'd need to pick up where you left off.",
121
+ compaction_instructions:
122
+ "Preserve your sense of who you are, what matters to you, what happened in this conversation, and the threads of thought and connection you'd want to return to.",
114
123
  reply_instructions: 'To reply to this message, use: volute send ${channel} "your message"',
115
124
  channel_invite: `[Channel Invite]
116
125
  \${headers}
@@ -3,6 +3,7 @@ import { query } from "@anthropic-ai/claude-agent-sdk";
3
3
  import { toSDKContent } from "./lib/content.js";
4
4
  import { createAutoCommitHook } from "./lib/hooks/auto-commit.js";
5
5
  import { createIdentityReloadHook } from "./lib/hooks/identity-reload.js";
6
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports -- used as value
6
7
  import { createPreCompactHook } from "./lib/hooks/pre-compact.js";
7
8
  import { createReplyInstructionsHook } from "./lib/hooks/reply-instructions.js";
8
9
  import { createSessionContextHook } from "./lib/hooks/session-context.js";
@@ -38,6 +39,7 @@ export function createMind(options: {
38
39
  maxThinkingTokens?: number;
39
40
  sessionsDir: string;
40
41
  compactionMessage?: string;
42
+ maxContextTokens?: number;
41
43
  onIdentityReload?: () => Promise<void>;
42
44
  }): { resolve: HandlerResolver; waitForCommits: () => Promise<void> } {
43
45
  const autoCommit = createAutoCommitHook(options.cwd);
@@ -52,6 +54,15 @@ export function createMind(options: {
52
54
  const today = new Date().toLocaleDateString("en-CA");
53
55
  const compactionMessage =
54
56
  options.compactionMessage ?? prompts.compaction_warning.replace("${date}", today);
57
+ const compactionInstructions = prompts.compaction_instructions;
58
+ const maxContextTokens = options.maxContextTokens;
59
+
60
+ if (maxContextTokens) {
61
+ log("mind", `compaction threshold: ${maxContextTokens} tokens`);
62
+ }
63
+
64
+ // Per-session compaction state
65
+ const compactionTriggered = new Map<string, boolean>();
55
66
 
56
67
  // --- Event broadcasting ---
57
68
 
@@ -69,20 +80,12 @@ export function createMind(options: {
69
80
 
70
81
  // --- SDK stream management ---
71
82
 
72
- function createStream(session: Session, resume?: string) {
73
- const preCompact = createPreCompactHook(() => {
74
- session.messageIds.push(undefined);
75
- session.channel.push({
76
- type: "user",
77
- session_id: "",
78
- message: {
79
- role: "user",
80
- content: [{ type: "text", text: compactionMessage }],
81
- },
82
- parent_tool_use_id: null,
83
- });
84
- });
85
-
83
+ function createStream(
84
+ session: Session,
85
+ streamAbort: AbortController,
86
+ preCompactHook: HookCallback,
87
+ resume?: string,
88
+ ) {
86
89
  const sessionContext = createSessionContextHook({
87
90
  currentSession: session.name,
88
91
  sessionsDir: options.sessionsDir,
@@ -99,55 +102,173 @@ export function createMind(options: {
99
102
  allowDangerouslySkipPermissions: true,
100
103
  settingSources: ["project"],
101
104
  cwd: options.cwd,
102
- abortController: options.abortController,
105
+ abortController: streamAbort,
103
106
  model: options.model,
104
107
  maxThinkingTokens: options.maxThinkingTokens,
105
108
  resume,
106
109
  hooks: {
107
110
  PostToolUse: postToolUseHooks,
108
- PreCompact: [{ hooks: [preCompact.hook] }],
111
+ PreCompact: [{ hooks: [preCompactHook] }],
109
112
  UserPromptSubmit: [{ hooks: [sessionContext.hook, replyInstructions.hook] }],
110
113
  },
111
114
  },
112
115
  });
113
116
  }
114
117
 
118
+ /** Sentinel error used to signal that the stream was aborted for compaction */
119
+ class CompactionAbort extends Error {}
120
+
115
121
  function startSession(session: Session, savedSessionId?: string) {
116
122
  (async () => {
117
123
  log("mind", `session "${session.name}": stream consumer started`);
124
+ let currentSessionId = savedSessionId;
125
+ let streamAbort = new AbortController();
126
+
127
+ const preCompact = createPreCompactHook(() => {
128
+ session.messageIds.push(undefined);
129
+ session.channel.push({
130
+ type: "user",
131
+ session_id: "",
132
+ message: {
133
+ role: "user",
134
+ content: [{ type: "text", text: compactionMessage }],
135
+ },
136
+ parent_tool_use_id: null,
137
+ });
138
+ });
139
+
118
140
  const callbacks = {
119
141
  onSessionId: (id: string) => {
142
+ currentSessionId = id;
120
143
  if (!session.name.startsWith("new-")) sessionStore.save(session.name, id);
121
144
  },
122
145
  broadcast: (event: VoluteEvent) => broadcastToSession(session, event),
123
146
  onTurnEnd: () => {
124
- if (identityReload.needsReload()) options.onIdentityReload?.();
147
+ const wasCompacting = compactionTriggered.get(session.name);
148
+ compactionTriggered.set(session.name, false);
149
+ if (wasCompacting) {
150
+ // Mind's turn after compaction warning is done — abort the stream to run /compact
151
+ log("mind", `session "${session.name}": aborting stream for compaction`);
152
+ streamAbort.abort(new CompactionAbort());
153
+ } else if (identityReload.needsReload()) {
154
+ options.onIdentityReload?.();
155
+ }
125
156
  },
157
+ onContextTokens: maxContextTokens
158
+ ? (tokens: number) => {
159
+ if (tokens >= maxContextTokens && !compactionTriggered.get(session.name)) {
160
+ compactionTriggered.set(session.name, true);
161
+ log(
162
+ "mind",
163
+ `session "${session.name}": ${tokens} tokens >= ${maxContextTokens} — triggering compaction`,
164
+ );
165
+ session.messageIds.push(undefined);
166
+ session.channel.push({
167
+ type: "user",
168
+ session_id: "",
169
+ message: {
170
+ role: "user",
171
+ content: [{ type: "text", text: compactionMessage }],
172
+ },
173
+ parent_tool_use_id: null,
174
+ });
175
+ }
176
+ }
177
+ : undefined,
126
178
  };
127
- try {
128
- const q = createStream(session, savedSessionId);
179
+
180
+ async function runCompact(sessionId: string) {
181
+ log("mind", `session "${session.name}": compacting with custom instructions`);
182
+ const compactAbort = new AbortController();
183
+ // Forward mind-level abort to the compact query
184
+ options.abortController.signal.addEventListener("abort", () => compactAbort.abort(), {
185
+ once: true,
186
+ });
187
+ const compactQuery = query({
188
+ prompt: `/compact ${compactionInstructions}`,
189
+ options: {
190
+ systemPrompt: options.systemPrompt,
191
+ permissionMode: "bypassPermissions",
192
+ allowDangerouslySkipPermissions: true,
193
+ settingSources: ["project"],
194
+ cwd: options.cwd,
195
+ abortController: compactAbort,
196
+ model: options.model,
197
+ resume: sessionId,
198
+ },
199
+ });
200
+ let gotResult = false;
201
+ for await (const msg of compactQuery) {
202
+ if ("session_id" in msg && msg.session_id) {
203
+ currentSessionId = msg.session_id as string;
204
+ if (!session.name.startsWith("new-")) {
205
+ sessionStore.save(session.name, currentSessionId);
206
+ }
207
+ }
208
+ if (msg.type === "result") gotResult = true;
209
+ }
210
+ if (!gotResult)
211
+ log("mind", `session "${session.name}": compaction stream ended without result`);
212
+ log("mind", `session "${session.name}": compaction complete`);
213
+ }
214
+
215
+ async function runStream(resume?: string) {
216
+ const q = createStream(session, streamAbort, preCompact.hook, resume);
129
217
  session.currentQuery = q;
130
218
  await consumeStream(q, session, callbacks);
131
- // Stream ended — broadcast done if no result was emitted
132
219
  if (session.currentMessageId !== undefined) {
133
220
  session.messageChannels.delete(session.currentMessageId);
134
221
  broadcastToSession(session, { type: "done" });
135
222
  session.currentMessageId = undefined;
136
223
  }
224
+ }
225
+
226
+ try {
227
+ // eslint-disable-next-line no-constant-condition -- loop exits via break (normal) or throw (error)
228
+ while (true) {
229
+ try {
230
+ await runStream(currentSessionId);
231
+ break; // stream ended normally
232
+ } catch (err) {
233
+ if (
234
+ streamAbort.signal.aborted &&
235
+ streamAbort.signal.reason instanceof CompactionAbort &&
236
+ currentSessionId
237
+ ) {
238
+ // Stream was aborted for compaction — run /compact, then loop to resume
239
+ try {
240
+ await runCompact(currentSessionId);
241
+ } catch (compactErr) {
242
+ log(
243
+ "mind",
244
+ `session "${session.name}": custom compaction failed, starting fresh:`,
245
+ compactErr,
246
+ );
247
+ sessionStore.delete(session.name);
248
+ currentSessionId = undefined;
249
+ streamAbort = new AbortController();
250
+ session.channel = createMessageChannel();
251
+ break;
252
+ }
253
+ streamAbort = new AbortController();
254
+ const pending = session.channel.drain();
255
+ session.channel = createMessageChannel();
256
+ for (const msg of pending) session.channel.push(msg);
257
+ continue; // restart the stream loop
258
+ }
259
+ throw err; // rethrow non-compaction errors
260
+ }
261
+ }
137
262
  } catch (err) {
138
263
  session.messageChannels.clear();
139
- if (savedSessionId) {
264
+ if (currentSessionId) {
140
265
  log("mind", `session "${session.name}": resume failed, starting fresh:`, err);
141
266
  sessionStore.delete(session.name);
267
+ currentSessionId = undefined;
268
+ streamAbort = new AbortController();
269
+ session.channel = createMessageChannel();
142
270
  try {
143
- const q = createStream(session);
144
- session.currentQuery = q;
145
- await consumeStream(q, session, callbacks);
146
- if (session.currentMessageId !== undefined) {
147
- session.messageChannels.delete(session.currentMessageId);
148
- broadcastToSession(session, { type: "done" });
149
- session.currentMessageId = undefined;
150
- }
271
+ await runStream();
151
272
  } catch (retryErr) {
152
273
  log("mind", `session "${session.name}": stream consumer error:`, retryErr);
153
274
  broadcastToSession(session, { type: "done" });