@goondocks/myco 0.21.1 → 0.21.2
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/{agent-eval-YK2VP2S4.js → agent-eval-2MQKTXX3.js} +4 -4
- package/dist/{agent-run-GEJBD2YD.js → agent-run-XJBTSVJR.js} +4 -4
- package/dist/{agent-tasks-5XSRGTRX.js → agent-tasks-7MWBZOC7.js} +4 -4
- package/dist/{chunk-VRI56337.js → chunk-4D22KTXY.js} +2 -2
- package/dist/{chunk-KTTSXYEK.js → chunk-6FBLL7MD.js} +8 -2
- package/dist/chunk-6FBLL7MD.js.map +1 -0
- package/dist/{chunk-N7Z3LUEZ.js → chunk-DBBO6FHE.js} +2 -10
- package/dist/{chunk-N7Z3LUEZ.js.map → chunk-DBBO6FHE.js.map} +1 -1
- package/dist/{chunk-EEOJWLMP.js → chunk-DMPCC7V6.js} +15 -3
- package/dist/chunk-DMPCC7V6.js.map +1 -0
- package/dist/{chunk-XL75KZGI.js → chunk-EKZG2MCD.js} +7 -3
- package/dist/chunk-EKZG2MCD.js.map +1 -0
- package/dist/{chunk-X2IRGXGF.js → chunk-HCT7RMM2.js} +154 -24
- package/dist/chunk-HCT7RMM2.js.map +1 -0
- package/dist/{chunk-NFO7BRCO.js → chunk-IMW5TJ3O.js} +5 -4
- package/dist/chunk-IMW5TJ3O.js.map +1 -0
- package/dist/{chunk-OZ3FBAK5.js → chunk-TFRUDNLI.js} +2 -2
- package/dist/{chunk-6ALVMIB4.js → chunk-TMAXWERS.js} +85 -2
- package/dist/chunk-TMAXWERS.js.map +1 -0
- package/dist/{chunk-QDLVIW2O.js → chunk-W5L5IHP5.js} +2 -2
- package/dist/{chunk-ENZR5NG7.js → chunk-Z55WGA2J.js} +2 -2
- package/dist/{cli-HSLIG7EX.js → cli-DDHTHU2J.js} +35 -35
- package/dist/{client-Z43DNLJH.js → client-PQU53UQU.js} +5 -3
- package/dist/{doctor-HJCWHAU4.js → doctor-QK6KFY6H.js} +4 -4
- package/dist/{executor-DO6QFC6G.js → executor-FJCMNSXM.js} +5 -5
- package/dist/{init-4KVK7W2E.js → init-GQPD6HHX.js} +5 -5
- package/dist/{main-4J4QZZTZ.js → main-4HKTZFIM.js} +365 -142
- package/dist/main-4HKTZFIM.js.map +1 -0
- package/dist/{open-7TXJQM3H.js → open-3P3DDAOA.js} +4 -4
- package/dist/{post-compact-7AEFVCZS.js → post-compact-QA5LME2J.js} +4 -4
- package/dist/{post-tool-use-TZINWWDH.js → post-tool-use-QRZMPNYL.js} +3 -3
- package/dist/{post-tool-use-failure-TCFEU2GI.js → post-tool-use-failure-XNHIKBZG.js} +4 -4
- package/dist/{pre-compact-LO2VZCGR.js → pre-compact-HDV6X5QM.js} +4 -4
- package/dist/{remove-F77AAALE.js → remove-USQDLGTJ.js} +4 -4
- package/dist/{restart-UEFDPMLT.js → restart-FQLZE2TW.js} +5 -5
- package/dist/{search-NHNVUAQQ.js → search-5COKV6TD.js} +4 -4
- package/dist/{server-AZJSTQEK.js → server-KRMBRW4T.js} +22 -6
- package/dist/{server-AZJSTQEK.js.map → server-KRMBRW4T.js.map} +1 -1
- package/dist/{session-3HLC5KOD.js → session-NJCUW3OX.js} +4 -4
- package/dist/{session-end-FS46UARX.js → session-end-XD27GRYF.js} +3 -3
- package/dist/{session-start-46KPFV2H.js → session-start-RDTXUSYL.js} +7 -7
- package/dist/{setup-llm-JMWSNQ2C.js → setup-llm-FYPPJI6W.js} +4 -4
- package/dist/src/agent/definitions/tasks/skill-evolve.yaml +4 -4
- package/dist/src/cli.js +1 -1
- package/dist/src/daemon/main.js +1 -1
- package/dist/src/hooks/post-tool-use.js +1 -1
- package/dist/src/hooks/session-end.js +1 -1
- package/dist/src/hooks/session-start.js +1 -1
- package/dist/src/hooks/stop.js +1 -1
- package/dist/src/hooks/user-prompt-submit.js +1 -1
- package/dist/src/mcp/server.js +1 -1
- package/dist/src/symbionts/templates/opencode/plugin.ts +41 -1
- package/dist/src/symbionts/templates/pi/plugin.ts +12 -1
- package/dist/{stats-MKMETHMA.js → stats-JCLZLA5G.js} +5 -5
- package/dist/{stop-OUEX6KA4.js → stop-B7XCXEM5.js} +3 -3
- package/dist/{stop-failure-2BWVNZEG.js → stop-failure-R6QZCUOZ.js} +4 -4
- package/dist/{subagent-start-J4VV6DEE.js → subagent-start-N7A622F3.js} +4 -4
- package/dist/{subagent-stop-JMLVEPIA.js → subagent-stop-SVOG5MZJ.js} +4 -4
- package/dist/{task-completed-65CHMMKA.js → task-completed-3DL5LJXF.js} +4 -4
- package/dist/{team-U2LDKIS4.js → team-VJ3M263F.js} +2 -2
- package/dist/ui/assets/{index-BUGor9dk.js → index-O1kNWlWM.js} +119 -119
- package/dist/ui/assets/index-z2Jm8i4A.css +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/{update-ZSHVXWSQ.js → update-TVXAUJMZ.js} +42 -8
- package/dist/update-TVXAUJMZ.js.map +1 -0
- package/dist/{user-prompt-submit-APMO6FVU.js → user-prompt-submit-KYO2VGLB.js} +7 -6
- package/dist/user-prompt-submit-KYO2VGLB.js.map +1 -0
- package/dist/{version-TXPPS3L5.js → version-LDFEALUJ.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-6ALVMIB4.js.map +0 -1
- package/dist/chunk-EEOJWLMP.js.map +0 -1
- package/dist/chunk-KTTSXYEK.js.map +0 -1
- package/dist/chunk-NFO7BRCO.js.map +0 -1
- package/dist/chunk-X2IRGXGF.js.map +0 -1
- package/dist/chunk-XL75KZGI.js.map +0 -1
- package/dist/main-4J4QZZTZ.js.map +0 -1
- package/dist/ui/assets/index-_OP4ifzH.css +0 -1
- package/dist/update-ZSHVXWSQ.js.map +0 -1
- package/dist/user-prompt-submit-APMO6FVU.js.map +0 -1
- /package/dist/{agent-eval-YK2VP2S4.js.map → agent-eval-2MQKTXX3.js.map} +0 -0
- /package/dist/{agent-run-GEJBD2YD.js.map → agent-run-XJBTSVJR.js.map} +0 -0
- /package/dist/{agent-tasks-5XSRGTRX.js.map → agent-tasks-7MWBZOC7.js.map} +0 -0
- /package/dist/{chunk-VRI56337.js.map → chunk-4D22KTXY.js.map} +0 -0
- /package/dist/{chunk-OZ3FBAK5.js.map → chunk-TFRUDNLI.js.map} +0 -0
- /package/dist/{chunk-QDLVIW2O.js.map → chunk-W5L5IHP5.js.map} +0 -0
- /package/dist/{chunk-ENZR5NG7.js.map → chunk-Z55WGA2J.js.map} +0 -0
- /package/dist/{cli-HSLIG7EX.js.map → cli-DDHTHU2J.js.map} +0 -0
- /package/dist/{client-Z43DNLJH.js.map → client-PQU53UQU.js.map} +0 -0
- /package/dist/{doctor-HJCWHAU4.js.map → doctor-QK6KFY6H.js.map} +0 -0
- /package/dist/{executor-DO6QFC6G.js.map → executor-FJCMNSXM.js.map} +0 -0
- /package/dist/{init-4KVK7W2E.js.map → init-GQPD6HHX.js.map} +0 -0
- /package/dist/{open-7TXJQM3H.js.map → open-3P3DDAOA.js.map} +0 -0
- /package/dist/{post-compact-7AEFVCZS.js.map → post-compact-QA5LME2J.js.map} +0 -0
- /package/dist/{post-tool-use-TZINWWDH.js.map → post-tool-use-QRZMPNYL.js.map} +0 -0
- /package/dist/{post-tool-use-failure-TCFEU2GI.js.map → post-tool-use-failure-XNHIKBZG.js.map} +0 -0
- /package/dist/{pre-compact-LO2VZCGR.js.map → pre-compact-HDV6X5QM.js.map} +0 -0
- /package/dist/{remove-F77AAALE.js.map → remove-USQDLGTJ.js.map} +0 -0
- /package/dist/{restart-UEFDPMLT.js.map → restart-FQLZE2TW.js.map} +0 -0
- /package/dist/{search-NHNVUAQQ.js.map → search-5COKV6TD.js.map} +0 -0
- /package/dist/{session-3HLC5KOD.js.map → session-NJCUW3OX.js.map} +0 -0
- /package/dist/{session-end-FS46UARX.js.map → session-end-XD27GRYF.js.map} +0 -0
- /package/dist/{session-start-46KPFV2H.js.map → session-start-RDTXUSYL.js.map} +0 -0
- /package/dist/{setup-llm-JMWSNQ2C.js.map → setup-llm-FYPPJI6W.js.map} +0 -0
- /package/dist/{stats-MKMETHMA.js.map → stats-JCLZLA5G.js.map} +0 -0
- /package/dist/{stop-OUEX6KA4.js.map → stop-B7XCXEM5.js.map} +0 -0
- /package/dist/{stop-failure-2BWVNZEG.js.map → stop-failure-R6QZCUOZ.js.map} +0 -0
- /package/dist/{subagent-start-J4VV6DEE.js.map → subagent-start-N7A622F3.js.map} +0 -0
- /package/dist/{subagent-stop-JMLVEPIA.js.map → subagent-stop-SVOG5MZJ.js.map} +0 -0
- /package/dist/{task-completed-65CHMMKA.js.map → task-completed-3DL5LJXF.js.map} +0 -0
- /package/dist/{team-U2LDKIS4.js.map → team-VJ3M263F.js.map} +0 -0
- /package/dist/{version-TXPPS3L5.js.map → version-LDFEALUJ.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root[data-theme=moss],:root[data-theme=dusk],:root[data-theme=plum],:root[data-theme=slate]{--secondary: #d3b172;--on-secondary: #3d2b0c;--secondary-container: #5a3f10;--tertiary: #d28a73;--on-tertiary: #44180e;--tertiary-container: #7f4334}:root[data-theme=moss].light,:root[data-theme=dusk].light,:root[data-theme=plum].light,:root[data-theme=slate].light{--secondary: #6b4e1e;--on-secondary: #ffffff;--secondary-container: #e6d1a3;--tertiary: #8f4d3c;--on-tertiary: #ffffff;--tertiary-container: #e7b5aa}:root[data-theme=sage]{--primary: #abcfb8;--on-primary: #163627;--primary-container: #7b9e89;--on-primary-container: #143525;--secondary: #edbf7f;--on-secondary: #442b00;--secondary-container: #60410b;--tertiary: #ffb4a1;--on-tertiary: #5d1806;--tertiary-container: #df7a60}:root[data-theme=sage].light{--primary: #446553;--on-primary: #ffffff;--primary-container: #7b9e89;--on-primary-container: #002113;--secondary: #60410b;--on-secondary: #ffffff;--secondary-container: #ffddb2;--tertiary: #8B5C44;--on-tertiary: #ffffff;--tertiary-container: #ffdbd2}:root[data-theme=moss]{--primary: #9ca884;--on-primary: #1a1a0c;--primary-container: #6e7a58;--on-primary-container: #1a1a0c;--surface: #0e110d;--surface-dim: #0a0c09;--surface-container-lowest: #070906;--surface-container-low: #181c14;--surface-container: #20241b;--surface-container-high: #2b3024;--surface-container-highest: #353a2d;--outline-variant: #3c4234}:root[data-theme=moss].light{--primary: #5b6c43;--on-primary: #ffffff;--primary-container: #c1ccb0;--on-primary-container: #1a1a0c;--surface: #f5f6ed;--surface-dim: #e8ebda;--surface-container-lowest: #ffffff;--surface-container-low: #f0f2e3;--surface-container: #e6e9d6;--surface-container-high: #d9ddc7;--surface-container-highest: #cdd2b8;--outline-variant: #c8ccb4}:root[data-theme=terracotta]{--primary: #d28a73;--on-primary: #44180e;--primary-container: #8a4c3a;--on-primary-container: #44180e;--secondary: #d3b172;--on-secondary: #3d2b0c;--secondary-container: #5a3f10;--tertiary: #abcfb8;--on-tertiary: #163627;--tertiary-container: #6f8f7b;--surface: #110e0c;--surface-dim: #0c0907;--surface-container-lowest: #0a0705;--surface-container-low: #1d1815;--surface-container: #28211c;--surface-container-high: #322a23;--surface-container-highest: #3d342c;--outline-variant: #45382f}:root[data-theme=terracotta].light{--primary: #8b4c36;--on-primary: #ffffff;--primary-container: #e7b3a0;--on-primary-container: #44180e;--secondary: #6b4e1e;--on-secondary: #ffffff;--secondary-container: #e6d1a3;--tertiary: #446553;--on-tertiary: #ffffff;--tertiary-container: #abcfb8;--surface: #faf2ee;--surface-dim: #ede0d9;--surface-container-lowest: #ffffff;--surface-container-low: #f5e8e1;--surface-container: #ebd9ce;--surface-container-high: #ddc7b8;--surface-container-highest: #cfb6a4;--outline-variant: #d4baa9}:root[data-theme=dusk]{--primary: #8faed1;--on-primary: #0c1620;--primary-container: #5a7aa0;--on-primary-container: #0c1620;--surface: #0d0f13;--surface-dim: #080a0e;--surface-container-lowest: #060810;--surface-container-low: #161a22;--surface-container: #1f242f;--surface-container-high: #29303c;--surface-container-highest: #333b48;--outline-variant: #393f4d}:root[data-theme=dusk].light{--primary: #3e5b80;--on-primary: #ffffff;--primary-container: #b5cae4;--on-primary-container: #0c1620;--surface: #f1f4f9;--surface-dim: #e2e7f0;--surface-container-lowest: #ffffff;--surface-container-low: #ebeff6;--surface-container: #dde4ee;--surface-container-high: #ccd6e2;--surface-container-highest: #bcc8d6;--outline-variant: #c2cbd8}:root[data-theme=plum]{--primary: #b59ec8;--on-primary: #1a0f24;--primary-container: #7d6992;--on-primary-container: #1a0f24;--surface: #100d13;--surface-dim: #0b080e;--surface-container-lowest: #08060b;--surface-container-low: #1c1722;--surface-container: #26202c;--surface-container-high: #322a3a;--surface-container-highest: #3d3447;--outline-variant: #443b4f}:root[data-theme=plum].light{--primary: #604a76;--on-primary: #ffffff;--primary-container: #d6c4e2;--on-primary-container: #1a0f24;--surface: #f7f3fa;--surface-dim: #ebe4f0;--surface-container-lowest: #ffffff;--surface-container-low: #f1ebf5;--surface-container: #e4dbeb;--surface-container-high: #d2c6dc;--surface-container-highest: #c0b1cd;--outline-variant: #c8b9d5}:root[data-theme=slate]{--primary: #a6b0b8;--on-primary: #161a1d;--primary-container: #72808b;--on-primary-container: #161a1d;--surface: #0e1012;--surface-dim: #090b0d;--surface-container-lowest: #07090a;--surface-container-low: #181c1f;--surface-container: #22272b;--surface-container-high: #2c3338;--surface-container-highest: #363f44;--outline-variant: #3b424a}:root[data-theme=slate].light{--primary: #525c65;--on-primary: #ffffff;--primary-container: #c8ced5;--on-primary-container: #161a1d;--surface: #f3f5f7;--surface-dim: #e5e8ec;--surface-container-lowest: #ffffff;--surface-container-low: #edf0f3;--surface-container: #e0e4e9;--surface-container-high: #d1d6dc;--surface-container-highest: #c1c8d0;--outline-variant: #c8cdd3}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:var(--font-ui, Inter),system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--font-data, JetBrains Mono),Fira Code,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--surface: #111111;--surface-dim: #0c0c0c;--surface-bright: #444444;--surface-container-lowest: #080808;--surface-container-low: #1a1a1a;--surface-container: #242424;--surface-container-high: #333333;--surface-container-highest: #424242;--surface-variant: #3a3a3a;--on-surface: #e5e2e1;--on-surface-variant: #c1c8c2;--outline: #8b928c;--outline-variant: #424843;--on-primary-container: #143525;--inverse-surface: #e5e2e1;--inverse-on-surface: #303030;--inverse-primary: #446553;--shadow-tint: 96, 65, 11;--ghost-border: color-mix(in srgb, var(--outline-variant), transparent 75%);--background: var(--surface);--foreground: var(--on-surface);--card: var(--surface-container-low);--card-foreground: var(--on-surface);--muted: var(--surface-container);--muted-foreground: var(--on-surface-variant);--accent: var(--surface-container-high);--accent-foreground: var(--on-surface);--border: var(--outline-variant);--input: var(--outline-variant);--ring: var(--primary);--destructive: var(--tertiary);--primary-foreground: var(--on-primary);--secondary-foreground: var(--on-surface);--radius: .375rem}.light{--surface: #F9F5E6;--surface-dim: #E8E1D1;--surface-bright: #FFFFFF;--surface-container-lowest: #F4EED8;--surface-container-low: #FFFFFF;--surface-container: #E8E1D1;--surface-container-high: #DDD6C6;--surface-container-highest: #D2CABB;--surface-variant: #D2CABB;--on-surface: #131313;--on-surface-variant: #424843;--outline: #8b928c;--outline-variant: #c1c8c2;--on-primary-container: #002113;--inverse-surface: #303030;--inverse-on-surface: #e5e2e1;--inverse-primary: #abcfb8;--shadow-tint: 96, 65, 11;--ghost-border: color-mix(in srgb, var(--outline-variant), transparent 75%);--background: var(--surface);--foreground: var(--on-surface);--card: var(--surface-container-low);--card-foreground: var(--on-surface);--muted: var(--surface-container);--muted-foreground: var(--on-surface-variant);--accent: var(--surface-container-high);--accent-foreground: var(--on-surface);--border: var(--outline-variant);--input: var(--outline-variant);--ring: var(--primary);--destructive: var(--tertiary);--primary-foreground: var(--on-primary);--secondary-foreground: var(--on-surface);--radius: .375rem}*{border-color:var(--ghost-border)}body{background-color:var(--surface);color:var(--on-surface);font-family:var(--font-ui, "Inter", system-ui, sans-serif);pointer-events:auto!important}.container{width:100%}@media(min-width:640px){.container{max-width:640px}}@media(min-width:768px){.container{max-width:768px}}@media(min-width:1024px){.container{max-width:1024px}}@media(min-width:1280px){.container{max-width:1280px}}@media(min-width:1536px){.container{max-width:1536px}}.config-slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:4px;border-radius:2px;background:var(--surface-container-high);outline:none;cursor:pointer}.config-slider:disabled{opacity:.5;cursor:not-allowed}.config-slider::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:14px;height:14px;border-radius:50%;background:var(--primary);border:2px solid var(--surface);box-shadow:0 0 0 1px var(--primary-container);cursor:pointer;-webkit-transition:box-shadow .15s ease;transition:box-shadow .15s ease}.config-slider::-webkit-slider-thumb:hover{box-shadow:0 0 0 4px color-mix(in srgb,var(--primary),transparent 75%)}.config-slider::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--primary);border:2px solid var(--surface);box-shadow:0 0 0 1px var(--primary-container);cursor:pointer}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.\!visible{visibility:visible!important}.visible{visibility:visible}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-3{top:.75rem;bottom:.75rem}.-right-0\.5{right:-.125rem}.-top-0\.5{top:-.125rem}.bottom-0{bottom:0}.bottom-2{bottom:.5rem}.bottom-3{bottom:.75rem}.bottom-4{bottom:1rem}.bottom-6{bottom:1.5rem}.left-0{left:0}.left-1\/2{left:50%}.left-2{left:.5rem}.left-3{left:.75rem}.left-4{left:1rem}.left-\[4\.5px\]{left:4.5px}.left-\[50\%\]{left:50%}.right-0{right:0}.right-0\.5{right:.125rem}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.right-\[332px\]{right:332px}.top-0{top:0}.top-0\.5{top:.125rem}.top-1\/2{top:50%}.top-12{top:3rem}.top-2{top:.5rem}.top-3{top:.75rem}.top-4{top:1rem}.top-\[50\%\]{top:50%}.top-full{top:100%}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-\[60\]{z-index:60}.-m-1{margin:-.25rem}.m-auto{margin:auto}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.-mt-\[60px\]{margin-top:-60px}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-\[14px\]{margin-bottom:14px}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-1\.5{margin-right:.375rem}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-auto{margin-top:auto}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.aspect-square{aspect-ratio:1 / 1}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-20{height:5rem}.h-24{height:6rem}.h-28{height:7rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-32{height:8rem}.h-4{height:1rem}.h-40{height:10rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-64{height:16rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[calc\(100vh-285px\)\]{height:calc(100vh - 285px)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:8rem}.max-h-40{max-height:10rem}.max-h-48{max-height:12rem}.max-h-72{max-height:18rem}.max-h-96{max-height:24rem}.max-h-\[140px\]{max-height:140px}.max-h-\[28rem\]{max-height:28rem}.max-h-\[32rem\]{max-height:32rem}.max-h-\[400px\]{max-height:400px}.max-h-\[70vh\]{max-height:70vh}.max-h-\[90vh\]{max-height:90vh}.min-h-\[200px\]{min-height:200px}.min-h-\[300px\]{min-height:300px}.min-h-\[320px\]{min-height:320px}.min-h-full{min-height:100%}.w-0\.5{width:.125rem}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-2\/5{width:40%}.w-20{width:5rem}.w-24{width:6rem}.w-28{width:7rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-3\/5{width:60%}.w-32{width:8rem}.w-4{width:1rem}.w-4\/5{width:80%}.w-40{width:10rem}.w-44{width:11rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-52{width:13rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-96{width:24rem}.w-\[120px\]{width:120px}.w-\[12px\]{width:12px}.w-\[132px\]{width:132px}.w-\[156px\]{width:156px}.w-\[20px\]{width:20px}.w-\[320px\]{width:320px}.w-\[48px\]{width:48px}.w-\[54px\]{width:54px}.w-\[68px\]{width:68px}.w-\[72px\]{width:72px}.w-\[90px\]{width:90px}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-5{min-width:1.25rem}.min-w-7{min-width:1.75rem}.min-w-\[140px\]{min-width:140px}.min-w-\[260px\]{min-width:260px}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-7xl{max-width:80rem}.max-w-\[140px\]{max-width:140px}.max-w-\[160px\]{max-width:160px}.max-w-\[180px\]{max-width:180px}.max-w-\[200px\]{max-width:200px}.max-w-\[220px\]{max-width:220px}.max-w-\[280px\]{max-width:280px}.max-w-\[300px\]{max-width:300px}.max-w-\[420px\]{max-width:420px}.max-w-\[90px\]{max-width:90px}.max-w-\[90vw\]{max-width:90vw}.max-w-\[calc\(100vw-3rem\)\]{max-width:calc(100vw - 3rem)}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-full{--tw-translate-x: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-5{--tw-translate-x: 1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-full{--tw-translate-x: 100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-rotate-90{--tw-rotate: -90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize-y{resize:vertical}.list-decimal{list-style-type:decimal}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0px}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-0{row-gap:0px}.space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-10>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2.5rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.self-start{align-self:flex-start}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-wrap{text-wrap:wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:var(--radius)}.rounded-sm{border-radius:.25rem}.rounded-xl{border-radius:.75rem}.rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.border{border-width:1px}.border-0{border-width:0px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-l-4{border-left-width:4px}.border-t{border-top-width:1px}.border-t-2{border-top-width:2px}.border-none{border-style:none}.border-\[var\(--ghost-border\)\]{border-color:var(--ghost-border)}.border-blue-500\/30{border-color:#3b82f64d}.border-border{border-color:var(--border)}.border-green-500\/20{border-color:#22c55e33}.border-green-500\/30{border-color:#22c55e4d}.border-input{border-color:var(--input)}.border-orange-500\/30{border-color:#f973164d}.border-outline{border-color:var(--outline)}.border-outline-variant{border-color:var(--outline-variant)}.border-primary{border-color:var(--primary)}.border-purple-500\/30{border-color:#a855f74d}.border-surface{border-color:var(--surface)}.border-transparent{border-color:transparent}.border-l-ochre{border-left-color:var(--secondary)}.border-l-sage{border-left-color:var(--primary)}.border-l-terracotta{border-left-color:var(--tertiary)}.border-t-amber-500{--tw-border-opacity: 1;border-top-color:rgb(245 158 11 / var(--tw-border-opacity, 1))}.border-t-ochre{border-top-color:var(--secondary)}.border-t-outline{border-top-color:var(--outline)}.border-t-sage{border-top-color:var(--primary)}.border-t-terracotta{border-top-color:var(--tertiary)}.border-t-transparent{border-top-color:transparent}.bg-\[var\(--surface-container-lowest\)\]{background-color:var(--surface-container-lowest)}.bg-background{background-color:var(--background)}.bg-black\/60{background-color:#0009}.bg-blue-500\/10{background-color:#3b82f61a}.bg-blue-500\/15{background-color:#3b82f626}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-500\/10{background-color:#22c55e1a}.bg-green-500\/15{background-color:#22c55e26}.bg-muted{background-color:var(--muted)}.bg-ochre{background-color:var(--secondary)}.bg-on-surface{background-color:var(--on-surface)}.bg-on-surface-variant{background-color:var(--on-surface-variant)}.bg-orange-500\/15{background-color:#f9731626}.bg-outline{background-color:var(--outline)}.bg-primary{background-color:var(--primary)}.bg-purple-500\/15{background-color:#a855f726}.bg-sage{background-color:var(--primary)}.bg-secondary{background-color:var(--secondary)}.bg-surface{background-color:var(--surface)}.bg-surface-bright{background-color:var(--surface-bright)}.bg-surface-container{background-color:var(--surface-container)}.bg-surface-container-high{background-color:var(--surface-container-high)}.bg-surface-container-highest{background-color:var(--surface-container-highest)}.bg-surface-container-low{background-color:var(--surface-container-low)}.bg-surface-container-lowest{background-color:var(--surface-container-lowest)}.bg-terracotta,.bg-tertiary{background-color:var(--tertiary)}.bg-transparent{background-color:transparent}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-primary{--tw-gradient-from: var(--primary) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-tertiary{--tw-gradient-from: var(--tertiary) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-primary-container{--tw-gradient-to: var(--primary-container) var(--tw-gradient-to-position)}.to-tertiary-container{--tw-gradient-to: var(--tertiary-container) var(--tw-gradient-to-position)}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-0{padding-left:0;padding-right:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-1{padding-bottom:.25rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pl-0\.5{padding-left:.125rem}.pl-11{padding-left:2.75rem}.pl-2{padding-left:.5rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-5{padding-left:1.25rem}.pl-6{padding-left:1.5rem}.pl-7{padding-left:1.75rem}.pl-9{padding-left:2.25rem}.pr-1{padding-right:.25rem}.pr-12{padding-right:3rem}.pr-2{padding-right:.5rem}.pr-3{padding-right:.75rem}.pr-4{padding-right:1rem}.pr-8{padding-right:2rem}.pt-0{padding-top:0}.pt-0\.5{padding-top:.125rem}.pt-1{padding-top:.25rem}.pt-12{padding-top:3rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-top{vertical-align:top}.font-mono{font-family:var(--font-data, JetBrains Mono),Fira Code,monospace}.font-sans{font-family:var(--font-ui, Inter),system-ui,sans-serif}.font-serif{font-family:var(--font-heading, Newsreader),Georgia,serif}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-5xl{font-size:3rem;line-height:1}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.normal-case{text-transform:none}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-5{line-height:1.25rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-\[0\.16em\]{letter-spacing:.16em}.tracking-\[0\.18em\]{letter-spacing:.18em}.tracking-\[0\.22em\]{letter-spacing:.22em}.tracking-\[0\.3em\]{letter-spacing:.3em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-card-foreground{color:var(--card-foreground)}.text-destructive{color:var(--destructive, var(--tertiary))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-input{color:var(--input)}.text-muted-foreground{color:var(--muted-foreground)}.text-ochre{color:var(--secondary)}.text-on-primary{color:var(--on-primary)}.text-on-surface{color:var(--on-surface)}.text-on-surface-variant{color:var(--on-surface-variant)}.text-orange-600{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.text-outline{color:var(--outline)}.text-primary{color:var(--primary)}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-sage{color:var(--primary)}.text-secondary{color:var(--secondary)}.text-terracotta,.text-tertiary{color:var(--tertiary)}.underline{text-decoration-line:underline}.no-underline{text-decoration-line:none}.underline-offset-4{text-underline-offset:4px}.accent-primary{accent-color:var(--primary)}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-30{opacity:.3}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.opacity-\[0\.04\]{opacity:.04}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_0_12px_rgba\(171\,207\,184\,0\.08\)\]{--tw-shadow: inset 0 0 12px rgba(171,207,184,.08);--tw-shadow-colored: inset 0 0 12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_0_12px_rgba\(171\,207\,184\,0\.2\)\]{--tw-shadow: inset 0 0 12px rgba(171,207,184,.2);--tw-shadow-colored: inset 0 0 12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-ambient{--tw-shadow: 0 24px 48px rgba(var(--shadow-tint), .06);--tw-shadow-colored: 0 24px 48px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-ochre-glow{--tw-shadow: 0 0 8px var(--secondary);--tw-shadow-colored: 0 0 8px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sage-glow{--tw-shadow: 0 0 8px var(--primary);--tw-shadow-colored: 0 0 8px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-terracotta-glow{--tw-shadow: 0 0 8px var(--tertiary);--tw-shadow-colored: 0 0 8px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-0{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-surface-container{--tw-ring-color: var(--surface-container)}.ring-offset-background{--tw-ring-offset-color: var(--background)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-sm{--tw-drop-shadow: drop-shadow(0 1px 1px rgb(0 0 0 / .05));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur{--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-\[2px\]{--tw-backdrop-blur: blur(2px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-xl{--tw-backdrop-blur: blur(24px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[border-color\,background-color\]{transition-property:border-color,background-color;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[border-color\]{transition-property:border-color;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[grid-template-rows\]{transition-property:grid-template-rows;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-150{transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-700{transition-duration:.7s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}@font-face{font-family:Geist Mono;src:url(/fonts/GeistMono-Variable.woff2) format("woff2");font-weight:100 900;font-style:normal;font-display:swap}@font-face{font-family:Newsreader;src:url(/fonts/Newsreader-Variable.woff2) format("woff2");font-weight:200 800;font-style:normal;font-display:swap}@font-face{font-family:Newsreader;src:url(/fonts/Newsreader-Italic-Variable.woff2) format("woff2");font-weight:200 800;font-style:italic;font-display:swap}@font-face{font-family:Inter;src:url(/fonts/Inter-Variable.woff2) format("woff2");font-weight:100 900;font-style:normal;font-display:swap}@font-face{font-family:JetBrains Mono;src:url(/fonts/JetBrainsMono-Variable.woff2) format("woff2");font-weight:100 800;font-style:normal;font-display:swap}.glass-panel{background:color-mix(in srgb,var(--surface-container) 60%,transparent);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}.hover-lift{transition:transform .2s ease,box-shadow .2s ease}.hover-lift:hover{transform:translateY(-2px);box-shadow:0 8px 24px rgba(var(--shadow-tint),.12)}.mycelial-connector{stroke-dasharray:4;opacity:.3}@keyframes pulse-slow{0%,to{opacity:.4}50%{opacity:.8}}.animate-pulse-slow{animation:pulse-slow 3s ease-in-out infinite}.prose-myco{font-family:var(--font-ui, "Inter", system-ui, sans-serif);font-size:.875rem;line-height:1.625;color:var(--on-surface-variant)}.prose-myco h1,.prose-myco h2,.prose-myco h3,.prose-myco h4{font-family:var(--font-heading, "Newsreader", serif);color:var(--on-surface);margin-top:1.25em;margin-bottom:.5em;font-weight:500}.prose-myco h1{font-size:1.25rem}.prose-myco h2{font-size:1.1rem}.prose-myco h3{font-size:.95rem}.prose-myco p{margin-top:.5em;margin-bottom:.5em}.prose-myco strong{color:var(--on-surface);font-weight:600}.prose-myco em{font-style:italic}.prose-myco ul,.prose-myco ol{padding-left:1.25em;margin-top:.5em;margin-bottom:.5em}.prose-myco li{margin-top:.25em}.prose-myco code{font-family:var(--font-data, "JetBrains Mono", monospace);font-size:.8em;padding:.15em .35em;border-radius:.2rem;background:var(--surface-container);color:var(--primary)}.prose-myco pre{font-family:var(--font-data, "JetBrains Mono", monospace);font-size:.75rem;padding:.75rem 1rem;border-radius:.375rem;background:var(--surface-container-lowest);color:var(--on-surface-variant);overflow-x:auto;margin-top:.75em;margin-bottom:.75em}.prose-myco pre code{background:transparent;padding:0;color:inherit}.prose-myco blockquote{border-left:2px solid var(--primary-container);padding-left:1em;margin-left:0;color:var(--on-surface-variant);font-style:italic}.prose-myco hr{border:none;border-top:1px solid var(--outline-variant);margin:1em 0}.prose-myco table{width:100%;border-collapse:collapse;font-size:.8rem}.prose-myco th,.prose-myco td{border:1px solid var(--outline-variant);padding:.35em .5em;text-align:left}.prose-myco th{background:var(--surface-container);font-weight:600;color:var(--on-surface)}.prose-myco a{color:var(--primary);text-decoration:underline}.prose-myco *:first-child{margin-top:0}.prose-myco *:last-child{margin-bottom:0}.prose-myco-compact{font-family:var(--font-ui, "Inter", system-ui, sans-serif);font-size:.8125rem;line-height:1.45;color:var(--on-surface-variant)}.prose-myco-compact h1,.prose-myco-compact h2,.prose-myco-compact h3,.prose-myco-compact h4,.prose-myco-compact h5,.prose-myco-compact h6,.prose-myco-compact p{display:inline;font-family:inherit;font-size:inherit;font-weight:inherit;color:inherit;margin:0}.prose-myco-compact h1+*:before,.prose-myco-compact h2+*:before,.prose-myco-compact h3+*:before,.prose-myco-compact h4+*:before,.prose-myco-compact p+*:before{content:" "}.prose-myco-compact strong{color:var(--on-surface);font-weight:600}.prose-myco-compact em{font-style:italic}.prose-myco-compact code{font-family:var(--font-data, "JetBrains Mono", monospace);font-size:.85em;padding:0 .25em;border-radius:.2rem;background:var(--surface-container);color:var(--primary)}.prose-myco-compact ul,.prose-myco-compact ol{display:inline;padding:0;margin:0}.prose-myco-compact li{display:inline;margin:0}.prose-myco-compact li:before{content:"• "}.prose-myco-compact li+li:before{content:" • "}.prose-myco-compact a{color:inherit;text-decoration:none}.prose-myco-compact pre,.prose-myco-compact blockquote,.prose-myco-compact hr,.prose-myco-compact table{display:none}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.file\:text-on-surface::file-selector-button{color:var(--on-surface)}.placeholder\:text-muted-foreground::-moz-placeholder{color:var(--muted-foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.last\:border-0:last-child{border-width:0px}.last\:border-b-0:last-child{border-bottom-width:0px}.hover\:translate-x-1:hover{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:bg-surface-bright:hover{background-color:var(--surface-bright)}.hover\:bg-surface-container-high:hover{background-color:var(--surface-container-high)}.hover\:bg-surface-container-highest:hover{background-color:var(--surface-container-highest)}.hover\:text-destructive:hover{color:var(--destructive, var(--tertiary))}.hover\:text-on-surface:hover{color:var(--on-surface)}.hover\:text-on-surface-variant:hover{color:var(--on-surface-variant)}.hover\:text-primary:hover{color:var(--primary)}.hover\:text-tertiary:hover{color:var(--tertiary)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-\[0_0_0_1px_rgba\(171\,207\,184\,0\.4\)\]:hover{--tw-shadow: 0 0 0 1px rgba(171,207,184,.4);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-\[0_0_0_1px_rgba\(255\,180\,161\,0\.4\)\]:hover{--tw-shadow: 0 0 0 1px rgba(255,180,161,.4);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-\[inset_3px_0_0_var\(--primary\)\]:hover{--tw-shadow: inset 3px 0 0 var(--primary);--tw-shadow-colored: inset 3px 0 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:ring-2:hover{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.hover\:brightness-110:hover{--tw-brightness: brightness(1.1);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.hover\:brightness-\[1\.08\]:hover{--tw-brightness: brightness(1.08);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:bg-surface-bright:focus{background-color:var(--surface-bright)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-ring:focus{--tw-ring-color: var(--ring)}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:bg-surface-bright:focus-visible{background-color:var(--surface-bright)}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-0:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-inset:focus-visible{--tw-ring-inset: inset}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: var(--ring)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.focus-visible\:ring-offset-surface:focus-visible{--tw-ring-offset-color: var(--surface)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:translate-x-0\.5{--tw-translate-x: .125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:text-primary{color:var(--primary)}.group:hover .group-hover\:opacity-100{opacity:1}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=on\]\:bg-primary[data-state=on]{background-color:var(--primary)}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:var(--accent)}.data-\[state\=on\]\:text-on-primary[data-state=on]{color:var(--on-primary)}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:var(--muted-foreground)}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.dark\:text-blue-400:is(.dark *){--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-orange-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 146 60 / var(--tw-text-opacity, 1))}.dark\:text-purple-400:is(.dark *){--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.dark\:hover\:brightness-\[1\.04\]:hover:is(.dark *){--tw-brightness: brightness(1.04);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}@media(min-width:640px){.sm\:max-w-4xl{max-width:56rem}.sm\:max-w-md{max-width:28rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:.5rem}.sm\:text-left{text-align:left}}@media(min-width:768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-start{align-items:flex-start}.lg\:justify-between{justify-content:space-between}.lg\:p-8{padding:2rem}}.\[\&\>\*\]\:min-w-0>*{min-width:0px}.\[\&\>\*\]\:text-on-surface-variant>*{color:var(--on-surface-variant)}.\[\&\>button\:last-child\]\:hidden>button:last-child{display:none}.\[\&\>span\]\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}
|
package/dist/ui/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Myco</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-O1kNWlWM.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-z2Jm8i4A.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
VAULT_GITIGNORE,
|
|
4
|
+
connectToDaemon,
|
|
4
5
|
registerSymbionts
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-W5L5IHP5.js";
|
|
6
7
|
import "./chunk-SAKJMNSR.js";
|
|
7
8
|
import "./chunk-OTQH5KZW.js";
|
|
8
9
|
import "./chunk-X3IGT5RV.js";
|
|
@@ -16,10 +17,10 @@ import "./chunk-MYX5NCRH.js";
|
|
|
16
17
|
import {
|
|
17
18
|
resolveVaultDir
|
|
18
19
|
} from "./chunk-TSM6VESW.js";
|
|
19
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-6FBLL7MD.js";
|
|
20
21
|
import {
|
|
21
22
|
getPluginVersion
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-Z55WGA2J.js";
|
|
23
24
|
import {
|
|
24
25
|
loadManifests,
|
|
25
26
|
resolvePackageRoot
|
|
@@ -37,6 +38,17 @@ import "./chunk-PZUWP5VK.js";
|
|
|
37
38
|
// src/cli/update.ts
|
|
38
39
|
import fs from "fs";
|
|
39
40
|
import path from "path";
|
|
41
|
+
import semver from "semver";
|
|
42
|
+
var VECTOR_METADATA_REBUILD_VERSION = "0.21.1";
|
|
43
|
+
function shouldTriggerEmbeddingRebuild(previousVersion, currentVersion) {
|
|
44
|
+
if (!semver.valid(currentVersion) || semver.lt(currentVersion, VECTOR_METADATA_REBUILD_VERSION)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
if (!previousVersion || !semver.valid(previousVersion)) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return semver.lt(previousVersion, VECTOR_METADATA_REBUILD_VERSION);
|
|
51
|
+
}
|
|
40
52
|
async function run(args) {
|
|
41
53
|
let projectRoot;
|
|
42
54
|
const projectIdx = args.indexOf("--project");
|
|
@@ -50,6 +62,10 @@ async function run(args) {
|
|
|
50
62
|
}
|
|
51
63
|
console.log(`Updating Myco vault at ${vaultDir}
|
|
52
64
|
`);
|
|
65
|
+
const stampPath = path.join(vaultDir, UPDATE_STAMP_FILENAME);
|
|
66
|
+
const previousVersion = fs.existsSync(stampPath) ? fs.readFileSync(stampPath, "utf-8").trim() || null : null;
|
|
67
|
+
const currentVersion = getPluginVersion();
|
|
68
|
+
const needsEmbeddingRebuild = shouldTriggerEmbeddingRebuild(previousVersion, currentVersion);
|
|
53
69
|
let updatedCount = 0;
|
|
54
70
|
const gitignorePath = path.join(vaultDir, ".gitignore");
|
|
55
71
|
const currentGitignore = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, "utf-8") : "";
|
|
@@ -84,10 +100,28 @@ async function run(args) {
|
|
|
84
100
|
} else {
|
|
85
101
|
console.log(" \u2013 No configured agents found");
|
|
86
102
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
103
|
+
let rebuildTriggeredSuccessfully = !needsEmbeddingRebuild;
|
|
104
|
+
if (needsEmbeddingRebuild) {
|
|
105
|
+
try {
|
|
106
|
+
const client = await connectToDaemon(vaultDir);
|
|
107
|
+
const response = await client.post("/embedding/rebuild", {});
|
|
108
|
+
if (response.ok) {
|
|
109
|
+
const data = response.data;
|
|
110
|
+
console.log(` \u2713 Triggered embedding rebuild for vector metadata refresh${data ? ` (${data.embedded ?? 0} embedded now, ${data.remaining_queue_depth ?? 0} remaining)` : ""}`);
|
|
111
|
+
updatedCount++;
|
|
112
|
+
rebuildTriggeredSuccessfully = true;
|
|
113
|
+
} else {
|
|
114
|
+
console.log(" !! Failed to trigger embedding rebuild after update");
|
|
115
|
+
}
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.log(` !! Failed to trigger embedding rebuild after update: ${error.message}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (rebuildTriggeredSuccessfully) {
|
|
121
|
+
try {
|
|
122
|
+
fs.writeFileSync(stampPath, currentVersion, "utf-8");
|
|
123
|
+
} catch {
|
|
124
|
+
}
|
|
91
125
|
}
|
|
92
126
|
console.log("");
|
|
93
127
|
if (updatedCount > 0) {
|
|
@@ -100,4 +134,4 @@ async function run(args) {
|
|
|
100
134
|
export {
|
|
101
135
|
run
|
|
102
136
|
};
|
|
103
|
-
//# sourceMappingURL=update-
|
|
137
|
+
//# sourceMappingURL=update-TVXAUJMZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/update.ts"],"sourcesContent":["import { resolveVaultDir } from '../vault/resolve.js';\nimport { VAULT_GITIGNORE, registerSymbionts } from './shared.js';\nimport { loadManifests, resolvePackageRoot } from '../symbionts/detect.js';\nimport { loadConfig, getEnabledSymbiontNames } from '../config/loader.js';\nimport { getPluginVersion } from '../version.js';\nimport { UPDATE_STAMP_FILENAME } from '../constants/update.js';\nimport { connectToDaemon } from './shared.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport semver from 'semver';\n\nconst VECTOR_METADATA_REBUILD_VERSION = '0.21.1';\n\nfunction shouldTriggerEmbeddingRebuild(previousVersion: string | null, currentVersion: string): boolean {\n if (!semver.valid(currentVersion) || semver.lt(currentVersion, VECTOR_METADATA_REBUILD_VERSION)) {\n return false;\n }\n if (!previousVersion || !semver.valid(previousVersion)) {\n return true;\n }\n return semver.lt(previousVersion, VECTOR_METADATA_REBUILD_VERSION);\n}\n\n// `myco update` is also the migration path for refreshing managed AGENTS.md content.\n\nexport async function run(args: string[]): Promise<void> {\n let projectRoot: string | undefined;\n const projectIdx = args.indexOf('--project');\n if (projectIdx !== -1 && args[projectIdx + 1]) {\n projectRoot = args[projectIdx + 1];\n }\n\n const vaultDir = projectRoot\n ? path.join(projectRoot, '.myco')\n : resolveVaultDir();\n if (!fs.existsSync(path.join(vaultDir, 'myco.yaml'))) {\n console.error(`No myco.yaml found in ${vaultDir}. Run 'myco init' first.`);\n process.exit(1);\n }\n\n console.log(`Updating Myco vault at ${vaultDir}\\n`);\n\n const stampPath = path.join(vaultDir, UPDATE_STAMP_FILENAME);\n const previousVersion = fs.existsSync(stampPath)\n ? fs.readFileSync(stampPath, 'utf-8').trim() || null\n : null;\n const currentVersion = getPluginVersion();\n const needsEmbeddingRebuild = shouldTriggerEmbeddingRebuild(previousVersion, currentVersion);\n\n let updatedCount = 0;\n\n // --- Update .gitignore to match current template ---\n\n const gitignorePath = path.join(vaultDir, '.gitignore');\n const currentGitignore = fs.existsSync(gitignorePath)\n ? fs.readFileSync(gitignorePath, 'utf-8')\n : '';\n\n if (currentGitignore !== VAULT_GITIGNORE) {\n fs.writeFileSync(gitignorePath, VAULT_GITIGNORE, 'utf-8');\n console.log(' \\u2713 Updated .gitignore');\n updatedCount++;\n } else {\n console.log(' \\u2013 .gitignore is current');\n }\n\n // --- Update symbiont registration ---\n\n const resolvedProjectRoot = projectRoot ?? path.dirname(vaultDir);\n const allManifests = loadManifests();\n const pkgRoot = resolvePackageRoot();\n\n const config = loadConfig(vaultDir);\n let configured: typeof allManifests;\n\n const enabledNames = getEnabledSymbiontNames(config);\n\n if (enabledNames) {\n // Explicit mode: only update enabled symbionts\n configured = allManifests.filter((m) => enabledNames.has(m.name));\n\n // Warn about registered-but-not-enabled symbionts\n for (const m of allManifests) {\n if (!enabledNames.has(m.name) && fs.existsSync(path.join(resolvedProjectRoot, m.configDir))) {\n console.log(` !! ${m.displayName} is registered but not enabled. Run 'myco remove --symbiont ${m.name}' to clean up.`);\n }\n }\n } else {\n // Fallback: configDir-exists heuristic (pre-existing installs without symbionts config)\n configured = allManifests.filter((m) =>\n fs.existsSync(path.join(resolvedProjectRoot, m.configDir)),\n );\n }\n\n if (configured.length > 0) {\n const registered = registerSymbionts(configured, resolvedProjectRoot, pkgRoot, 'Updated');\n updatedCount += registered;\n } else {\n console.log(' \\u2013 No configured agents found');\n }\n\n let rebuildTriggeredSuccessfully = !needsEmbeddingRebuild;\n if (needsEmbeddingRebuild) {\n try {\n const client = await connectToDaemon(vaultDir);\n const response = await client.post('/embedding/rebuild', {});\n if (response.ok) {\n const data = response.data as { embedded?: number; remaining_queue_depth?: number } | undefined;\n console.log(` ✓ Triggered embedding rebuild for vector metadata refresh${data ? ` (${data.embedded ?? 0} embedded now, ${data.remaining_queue_depth ?? 0} remaining)` : ''}`);\n updatedCount++;\n rebuildTriggeredSuccessfully = true;\n } else {\n console.log(' !! Failed to trigger embedding rebuild after update');\n }\n } catch (error) {\n console.log(` !! Failed to trigger embedding rebuild after update: ${(error as Error).message}`);\n }\n }\n\n // --- Write version stamp ---\n if (rebuildTriggeredSuccessfully) {\n try {\n fs.writeFileSync(stampPath, currentVersion, 'utf-8');\n } catch {\n // Non-fatal — stamp write failure shouldn't break the update\n }\n }\n\n // --- Summary ---\n\n console.log('');\n if (updatedCount > 0) {\n console.log(`Updated ${updatedCount} item${updatedCount > 1 ? 's' : ''}.`);\n } else {\n console.log('Everything is up to date.');\n }\n console.log('Run `myco doctor` to verify setup health.');\n}\n"],"mappings":"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","names":[]}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
evaluateUserPromptRules,
|
|
7
7
|
readTranscriptMeta
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-EKZG2MCD.js";
|
|
9
9
|
import {
|
|
10
10
|
normalizeHookInput,
|
|
11
11
|
readStdin
|
|
@@ -15,9 +15,10 @@ import {
|
|
|
15
15
|
resolveVaultDir
|
|
16
16
|
} from "./chunk-TSM6VESW.js";
|
|
17
17
|
import {
|
|
18
|
-
DaemonClient
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
DaemonClient,
|
|
19
|
+
isIgnoredEventResponse
|
|
20
|
+
} from "./chunk-6FBLL7MD.js";
|
|
21
|
+
import "./chunk-Z55WGA2J.js";
|
|
21
22
|
import {
|
|
22
23
|
loadManifests
|
|
23
24
|
} from "./chunk-Z66IT5KL.js";
|
|
@@ -68,7 +69,7 @@ async function main() {
|
|
|
68
69
|
agent: input.agent,
|
|
69
70
|
transcript_path: input.transcriptPath
|
|
70
71
|
});
|
|
71
|
-
if (!eventResult.ok) {
|
|
72
|
+
if (!eventResult.ok || isIgnoredEventResponse(eventResult.data)) {
|
|
72
73
|
const buffer = new EventBuffer(path.join(VAULT_DIR, "buffer"), sessionId);
|
|
73
74
|
buffer.append({ type: "user_prompt", prompt, transcript_path: input.transcriptPath });
|
|
74
75
|
}
|
|
@@ -88,4 +89,4 @@ ${sessionLine}` : sessionLine;
|
|
|
88
89
|
export {
|
|
89
90
|
main
|
|
90
91
|
};
|
|
91
|
-
//# sourceMappingURL=user-prompt-submit-
|
|
92
|
+
//# sourceMappingURL=user-prompt-submit-KYO2VGLB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/user-prompt-submit.ts"],"sourcesContent":["import { DaemonClient, isIgnoredEventResponse } from './client.js';\nimport { readStdin } from './read-stdin.js';\nimport { normalizeHookInput } from './normalize.js';\nimport { evaluateUserPromptRules } from './capture-rules.js';\nimport { readTranscriptMeta } from './transcript-meta.js';\nimport { loadManifests } from '../symbionts/detect.js';\nimport { EventBuffer } from '../capture/buffer.js';\nimport { resolveVaultDir } from '../vault/resolve.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport async function main() {\n const VAULT_DIR = resolveVaultDir();\n if (!fs.existsSync(path.join(VAULT_DIR, 'myco.yaml'))) return;\n\n try {\n const rawInput = JSON.parse(await readStdin());\n const input = normalizeHookInput(rawInput);\n const rawPrompt = input.prompt ?? '';\n const sessionId = input.sessionId;\n\n // Apply generic capture rules owned by each symbiont's manifest.\n // The hook stays symbiont-agnostic — per-agent behavior lives in YAML.\n // Pass structural context so rules can key on things like\n // `transcript_path_missing` without doing their own text mining.\n const transcriptMeta = input.transcriptPath ? readTranscriptMeta(input.transcriptPath) : undefined;\n const decision = evaluateUserPromptRules(loadManifests(), input.agent, {\n prompt: rawPrompt,\n transcriptPath: input.transcriptPath,\n transcriptMeta: transcriptMeta ?? undefined,\n });\n\n const client = new DaemonClient(VAULT_DIR);\n // Spawn daemon if needed but don't block on full health check backoff.\n // The event POST will fail fast if daemon isn't ready — buffer absorbs it.\n if (!(await client.isHealthy())) {\n client.spawnDaemon();\n }\n\n if (decision.action === 'drop') {\n // A rule classified this prompt as a phantom sub-invocation (e.g., an\n // agent's internal title-generation call). SessionStart already\n // registered the session row; delete it so it doesn't linger as a\n // zero-prompt ghost in the UI. Silently tolerate failures — the\n // session-maintenance sweep will clean up stragglers within the\n // stale threshold as a safety net.\n process.stderr.write(`[myco] user-prompt-submit: dropped (${decision.reason ?? 'rule'})\\n`);\n await client.delete(`/api/sessions/${sessionId}`);\n return;\n }\n\n const prompt = decision.action === 'rewrite' ? decision.prompt : rawPrompt;\n if (decision.action === 'rewrite') {\n process.stderr.write(`[myco] user-prompt-submit: rewritten (${decision.reason ?? 'rule'})\\n`);\n }\n\n // Forward prompt as event for capture\n const eventResult = await client.post('/events', {\n type: 'user_prompt',\n prompt,\n session_id: sessionId,\n agent: input.agent,\n transcript_path: input.transcriptPath,\n });\n\n // Buffer on transport failure OR server-side drop (200 with `ignored`).\n // A server-side drop means a capture rule discarded the event; buffering\n // it lets reconcileBufferBatches recover the prompt once the rule is fixed.\n if (!eventResult.ok || isIgnoredEventResponse(eventResult.data)) {\n const buffer = new EventBuffer(path.join(VAULT_DIR, 'buffer'), sessionId);\n buffer.append({ type: 'user_prompt', prompt, transcript_path: input.transcriptPath });\n }\n\n // Search for relevant spores to inject as context for this prompt.\n // The daemon does a vector search against the prompt text and returns\n // any high-relevance spores. This is fast (~20ms) — no LLM call.\n const contextResult = await client.post('/context/prompt', {\n prompt,\n session_id: sessionId,\n });\n\n // Always include the session ID so the agent can pass it to myco_remember.\n // Uses Session:: format consistent with daemon context injection (Branch::, Session::).\n const sessionLine = `Session:: \\`${sessionId}\\``;\n const contextText = contextResult.ok && contextResult.data?.text\n ? `${contextResult.data.text}\\n${sessionLine}`\n : sessionLine;\n\n process.stdout.write(contextText);\n } catch (error) {\n process.stderr.write(`[myco] user-prompt-submit error: ${(error as Error).message}\\n`);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,eAAsB,OAAO;AAC3B,QAAM,YAAY,gBAAgB;AAClC,MAAI,CAAC,GAAG,WAAW,KAAK,KAAK,WAAW,WAAW,CAAC,EAAG;AAEvD,MAAI;AACF,UAAM,WAAW,KAAK,MAAM,MAAM,UAAU,CAAC;AAC7C,UAAM,QAAQ,mBAAmB,QAAQ;AACzC,UAAM,YAAY,MAAM,UAAU;AAClC,UAAM,YAAY,MAAM;AAMxB,UAAM,iBAAiB,MAAM,iBAAiB,mBAAmB,MAAM,cAAc,IAAI;AACzF,UAAM,WAAW,wBAAwB,cAAc,GAAG,MAAM,OAAO;AAAA,MACrE,QAAQ;AAAA,MACR,gBAAgB,MAAM;AAAA,MACtB,gBAAgB,kBAAkB;AAAA,IACpC,CAAC;AAED,UAAM,SAAS,IAAI,aAAa,SAAS;AAGzC,QAAI,CAAE,MAAM,OAAO,UAAU,GAAI;AAC/B,aAAO,YAAY;AAAA,IACrB;AAEA,QAAI,SAAS,WAAW,QAAQ;AAO9B,cAAQ,OAAO,MAAM,uCAAuC,SAAS,UAAU,MAAM;AAAA,CAAK;AAC1F,YAAM,OAAO,OAAO,iBAAiB,SAAS,EAAE;AAChD;AAAA,IACF;AAEA,UAAM,SAAS,SAAS,WAAW,YAAY,SAAS,SAAS;AACjE,QAAI,SAAS,WAAW,WAAW;AACjC,cAAQ,OAAO,MAAM,yCAAyC,SAAS,UAAU,MAAM;AAAA,CAAK;AAAA,IAC9F;AAGA,UAAM,cAAc,MAAM,OAAO,KAAK,WAAW;AAAA,MAC/C,MAAM;AAAA,MACN;AAAA,MACA,YAAY;AAAA,MACZ,OAAO,MAAM;AAAA,MACb,iBAAiB,MAAM;AAAA,IACzB,CAAC;AAKD,QAAI,CAAC,YAAY,MAAM,uBAAuB,YAAY,IAAI,GAAG;AAC/D,YAAM,SAAS,IAAI,YAAY,KAAK,KAAK,WAAW,QAAQ,GAAG,SAAS;AACxE,aAAO,OAAO,EAAE,MAAM,eAAe,QAAQ,iBAAiB,MAAM,eAAe,CAAC;AAAA,IACtF;AAKA,UAAM,gBAAgB,MAAM,OAAO,KAAK,mBAAmB;AAAA,MACzD;AAAA,MACA,YAAY;AAAA,IACd,CAAC;AAID,UAAM,cAAc,eAAe,SAAS;AAC5C,UAAM,cAAc,cAAc,MAAM,cAAc,MAAM,OACxD,GAAG,cAAc,KAAK,IAAI;AAAA,EAAK,WAAW,KAC1C;AAEJ,YAAQ,OAAO,MAAM,WAAW;AAAA,EAClC,SAAS,OAAO;AACd,YAAQ,OAAO,MAAM,oCAAqC,MAAgB,OAAO;AAAA,CAAI;AAAA,EACvF;AACF;","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
getPluginVersion
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Z55WGA2J.js";
|
|
5
5
|
import "./chunk-LPUQPDC2.js";
|
|
6
6
|
import "./chunk-PZUWP5VK.js";
|
|
7
7
|
export {
|
|
8
8
|
getPluginVersion
|
|
9
9
|
};
|
|
10
|
-
//# sourceMappingURL=version-
|
|
10
|
+
//# sourceMappingURL=version-LDFEALUJ.js.map
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../myco-team/src/cli.ts","../src/config/secrets.ts","../../myco-deploy/src/cloudflare.ts","../../myco-deploy/src/local-config.ts"],"sourcesContent":["/**\n * CLI team commands — provision and manage Cloudflare team sync infrastructure.\n *\n * `myco team init` — Provision D1 database, Vectorize index, deploy worker.\n * `myco team upgrade` — Redeploy worker with updated source.\n */\n\nimport crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { CONFIG_FILENAME, loadConfig, updateTeamConfig } from '@myco/config/loader.js';\nimport { writeSecret, readSecrets } from '@myco/config/secrets.js';\nimport { WRANGLER_COMMAND_TIMEOUT_MS, TEAM_API_KEY_SECRET, TEAM_MCP_TOKEN_SECRET } from '@myco/constants.js';\nimport { SCHEMA_VERSION } from '@myco/db/schema.js';\nimport {\n extractJsonArray,\n installDeploymentDeps,\n maskSecret,\n parseD1Id,\n parseKvNamespaceId,\n parseWorkerUrl,\n readJsonConfig,\n resolveHomeConfigPath,\n resolveVaultConfigPath,\n runWrangler,\n stageDeploymentDir,\n writeJsonConfig,\n} from '@myco-deploy/index.js';\n\ndeclare const __MYCO_TEAM_VERSION__: string;\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Number of random bytes for API key generation. */\nconst API_KEY_BYTES = 32;\n\n/** Vectorize index dimensions (must match the embedding model). */\nconst VECTORIZE_DIMENSIONS = '1024';\n\n/** Vectorize distance metric. */\nconst VECTORIZE_METRIC = 'cosine';\n\n/** Prefix for team resource names. */\nconst TEAM_RESOURCE_PREFIX = 'myco-team';\n\n/** Length of the project hash suffix for unique resource naming. */\nconst PROJECT_HASH_LENGTH = 8;\n\n\n/** Source directory for worker files (relative to package root). */\nconst WORKER_SOURCE_DIR = 'worker';\n\n/** Team sync state directory within the vault. */\nconst TEAM_STATE_DIR = 'team';\nconst TEAM_DEPLOY_DIR = 'worker';\nconst TEAM_CONFIG_FILE = 'config.json';\nconst LEGACY_TEAM_CONFIG_DIR = '.myco-team';\nconst LEGACY_TEAM_DEPLOY_DIR = '.team-worker';\nconst TEAM_CONFIG_VERSION = 1;\nconst TEAM_MCP_ROTATION_RETRY_ATTEMPTS = 10;\nconst TEAM_MCP_ROTATION_RETRY_DELAY_MS = 1500;\n\n/** Regex to match wrangler.toml name field. */\nconst TOML_NAME_REGEX = /^name\\s*=\\s*\"[^\"]*\"/m;\n\n/** Regex to match wrangler.toml D1 placeholder. */\nconst TOML_D1_PLACEHOLDER_REGEX = /<YOUR_D1_DATABASE_ID>/g;\n\n/** Regex to match wrangler.toml database_name field. */\nconst TOML_DB_NAME_REGEX = /database_name\\s*=\\s*\"[^\"]*\"/g;\n\n/** Regex to match wrangler.toml index_name field. */\nconst TOML_INDEX_NAME_REGEX = /index_name\\s*=\\s*\"[^\"]*\"/g;\n\n/** Regex to match wrangler.toml team package version placeholder. */\nconst TOML_TEAM_PACKAGE_VERSION_REGEX = /MYCO_TEAM_PACKAGE_VERSION\\s*=\\s*\"[^\"]*\"/g;\n\n/** Regex to match wrangler.toml Myco schema version placeholder. */\nconst TOML_MYCO_SCHEMA_VERSION_REGEX = /MYCO_SCHEMA_VERSION\\s*=\\s*\"[^\"]*\"/g;\n\n/** Regex to match database_id in existing wrangler.toml. */\nconst TOML_DB_ID_REGEX = /database_id\\s*=\\s*\"([^\"]+)\"/;\n\n/** Regex to match wrangler.toml KV namespace placeholder. */\nconst TOML_KV_PLACEHOLDER_REGEX = /<YOUR_KV_NAMESPACE_ID>/g;\n\n/** Regex to extract the KV namespace ID from an existing wrangler.toml. */\nconst TOML_KV_ID_REGEX = /\\[\\[kv_namespaces\\]\\][\\s\\S]*?id\\s*=\\s*\"([0-9a-f]+)\"/;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Generate a project hash from vault dir for unique resource naming. */\nfunction projectHash(vaultDir: string): string {\n const hash = crypto.createHash('sha256').update(vaultDir).digest('hex');\n return hash.slice(0, PROJECT_HASH_LENGTH);\n}\n\n/** Build the unique resource name for this project's team infrastructure. */\nfunction resourceName(vaultDir: string): string {\n return `${TEAM_RESOURCE_PREFIX}-${projectHash(vaultDir)}`;\n}\n\nfunction resolvePackageRoot(): string {\n const override = process.env.MYCO_TEAM_PACKAGE_ROOT?.trim();\n if (override) return override;\n return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');\n}\n\nexport function getTeamPackageVersion(): string {\n if (typeof __MYCO_TEAM_VERSION__ !== 'undefined') {\n return __MYCO_TEAM_VERSION__;\n }\n\n const packageRoot = resolvePackageRoot();\n const candidatePaths = [\n path.join(packageRoot, 'package.json'),\n path.join(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'), 'package.json'),\n ];\n\n for (const candidatePath of candidatePaths) {\n if (!fs.existsSync(candidatePath)) continue;\n const packageJson = JSON.parse(fs.readFileSync(candidatePath, 'utf-8')) as { version?: string };\n if (packageJson.version) return packageJson.version;\n }\n\n return '0.1.0';\n}\n\nfunction getMycoSchemaVersion(): string {\n return String(SCHEMA_VERSION);\n}\n\nexport interface TeamLocalConfig {\n worker_name: string;\n worker_url: string;\n package_version: string;\n created_at: string;\n last_upgraded: string;\n config_version: number;\n}\n\ninterface LegacyTeamLocalConfig extends TeamLocalConfig {\n api_key?: string;\n mcp_token?: string | null;\n vault_dir?: string;\n}\n\nfunction resolveLocalConfigPath(vaultDir: string): string {\n return resolveVaultConfigPath(vaultDir, TEAM_STATE_DIR, TEAM_CONFIG_FILE);\n}\n\nfunction resolveLegacyLocalConfigPath(): string {\n return resolveHomeConfigPath(LEGACY_TEAM_CONFIG_DIR, TEAM_CONFIG_FILE);\n}\n\nfunction resolveDeployDir(vaultDir: string): string {\n return path.join(vaultDir, TEAM_STATE_DIR, TEAM_DEPLOY_DIR);\n}\n\nfunction resolveLegacyDeployDir(vaultDir: string): string {\n return path.join(vaultDir, LEGACY_TEAM_DEPLOY_DIR);\n}\n\nfunction writeLocalConfig(vaultDir: string, config: TeamLocalConfig): void {\n writeJsonConfig(resolveLocalConfigPath(vaultDir), config);\n}\n\nfunction migrateLegacyDeployDir(vaultDir: string): void {\n const legacyDeployDir = resolveLegacyDeployDir(vaultDir);\n const nextDeployDir = resolveDeployDir(vaultDir);\n if (!fs.existsSync(legacyDeployDir) || fs.existsSync(nextDeployDir)) return;\n\n fs.mkdirSync(path.dirname(nextDeployDir), { recursive: true });\n fs.renameSync(legacyDeployDir, nextDeployDir);\n}\n\nfunction readLocalConfig(vaultDir: string): TeamLocalConfig | null {\n const config = readJsonConfig<TeamLocalConfig>(resolveLocalConfigPath(vaultDir));\n if (config) {\n migrateLegacyDeployDir(vaultDir);\n return config;\n }\n\n const legacyConfig = readJsonConfig<LegacyTeamLocalConfig>(resolveLegacyLocalConfigPath());\n if (!legacyConfig) return null;\n if (legacyConfig.vault_dir && legacyConfig.vault_dir !== vaultDir) return null;\n\n const migrated: TeamLocalConfig = {\n worker_name: legacyConfig.worker_name,\n worker_url: legacyConfig.worker_url,\n package_version: legacyConfig.package_version,\n created_at: legacyConfig.created_at,\n last_upgraded: legacyConfig.last_upgraded,\n config_version: legacyConfig.config_version ?? TEAM_CONFIG_VERSION,\n };\n writeLocalConfig(vaultDir, migrated);\n if (legacyConfig.api_key) writeSecret(vaultDir, TEAM_API_KEY_SECRET, legacyConfig.api_key);\n if (legacyConfig.mcp_token) writeSecret(vaultDir, TEAM_MCP_TOKEN_SECRET, legacyConfig.mcp_token);\n migrateLegacyDeployDir(vaultDir);\n return migrated;\n}\n\nfunction requireLocalConfig(vaultDir: string): TeamLocalConfig {\n const config = readLocalConfig(vaultDir);\n if (config) return config;\n\n console.error(`No local myco-team config found at ${resolveLocalConfigPath(vaultDir)}`);\n process.exit(1);\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function rotateMcpTokenWithRetry(workerUrl: string, apiKey: string): Promise<string> {\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= TEAM_MCP_ROTATION_RETRY_ATTEMPTS; attempt += 1) {\n try {\n return await rotateMcpTokenForWorker(workerUrl, apiKey);\n } catch (error) {\n lastError = error as Error;\n const isRetryable =\n lastError.message.includes('401') &&\n lastError.message.includes('Invalid API key') &&\n attempt < TEAM_MCP_ROTATION_RETRY_ATTEMPTS;\n if (!isRetryable) {\n throw lastError;\n }\n await delay(TEAM_MCP_ROTATION_RETRY_DELAY_MS);\n }\n }\n\n throw lastError ?? new Error('MCP token rotation failed');\n}\n\n/** Run a wrangler command and return stdout. Throws on failure, surfacing stderr. */\nfunction wrangler(args: string[], options?: { cwd?: string }): string {\n return runWrangler(args, { cwd: options?.cwd, timeoutMs: WRANGLER_COMMAND_TIMEOUT_MS });\n}\n\n/** Find the worker source directory. Checks dist layout first (installed), then source layout (dev). */\nfunction locateWorkerSource(): string {\n const root = resolvePackageRoot();\n const distPath = path.join(root, 'dist', WORKER_SOURCE_DIR);\n if (fs.existsSync(distPath)) return distPath;\n const srcPath = path.join(root, WORKER_SOURCE_DIR);\n if (fs.existsSync(srcPath)) return srcPath;\n throw new Error(`Cannot find ${WORKER_SOURCE_DIR} — are you running from the myco-team package?`);\n}\n\n/**\n * Copy worker source to the vault deployment directory and patch wrangler.toml\n * with actual D1 database ID and resource names.\n */\nfunction prepareDeployDir(vaultDir: string, d1Id: string, kvId: string): string {\n const srcDir = locateWorkerSource();\n const deployDir = resolveDeployDir(vaultDir);\n const name = resourceName(vaultDir);\n return stageDeploymentDir({\n sourceDir: srcDir,\n deployDir,\n reset: true,\n textPatches: [{\n filePath: 'wrangler.toml',\n transforms: [\n (toml) => toml.replace(TOML_NAME_REGEX, `name = \"${name}\"`),\n (toml) => toml.replace(TOML_D1_PLACEHOLDER_REGEX, d1Id),\n (toml) => toml.replace(TOML_DB_NAME_REGEX, `database_name = \"${name}\"`),\n (toml) => toml.replace(TOML_INDEX_NAME_REGEX, `index_name = \"${name}-vectors\"`),\n (toml) => toml.replace(TOML_KV_PLACEHOLDER_REGEX, kvId),\n (toml) => toml.replace(TOML_TEAM_PACKAGE_VERSION_REGEX, `MYCO_TEAM_PACKAGE_VERSION = \"${getTeamPackageVersion()}\"`),\n (toml) => toml.replace(TOML_MYCO_SCHEMA_VERSION_REGEX, `MYCO_SCHEMA_VERSION = \"${getMycoSchemaVersion()}\"`),\n ],\n }],\n installDepsTimeoutMs: WRANGLER_COMMAND_TIMEOUT_MS * 3,\n });\n}\n\n/** Ensure a KV namespace exists for this project. Returns the namespace ID. */\nfunction ensureKvNamespace(name: string): string {\n const kvName = `${name}-secrets`;\n const lookupExisting = (): string => {\n const listOutput = wrangler(['kv', 'namespace', 'list']);\n const namespaces = extractJsonArray(listOutput) as Array<{ id: string; title: string }>;\n // Wrangler sometimes rewrites hyphens to underscores in titles\n const normalize = (s: string) => s.replace(/[-_]/g, '');\n const target = normalize(kvName);\n const existing = namespaces.find((ns) => normalize(ns.title) === target || normalize(ns.title).endsWith(target));\n if (!existing) throw new Error(`KV namespace \"${kvName}\" not found in list of ${namespaces.length} namespaces`);\n return existing.id;\n };\n\n try {\n const output = wrangler(['kv', 'namespace', 'create', kvName]);\n return parseKvNamespaceId(output);\n // Created successfully but we couldn't parse — fall back to list lookup\n } catch (err) {\n const errMsg = (err as Error).message;\n if (errMsg.includes('already exists') || errMsg.includes('duplicate') || errMsg.includes('same title')) {\n return lookupExisting();\n }\n throw err;\n }\n}\n\nasync function rotateMcpTokenForWorker(workerUrl: string, apiKey: string): Promise<string> {\n const response = await fetch(`${workerUrl}/mcp/rotate`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) {\n throw new Error(`MCP token rotation failed: ${response.status} ${await response.text()}`);\n }\n const body = await response.json() as { token?: string };\n if (!body.token) {\n throw new Error('MCP token rotation response did not include a token');\n }\n return body.token;\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\nexport async function teamInit(vaultDir: string): Promise<void> {\n console.log('Provisioning team sync infrastructure...\\n');\n\n // 1. Check for wrangler\n try {\n const version = wrangler(['--version']).trim();\n console.log(`wrangler: ${version}`);\n } catch {\n console.error('Error: wrangler CLI not found. Install it with: npm install -g wrangler');\n process.exit(1);\n }\n\n // 2. Check auth\n try {\n wrangler(['whoami']);\n console.log('Cloudflare auth: OK\\n');\n } catch {\n console.error('Error: Not authenticated with Cloudflare. Run: wrangler login');\n process.exit(1);\n }\n\n const name = resourceName(vaultDir);\n console.log(`Resource name: ${name}\\n`);\n\n // 3. Create D1 database (or reuse existing)\n console.log('Creating D1 database...');\n let d1Id: string;\n try {\n const d1Output = wrangler(['d1', 'create', name]);\n d1Id = parseD1Id(d1Output);\n console.log(`D1 database created: ${d1Id}\\n`);\n } catch (err) {\n const errMsg = (err as Error).message;\n if (errMsg.includes('already exists')) {\n console.log('D1 database already exists, looking up ID...');\n const listOutput = wrangler(['d1', 'list', '--json']);\n const databases = JSON.parse(listOutput) as Array<{ name: string; uuid: string }>;\n const existing = databases.find((db) => db.name === name);\n if (!existing) {\n console.error(`D1 database \"${name}\" reported as existing but not found in list`);\n process.exit(1);\n }\n d1Id = existing.uuid;\n console.log(`Reusing D1 database: ${d1Id}\\n`);\n } else {\n console.error(`Failed to create D1 database: ${errMsg}`);\n process.exit(1);\n }\n }\n\n // 4. Create Vectorize index (or reuse existing)\n console.log('Creating Vectorize index...');\n try {\n wrangler(['vectorize', 'create', `${name}-vectors`, '--dimensions', VECTORIZE_DIMENSIONS, '--metric', VECTORIZE_METRIC]);\n console.log('Vectorize index created\\n');\n } catch (err) {\n const errMsg = (err as Error).message;\n if (errMsg.includes('already exists') || errMsg.includes('duplicate_name')) {\n console.log('Vectorize index already exists, reusing\\n');\n } else {\n console.error(`Failed to create Vectorize index: ${errMsg}`);\n process.exit(1);\n }\n }\n\n // 5. Create KV namespace for runtime secrets (MCP tokens)\n console.log('Creating KV namespace for secrets...');\n let kvId: string;\n try {\n kvId = ensureKvNamespace(name);\n console.log(`KV namespace ready: ${kvId}\\n`);\n } catch (err) {\n console.error(`Failed to create KV namespace: ${(err as Error).message}`);\n process.exit(1);\n }\n\n // 6. Generate API key\n const apiKey = crypto.randomBytes(API_KEY_BYTES).toString('hex');\n\n // 7. Prepare deployment directory\n console.log('Preparing worker deployment...');\n const deployDir = prepareDeployDir(vaultDir, d1Id, kvId);\n\n // 7. Set API key secret via wrangler\n console.log('Setting API key secret...');\n try {\n runWrangler(['secret', 'put', TEAM_API_KEY_SECRET, '--name', name], {\n cwd: deployDir,\n input: apiKey,\n timeoutMs: WRANGLER_COMMAND_TIMEOUT_MS,\n });\n console.log('Secret set\\n');\n } catch (err) {\n console.error(`Failed to set API key secret: ${(err as Error).message}`);\n process.exit(1);\n }\n\n // 8. Deploy worker\n console.log('Deploying worker...');\n let workerUrl: string;\n try {\n const deployOutput = wrangler(['deploy'], { cwd: deployDir });\n workerUrl = parseWorkerUrl(deployOutput);\n console.log(`Worker deployed: ${workerUrl}\\n`);\n } catch (err) {\n console.error(`Failed to deploy worker: ${(err as Error).message}`);\n process.exit(1);\n }\n\n // 9. Seed team config in the Worker\n console.log('Setting team configuration...');\n try {\n const { getMachineId } = await import('@myco/daemon/machine-id.js');\n const creatorMachineId = await getMachineId(vaultDir);\n await fetch(`${workerUrl}/config`, {\n method: 'PUT',\n headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n team_name: name,\n embedding_model: '@cf/baai/bge-m3',\n embedding_dimensions: '1024',\n created_at: String(Math.floor(Date.now() / 1000)),\n created_by: creatorMachineId,\n }),\n });\n console.log('Team config saved\\n');\n } catch {\n console.log('Warning: could not seed team config (non-fatal)\\n');\n }\n\n let mcpToken: string | null = null;\n try {\n mcpToken = await rotateMcpTokenForWorker(workerUrl, apiKey);\n } catch {\n // Non-fatal. The daemon can also fetch the token later through /connect.\n }\n\n // 10. Save config and API key locally\n updateTeamConfig(vaultDir, {\n enabled: true,\n worker_url: workerUrl,\n });\n writeSecret(vaultDir, TEAM_API_KEY_SECRET, apiKey);\n if (mcpToken) writeSecret(vaultDir, TEAM_MCP_TOKEN_SECRET, mcpToken);\n writeLocalConfig(vaultDir, {\n worker_name: name,\n worker_url: workerUrl,\n package_version: getTeamPackageVersion(),\n created_at: new Date().toISOString(),\n last_upgraded: new Date().toISOString(),\n config_version: TEAM_CONFIG_VERSION,\n });\n\n console.log('Team sync configured!\\n');\n console.log(` URL: ${workerUrl}`);\n console.log(` API Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`);\n if (mcpToken) {\n console.log(` MCP: ${mcpToken.slice(0, 8)}...${mcpToken.slice(-4)}`);\n }\n console.log('\\nShare the URL and API key with teammates so they can connect.');\n}\n\n// ---------------------------------------------------------------------------\n// Shared upgrade logic (used by CLI and daemon API)\n// ---------------------------------------------------------------------------\n\nexport interface UpgradeResult {\n success: boolean;\n worker_url?: string;\n version?: string;\n error?: string;\n}\n\n/**\n * Upgrade the team sync worker: re-copy source, patch config, redeploy.\n * Returns a result instead of calling process.exit — safe for both CLI and daemon.\n */\nexport function upgradeWorker(vaultDir: string): UpgradeResult {\n const config = loadConfig(vaultDir);\n if (!config.team.worker_url) {\n return { success: false, error: 'No team sync configured. Run: myco team init' };\n }\n\n migrateLegacyDeployDir(vaultDir);\n const deployDir = resolveDeployDir(vaultDir);\n const tomlPath = path.join(deployDir, 'wrangler.toml');\n\n if (!fs.existsSync(tomlPath)) {\n return { success: false, error: 'No deployment directory found. Run: myco team init' };\n }\n\n // Read ALL existing resource identifiers from current wrangler.toml.\n const existingToml = fs.readFileSync(tomlPath, 'utf-8');\n const d1Match = existingToml.match(TOML_DB_ID_REGEX);\n if (!d1Match || d1Match[1] === '<YOUR_D1_DATABASE_ID>') {\n return { success: false, error: 'Cannot determine D1 database ID from existing deployment. Run: myco team init' };\n }\n const d1Id = d1Match[1];\n\n const nameMatch = existingToml.match(/^name\\s*=\\s*\"([^\"]*)\"/m);\n const dbNameMatch = existingToml.match(/database_name\\s*=\\s*\"([^\"]*)\"/);\n const indexNameMatch = existingToml.match(/index_name\\s*=\\s*\"([^\"]*)\"/);\n const workerName = nameMatch?.[1] ?? resourceName(vaultDir);\n\n // KV namespace may not exist on older deployments — create or reuse.\n const kvMatch = existingToml.match(TOML_KV_ID_REGEX);\n let kvId: string;\n if (kvMatch) {\n kvId = kvMatch[1];\n } else {\n try {\n kvId = ensureKvNamespace(workerName);\n } catch (err) {\n return { success: false, error: `Failed to provision KV namespace: ${(err as Error).message}` };\n }\n }\n\n try {\n stageDeploymentDir({\n sourceDir: locateWorkerSource(),\n deployDir,\n textPatches: [{\n filePath: 'wrangler.toml',\n transforms: [\n (toml) => toml.replace(TOML_NAME_REGEX, `name = \"${workerName}\"`),\n (toml) => toml.replace(TOML_D1_PLACEHOLDER_REGEX, d1Id),\n (toml) => toml.replace(TOML_DB_NAME_REGEX, `database_name = \"${dbNameMatch?.[1] ?? workerName}\"`),\n (toml) => toml.replace(TOML_INDEX_NAME_REGEX, `index_name = \"${indexNameMatch?.[1] ?? `${workerName}-vectors`}\"`),\n (toml) => toml.replace(TOML_KV_PLACEHOLDER_REGEX, kvId),\n (toml) => toml.replace(TOML_TEAM_PACKAGE_VERSION_REGEX, `MYCO_TEAM_PACKAGE_VERSION = \"${getTeamPackageVersion()}\"`),\n (toml) => toml.replace(TOML_MYCO_SCHEMA_VERSION_REGEX, `MYCO_SCHEMA_VERSION = \"${getMycoSchemaVersion()}\"`),\n ],\n }],\n installDepsTimeoutMs: WRANGLER_COMMAND_TIMEOUT_MS * 3,\n });\n } catch (err) {\n return { success: false, error: `Failed to install worker dependencies: ${(err as Error).message}` };\n }\n\n // Re-set API key secret before deploy (deploy can wipe secrets)\n const secrets = readSecrets(vaultDir);\n const apiKey = secrets[TEAM_API_KEY_SECRET];\n if (apiKey) {\n try {\n runWrangler(['secret', 'put', TEAM_API_KEY_SECRET, '--name', workerName], {\n cwd: deployDir,\n input: apiKey,\n timeoutMs: WRANGLER_COMMAND_TIMEOUT_MS,\n });\n } catch {\n // Non-fatal — secret may already be set\n }\n }\n\n // Redeploy\n try {\n const deployOutput = wrangler(['deploy'], { cwd: deployDir });\n const workerUrl = parseWorkerUrl(deployOutput);\n const version = getTeamPackageVersion();\n\n updateTeamConfig(vaultDir, {\n worker_url: workerUrl,\n });\n const localConfig = readLocalConfig(vaultDir);\n if (localConfig) {\n writeLocalConfig(vaultDir, {\n ...localConfig,\n worker_name: workerName,\n worker_url: workerUrl,\n package_version: version,\n last_upgraded: new Date().toISOString(),\n });\n }\n\n return { success: true, worker_url: workerUrl, version };\n } catch (err) {\n return { success: false, error: `Failed to deploy worker: ${(err as Error).message}` };\n }\n}\n\n// ---------------------------------------------------------------------------\n// CLI wrapper\n// ---------------------------------------------------------------------------\n\nexport async function teamUpgrade(vaultDir: string): Promise<void> {\n console.log('Upgrading team sync worker...\\n');\n const result = upgradeWorker(vaultDir);\n if (!result.success) {\n console.error(result.error);\n process.exit(1);\n }\n console.log(`Worker deployed: ${result.worker_url}`);\n console.log(`Version: ${result.version}`);\n console.log('\\nUpgrade complete.');\n}\n\nexport async function teamStatus(vaultDir: string): Promise<void> {\n const config = requireLocalConfig(vaultDir);\n const secrets = readSecrets(vaultDir);\n\n console.log(`Worker: ${config.worker_name}`);\n console.log(`URL: ${config.worker_url}`);\n console.log(`API Key: ${maskSecret(secrets[TEAM_API_KEY_SECRET] ?? null)}`);\n console.log(`MCP Token: ${maskSecret(secrets[TEAM_MCP_TOKEN_SECRET] ?? null)}`);\n console.log(`Package v: ${config.package_version}`);\n console.log(`Created: ${config.created_at}`);\n console.log(`Upgraded: ${config.last_upgraded}`);\n console.log(`Config v: ${config.config_version}`);\n}\n\nexport async function teamRotateTokens(vaultDir: string, which: 'api' | 'mcp' | 'all' = 'all'): Promise<void> {\n const config = requireLocalConfig(vaultDir);\n const secrets = readSecrets(vaultDir);\n let currentApiKey = secrets[TEAM_API_KEY_SECRET] ?? '';\n let currentMcpToken = secrets[TEAM_MCP_TOKEN_SECRET] ?? null;\n\n let nextConfig = { ...config };\n\n if (which === 'api' || which === 'all') {\n const apiKey = crypto.randomBytes(API_KEY_BYTES).toString('hex');\n runWrangler(['secret', 'put', TEAM_API_KEY_SECRET, '--name', config.worker_name], {\n cwd: resolveDeployDir(vaultDir),\n input: apiKey,\n timeoutMs: WRANGLER_COMMAND_TIMEOUT_MS,\n });\n writeSecret(vaultDir, TEAM_API_KEY_SECRET, apiKey);\n currentApiKey = apiKey;\n nextConfig = {\n ...nextConfig,\n package_version: getTeamPackageVersion(),\n last_upgraded: new Date().toISOString(),\n };\n writeLocalConfig(vaultDir, nextConfig);\n }\n\n if (which === 'mcp' || which === 'all') {\n try {\n currentMcpToken = await rotateMcpTokenWithRetry(config.worker_url, currentApiKey);\n if (currentMcpToken) writeSecret(vaultDir, TEAM_MCP_TOKEN_SECRET, currentMcpToken);\n } catch (error) {\n writeLocalConfig(vaultDir, {\n ...nextConfig,\n last_upgraded: new Date().toISOString(),\n });\n throw new Error(\n `API key rotation completed, but MCP token rotation failed. Local config was updated to the new API key.\\n${(error as Error).message}`,\n );\n }\n }\n\n nextConfig.last_upgraded = new Date().toISOString();\n writeLocalConfig(vaultDir, nextConfig);\n\n console.log(`API Key: ${maskSecret(currentApiKey)}`);\n console.log(`MCP Token: ${maskSecret(currentMcpToken)}`);\n}\n\nexport async function teamDestroy(vaultDir: string): Promise<void> {\n const config = requireLocalConfig(vaultDir);\n const errors: string[] = [];\n const deployDir = resolveDeployDir(vaultDir);\n\n try {\n wrangler(['delete', config.worker_name], { cwd: deployDir });\n } catch (error) {\n errors.push(`worker delete failed: ${(error as Error).message}`);\n }\n\n try {\n wrangler(['vectorize', 'delete', `${config.worker_name}-vectors`]);\n } catch (error) {\n errors.push(`vectorize delete failed: ${(error as Error).message}`);\n }\n\n try {\n const databases = JSON.parse(wrangler(['d1', 'list', '--json'])) as Array<{ name: string; uuid: string }>;\n const database = databases.find((entry) => entry.name === config.worker_name);\n if (database) {\n wrangler(['d1', 'delete', database.name, '--skip-confirmation']);\n }\n } catch (error) {\n errors.push(`d1 delete failed: ${(error as Error).message}`);\n }\n\n try {\n const namespaces = extractJsonArray(wrangler(['kv', 'namespace', 'list'])) as Array<{ id: string; title: string }>;\n const namespace = namespaces.find((entry) => entry.title === `${config.worker_name}-secrets`);\n if (namespace) {\n wrangler(['kv', 'namespace', 'delete', '--namespace-id', namespace.id, '--skip-confirmation']);\n }\n } catch (error) {\n errors.push(`kv delete failed: ${(error as Error).message}`);\n }\n\n if (errors.length > 0) {\n throw new Error(`Team destroy incomplete. Local state preserved for retry.\\n${errors.join('\\n')}`);\n }\n\n fs.rmSync(path.join(vaultDir, TEAM_STATE_DIR), { recursive: true, force: true });\n console.log(`Destroyed local myco-team state for ${config.worker_name}.`);\n}\n","/**\n * Secrets file utilities for API key storage outside git.\n *\n * Secrets are stored in `secrets.env` inside the vault directory.\n * This file is gitignored (see VAULT_GITIGNORE) and never committed.\n * Format: KEY=value, one per line (same as .env).\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nconst SECRETS_FILE = 'secrets.env';\n\n/** Read all secrets from <vault>/secrets.env as key-value pairs. */\nexport function readSecrets(vaultDir: string): Record<string, string> {\n const secretsPath = path.join(vaultDir, SECRETS_FILE);\n if (!fs.existsSync(secretsPath)) return {};\n\n const secrets: Record<string, string> = {};\n for (const line of fs.readFileSync(secretsPath, 'utf-8').split('\\n')) {\n const match = line.match(/^\\s*([^#=]+?)\\s*=\\s*(.*?)\\s*$/);\n if (match) {\n secrets[match[1]] = match[2];\n }\n }\n return secrets;\n}\n\n/** Write a secret to <vault>/secrets.env, preserving existing entries. */\nexport function writeSecret(vaultDir: string, key: string, value: string): void {\n const secretsPath = path.join(vaultDir, SECRETS_FILE);\n const existing = readSecrets(vaultDir);\n existing[key] = value;\n\n const content = Object.entries(existing)\n .map(([k, v]) => `${k}=${v}`)\n .join('\\n') + '\\n';\n\n fs.writeFileSync(secretsPath, content, 'utf-8');\n}\n\n/** Remove one or more secrets from <vault>/secrets.env, preserving remaining entries. */\nexport function deleteSecrets(vaultDir: string, keys: string[]): void {\n const secretsPath = path.join(vaultDir, SECRETS_FILE);\n if (!fs.existsSync(secretsPath)) return;\n\n const existing = readSecrets(vaultDir);\n for (const key of keys) delete existing[key];\n\n const entries = Object.entries(existing);\n if (entries.length === 0) {\n fs.rmSync(secretsPath, { force: true });\n return;\n }\n\n const content = entries\n .map(([k, v]) => `${k}=${v}`)\n .join('\\n') + '\\n';\n\n fs.writeFileSync(secretsPath, content, 'utf-8');\n}\n\n/** Load secrets from <vault>/secrets.env into process.env (without overwriting existing vars). */\nexport function loadSecrets(vaultDir: string): void {\n const secrets = readSecrets(vaultDir);\n for (const [key, value] of Object.entries(secrets)) {\n if (!process.env[key]) {\n process.env[key] = value;\n }\n }\n}\n","import { execFileSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nconst WORKER_URL_REGEX = /(https:\\/\\/[^\\s]+\\.workers\\.dev)/;\nconst D1_ID_JSON_REGEX = /\"database_id\"\\s*:\\s*\"([0-9a-f-]{36})\"/i;\nconst D1_ID_TEXT_REGEX = /id:\\s*([0-9a-f-]{36})/i;\nconst KV_ID_REGEX = /\"id\":\\s*\"([0-9a-f]+)\"/i;\n\nexport interface WranglerOptions {\n cwd?: string;\n input?: string;\n timeoutMs: number;\n}\n\nexport interface TextPatch {\n filePath: string;\n transforms: Array<(text: string) => string>;\n}\n\nexport interface StageDeploymentDirOptions {\n sourceDir: string;\n deployDir: string;\n reset?: boolean;\n extraCopies?: Array<{ sourceDir: string; destinationSubdir: string }>;\n textPatches?: TextPatch[];\n installDepsTimeoutMs?: number | null;\n}\n\nexport function buildCommandEnv(): NodeJS.ProcessEnv {\n const nodeBinDir = path.dirname(process.execPath);\n const pathValue = process.env.PATH\n ? `${nodeBinDir}${path.delimiter}${process.env.PATH}`\n : nodeBinDir;\n return { ...process.env, PATH: pathValue };\n}\n\nexport function runWrangler(args: string[], options: WranglerOptions): string {\n try {\n return execFileSync('wrangler', args, {\n cwd: options.cwd,\n env: buildCommandEnv(),\n input: options.input,\n encoding: 'utf-8',\n timeout: options.timeoutMs,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n } catch (error) {\n const execError = error as Error & { stderr?: Buffer | string; stdout?: Buffer | string };\n const stderr = execError.stderr?.toString() ?? '';\n const stdout = execError.stdout?.toString() ?? '';\n const detail = [stderr, stdout].filter(Boolean).join('\\n').trim();\n throw new Error(detail || execError.message);\n }\n}\n\nexport function installDeploymentDeps(deployDir: string, timeoutMs: number): void {\n const packageJsonPath = path.join(deployDir, 'package.json');\n if (!fs.existsSync(packageJsonPath)) return;\n\n execFileSync('npm', ['install', '--silent', '--no-audit', '--no-fund'], {\n cwd: deployDir,\n env: buildCommandEnv(),\n encoding: 'utf-8',\n timeout: timeoutMs,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n}\n\nexport function parseWorkerUrl(output: string): string {\n const workerUrl = output.match(WORKER_URL_REGEX)?.[1];\n if (!workerUrl) {\n throw new Error(`Could not parse worker URL from deploy output:\\n${output}`);\n }\n return workerUrl;\n}\n\nexport function parseD1Id(output: string): string {\n const jsonMatch = output.match(D1_ID_JSON_REGEX);\n if (jsonMatch) return jsonMatch[1];\n\n const textMatch = output.match(D1_ID_TEXT_REGEX);\n if (textMatch) return textMatch[1];\n\n throw new Error(`Could not parse D1 database ID from wrangler output:\\n${output}`);\n}\n\nexport function parseKvNamespaceId(output: string): string {\n const kvId = output.match(KV_ID_REGEX)?.[1];\n if (!kvId) {\n throw new Error(`Could not parse KV namespace ID from wrangler output:\\n${output}`);\n }\n return kvId;\n}\n\nexport function extractJsonArray(output: string): unknown[] {\n const start = output.indexOf('[');\n const end = output.lastIndexOf(']');\n if (start === -1 || end === -1 || end < start) {\n throw new Error(`No JSON array found in output:\\n${output}`);\n }\n return JSON.parse(output.slice(start, end + 1)) as unknown[];\n}\n\nexport function stageDeploymentDir(options: StageDeploymentDirOptions): string {\n if (options.reset) {\n fs.rmSync(options.deployDir, { recursive: true, force: true });\n }\n fs.mkdirSync(options.deployDir, { recursive: true });\n fs.cpSync(options.sourceDir, options.deployDir, { recursive: true });\n\n for (const copy of options.extraCopies ?? []) {\n fs.cpSync(copy.sourceDir, path.join(options.deployDir, copy.destinationSubdir), { recursive: true });\n }\n\n for (const patch of options.textPatches ?? []) {\n const absolutePath = path.join(options.deployDir, patch.filePath);\n let nextText = fs.readFileSync(absolutePath, 'utf-8');\n for (const transform of patch.transforms) {\n nextText = transform(nextText);\n }\n fs.writeFileSync(absolutePath, nextText, 'utf-8');\n }\n\n if (options.installDepsTimeoutMs) {\n installDeploymentDeps(options.deployDir, options.installDepsTimeoutMs);\n }\n\n return options.deployDir;\n}\n","import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nconst MYCO_HOME_OVERRIDE_ENV = 'MYCO_HOME_OVERRIDE';\n\nexport function resolveHomeDir(): string {\n return process.env[MYCO_HOME_OVERRIDE_ENV]?.trim() || os.homedir();\n}\n\nexport function resolveHomeConfigPath(configDir: string, fileName: string): string {\n return path.join(resolveHomeDir(), configDir, fileName);\n}\n\nexport function resolveNamedHomeConfigPath(configDir: string, name: string, fileName: string): string {\n return path.join(resolveHomeDir(), configDir, name, fileName);\n}\n\nexport function resolveVaultConfigPath(vaultDir: string, configDir: string, fileName: string): string {\n return path.join(vaultDir, configDir, fileName);\n}\n\nexport function readJsonConfig<T>(configPath: string): T | null {\n if (!fs.existsSync(configPath)) return null;\n return JSON.parse(fs.readFileSync(configPath, 'utf-8')) as T;\n}\n\nexport function writeJsonConfig(configPath: string, value: unknown): void {\n fs.mkdirSync(path.dirname(configPath), { recursive: true });\n fs.writeFileSync(configPath, `${JSON.stringify(value, null, 2)}\\n`, { encoding: 'utf-8', mode: 0o600 });\n fs.chmodSync(configPath, 0o600);\n}\n\nexport function maskSecret(secret: string | null): string | null {\n if (!secret) return null;\n if (secret.length <= 8) return secret;\n return `${secret.slice(0, 4)}...${secret.slice(-4)}`;\n}\n\nexport function createHexToken(byteLength: number): string {\n return crypto.randomBytes(byteLength).toString('hex');\n}\n"],"mappings":"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","names":["crypto","fs","path","fs","path","fs","path","path","fs","crypto","path","fs","path","fs","crypto"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/vault/types.ts","../src/mcp/tool-definitions.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const SessionFrontmatterSchema = z.object({\n type: z.literal('session'),\n id: z.string(),\n agent: z.string(),\n user: z.string(),\n started: z.string(),\n ended: z.string().optional(),\n parent: z.string().optional(),\n parent_reason: z.string().optional(),\n plan: z.string().optional(), // backward compat read path\n plans: z.array(z.string()).optional(), // new: multiple plans\n branch: z.string().optional(),\n tags: z.array(z.string()).default([]),\n tools_used: z.number().int().optional(),\n files_changed: z.number().int().optional(),\n});\n\nexport const PLAN_STATUSES = ['active', 'in_progress', 'completed', 'abandoned'] as const;\n\nexport const PlanFrontmatterSchema = z.object({\n type: z.literal('plan'),\n id: z.string(),\n status: z.enum(PLAN_STATUSES).default('active'),\n created: z.string(),\n author: z.string().optional(),\n tags: z.array(z.string()).default([]),\n});\n\nexport const OBSERVATION_TYPES = ['gotcha', 'bug_fix', 'decision', 'discovery', 'trade_off', 'cross-cutting'] as const;\n\nexport const SPORE_STATUSES = ['active', 'superseded', 'archived'] as const;\nexport type SporeStatus = (typeof SPORE_STATUSES)[number];\n\nexport const SporeFrontmatterSchema = z.object({\n type: z.literal('spore'),\n id: z.string(),\n observation_type: z.string(),\n status: z.enum(SPORE_STATUSES).default('active'),\n session: z.string().optional(),\n plan: z.string().optional(),\n superseded_by: z.string().optional(),\n consolidated_from: z.array(z.string()).optional(),\n created: z.string(),\n tags: z.array(z.string()).default([]),\n});\n\nexport const ARTIFACT_TYPES = ['spec', 'plan', 'rfc', 'doc', 'other'] as const;\nexport type ArtifactType = (typeof ARTIFACT_TYPES)[number];\n\nexport const ArtifactFrontmatterSchema = z.object({\n type: z.literal('artifact'),\n id: z.string(),\n artifact_type: z.enum(ARTIFACT_TYPES).default('other'),\n source_path: z.string(),\n title: z.string(),\n last_captured_by: z.string(),\n created: z.string(),\n updated: z.string(),\n tags: z.array(z.string()).default([]),\n});\n\nexport const TeamMemberFrontmatterSchema = z.object({\n type: z.literal('team-member'),\n user: z.string(),\n joined: z.string(),\n role: z.string().optional(),\n tags: z.array(z.string()).default([]),\n});\n\nexport type SessionFrontmatter = z.infer<typeof SessionFrontmatterSchema>;\nexport type PlanFrontmatter = z.infer<typeof PlanFrontmatterSchema>;\nexport type SporeFrontmatter = z.infer<typeof SporeFrontmatterSchema>;\nexport type ObservationType = SporeFrontmatter['observation_type'];\nexport type ArtifactFrontmatter = z.infer<typeof ArtifactFrontmatterSchema>;\nexport type TeamMemberFrontmatter = z.infer<typeof TeamMemberFrontmatterSchema>;\n\nexport type NoteFrontmatter =\n | SessionFrontmatter\n | PlanFrontmatter\n | SporeFrontmatter\n | ArtifactFrontmatter\n | TeamMemberFrontmatter;\n\nexport interface VaultNote<T extends NoteFrontmatter = NoteFrontmatter> {\n path: string;\n frontmatter: T;\n content: string;\n}\n\nconst schemasByType: Record<string, z.ZodSchema> = {\n session: SessionFrontmatterSchema,\n plan: PlanFrontmatterSchema,\n spore: SporeFrontmatterSchema,\n artifact: ArtifactFrontmatterSchema,\n 'team-member': TeamMemberFrontmatterSchema,\n};\n\nexport function parseNoteFrontmatter(data: Record<string, unknown>): NoteFrontmatter {\n const type = data.type as string;\n const schema = schemasByType[type];\n if (!schema) {\n throw new Error(`Unknown note type: ${type}. Known types: ${Object.keys(schemasByType).join(', ')}`);\n }\n // gray-matter and YAML.parse return Date objects for ISO date strings.\n // Coerce them to strings before Zod validation.\n const coerced = coerceDatesToStrings(data);\n return schema.parse(coerced) as NoteFrontmatter;\n}\n\nfunction coerceDatesToStrings(obj: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value instanceof Date) {\n result[key] = value.toISOString();\n } else if (Array.isArray(value)) {\n result[key] = value.map((item) => item instanceof Date ? item.toISOString() : item);\n } else if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n result[key] = coerceDatesToStrings(value as Record<string, unknown>);\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n","/**\n * MCP tool names, descriptions, and schema definitions.\n * Single source of truth for all tool metadata — referenced by the MCP server\n * and available to tests, logging, and documentation generators.\n */\nimport { OBSERVATION_TYPES, PLAN_STATUSES } from '../vault/types.js';\nimport { MCP_SEARCH_DEFAULT_LIMIT, MCP_SESSIONS_DEFAULT_LIMIT, MCP_SKILLS_DEFAULT_LIMIT } from '../constants.js';\n\n/** Plan statuses plus 'all' for filtering. */\nconst PLAN_STATUS_FILTER = [...PLAN_STATUSES, 'all'] as const;\nconst DEFAULT_CORTEX_PRIORITY = 100;\n\ninterface ToolInputSchema {\n type: 'object';\n properties: Record<string, unknown>;\n required?: string[];\n}\n\nexport interface ToolCortexMetadata {\n guidance: string;\n priority?: number;\n requiresTeam?: boolean;\n requiresCollective?: boolean;\n}\n\n/**\n * MCP tool annotations. These follow the MCP spec's `annotations` envelope\n * so clients can show the right UI affordances (confirm-before-run for\n * destructive tools, quiet auto-run for read-only ones, etc.). Bundle D\n * makes these mandatory for every Myco-registered tool.\n */\nexport interface ToolAnnotations {\n /** True if the tool never mutates state. */\n readOnlyHint: boolean;\n /**\n * True if the tool can destroy data or start work that's hard to undo.\n * For multi-op tools, set true if ANY op is destructive and describe\n * the op matrix in the tool description.\n */\n destructiveHint: boolean;\n /** True if calling the tool twice with the same input is safe. */\n idempotentHint: boolean;\n /** True if the tool reaches outside the local vault (network, other machines). */\n openWorldHint: boolean;\n}\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: ToolInputSchema;\n annotations?: ToolAnnotations;\n cortex?: ToolCortexMetadata;\n}\n\nexport function getToolCortexPriority(tool: Pick<ToolDefinition, 'cortex'>): number {\n return tool.cortex?.priority ?? DEFAULT_CORTEX_PRIORITY;\n}\n\n// --- Tool names ---\nexport const TOOL_SEARCH = 'myco_search';\nexport const TOOL_RECALL = 'myco_recall';\nexport const TOOL_REMEMBER = 'myco_remember';\nexport const TOOL_PLANS = 'myco_plans';\nexport const TOOL_SAVE_PLAN = 'myco_save_plan';\nexport const TOOL_SESSIONS = 'myco_sessions';\nexport const TOOL_TEAM = 'myco_team';\nexport const TOOL_GRAPH = 'myco_graph';\nexport const TOOL_SUPERSEDE = 'myco_supersede';\nexport const TOOL_CONSOLIDATE = 'myco_consolidate';\nexport const TOOL_CONTEXT = 'myco_context';\nexport const TOOL_SKILLS = 'myco_skills';\nexport const TOOL_SKILL_CANDIDATES = 'myco_skill_candidates';\nexport const TOOL_COLLECTIVE_SEARCH = 'collective_search';\nexport const TOOL_COLLECTIVE_PROJECTS = 'collective_projects';\nexport const TOOL_COLLECTIVE_PROJECT = 'collective_project';\nexport const TOOL_CORTEX = 'myco_cortex';\nexport const TOOL_RUNS = 'myco_runs';\nexport const TOOL_EVALUATIONS = 'myco_evaluations';\nexport const TOOL_WRITE_INTENTS = 'myco_write_intents';\nexport const TOOL_PHASE_AUDIT = 'myco_phase_audit';\nexport const TOOL_RESUME_RUN = 'myco_resume_run';\nexport const TOOL_DIGEST_REVISIONS = 'myco_digest_revisions';\n\n// --- Shared property descriptions (used by multiple tools) ---\nconst PROP_BRANCH = 'Git branch name to find related sessions and plans';\nconst PROP_SINCE = 'ISO timestamp — entries after this date';\nconst PROP_TAGS = 'Tags for discoverability — component names, technologies, concepts';\n\n// --- Tool definitions ---\nexport const TOOL_DEFINITIONS: ToolDefinition[] = [\n {\n name: TOOL_SEARCH,\n description: 'Search the vault for prior sessions, spores, plans, and artifacts. Use before making design decisions, when debugging non-obvious issues, or when wondering why code is structured a certain way.',\n cortex: {\n guidance: 'Use for prior decisions, bugs, and rationale when you know the topic but not the exact note.',\n priority: 20,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n query: { type: 'string', description: 'Natural language search query — describe what you are looking for' },\n type: { type: 'string', enum: ['session', 'plan', 'spore', 'all'], description: 'Filter by note type (default: all)' },\n limit: { type: 'number', description: `Max results (default: ${MCP_SEARCH_DEFAULT_LIMIT})` },\n },\n required: ['query'],\n },\n },\n {\n name: TOOL_RECALL,\n description: 'Look up a specific vault note by ID — returns the full content of a session, spore, or plan. Use when you have a note ID from search results or graph traversal and need the complete details.',\n cortex: {\n guidance: 'Use after search finds a promising result and you need the full note.',\n priority: 30,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n note_id: { type: 'string', description: 'Note ID to look up (e.g., \"session-abc123\", \"decision-xyz789\", \"plan-feature-x\")' },\n },\n required: ['note_id'],\n },\n },\n {\n name: TOOL_REMEMBER,\n description: 'Save a decision, gotcha, bug fix, discovery, or trade-off as a permanent spore. Use after making a key decision, fixing a tricky bug, discovering something non-obvious, or encountering a gotcha. Session association is derived by the daemon — the MCP client does not pass it.',\n cortex: {\n guidance: 'Use to save durable decisions, gotchas, discoveries, or bug fixes from this work.',\n priority: 90,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n content: { type: 'string', description: 'The observation — include context, reasoning, and what someone encountering this in the future needs to know' },\n type: { type: 'string', enum: OBSERVATION_TYPES, description: `Observation type: ${OBSERVATION_TYPES.join(', ')}` },\n tags: { type: 'array', items: { type: 'string' }, description: PROP_TAGS },\n },\n required: ['content', 'type'],\n },\n },\n {\n name: TOOL_PLANS,\n description: 'List or delete implementation plans. op: \"list\" (default) returns plan summaries — filter by status, session, or a single id. op: \"delete\" removes a plan by id; cross-machine rows require force_remote: true. Use list to check what work is in flight before starting new tasks; use delete when retiring obsolete plans.',\n annotations: {\n // Destructive because op: \"delete\" removes a plan and enqueues a tombstone.\n // Consumers should confirm before running this tool with op: \"delete\".\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n cortex: {\n guidance: 'Use op: \"list\" before implementation when approved plans or specs may already exist; pass session to scope to the current work, or id to fetch a single plan with content.',\n priority: 50,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n op: { type: 'string', enum: ['list', 'delete'], description: 'Operation (default: \"list\")' },\n status: { type: 'string', enum: PLAN_STATUS_FILTER, description: 'Filter by status (default: all statuses); ignored for op: \"delete\"' },\n id: { type: 'string', description: 'Plan id. Required for op: \"delete\". For op: \"list\" returns that plan with content.' },\n session: { type: 'string', description: 'Filter list to plans belonging to this session; mutually exclusive with id.' },\n limit: { type: 'number', description: 'Max results for op: \"list\"' },\n force_remote: { type: 'boolean', description: 'Allow op: \"delete\" to remove a plan belonging to another machine. Enqueues a tombstone for team sync.' },\n },\n },\n },\n {\n name: TOOL_SAVE_PLAN,\n description: 'Persist a plan directly into Myco for a session. Use this when you generated or revised a plan and want it captured reliably. Pass exactly one of `source_path` or `plan_key` — `source_path` when the plan is also written to disk (so direct persistence and file capture reconcile to one logical plan), or `plan_key` for non-file-backed plans. The daemon rejects requests that set neither or both. Note: plan_key creates a stable namespace (session:<id>:key:<name>) distinct from transcript <tag> capture (session:<id>:tag:<name>) — the two do not merge. Dropping the transcript tag while also calling myco_save_plan with plan_key=tag will produce two separate rows.',\n cortex: {\n guidance: 'Use when you create or materially revise a plan and want it persisted to Myco. Pass `source_path` when the plan is also written to disk; otherwise use a stable `plan_key`. Note: `plan_key` rows are a separate namespace from transcript `<tag>` capture — reusing the same name in both channels creates two rows, not one.',\n priority: 60,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n session_id: { type: 'string', description: 'Session id the plan belongs to' },\n content: { type: 'string', description: 'Markdown plan content to persist' },\n source_path: { type: 'string', description: 'Path to the plan file when the plan is also written to disk. Pass this OR plan_key, never both.' },\n plan_key: { type: 'string', description: 'Stable key for non-file-backed plans (for example: primary). Pass this OR source_path, never both.' },\n title: { type: 'string', description: 'Optional explicit title. Defaults to the first Markdown H1, then file name or humanized plan_key.' },\n status: { type: 'string', enum: PLAN_STATUSES, description: `Plan status: ${PLAN_STATUSES.join(', ')}` },\n tags: { type: 'array', items: { type: 'string' }, description: PROP_TAGS },\n },\n required: ['session_id', 'content'],\n },\n },\n {\n name: TOOL_SESSIONS,\n description: 'Browse past coding sessions with summaries, tools used, and linked spores. Use to understand what work has been done on a feature or branch.',\n cortex: {\n guidance: 'Use when continuing related work or recovering recent implementation context.',\n priority: 40,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n plan: { type: 'string', description: 'Filter to the session linked to this plan id' },\n branch: { type: 'string', description: PROP_BRANCH },\n user: { type: 'string', description: 'Filter sessions by user' },\n since: { type: 'string', description: PROP_SINCE },\n status: { type: 'string', description: 'Filter by session status (e.g., active, completed)' },\n limit: { type: 'number', description: `Max results (default: ${MCP_SESSIONS_DEFAULT_LIMIT})` },\n },\n },\n },\n {\n name: TOOL_TEAM,\n description: 'List team members registered in the vault. Returns id, user, role, joined, and tags per member. Phase-1 scope: no filters.',\n cortex: {\n guidance: 'Use for current team topology and shared project context.',\n priority: 70,\n requiresTeam: true,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {},\n },\n },\n {\n name: TOOL_GRAPH,\n description: 'Traverse connections between records via graph edges — explore how sessions, spores, and plans relate to each other.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n note_id: { type: 'string', description: 'Note ID to start from (e.g., \"session-abc123\" or \"decision-xyz789\")' },\n direction: { type: 'string', enum: ['incoming', 'outgoing', 'both'], description: 'Link direction to follow (default: both)' },\n depth: { type: 'number', description: 'How many hops to traverse, 1-3 (default: 1)' },\n },\n required: ['note_id'],\n },\n },\n {\n name: TOOL_SUPERSEDE,\n description: 'Mark a spore as outdated and replaced by a newer one. Use when a decision was reversed, a gotcha was fixed, a discovery was wrong, or the codebase changed and an observation no longer applies. The old spore is preserved but marked superseded.',\n cortex: {\n guidance: 'Use when existing knowledge is outdated and should stop guiding future runs.',\n priority: 100,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n old_spore_id: { type: 'string', description: 'ID of the outdated spore (e.g., \"decision-abc123\")' },\n new_spore_id: { type: 'string', description: 'ID of the replacement spore' },\n reason: { type: 'string', description: 'Why the old spore is being superseded' },\n },\n required: ['old_spore_id', 'new_spore_id'],\n },\n },\n {\n name: TOOL_CONSOLIDATE,\n description: 'Merge 2+ related spores into a single comprehensive wisdom note. Inserts a new spore with the consolidated content; each source spore is marked superseded with a resolution_events row linking it to the new wisdom spore. Use when multiple observations describe aspects of the same insight, share a root cause, or would be more useful as one reference.',\n cortex: {\n guidance: 'Use when several related learnings should become one durable wisdom artifact.',\n priority: 110,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n source_spore_ids: { type: 'array', items: { type: 'string' }, description: 'IDs of the spores to merge (minimum 2)' },\n consolidated_content: { type: 'string', description: 'The merged, comprehensive content — synthesize, do not just concatenate' },\n observation_type: { type: 'string', enum: OBSERVATION_TYPES, description: `Type for the consolidated wisdom note: ${OBSERVATION_TYPES.join(', ')}` },\n tags: { type: 'array', items: { type: 'string' }, description: PROP_TAGS },\n reason: { type: 'string', description: 'Optional reason recorded on each resolution event' },\n },\n required: ['source_spore_ids', 'consolidated_content', 'observation_type'],\n },\n },\n {\n name: TOOL_CONTEXT,\n description: \"Retrieve Myco's pre-computed project digest — a rich, always-current synthesis of project history, decisions, patterns, active work, and institutional knowledge. Call this at the start of a new task or session to orient yourself on the project before taking action; call it again after long interruptions or when switching contexts. This is NOT a search — it's the project's accumulated understanding, served instantly. Available tiers: 1500 (executive briefing, one-screen overview), 5000 (deep onboarding, default), 10000 (comprehensive institutional knowledge). Prefer this over myco_search when you need broad project orientation; use myco_search when you need to find specific prior decisions or bug fixes.\",\n cortex: {\n guidance: 'Use for broad project orientation or when you want the current digest before planning changes.',\n priority: 10,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n tier: {\n type: 'number',\n enum: [1500, 5000, 10000],\n description: 'Token budget tier. Larger tiers include more detail. Default: 5000.',\n },\n },\n },\n },\n {\n name: TOOL_SKILLS,\n description: 'List and inspect skills generated by Myco. Use to see what skills are active, check skill details, or find skills by status.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n id: { type: 'string', description: 'Get a specific skill by ID or name' },\n status: { type: 'string', description: 'Filter by status: active, stale, retired' },\n limit: { type: 'number', description: `Max results (default: ${MCP_SKILLS_DEFAULT_LIMIT})` },\n },\n },\n },\n {\n name: TOOL_SKILL_CANDIDATES,\n description: 'List and manage skill candidates — observations identified as potential skills. Use to see pending candidates, approve, or dismiss them.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n id: { type: 'string', description: 'Get a specific candidate by ID' },\n action: { type: 'string', enum: ['list', 'approve', 'dismiss'], description: \"Action to perform (default: 'list')\" },\n status: { type: 'string', description: 'Filter by status: identified, approved, generated, dismissed' },\n limit: { type: 'number', description: `Max results (default: ${MCP_SKILLS_DEFAULT_LIMIT})` },\n },\n },\n },\n {\n name: TOOL_CORTEX,\n description: 'Cortex instruction + prompt-builder surface. op: \"get\" returns the current session-start instructions snapshot. op: \"refresh\" triggers the cortex-instructions task to regenerate them. op: \"build_prompt\" starts the cortex-prompt-builder task for a goal (required) and optional symbiont. op: \"get_prompt_result\" polls a prompt-builder run by run_id. Refresh and build_prompt are not read-only — they start background runs.',\n annotations: {\n // Mixed: get/get_prompt_result are read-only, refresh/build_prompt kick\n // off background work. Mark conservatively — consumers should not silently\n // auto-run this tool.\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n cortex: {\n guidance: 'Use op: \"get\" to read your own session-start Cortex instructions; use op: \"build_prompt\" + \"get_prompt_result\" when you need the prompt-builder to draft a prompt for a specific goal.',\n priority: 95,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n op: { type: 'string', enum: ['get', 'refresh', 'build_prompt', 'get_prompt_result'], description: 'Cortex operation' },\n run_id: { type: 'string', description: 'Required for op: \"get_prompt_result\"' },\n goal: { type: 'string', description: 'Required for op: \"build_prompt\" — the task the prompt will be built for' },\n symbiont: { type: 'string', description: 'Optional symbiont/agent name the prompt should be tuned for; defaults to the first enabled symbiont' },\n },\n required: ['op'],\n },\n },\n {\n name: TOOL_RUNS,\n description: 'Read agent run history. op: \"list\" (default) returns recent runs with runtime/provider/model/token/cost/reasoning fields — filter by task, agent_id, limit. op: \"get\" with id returns a single run including write_intents totals and duration_ms. Use after a run completes to check your own token budget, cost, and reasoning level — particularly useful when debugging a run that exhausted context.',\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n cortex: {\n guidance: 'Use op: \"get\" with your run id to check your own token budget, cost, and reasoning level — especially after a run that exhausted context or failed. Use op: \"list\" to browse recent runs for a task.',\n priority: 85,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n op: { type: 'string', enum: ['list', 'get'], description: 'Operation (default: \"list\")' },\n id: { type: 'string', description: 'Required for op: \"get\" — the run id' },\n task: { type: 'string', description: 'Filter op: \"list\" by task name' },\n agent_id: { type: 'string', description: 'Filter op: \"list\" by agent id' },\n limit: { type: 'number', description: 'Max results for op: \"list\" (default: 50)' },\n },\n },\n },\n {\n name: TOOL_EVALUATIONS,\n description: 'Create, list, or fetch agent evaluations. An evaluation fans out a single task across a cartesian product of (runtime × reasoning × model) cells so outputs can be compared side by side. op: \"list\" (default) returns newest-first summaries with an optional limit. op: \"get\" with id returns the evaluation + child runs + aggregate stats. op: \"create\" requires task_id and matrix; cells execute sequentially in the background — the response returns the evaluationId + cellCount. op: \"create\" is NOT read-only; it starts background runs.',\n annotations: {\n // Mixed ops: list/get are read-only, create kicks off background runs.\n // Mark conservatively so clients confirm before auto-running with op: \"create\".\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n cortex: {\n guidance: 'Use op: \"list\" to see recent matrix evaluations, op: \"get\" to inspect cells + aggregate stats, and op: \"create\" to fan a task out across runtime/reasoning/model cells for side-by-side comparison.',\n priority: 88,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n op: { type: 'string', enum: ['list', 'get', 'create'], description: 'Operation (default: \"list\")' },\n status: { type: 'string', description: 'Filter op: \"list\" by status (reserved; currently ignored by the route)' },\n limit: { type: 'number', description: 'Max results for op: \"list\" (default: 50)' },\n id: { type: 'string', description: 'Required for op: \"get\" — the evaluation id' },\n task_id: { type: 'string', description: 'Required for op: \"create\" — id of the agent task to evaluate' },\n matrix: {\n type: 'object',\n description: 'Required for op: \"create\". Matrix payload: { runtimes?, reasoningLevels?, models?, dryRun?, notes?, phases? }. Empty arrays expand to defaults. See /api/agent/evaluations POST body for full shape.',\n },\n notes: { type: 'string', description: 'Optional notes stored alongside the evaluation row (op: \"create\" only)' },\n },\n },\n },\n {\n name: TOOL_WRITE_INTENTS,\n description: 'Inspect the write-intents recorded during a dry-run — what the agent would have done (tool_name, tool_input, synthetic_output) without actually writing. Paginated via limit (default 500, max 5000) and offset. Use with myco_runs to verify safety before re-running the same task without dry_run.',\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n cortex: {\n guidance: 'Use after a dry-run to inspect what writes the agent would have performed — close the \"dry-run → verify → real-run\" loop before repeating the task without dry_run.',\n priority: 86,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n run_id: { type: 'string', description: 'The run id whose write-intents you want to inspect' },\n limit: { type: 'number', description: 'Max results (default: 500, max: 5000)' },\n offset: { type: 'number', description: 'Pagination offset (default: 0)' },\n },\n required: ['run_id'],\n },\n },\n {\n name: TOOL_PHASE_AUDIT,\n description: 'Read the per-phase audit trail for an agent run — what each phase did, its cost, tool-call counts, reasoning level, and any write intents. Returns a joined view over agent_runs, agent_reports, agent_turns, usage_data, checkpoints, and (for dry runs) agent_run_write_intents. Essential for debugging a failed or mis-executing run.',\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n cortex: {\n guidance: 'Use when debugging a failed or mis-executing run — returns the per-phase cost, tool counts, reasoning level, and write intents in one payload.',\n priority: 87,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n run_id: { type: 'string', description: 'The run id whose phase audit you want to inspect' },\n },\n required: ['run_id'],\n },\n },\n {\n name: TOOL_RESUME_RUN,\n description: 'Resume a paused or interrupted agent run. The run must be in a resumable state (resumable=1 AND status=\"failed\" per the route) — check status via myco_runs first. The resume starts a new background phase and returns immediately with {ok, message, runId}. NOT idempotent: each successful call starts a fresh phase.',\n annotations: {\n // Starts a new background phase; mark as mutating + non-idempotent so\n // clients confirm before repeating. Not \"destructive\" (no data is\n // removed) but also not \"read-only\".\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n cortex: {\n guidance: 'Use to resume a paused or interrupted agent run after verifying (via myco_runs) that its resumable flag is set and its status is \"failed\".',\n priority: 89,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n id: { type: 'string', description: 'The run id to resume' },\n mode: { type: 'string', enum: ['manual', 'scheduled'], description: 'Resume mode (default: \"manual\"). Scheduled is reserved for the daemon scheduler.' },\n },\n required: ['id'],\n },\n },\n {\n name: TOOL_DIGEST_REVISIONS,\n description: 'List historical digest revisions for the given (agent_id, tier). Revisions are append-only, so this surface shows how the project\\'s digest has evolved over time. tier is required; agent_id defaults to the primary agent on the daemon side. Restore (rolling a past revision back into the live digest) is intentionally UI-only and is NOT exposed via MCP.',\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n cortex: {\n guidance: 'Use to see how the project digest has evolved for a given tier — restore is UI-only.',\n priority: 92,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n agent_id: { type: 'string', description: 'Optional — defaults to the primary agent on the daemon side' },\n tier: { type: 'number', description: 'Required — the digest tier (for example 1500, 5000, 10000)' },\n limit: { type: 'number', description: 'Max results (default: 50)' },\n },\n required: ['tier'],\n },\n },\n];\n\nexport const COLLECTIVE_TOOL_DEFINITIONS: ToolDefinition[] = [\n {\n name: TOOL_COLLECTIVE_SEARCH,\n description: 'Search across connected projects in the active Myco Collective. Results include project attribution.',\n cortex: {\n guidance: 'Use for cross-project knowledge across the connected collective.',\n priority: 80,\n requiresCollective: true,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n query: { type: 'string', description: 'Natural language search query across the connected Collective projects' },\n project: { type: 'string', description: 'Optional project id or project name filter' },\n limit: { type: 'number', description: `Max results (default: ${MCP_SEARCH_DEFAULT_LIMIT})` },\n },\n required: ['query'],\n },\n },\n {\n name: TOOL_COLLECTIVE_PROJECTS,\n description: 'List the projects connected to the active Myco Collective.',\n cortex: {\n guidance: 'Use to discover relevant collective projects before drilling deeper.',\n priority: 81,\n requiresCollective: true,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {},\n },\n },\n {\n name: TOOL_COLLECTIVE_PROJECT,\n description: 'Get metadata for a single project connected to the active Myco Collective.',\n cortex: {\n guidance: 'Use when you know the collective project and need its focused context.',\n priority: 82,\n requiresCollective: true,\n },\n inputSchema: {\n type: 'object' as const,\n properties: {\n project: { type: 'string', description: 'Project id or project name' },\n include_digest: { type: 'boolean', description: 'Request digest information when available' },\n },\n required: ['project'],\n },\n },\n] as const;\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/client.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { DAEMON_CLIENT_TIMEOUT_MS, DAEMON_HEALTH_CHECK_TIMEOUT_MS, DAEMON_HEALTH_RETRY_DELAYS, DAEMON_STALE_GRACE_PERIOD_MS } from '../constants.js';\nimport { getPluginVersion } from '../version.js';\n\ninterface DaemonInfo {\n pid: number;\n port: number;\n}\n\n/**\n * Resolve the CLI entry point for spawning daemon processes.\n * Uses process.argv[1] so the daemon restarts from the same binary\n * (myco-dev vs global myco) that launched the current process.\n */\nexport function resolveCliEntryPath(): { execPath: string; cliEntry: string } {\n return { execPath: process.execPath, cliEntry: process.argv[1] };\n}\n\ninterface HealthResponse {\n myco: boolean;\n version?: string;\n}\n\ninterface ClientResult {\n ok: boolean;\n data?: any;\n}\n\n/**\n * Attempt to parse a non-ok response body as JSON so callers can surface\n * the daemon's structured error envelope (e.g. `{error: {code, message}}`).\n * Returns `undefined` if the body is empty, not JSON, or otherwise fails to\n * parse — callers that ignore `data` on failure still work unchanged.\n */\nasync function parseErrorBody(res: Response): Promise<unknown> {\n try {\n return await res.json();\n } catch {\n return undefined;\n }\n}\n\nexport class DaemonClient {\n private vaultDir: string;\n\n constructor(vaultDir: string) {\n this.vaultDir = vaultDir;\n }\n\n async post(endpoint: string, body: unknown): Promise<ClientResult> {\n try {\n const info = this.readDaemonJson();\n if (!info) return { ok: false };\n\n const res = await fetch(`http://127.0.0.1:${info.port}${endpoint}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n });\n\n if (!res.ok) return { ok: false, data: await parseErrorBody(res) };\n const data = await res.json();\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n }\n\n async put(endpoint: string, body: unknown): Promise<ClientResult> {\n try {\n const info = this.readDaemonJson();\n if (!info) return { ok: false };\n\n const res = await fetch(`http://127.0.0.1:${info.port}${endpoint}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n });\n\n if (!res.ok) return { ok: false, data: await parseErrorBody(res) };\n const data = await res.json();\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n }\n\n async get(endpoint: string): Promise<ClientResult> {\n try {\n const info = this.readDaemonJson();\n if (!info) return { ok: false };\n\n const res = await fetch(`http://127.0.0.1:${info.port}${endpoint}`, {\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n });\n\n if (!res.ok) return { ok: false, data: await parseErrorBody(res) };\n const data = await res.json();\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n }\n\n async delete(endpoint: string, body?: unknown): Promise<ClientResult> {\n try {\n const info = this.readDaemonJson();\n if (!info) return { ok: false };\n\n const init: RequestInit = {\n method: 'DELETE',\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n };\n if (body !== undefined) {\n init.headers = { 'Content-Type': 'application/json' };\n init.body = JSON.stringify(body);\n }\n\n const res = await fetch(`http://127.0.0.1:${info.port}${endpoint}`, init);\n\n if (!res.ok) return { ok: false, data: await parseErrorBody(res) };\n const data = await res.json();\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n }\n\n async isHealthy(cachedInfo?: DaemonInfo | null): Promise<boolean> {\n try {\n const info = cachedInfo ?? this.readDaemonJson();\n if (!info) return false;\n\n const res = await fetch(`http://127.0.0.1:${info.port}/health`, {\n signal: AbortSignal.timeout(DAEMON_HEALTH_CHECK_TIMEOUT_MS),\n });\n if (!res.ok) return false;\n const data = await res.json() as HealthResponse;\n return data.myco === true;\n } catch {\n return false;\n }\n }\n\n /**\n * Check if the daemon is running a stale version.\n * Returns true if the daemon's version doesn't match the current plugin version.\n * Skips the check if daemon.json was written recently (grace period) to prevent\n * rapid restart loops from concurrent hooks or session reloads.\n */\n private async isStale(info: DaemonInfo): Promise<boolean> {\n try {\n const jsonPath = path.join(this.vaultDir, 'daemon.json');\n const stat = fs.statSync(jsonPath);\n if (Date.now() - stat.mtimeMs < DAEMON_STALE_GRACE_PERIOD_MS) {\n return false;\n }\n\n const res = await fetch(`http://127.0.0.1:${info.port}/health`, {\n signal: AbortSignal.timeout(DAEMON_HEALTH_CHECK_TIMEOUT_MS),\n });\n if (!res.ok) return false;\n const data = await res.json() as HealthResponse;\n if (!data.myco) return false;\n\n // No version in response = old daemon that predates this check\n if (!data.version) return true;\n\n return data.version !== getPluginVersion();\n } catch {\n return false;\n }\n }\n\n /**\n * Kill the running daemon process.\n */\n private killDaemon(info: DaemonInfo | null): void {\n try {\n if (!info) return;\n process.kill(info.pid, 'SIGTERM');\n } catch { /* already dead */ }\n try {\n fs.unlinkSync(path.join(this.vaultDir, 'daemon.json'));\n } catch { /* already gone */ }\n }\n\n /**\n * Ensure the daemon is running. Spawns it if unhealthy.\n * When checkStale is true (default), also restarts a healthy daemon if its\n * version doesn't match the current plugin version. Use checkStale: false\n * for hooks that just need the daemon alive (e.g., stop) without triggering\n * version-driven restarts.\n */\n async ensureRunning(opts?: { checkStale?: boolean }): Promise<boolean> {\n const checkStale = opts?.checkStale ?? true;\n const info = this.readDaemonJson();\n\n if (checkStale && info && await this.isStale(info)) {\n this.killDaemon(info);\n // Brief pause for port release\n await new Promise((r) => setTimeout(r, 200));\n } else if (await this.isHealthy(info)) {\n return true;\n }\n\n this.spawnDaemon();\n\n for (const delay of DAEMON_HEALTH_RETRY_DELAYS) {\n await new Promise((r) => setTimeout(r, delay));\n if (await this.isHealthy()) return true;\n }\n return false;\n }\n\n spawnDaemon(): void {\n const { execPath, cliEntry } = resolveCliEntryPath();\n const child = spawn(execPath, [cliEntry, 'daemon', '--vault', this.vaultDir], {\n detached: true,\n stdio: 'ignore',\n });\n child.unref();\n }\n\n private readDaemonJson(): DaemonInfo | null {\n try {\n const jsonPath = path.join(this.vaultDir, 'daemon.json');\n const content = fs.readFileSync(jsonPath, 'utf-8');\n const info = JSON.parse(content);\n if (typeof info.port !== 'number') return null;\n return info as DaemonInfo;\n } catch {\n return null;\n }\n }\n}\n"],"mappings":"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","names":[]}
|