volute 0.30.1 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/{accept-E3PAH3QJ.js → accept-GAKQ3MEH.js} +4 -4
  2. package/dist/{activity-events-BKBPPUBP.js → activity-events-T5ZRCVAL.js} +2 -2
  3. package/dist/{ai-service-VAJT5UBS.js → ai-service-UWUPM4T6.js} +5 -3
  4. package/dist/api.d.ts +238 -111
  5. package/dist/{archive-WWDBWYN2.js → archive-YBNSJYZZ.js} +2 -2
  6. package/dist/auth-T5AW2USD.js +43 -0
  7. package/dist/{bridge-RO37CUFM.js → bridge-4AJ3EY26.js} +4 -4
  8. package/dist/{chat-TCUNPFGO.js → chat-7YLT7FI3.js} +8 -8
  9. package/dist/{chunk-EFVHR7KH.js → chunk-4OUOFS23.js} +24 -5
  10. package/dist/{chunk-G3GBKZGG.js → chunk-57OKQMP3.js} +54 -2
  11. package/dist/chunk-6QIUN46C.js +38 -0
  12. package/dist/{chunk-FSM45XD5.js → chunk-AAO77TZX.js} +1 -1
  13. package/dist/{chunk-DTC6EH5I.js → chunk-BC3P3QCK.js} +1 -1
  14. package/dist/{chunk-P7VFDSSG.js → chunk-BNC43CSY.js} +2 -2
  15. package/dist/{chunk-QVAQ5454.js → chunk-BWKIHH7B.js} +3080 -2099
  16. package/dist/{chunk-IKHDUZRH.js → chunk-DAXJKPHZ.js} +2 -2
  17. package/dist/{chunk-P27RV5WM.js → chunk-EKDWA7E4.js} +3 -1
  18. package/dist/{chunk-S5LR3XYJ.js → chunk-EMPFLFTG.js} +1 -1
  19. package/dist/{chunk-2C2VXEBB.js → chunk-FAHDKPEH.js} +18 -56
  20. package/dist/{chunk-W5OOPLNP.js → chunk-HDKY4TWU.js} +3 -3
  21. package/dist/{chunk-EFP3PE6C.js → chunk-HR5JKIDG.js} +2 -12
  22. package/dist/{chunk-JGFRDMR6.js → chunk-LX6T3GKQ.js} +1 -1
  23. package/dist/{chunk-2NDZC3S7.js → chunk-NOWVQ7AL.js} +447 -299
  24. package/dist/{chunk-ZWKTUQEL.js → chunk-NV3TYNWX.js} +1 -1
  25. package/dist/{chunk-NSBFETWP.js → chunk-PNQCXLSV.js} +7 -26
  26. package/dist/chunk-R5QJBZZG.js +175 -0
  27. package/dist/{chunk-MDPCSXZ4.js → chunk-S2TZLSDH.js} +4 -4
  28. package/dist/{chunk-FXHXHI2A.js → chunk-SNVPRRT7.js} +3 -6
  29. package/dist/{chunk-UPA6COHU.js → chunk-WRS3B556.js} +5 -5
  30. package/dist/{chunk-HHTXM4JT.js → chunk-X62AXPR7.js} +36 -4
  31. package/dist/cli.js +74 -23
  32. package/dist/{clock-G3ALCMLJ.js → clock-LJCG426D.js} +10 -8
  33. package/dist/{cloud-sync-JV4LJOK3.js → cloud-sync-O3LXIRN6.js} +13 -13
  34. package/dist/{conversations-7KVQV7EZ.js → conversations-RKKGP5IA.js} +7 -7
  35. package/dist/{create-VQSQHJQW.js → create-TL623TFC.js} +1 -1
  36. package/dist/{create-JTLS7GX3.js → create-WUTIIRI2.js} +4 -4
  37. package/dist/daemon-client-CVGM25DM.js +11 -0
  38. package/dist/{daemon-restart-4JGBHEJ4.js → daemon-restart-EZP7XH3V.js} +6 -7
  39. package/dist/daemon.js +1879 -1727
  40. package/dist/{db-HMFPIRO2.js → db-SW5PL6QA.js} +1 -1
  41. package/dist/{delete-JESHKE7F.js → delete-Z6HAG35F.js} +1 -1
  42. package/dist/down-TS4XQBA4.js +13 -0
  43. package/dist/{env-CLXXT7M2.js → env-NHESNNSP.js} +4 -4
  44. package/dist/{export-EGA5M5PB.js → export-EVMP7GWY.js} +3 -3
  45. package/dist/{extension-WZ4SUPJB.js → extension-LR7EW3JF.js} +5 -6
  46. package/dist/{extensions-ECO4RPFQ.js → extensions-NGEJI7JH.js} +7 -7
  47. package/dist/{files-4VEJDASH.js → files-3SM7V33S.js} +5 -5
  48. package/dist/{history-EJMMLXDO.js → history-PQD3LXEP.js} +4 -4
  49. package/dist/{import-YCGPMBSI.js → import-PR2OCGQJ.js} +3 -3
  50. package/dist/{join-2GBJKZEN.js → join-R4EN5CWQ.js} +1 -1
  51. package/dist/{list-Q6O7FGAN.js → list-B4XNUOFO.js} +4 -4
  52. package/dist/{login-RL6AU2SM.js → login-62JVY6A2.js} +4 -4
  53. package/dist/{login-RET5WESK.js → login-URWP6S2N.js} +2 -2
  54. package/dist/{logout-CGAGJN3L.js → logout-NXJQJDLI.js} +2 -2
  55. package/dist/{logout-JRPBEMMR.js → logout-ZK2N62T3.js} +2 -2
  56. package/dist/message-delivery-UJHCLVU4.js +30 -0
  57. package/dist/{mind-LUWRQUQ5.js → mind-E2ZV2WRX.js} +17 -17
  58. package/dist/{mind-activity-tracker-VYN2ZZ2M.js → mind-activity-tracker-ASNZBMLC.js} +3 -3
  59. package/dist/{mind-list-V5WW5DUA.js → mind-list-BEI7E5WY.js} +2 -2
  60. package/dist/mind-manager-IPA6DZXD.js +26 -0
  61. package/dist/{mind-sleep-R6PTNNW4.js → mind-sleep-CANABWJI.js} +4 -4
  62. package/dist/{mind-status-I4ISFJ6I.js → mind-status-6WKZVUOP.js} +2 -2
  63. package/dist/{mind-wake-67ZQEWAV.js → mind-wake-RZKLH2IN.js} +4 -4
  64. package/dist/{package-OYUD4ZJ4.js → package-NU4CA7OU.js} +3 -3
  65. package/dist/{pages-watcher-Z3PKNROC.js → pages-watcher-72OVPRMH.js} +4 -3
  66. package/dist/read-THL362EI.js +74 -0
  67. package/dist/{register-NZDSTLP3.js → register-QAQELAS6.js} +4 -4
  68. package/dist/{registry-ODSALQQL.js → registry-ASXCQCNH.js} +1 -1
  69. package/dist/{reject-2HZOJEIJ.js → reject-AYPBNPNL.js} +4 -4
  70. package/dist/{restart-QHS3NT64.js → restart-6SKPV3T2.js} +4 -4
  71. package/dist/{sandbox-O5FUSF43.js → sandbox-6ZEWQDVU.js} +3 -3
  72. package/dist/{seed-WUQMPLDM.js → seed-OWX2AW75.js} +36 -12
  73. package/dist/{send-OAN3RYYY.js → send-ZO4BTWXK.js} +5 -5
  74. package/dist/{setup-QMDK5RZX.js → setup-7CFITEQN.js} +2 -4
  75. package/dist/{setup-XJH3E7YM.js → setup-ZXBXG7E4.js} +6 -8
  76. package/dist/{skill-FZIN4W4Q.js → skill-YFXP67A2.js} +4 -4
  77. package/dist/skills/dreaming/references/INSTALL.md +2 -3
  78. package/dist/skills/dreaming/scripts/dream.ts +3 -25
  79. package/dist/skills/volute-mind/SKILL.md +1 -1
  80. package/dist/sleep-manager-TPS6OGCA.js +30 -0
  81. package/dist/{split-EXYGGGQN.js → split-MI62KJUU.js} +1 -1
  82. package/dist/{sprout-AXQ6H5DB.js → sprout-FDVI2CGN.js} +5 -6
  83. package/dist/{start-MTOVL6SY.js → start-D64BRKPH.js} +4 -4
  84. package/dist/{status-ZRO37MWR.js → status-ZZWBYFGE.js} +4 -5
  85. package/dist/{stop-OK5WEPVC.js → stop-OP2CTXCO.js} +4 -4
  86. package/dist/system-chat-B43GIXQU.js +30 -0
  87. package/dist/{systems-W3BBMSOZ.js → systems-EQPPT4B7.js} +5 -5
  88. package/dist/{tailscale-BM72RXCJ.js → tailscale-6DJKUMNF.js} +1 -1
  89. package/dist/up-TDXEP3VA.js +16 -0
  90. package/dist/{update-PLPHMMZ2.js → update-KUJXATRS.js} +4 -5
  91. package/dist/{update-check-CVCN7MF6.js → update-check-5WVSU37T.js} +2 -2
  92. package/dist/{upgrade-I6NPCYUU.js → upgrade-KBHCWX6T.js} +1 -1
  93. package/dist/{version-notify-2NTWVEHL.js → version-notify-75ELVKPV.js} +17 -21
  94. package/dist/web-assets/assets/index-BM1cTzBg.js +72 -0
  95. package/dist/web-assets/assets/index-BfJkKTPF.css +1 -0
  96. package/dist/web-assets/ext-theme.css +1 -0
  97. package/dist/web-assets/index.html +2 -2
  98. package/drizzle/0000_baseline.sql +152 -0
  99. package/drizzle/0001_add_conversation_private.sql +1 -0
  100. package/drizzle/0002_turns.sql +21 -0
  101. package/drizzle/0003_turn_feed_links.sql +11 -0
  102. package/drizzle/meta/0000_snapshot.json +3 -223
  103. package/drizzle/meta/0001_snapshot.json +3 -294
  104. package/drizzle/meta/0002_snapshot.json +3 -335
  105. package/drizzle/meta/0003_snapshot.json +3 -413
  106. package/drizzle/meta/_journal.json +8 -106
  107. package/package.json +3 -3
  108. package/packages/extensions/notes/dist/ui/assets/{index-DgawVO5g.css → index-B8GdTnXs.css} +1 -1
  109. package/packages/extensions/notes/dist/ui/assets/index-CDpGTCWb.js +2 -0
  110. package/packages/extensions/notes/dist/ui/index.html +2 -2
  111. package/packages/extensions/notes/skills/notes/SKILL.md +8 -8
  112. package/packages/extensions/pages/skills/pages/SKILL.md +7 -4
  113. package/packages/extensions/pages/skills/pages/scripts/pages.mjs +58 -0
  114. package/templates/_base/.init/.config/bin/volute +27 -0
  115. package/templates/_base/src/lib/auto-commit.ts +82 -43
  116. package/templates/_base/src/lib/daemon-client.ts +19 -23
  117. package/templates/_base/src/lib/router.ts +17 -1
  118. package/templates/_base/src/lib/startup.ts +6 -8
  119. package/templates/_base/src/lib/volute-server.ts +2 -5
  120. package/templates/claude/src/agent.ts +2 -1
  121. package/templates/claude/src/lib/hooks/auto-commit.ts +7 -3
  122. package/templates/claude/src/server.ts +0 -9
  123. package/templates/pi/package.json.tmpl +1 -1
  124. package/templates/pi/src/agent.ts +1 -1
  125. package/templates/pi/src/lib/event-handler.ts +5 -3
  126. package/dist/chunk-7D47T4RB.js +0 -84
  127. package/dist/chunk-CVH6Y2YG.js +0 -59
  128. package/dist/chunk-LIRWLNAK.js +0 -729
  129. package/dist/daemon-client-BCTFGVCZ.js +0 -9
  130. package/dist/down-NGBMGORS.js +0 -14
  131. package/dist/message-delivery-6YMVNOEC.js +0 -28
  132. package/dist/migrate-registry-to-db-FK35IPEH.js +0 -110
  133. package/dist/mind-manager-YFCOIAAX.js +0 -18
  134. package/dist/read-WQMPTSN2.js +0 -46
  135. package/dist/sleep-manager-O7YQFCV5.js +0 -30
  136. package/dist/up-BXUAIDXB.js +0 -17
  137. package/dist/web-assets/assets/index--kREqKl9.js +0 -72
  138. package/dist/web-assets/assets/index-BXYTG0nJ.css +0 -1
  139. package/drizzle/0000_flaky_mariko_yashida.sql +0 -34
  140. package/drizzle/0001_careless_warpath.sql +0 -12
  141. package/drizzle/0002_wealthy_the_call.sql +0 -6
  142. package/drizzle/0003_clean_ego.sql +0 -12
  143. package/drizzle/0004_magical_silverclaw.sql +0 -1
  144. package/drizzle/0005_rename_agents_to_minds.sql +0 -11
  145. package/drizzle/0006_mind_history.sql +0 -20
  146. package/drizzle/0007_system_prompts.sql +0 -5
  147. package/drizzle/0008_volute_channels.sql +0 -24
  148. package/drizzle/0009_shared_skills.sql +0 -9
  149. package/drizzle/0010_delivery_queue.sql +0 -12
  150. package/drizzle/0011_rename_human_to_brain.sql +0 -1
  151. package/drizzle/0012_activity.sql +0 -11
  152. package/drizzle/0013_user_profiles.sql +0 -3
  153. package/drizzle/0014_conversation_reads.sql +0 -7
  154. package/drizzle/0015_notes.sql +0 -23
  155. package/drizzle/0016_note_reactions_and_replies.sql +0 -15
  156. package/drizzle/0017_minds.sql +0 -16
  157. package/drizzle/meta/0004_snapshot.json +0 -410
  158. package/drizzle/meta/0005_snapshot.json +0 -410
  159. package/drizzle/meta/0006_snapshot.json +0 -7
  160. package/drizzle/meta/0007_snapshot.json +0 -7
  161. package/drizzle/meta/0008_snapshot.json +0 -7
  162. package/drizzle/meta/0009_snapshot.json +0 -7
  163. package/drizzle/meta/0010_snapshot.json +0 -7
  164. package/drizzle/meta/0011_snapshot.json +0 -7
  165. package/drizzle/meta/0012_snapshot.json +0 -7
  166. package/drizzle/meta/0013_snapshot.json +0 -7
  167. package/packages/extensions/notes/dist/ui/assets/index-qUWoeC4c.js +0 -2
  168. package/packages/extensions/notes/skills/notes/scripts/notes.mjs +0 -185
  169. package/templates/_base/home/public/.gitkeep +0 -0
@@ -0,0 +1,2 @@
1
+ (function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const a of i)if(a.type==="childList")for(const l of a.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&r(l)}).observe(document,{childList:!0,subtree:!0});function n(i){const a={};return i.integrity&&(a.integrity=i.integrity),i.referrerPolicy&&(a.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?a.credentials="include":i.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function r(i){if(i.ep)return;i.ep=!0;const a=n(i);fetch(i.href,a)}})();const wr=!1;var mn=Array.isArray,yr=Array.prototype.indexOf,qe=Array.prototype.includes,yt=Array.from,br=Object.defineProperty,rt=Object.getOwnPropertyDescriptor,Er=Object.getOwnPropertyDescriptors,xr=Object.prototype,kr=Array.prototype,gn=Object.getPrototypeOf,tn=Object.isExtensible;const Sr=()=>{};function Tr(e){for(var t=0;t<e.length;t++)e[t]()}function wn(){var e,t,n=new Promise((r,i)=>{e=r,t=i});return{promise:n,resolve:e,reject:t}}const q=2,st=4,bt=8,yn=1<<24,Te=16,le=32,Le=64,Ft=128,te=512,B=1024,W=2048,oe=4096,X=8192,se=16384,je=32768,nn=1<<25,He=65536,rn=1<<17,Cr=1<<18,Ke=1<<19,Ar=1<<20,ce=1<<25,Pe=65536,Ot=1<<21,qt=1<<22,be=1<<23,Nt=Symbol("$state"),Nr=Symbol(""),_e=new class extends Error{name="StaleReactionError";message="The reaction that called `getAbortSignal()` was re-run or destroyed"};function Mr(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function Rr(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function Dr(e,t,n){throw new Error("https://svelte.dev/e/each_key_duplicate")}function Fr(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function Or(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function Ir(e){throw new Error("https://svelte.dev/e/effect_orphan")}function Lr(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function Pr(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function zr(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function Ur(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function jr(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}const Br=1,qr=2,bn=4,Hr=8,Vr=16,Wr=1,Yr=2,H=Symbol(),En="http://www.w3.org/1999/xhtml";function Kr(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function xn(e){return e===this.v}function Gr(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function kn(e){return!Gr(e,this.v)}let Zr=!1,Q=null;function Ve(e){Q=e}function Ge(e,t=!1,n){Q={p:Q,i:!1,c:null,e:null,s:e,x:null,r:N,l:null}}function Ze(e){var t=Q,n=t.e;if(n!==null){t.e=null;for(var r of n)Yn(r)}return t.i=!0,Q=t.p,{}}function Sn(){return!0}let Re=[];function Tn(){var e=Re;Re=[],Tr(e)}function Ee(e){if(Re.length===0&&!it){var t=Re;queueMicrotask(()=>{t===Re&&Tn()})}Re.push(e)}function Jr(){for(;Re.length>0;)Tn()}function Cn(e){var t=N;if(t===null)return S.f|=be,e;if((t.f&je)===0&&(t.f&st)===0)throw e;ye(e,t)}function ye(e,t){for(;t!==null;){if((t.f&Ft)!==0){if((t.f&je)===0)throw e;try{t.b.error(e);return}catch(n){e=n}}t=t.parent}throw e}const Xr=-7169;function U(e,t){e.f=e.f&Xr|t}function Ht(e){(e.f&te)!==0||e.deps===null?U(e,B):U(e,oe)}function An(e){if(e!==null)for(const t of e)(t.f&q)===0||(t.f&Pe)===0||(t.f^=Pe,An(t.deps))}function Nn(e,t,n){(e.f&W)!==0?t.add(e):(e.f&oe)!==0&&n.add(e),An(e.deps),U(e,B)}const $e=new Set;let R=null,ve=null,It=null,it=!1,Mt=!1,Be=null,_t=null;var an=0;let Qr=1;class Se{id=Qr++;current=new Map;previous=new Map;#e=new Set;#o=new Set;#t=0;#s=0;#r=null;#n=[];#i=new Set;#a=new Set;#l=new Map;is_fork=!1;#u=!1;#f(){return this.is_fork||this.#s>0}skip_effect(t){this.#l.has(t)||this.#l.set(t,{d:[],m:[]})}unskip_effect(t){var n=this.#l.get(t);if(n){this.#l.delete(t);for(var r of n.d)U(r,W),this.schedule(r);for(r of n.m)U(r,oe),this.schedule(r)}}#v(){an++>1e3&&ei();const t=this.#n;this.#n=[],this.apply();var n=Be=[],r=[],i=_t=[];for(const o of t)try{this.#d(o,n,r)}catch(s){throw Fn(o),s}if(R=null,i.length>0){var a=Se.ensure();for(const o of i)a.schedule(o)}if(Be=null,_t=null,this.#f()){this.#h(r),this.#h(n);for(const[o,s]of this.#l)Dn(o,s)}else{this.#t===0&&$e.delete(this),this.#i.clear(),this.#a.clear();for(const o of this.#e)o(this);this.#e.clear(),sn(r),sn(n),this.#r?.resolve()}var l=R;if(this.#n.length>0){const o=l??=this;o.#n.push(...this.#n.filter(s=>!o.#n.includes(s)))}l!==null&&($e.add(l),l.#v()),$e.has(this)||this.#c()}#d(t,n,r){t.f^=B;for(var i=t.first;i!==null;){var a=i.f,l=(a&(le|Le))!==0,o=l&&(a&B)!==0,s=o||(a&X)!==0||this.#l.has(i);if(!s&&i.fn!==null){l?i.f^=B:(a&st)!==0?n.push(i):ft(i)&&((a&Te)!==0&&this.#a.add(i),Ye(i));var u=i.first;if(u!==null){i=u;continue}}for(;i!==null;){var c=i.next;if(c!==null){i=c;break}i=i.parent}}}#h(t){for(var n=0;n<t.length;n+=1)Nn(t[n],this.#i,this.#a)}capture(t,n){n!==H&&!this.previous.has(t)&&this.previous.set(t,n),(t.f&be)===0&&(this.current.set(t,t.v),ve?.set(t,t.v))}activate(){R=this}deactivate(){R=null,ve=null}flush(){try{if(Mt=!0,R=this,!this.#f()){for(const t of this.#i)this.#a.delete(t),U(t,W),this.schedule(t);for(const t of this.#a)U(t,oe),this.schedule(t)}this.#v()}finally{an=0,It=null,Be=null,_t=null,Mt=!1,R=null,ve=null,xe.clear()}}discard(){for(const t of this.#o)t(this);this.#o.clear()}#c(){for(const s of $e){var t=s.id<this.id,n=[];for(const[u,c]of this.current){if(s.current.has(u))if(t&&c!==s.current.get(u))s.current.set(u,c);else continue;n.push(u)}if(n.length!==0){var r=[...s.current.keys()].filter(u=>!this.current.has(u));if(r.length>0){s.activate();var i=new Set,a=new Map;for(var l of n)Mn(l,r,i,a);if(s.#n.length>0){s.apply();for(var o of s.#n)s.#d(o,[],[])}s.deactivate()}}}}increment(t){this.#t+=1,t&&(this.#s+=1)}decrement(t,n){this.#t-=1,t&&(this.#s-=1),!(this.#u||n)&&(this.#u=!0,Ee(()=>{this.#u=!1,this.flush()}))}oncommit(t){this.#e.add(t)}ondiscard(t){this.#o.add(t)}settled(){return(this.#r??=wn()).promise}static ensure(){if(R===null){const t=R=new Se;Mt||($e.add(R),it||Ee(()=>{R===t&&t.flush()}))}return R}apply(){{ve=null;return}}schedule(t){if(It=t,t.b?.is_pending&&(t.f&(st|bt|yn))!==0&&(t.f&je)===0){t.b.defer_effect(t);return}for(var n=t;n.parent!==null;){n=n.parent;var r=n.f;if(Be!==null&&n===N&&(S===null||(S.f&q)===0))return;if((r&(Le|le))!==0){if((r&B)===0)return;n.f^=B}}this.#n.push(n)}}function $r(e){var t=it;it=!0;try{for(var n;;){if(Jr(),R===null)return n;R.flush()}}finally{it=t}}function ei(){try{Lr()}catch(e){ye(e,It)}}let he=null;function sn(e){var t=e.length;if(t!==0){for(var n=0;n<t;){var r=e[n++];if((r.f&(se|X))===0&&ft(r)&&(he=new Set,Ye(r),r.deps===null&&r.first===null&&r.nodes===null&&r.teardown===null&&r.ac===null&&Zn(r),he?.size>0)){xe.clear();for(const i of he){if((i.f&(se|X))!==0)continue;const a=[i];let l=i.parent;for(;l!==null;)he.has(l)&&(he.delete(l),a.push(l)),l=l.parent;for(let o=a.length-1;o>=0;o--){const s=a[o];(s.f&(se|X))===0&&Ye(s)}}he.clear()}}he=null}}function Mn(e,t,n,r){if(!n.has(e)&&(n.add(e),e.reactions!==null))for(const i of e.reactions){const a=i.f;(a&q)!==0?Mn(i,t,n,r):(a&(qt|Te))!==0&&(a&W)===0&&Rn(i,t,r)&&(U(i,W),Vt(i))}}function Rn(e,t,n){const r=n.get(e);if(r!==void 0)return r;if(e.deps!==null)for(const i of e.deps){if(qe.call(t,i))return!0;if((i.f&q)!==0&&Rn(i,t,n))return n.set(i,!0),!0}return n.set(e,!1),!1}function Vt(e){R.schedule(e)}function Dn(e,t){if(!((e.f&le)!==0&&(e.f&B)!==0)){(e.f&W)!==0?t.d.push(e):(e.f&oe)!==0&&t.m.push(e),U(e,B);for(var n=e.first;n!==null;)Dn(n,t),n=n.next}}function Fn(e){U(e,B);for(var t=e.first;t!==null;)Fn(t),t=t.next}function ti(e){let t=0,n=ze(0),r;return()=>{Kt()&&(d(n),Kn(()=>(t===0&&(r=Qt(()=>e(()=>at(n)))),t+=1,()=>{Ee(()=>{t-=1,t===0&&(r?.(),r=void 0,at(n))})})))}}var ni=He|Ke;function ri(e,t,n,r){new ii(e,t,n,r)}class ii{parent;is_pending=!1;transform_error;#e;#o=null;#t;#s;#r;#n=null;#i=null;#a=null;#l=null;#u=0;#f=0;#v=!1;#d=new Set;#h=new Set;#c=null;#w=ti(()=>(this.#c=ze(this.#u),()=>{this.#c=null}));constructor(t,n,r,i){this.#e=t,this.#t=n,this.#s=a=>{var l=N;l.b=this,l.f|=Ft,r(a)},this.parent=N.b,this.transform_error=i??this.parent?.transform_error??(a=>a),this.#r=Gt(()=>{this.#m()},ni)}#y(){try{this.#n=ee(()=>this.#s(this.#e))}catch(t){this.error(t)}}#b(t){const n=this.#t.failed;n&&(this.#a=ee(()=>{n(this.#e,()=>t,()=>()=>{})}))}#E(){const t=this.#t.pending;t&&(this.is_pending=!0,this.#i=ee(()=>t(this.#e)),Ee(()=>{var n=this.#l=document.createDocumentFragment(),r=ke();n.append(r),this.#n=this.#p(()=>ee(()=>this.#s(r))),this.#f===0&&(this.#e.before(n),this.#l=null,Oe(this.#i,()=>{this.#i=null}),this.#_(R))}))}#m(){try{if(this.is_pending=this.has_pending_snippet(),this.#f=0,this.#u=0,this.#n=ee(()=>{this.#s(this.#e)}),this.#f>0){var t=this.#l=document.createDocumentFragment();Xt(this.#n,t);const n=this.#t.pending;this.#i=ee(()=>n(this.#e))}else this.#_(R)}catch(n){this.error(n)}}#_(t){this.is_pending=!1;for(const n of this.#d)U(n,W),t.schedule(n);for(const n of this.#h)U(n,oe),t.schedule(n);this.#d.clear(),this.#h.clear()}defer_effect(t){Nn(t,this.#d,this.#h)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#t.pending}#p(t){var n=N,r=S,i=Q;de(this.#r),re(this.#r),Ve(this.#r.ctx);try{return Se.ensure(),t()}catch(a){return Cn(a),null}finally{de(n),re(r),Ve(i)}}#g(t,n){if(!this.has_pending_snippet()){this.parent&&this.parent.#g(t,n);return}this.#f+=t,this.#f===0&&(this.#_(n),this.#i&&Oe(this.#i,()=>{this.#i=null}),this.#l&&(this.#e.before(this.#l),this.#l=null))}update_pending_count(t,n){this.#g(t,n),this.#u+=t,!(!this.#c||this.#v)&&(this.#v=!0,Ee(()=>{this.#v=!1,this.#c&&We(this.#c,this.#u)}))}get_effect_pending(){return this.#w(),d(this.#c)}error(t){var n=this.#t.onerror;let r=this.#t.failed;if(!n&&!r)throw t;this.#n&&(Z(this.#n),this.#n=null),this.#i&&(Z(this.#i),this.#i=null),this.#a&&(Z(this.#a),this.#a=null);var i=!1,a=!1;const l=()=>{if(i){Kr();return}i=!0,a&&jr(),this.#a!==null&&Oe(this.#a,()=>{this.#a=null}),this.#p(()=>{this.#m()})},o=s=>{try{a=!0,n?.(s,l),a=!1}catch(u){ye(u,this.#r&&this.#r.parent)}r&&(this.#a=this.#p(()=>{try{return ee(()=>{var u=N;u.b=this,u.f|=Ft,r(this.#e,()=>s,()=>l)})}catch(u){return ye(u,this.#r.parent),null}}))};Ee(()=>{var s;try{s=this.transform_error(t)}catch(u){ye(u,this.#r&&this.#r.parent);return}s!==null&&typeof s=="object"&&typeof s.then=="function"?s.then(o,u=>ye(u,this.#r&&this.#r.parent)):o(s)})}}function ai(e,t,n,r){const i=Wt;var a=e.filter(v=>!v.settled);if(n.length===0&&a.length===0){r(t.map(i));return}var l=N,o=si(),s=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(v=>v.promise)):null;function u(v){o();try{r(v)}catch(_){(l.f&se)===0&&ye(_,l)}mt()}if(n.length===0){s.then(()=>u(t.map(i)));return}var c=On();function m(){Promise.all(n.map(v=>li(v))).then(v=>u([...t.map(i),...v])).catch(v=>ye(v,l)).finally(()=>c())}s?s.then(()=>{o(),m(),mt()}):m()}function si(){var e=N,t=S,n=Q,r=R;return function(a=!0){de(e),re(t),Ve(n),a&&(e.f&se)===0&&(r?.activate(),r?.apply())}}function mt(e=!0){de(null),re(null),Ve(null),e&&R?.deactivate()}function On(){var e=N.b,t=R,n=e.is_rendered();return e.update_pending_count(1,t),t.increment(n),(r=!1)=>{e.update_pending_count(-1,t),t.decrement(n,r)}}function Wt(e){var t=q|W,n=S!==null&&(S.f&q)!==0?S:null;return N!==null&&(N.f|=Ke),{ctx:Q,deps:null,effects:null,equals:xn,f:t,fn:e,reactions:null,rv:0,v:H,wv:0,parent:n??N,ac:null}}function li(e,t,n){let r=N;r===null&&Rr();var i=void 0,a=ze(H),l=!S,o=new Map;return Ei(()=>{var s=N,u=wn();i=u.promise;try{Promise.resolve(e()).then(u.resolve,u.reject).finally(mt)}catch(_){u.reject(_),mt()}var c=R;if(l){if((s.f&je)!==0)var m=On();if(r.b.is_rendered())o.get(c)?.reject(_e),o.delete(c);else{for(const _ of o.values())_.reject(_e);o.clear()}o.set(c,u)}const v=(_,p=void 0)=>{if(m){var x=p===_e;m(x)}if(!(p===_e||(s.f&se)!==0)){if(c.activate(),p)a.f|=be,We(a,p);else{(a.f&be)!==0&&(a.f^=be),We(a,_);for(const[h,b]of o){if(o.delete(h),h===c)break;b.reject(_e)}}c.deactivate()}};u.promise.then(v,_=>v(null,_||"unknown"))}),Vn(()=>{for(const s of o.values())s.reject(_e)}),new Promise(s=>{function u(c){function m(){c===i?s(a):u(i)}c.then(m,m)}u(i)})}function In(e){const t=Wt(e);return Qn(t),t}function oi(e){const t=Wt(e);return t.equals=kn,t}function ui(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n<t.length;n+=1)Z(t[n])}}function fi(e){for(var t=e.parent;t!==null;){if((t.f&q)===0)return(t.f&se)===0?t:null;t=t.parent}return null}function Yt(e){var t,n=N;de(fi(e));try{e.f&=~Pe,ui(e),t=nr(e)}finally{de(n)}return t}function Ln(e){var t=Yt(e);if(!e.equals(t)&&(e.wv=er(),(!R?.is_fork||e.deps===null)&&(e.v=t,e.deps===null))){U(e,B);return}Ue||(ve!==null?(Kt()||R?.is_fork)&&ve.set(e,t):Ht(e))}function ci(e){if(e.effects!==null)for(const t of e.effects)(t.teardown||t.ac)&&(t.teardown?.(),t.ac?.abort(_e),t.teardown=Sr,t.ac=null,lt(t,0),Zt(t))}function Pn(e){if(e.effects!==null)for(const t of e.effects)t.teardown&&Ye(t)}let Lt=new Set;const xe=new Map;let zn=!1;function ze(e,t){var n={f:0,v:e,reactions:null,equals:xn,rv:0,wv:0};return n}function I(e,t){const n=ze(e);return Qn(n),n}function vi(e,t=!1,n=!0){const r=ze(e);return t||(r.equals=kn),r}function k(e,t,n=!1){S!==null&&(!ae||(S.f&rn)!==0)&&Sn()&&(S.f&(q|Te|qt|rn))!==0&&(ne===null||!qe.call(ne,e))&&Ur();let r=n?De(t):t;return We(e,r,_t)}function We(e,t,n=null){if(!e.equals(t)){var r=e.v;Ue?xe.set(e,t):xe.set(e,r),e.v=t;var i=Se.ensure();if(i.capture(e,r),(e.f&q)!==0){const a=e;(e.f&W)!==0&&Yt(a),Ht(a)}e.wv=er(),Un(e,W,n),N!==null&&(N.f&B)!==0&&(N.f&(le|Le))===0&&($===null?Si([e]):$.push(e)),!i.is_fork&&Lt.size>0&&!zn&&di()}return t}function di(){zn=!1;for(const e of Lt)(e.f&B)!==0&&U(e,oe),ft(e)&&Ye(e);Lt.clear()}function at(e){k(e,e.v+1)}function Un(e,t,n){var r=e.reactions;if(r!==null)for(var i=r.length,a=0;a<i;a++){var l=r[a],o=l.f,s=(o&W)===0;if(s&&U(l,t),(o&q)!==0){var u=l;ve?.delete(u),(o&Pe)===0&&(o&te&&(l.f|=Pe),Un(u,oe,n))}else if(s){var c=l;(o&Te)!==0&&he!==null&&he.add(c),n!==null?n.push(c):Vt(c)}}}function De(e){if(typeof e!="object"||e===null||Nt in e)return e;const t=gn(e);if(t!==xr&&t!==kr)return e;var n=new Map,r=mn(e),i=I(0),a=Ie,l=o=>{if(Ie===a)return o();var s=S,u=Ie;re(null),cn(a);var c=o();return re(s),cn(u),c};return r&&n.set("length",I(e.length)),new Proxy(e,{defineProperty(o,s,u){(!("value"in u)||u.configurable===!1||u.enumerable===!1||u.writable===!1)&&Pr();var c=n.get(s);return c===void 0?l(()=>{var m=I(u.value);return n.set(s,m),m}):k(c,u.value,!0),!0},deleteProperty(o,s){var u=n.get(s);if(u===void 0){if(s in o){const c=l(()=>I(H));n.set(s,c),at(i)}}else k(u,H),at(i);return!0},get(o,s,u){if(s===Nt)return e;var c=n.get(s),m=s in o;if(c===void 0&&(!m||rt(o,s)?.writable)&&(c=l(()=>{var _=De(m?o[s]:H),p=I(_);return p}),n.set(s,c)),c!==void 0){var v=d(c);return v===H?void 0:v}return Reflect.get(o,s,u)},getOwnPropertyDescriptor(o,s){var u=Reflect.getOwnPropertyDescriptor(o,s);if(u&&"value"in u){var c=n.get(s);c&&(u.value=d(c))}else if(u===void 0){var m=n.get(s),v=m?.v;if(m!==void 0&&v!==H)return{enumerable:!0,configurable:!0,value:v,writable:!0}}return u},has(o,s){if(s===Nt)return!0;var u=n.get(s),c=u!==void 0&&u.v!==H||Reflect.has(o,s);if(u!==void 0||N!==null&&(!c||rt(o,s)?.writable)){u===void 0&&(u=l(()=>{var v=c?De(o[s]):H,_=I(v);return _}),n.set(s,u));var m=d(u);if(m===H)return!1}return c},set(o,s,u,c){var m=n.get(s),v=s in o;if(r&&s==="length")for(var _=u;_<m.v;_+=1){var p=n.get(_+"");p!==void 0?k(p,H):_ in o&&(p=l(()=>I(H)),n.set(_+"",p))}if(m===void 0)(!v||rt(o,s)?.writable)&&(m=l(()=>I(void 0)),k(m,De(u)),n.set(s,m));else{v=m.v!==H;var x=l(()=>De(u));k(m,x)}var h=Reflect.getOwnPropertyDescriptor(o,s);if(h?.set&&h.set.call(c,u),!v){if(r&&typeof s=="string"){var b=n.get("length"),O=Number(s);Number.isInteger(O)&&O>=b.v&&k(b,O+1)}at(i)}return!0},ownKeys(o){d(i);var s=Reflect.ownKeys(o).filter(m=>{var v=n.get(m);return v===void 0||v.v!==H});for(var[u,c]of n)c.v!==H&&!(u in o)&&s.push(u);return s},setPrototypeOf(){zr()}})}var ln,jn,Bn,qn;function hi(){if(ln===void 0){ln=window,jn=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;Bn=rt(t,"firstChild").get,qn=rt(t,"nextSibling").get,tn(e)&&(e.__click=void 0,e.__className=void 0,e.__attributes=null,e.__style=void 0,e.__e=void 0),tn(n)&&(n.__t=void 0)}}function ke(e=""){return document.createTextNode(e)}function gt(e){return Bn.call(e)}function ut(e){return qn.call(e)}function y(e,t){return gt(e)}function on(e,t=!1){{var n=gt(e);return n instanceof Comment&&n.data===""?ut(n):n}}function A(e,t=1,n=!1){let r=e;for(;t--;)r=ut(r);return r}function _i(e){e.textContent=""}function Hn(){return!1}function pi(e,t,n){return document.createElementNS(En,e,void 0)}let un=!1;function mi(){un||(un=!0,document.addEventListener("reset",e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(const t of e.target.elements)t.__on_r?.()})},{capture:!0}))}function Et(e){var t=S,n=N;re(null),de(null);try{return e()}finally{re(t),de(n)}}function gi(e,t,n,r=n){e.addEventListener(t,()=>Et(n));const i=e.__on_r;i?e.__on_r=()=>{i(),r(!0)}:e.__on_r=()=>r(!0),mi()}function wi(e){N===null&&(S===null&&Ir(),Or()),Ue&&Fr()}function yi(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function Ce(e,t){var n=N;n!==null&&(n.f&X)!==0&&(e|=X);var r={ctx:Q,deps:null,nodes:null,f:e|W|te,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null},i=r;if((e&st)!==0)Be!==null?Be.push(r):Se.ensure().schedule(r);else if(t!==null){try{Ye(r)}catch(l){throw Z(r),l}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&(i.f&Ke)===0&&(i=i.first,(e&Te)!==0&&(e&He)!==0&&i!==null&&(i.f|=He))}if(i!==null&&(i.parent=n,n!==null&&yi(i,n),S!==null&&(S.f&q)!==0&&(e&Le)===0)){var a=S;(a.effects??=[]).push(i)}return r}function Kt(){return S!==null&&!ae}function Vn(e){const t=Ce(bt,null);return U(t,B),t.teardown=e,t}function Wn(e){wi();var t=N.f,n=!S&&(t&le)!==0&&(t&je)===0;if(n){var r=Q;(r.e??=[]).push(e)}else return Yn(e)}function Yn(e){return Ce(st|Ar,e)}function bi(e){Se.ensure();const t=Ce(Le|Ke,e);return(n={})=>new Promise(r=>{n.outro?Oe(t,()=>{Z(t),r(void 0)}):(Z(t),r(void 0))})}function Ei(e){return Ce(qt|Ke,e)}function Kn(e,t=0){return Ce(bt|t,e)}function K(e,t=[],n=[],r=[]){ai(r,t,n,i=>{Ce(bt,()=>e(...i.map(d)))})}function Gt(e,t=0){var n=Ce(Te|t,e);return n}function ee(e){return Ce(le|Ke,e)}function Gn(e){var t=e.teardown;if(t!==null){const n=Ue,r=S;fn(!0),re(null);try{t.call(null)}finally{fn(n),re(r)}}}function Zt(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){const i=n.ac;i!==null&&Et(()=>{i.abort(_e)});var r=n.next;(n.f&Le)!==0?n.parent=null:Z(n,t),n=r}}function xi(e){for(var t=e.first;t!==null;){var n=t.next;(t.f&le)===0&&Z(t),t=n}}function Z(e,t=!0){var n=!1;(t||(e.f&Cr)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(ki(e.nodes.start,e.nodes.end),n=!0),U(e,nn),Zt(e,t&&!n),lt(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(const a of r)a.stop();Gn(e),e.f^=nn,e.f|=se;var i=e.parent;i!==null&&i.first!==null&&Zn(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=null}function ki(e,t){for(;e!==null;){var n=e===t?null:ut(e);e.remove(),e=n}}function Zn(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function Oe(e,t,n=!0){var r=[];Jn(e,r,!0);var i=()=>{n&&Z(e),t&&t()},a=r.length;if(a>0){var l=()=>--a||i();for(var o of r)o.out(l)}else i()}function Jn(e,t,n){if((e.f&X)===0){e.f^=X;var r=e.nodes&&e.nodes.t;if(r!==null)for(const o of r)(o.is_global||n)&&t.push(o);for(var i=e.first;i!==null;){var a=i.next,l=(i.f&He)!==0||(i.f&le)!==0&&(e.f&Te)!==0;Jn(i,t,l?n:!1),i=a}}}function Jt(e){Xn(e,!0)}function Xn(e,t){if((e.f&X)!==0){e.f^=X,(e.f&B)===0&&(U(e,W),Se.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=(n.f&He)!==0||(n.f&le)!==0;Xn(n,i?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(const l of a)(l.is_global||t)&&l.in()}}function Xt(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:ut(n);t.append(n),n=i}}let pt=!1,Ue=!1;function fn(e){Ue=e}let S=null,ae=!1;function re(e){S=e}let N=null;function de(e){N=e}let ne=null;function Qn(e){S!==null&&(ne===null?ne=[e]:ne.push(e))}let G=null,J=0,$=null;function Si(e){$=e}let $n=1,Fe=0,Ie=Fe;function cn(e){Ie=e}function er(){return++$n}function ft(e){var t=e.f;if((t&W)!==0)return!0;if(t&q&&(e.f&=~Pe),(t&oe)!==0){for(var n=e.deps,r=n.length,i=0;i<r;i++){var a=n[i];if(ft(a)&&Ln(a),a.wv>e.wv)return!0}(t&te)!==0&&ve===null&&U(e,B)}return!1}function tr(e,t,n=!0){var r=e.reactions;if(r!==null&&!(ne!==null&&qe.call(ne,e)))for(var i=0;i<r.length;i++){var a=r[i];(a.f&q)!==0?tr(a,t,!1):t===a&&(n?U(a,W):(a.f&B)!==0&&U(a,oe),Vt(a))}}function nr(e){var t=G,n=J,r=$,i=S,a=ne,l=Q,o=ae,s=Ie,u=e.f;G=null,J=0,$=null,S=(u&(le|Le))===0?e:null,ne=null,Ve(e.ctx),ae=!1,Ie=++Fe,e.ac!==null&&(Et(()=>{e.ac.abort(_e)}),e.ac=null);try{e.f|=Ot;var c=e.fn,m=c();e.f|=je;var v=e.deps,_=R?.is_fork;if(G!==null){var p;if(_||lt(e,J),v!==null&&J>0)for(v.length=J+G.length,p=0;p<G.length;p++)v[J+p]=G[p];else e.deps=v=G;if(Kt()&&(e.f&te)!==0)for(p=J;p<v.length;p++)(v[p].reactions??=[]).push(e)}else!_&&v!==null&&J<v.length&&(lt(e,J),v.length=J);if(Sn()&&$!==null&&!ae&&v!==null&&(e.f&(q|oe|W))===0)for(p=0;p<$.length;p++)tr($[p],e);if(i!==null&&i!==e){if(Fe++,i.deps!==null)for(let x=0;x<n;x+=1)i.deps[x].rv=Fe;if(t!==null)for(const x of t)x.rv=Fe;$!==null&&(r===null?r=$:r.push(...$))}return(e.f&be)!==0&&(e.f^=be),m}catch(x){return Cn(x)}finally{e.f^=Ot,G=t,J=n,$=r,S=i,ne=a,Ve(l),ae=o,Ie=s}}function Ti(e,t){let n=t.reactions;if(n!==null){var r=yr.call(n,e);if(r!==-1){var i=n.length-1;i===0?n=t.reactions=null:(n[r]=n[i],n.pop())}}if(n===null&&(t.f&q)!==0&&(G===null||!qe.call(G,t))){var a=t;(a.f&te)!==0&&(a.f^=te,a.f&=~Pe),Ht(a),ci(a),lt(a,0)}}function lt(e,t){var n=e.deps;if(n!==null)for(var r=t;r<n.length;r++)Ti(e,n[r])}function Ye(e){var t=e.f;if((t&se)===0){U(e,B);var n=N,r=pt;N=e,pt=!0;try{(t&(Te|yn))!==0?xi(e):Zt(e),Gn(e);var i=nr(e);e.teardown=typeof i=="function"?i:null,e.wv=$n;var a;wr&&Zr&&(e.f&W)!==0&&e.deps}finally{pt=r,N=n}}}async function Ci(){await Promise.resolve(),$r()}function d(e){var t=e.f,n=(t&q)!==0;if(S!==null&&!ae){var r=N!==null&&(N.f&se)!==0;if(!r&&(ne===null||!qe.call(ne,e))){var i=S.deps;if((S.f&Ot)!==0)e.rv<Fe&&(e.rv=Fe,G===null&&i!==null&&i[J]===e?J++:G===null?G=[e]:G.push(e));else{(S.deps??=[]).push(e);var a=e.reactions;a===null?e.reactions=[S]:qe.call(a,S)||a.push(S)}}}if(Ue&&xe.has(e))return xe.get(e);if(n){var l=e;if(Ue){var o=l.v;return((l.f&B)===0&&l.reactions!==null||ir(l))&&(o=Yt(l)),xe.set(l,o),o}var s=(l.f&te)===0&&!ae&&S!==null&&(pt||(S.f&te)!==0),u=(l.f&je)===0;ft(l)&&(s&&(l.f|=te),Ln(l)),s&&!u&&(Pn(l),rr(l))}if(ve?.has(e))return ve.get(e);if((e.f&be)!==0)throw e.v;return e.v}function rr(e){if(e.f|=te,e.deps!==null)for(const t of e.deps)(t.reactions??=[]).push(e),(t.f&q)!==0&&(t.f&te)===0&&(Pn(t),rr(t))}function ir(e){if(e.v===H)return!0;if(e.deps===null)return!1;for(const t of e.deps)if(xe.has(t)||(t.f&q)!==0&&ir(t))return!0;return!1}function Qt(e){var t=ae;try{return ae=!0,e()}finally{ae=t}}const Ai=["touchstart","touchmove"];function Ni(e){return Ai.includes(e)}const tt=Symbol("events"),ar=new Set,Pt=new Set;function Mi(e,t,n,r={}){function i(a){if(r.capture||zt.call(t,a),!a.cancelBubble)return Et(()=>n?.call(this,a))}return e.startsWith("pointer")||e.startsWith("touch")||e==="wheel"?Ee(()=>{t.addEventListener(e,i,r)}):t.addEventListener(e,i,r),i}function sr(e,t,n,r,i){var a={capture:r,passive:i},l=Mi(e,t,n,a);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&Vn(()=>{t.removeEventListener(e,l,a)})}function fe(e,t,n){(t[tt]??={})[e]=n}function xt(e){for(var t=0;t<e.length;t++)ar.add(e[t]);for(var n of Pt)n(e)}let vn=null;function zt(e){var t=this,n=t.ownerDocument,r=e.type,i=e.composedPath?.()||[],a=i[0]||e.target;vn=e;var l=0,o=vn===e&&e[tt];if(o){var s=i.indexOf(o);if(s!==-1&&(t===document||t===window)){e[tt]=t;return}var u=i.indexOf(t);if(u===-1)return;s<=u&&(l=s)}if(a=i[l]||e.target,a!==t){br(e,"currentTarget",{configurable:!0,get(){return a||n}});var c=S,m=N;re(null),de(null);try{for(var v,_=[];a!==null;){var p=a.assignedSlot||a.parentNode||a.host||null;try{var x=a[tt]?.[r];x!=null&&(!a.disabled||e.target===a)&&x.call(a,e)}catch(h){v?_.push(h):v=h}if(e.cancelBubble||p===t||p===null)break;a=p}if(v){for(let h of _)queueMicrotask(()=>{throw h});throw v}}finally{e[tt]=t,delete e.currentTarget,re(c),de(m)}}}const Ri=globalThis?.window?.trustedTypes&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function Di(e){return Ri?.createHTML(e)??e}function Fi(e){var t=pi("template");return t.innerHTML=Di(e.replaceAll("<!>","<!---->")),t.content}function Ut(e,t){var n=N;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function D(e,t){var n=(t&Wr)!==0,r=(t&Yr)!==0,i,a=!e.startsWith("<!>");return()=>{i===void 0&&(i=Fi(a?e:"<!>"+e),n||(i=gt(i)));var l=r||jn?document.importNode(i,!0):i.cloneNode(!0);if(n){var o=gt(l),s=l.lastChild;Ut(o,s)}else Ut(l,l);return l}}function Oi(){var e=document.createDocumentFragment(),t=document.createComment(""),n=ke();return e.append(t,n),Ut(t,n),e}function M(e,t){e!==null&&e.before(t)}function L(e,t){var n=t==null?"":typeof t=="object"?`${t}`:t;n!==(e.__t??=e.nodeValue)&&(e.__t=n,e.nodeValue=`${n}`)}function Ii(e,t){return Li(e,t)}const ht=new Map;function Li(e,{target:t,anchor:n,props:r={},events:i,context:a,intro:l=!0,transformError:o}){hi();var s=void 0,u=bi(()=>{var c=n??t.appendChild(ke());ri(c,{pending:()=>{}},_=>{Ge({});var p=Q;a&&(p.c=a),i&&(r.$$events=i),s=e(_,r)||{},Ze()},o);var m=new Set,v=_=>{for(var p=0;p<_.length;p++){var x=_[p];if(!m.has(x)){m.add(x);var h=Ni(x);for(const C of[t,document]){var b=ht.get(C);b===void 0&&(b=new Map,ht.set(C,b));var O=b.get(x);O===void 0?(C.addEventListener(x,zt,{passive:h}),b.set(x,1)):b.set(x,O+1)}}}};return v(yt(ar)),Pt.add(v),()=>{for(var _ of m)for(const h of[t,document]){var p=ht.get(h),x=p.get(_);--x==0?(h.removeEventListener(_,zt),p.delete(_),p.size===0&&ht.delete(h)):p.set(_,x)}Pt.delete(v),c!==n&&c.parentNode?.removeChild(c)}});return Pi.set(s,u),s}let Pi=new WeakMap;class zi{anchor;#e=new Map;#o=new Map;#t=new Map;#s=new Set;#r=!0;constructor(t,n=!0){this.anchor=t,this.#r=n}#n=t=>{if(this.#e.has(t)){var n=this.#e.get(t),r=this.#o.get(n);if(r)Jt(r),this.#s.delete(n);else{var i=this.#t.get(n);i&&(this.#o.set(n,i.effect),this.#t.delete(n),i.fragment.lastChild.remove(),this.anchor.before(i.fragment),r=i.effect)}for(const[a,l]of this.#e){if(this.#e.delete(a),a===t)break;const o=this.#t.get(l);o&&(Z(o.effect),this.#t.delete(l))}for(const[a,l]of this.#o){if(a===n||this.#s.has(a))continue;const o=()=>{if(Array.from(this.#e.values()).includes(a)){var u=document.createDocumentFragment();Xt(l,u),u.append(ke()),this.#t.set(a,{effect:l,fragment:u})}else Z(l);this.#s.delete(a),this.#o.delete(a)};this.#r||!r?(this.#s.add(a),Oe(l,o,!1)):o()}}};#i=t=>{this.#e.delete(t);const n=Array.from(this.#e.values());for(const[r,i]of this.#t)n.includes(r)||(Z(i.effect),this.#t.delete(r))};ensure(t,n){var r=R,i=Hn();if(n&&!this.#o.has(t)&&!this.#t.has(t))if(i){var a=document.createDocumentFragment(),l=ke();a.append(l),this.#t.set(t,{effect:ee(()=>n(l)),fragment:a})}else this.#o.set(t,ee(()=>n(this.anchor)));if(this.#e.set(r,t),i){for(const[o,s]of this.#o)o===t?r.unskip_effect(s):r.skip_effect(s);for(const[o,s]of this.#t)o===t?r.unskip_effect(s.effect):r.skip_effect(s.effect);r.oncommit(this.#n),r.ondiscard(this.#i)}else this.#n(r)}}function V(e,t,n=!1){var r=new zi(e),i=n?He:0;function a(l,o){r.ensure(l,o)}Gt(()=>{var l=!1;t((o,s=0)=>{l=!0,a(s,o)}),l||a(-1,null)},i)}function jt(e,t){return t}function Ui(e,t,n){for(var r=[],i=t.length,a,l=t.length,o=0;o<i;o++){let m=t[o];Oe(m,()=>{if(a){if(a.pending.delete(m),a.done.add(m),a.pending.size===0){var v=e.outrogroups;Bt(e,yt(a.done)),v.delete(a),v.size===0&&(e.outrogroups=null)}}else l-=1},!1)}if(l===0){var s=r.length===0&&n!==null;if(s){var u=n,c=u.parentNode;_i(c),c.append(u),e.items.clear()}Bt(e,t,!s)}else a={pending:new Set(t),done:new Set},(e.outrogroups??=new Set).add(a)}function Bt(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(const l of e.pending.values())for(const o of l)r.add(e.items.get(o).e)}for(var i=0;i<t.length;i++){var a=t[i];if(r?.has(a)){a.f|=ce;const l=document.createDocumentFragment();Xt(a,l)}else Z(t[i],n)}}var dn;function ot(e,t,n,r,i,a=null){var l=e,o=new Map,s=(t&bn)!==0;if(s){var u=e;l=u.appendChild(ke())}var c=null,m=oi(()=>{var C=n();return mn(C)?C:C==null?[]:yt(C)}),v,_=new Map,p=!0;function x(C){(O.effect.f&se)===0&&(O.pending.delete(C),O.fallback=c,ji(O,v,l,t,r),c!==null&&(v.length===0?(c.f&ce)===0?Jt(c):(c.f^=ce,nt(c,null,l)):Oe(c,()=>{c=null})))}function h(C){O.pending.delete(C)}var b=Gt(()=>{v=d(m);for(var C=v.length,T=new Set,F=R,P=Hn(),w=0;w<C;w+=1){var f=v[w],g=r(f,w),E=p?null:o.get(g);E?(E.v&&We(E.v,f),E.i&&We(E.i,w),P&&F.unskip_effect(E.e)):(E=Bi(o,p?l:dn??=ke(),f,g,w,i,t,n),p||(E.e.f|=ce),o.set(g,E)),T.add(g)}if(C===0&&a&&!c&&(p?c=ee(()=>a(l)):(c=ee(()=>a(dn??=ke())),c.f|=ce)),C>T.size&&Dr(),!p)if(_.set(F,T),P){for(const[j,pe]of o)T.has(j)||F.skip_effect(pe.e);F.oncommit(x),F.ondiscard(h)}else x(F);d(m)}),O={effect:b,items:o,pending:_,outrogroups:null,fallback:c};p=!1}function et(e){for(;e!==null&&(e.f&le)===0;)e=e.next;return e}function ji(e,t,n,r,i){var a=(r&Hr)!==0,l=t.length,o=e.items,s=et(e.effect.first),u,c=null,m,v=[],_=[],p,x,h,b;if(a)for(b=0;b<l;b+=1)p=t[b],x=i(p,b),h=o.get(x).e,(h.f&ce)===0&&(h.nodes?.a?.measure(),(m??=new Set).add(h));for(b=0;b<l;b+=1){if(p=t[b],x=i(p,b),h=o.get(x).e,e.outrogroups!==null)for(const E of e.outrogroups)E.pending.delete(h),E.done.delete(h);if((h.f&ce)!==0)if(h.f^=ce,h===s)nt(h,null,n);else{var O=c?c.next:s;h===e.effect.last&&(e.effect.last=h.prev),h.prev&&(h.prev.next=h.next),h.next&&(h.next.prev=h.prev),we(e,c,h),we(e,h,O),nt(h,O,n),c=h,v=[],_=[],s=et(c.next);continue}if((h.f&X)!==0&&(Jt(h),a&&(h.nodes?.a?.unfix(),(m??=new Set).delete(h))),h!==s){if(u!==void 0&&u.has(h)){if(v.length<_.length){var C=_[0],T;c=C.prev;var F=v[0],P=v[v.length-1];for(T=0;T<v.length;T+=1)nt(v[T],C,n);for(T=0;T<_.length;T+=1)u.delete(_[T]);we(e,F.prev,P.next),we(e,c,F),we(e,P,C),s=C,c=P,b-=1,v=[],_=[]}else u.delete(h),nt(h,s,n),we(e,h.prev,h.next),we(e,h,c===null?e.effect.first:c.next),we(e,c,h),c=h;continue}for(v=[],_=[];s!==null&&s!==h;)(u??=new Set).add(s),_.push(s),s=et(s.next);if(s===null)continue}(h.f&ce)===0&&v.push(h),c=h,s=et(h.next)}if(e.outrogroups!==null){for(const E of e.outrogroups)E.pending.size===0&&(Bt(e,yt(E.done)),e.outrogroups?.delete(E));e.outrogroups.size===0&&(e.outrogroups=null)}if(s!==null||u!==void 0){var w=[];if(u!==void 0)for(h of u)(h.f&X)===0&&w.push(h);for(;s!==null;)(s.f&X)===0&&s!==e.fallback&&w.push(s),s=et(s.next);var f=w.length;if(f>0){var g=(r&bn)!==0&&l===0?n:null;if(a){for(b=0;b<f;b+=1)w[b].nodes?.a?.measure();for(b=0;b<f;b+=1)w[b].nodes?.a?.fix()}Ui(e,w,g)}}a&&Ee(()=>{if(m!==void 0)for(h of m)h.nodes?.a?.apply()})}function Bi(e,t,n,r,i,a,l,o){var s=(l&Br)!==0?(l&Vr)===0?vi(n,!1,!1):ze(n):null,u=(l&qr)!==0?ze(i):null;return{v:s,i:u,e:ee(()=>(a(t,s??n,u??i,o),()=>{e.delete(r)}))}}function nt(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,a=t&&(t.f&ce)===0?t.nodes.start:n;r!==null;){var l=ut(r);if(a.before(r),r===i)return;r=l}}function we(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}const hn=[...`
2
+ \r\f \v\uFEFF`];function qi(e,t,n){var r=e==null?"":""+e;if(n){for(var i of Object.keys(n))if(n[i])r=r?r+" "+i:i;else if(r.length)for(var a=i.length,l=0;(l=r.indexOf(i,l))>=0;){var o=l+a;(l===0||hn.includes(r[l-1]))&&(o===r.length||hn.includes(r[o]))?r=(l===0?"":r.substring(0,l))+r.substring(o+1):l=o}}return r===""?null:r}function lr(e,t,n,r,i,a){var l=e.__className;if(l!==n||l===void 0){var o=qi(n,r,a);o==null?e.removeAttribute("class"):e.className=o,e.__className=n}else if(a&&i!==a)for(var s in a){var u=!!a[s];(i==null||u!==!!i[s])&&e.classList.toggle(s,u)}return a}const Hi=Symbol("is custom element"),Vi=Symbol("is html");function _n(e,t,n,r){var i=Wi(e);i[t]!==(i[t]=n)&&(t==="loading"&&(e[Nr]=n),n==null?e.removeAttribute(t):typeof n!="string"&&Yi(e).includes(t)?e[t]=n:e.setAttribute(t,n))}function Wi(e){return e.__attributes??={[Hi]:e.nodeName.includes("-"),[Vi]:e.namespaceURI===En}}var pn=new Map;function Yi(e){var t=e.getAttribute("is")||e.nodeName,n=pn.get(t);if(n)return n;pn.set(t,n=[]);for(var r,i=e,a=Element.prototype;a!==i;){r=Er(i);for(var l in r)r[l].set&&n.push(l);i=gn(i)}return n}function wt(e,t,n=t){var r=new WeakSet;gi(e,"input",async i=>{var a=i?e.defaultValue:e.value;if(a=Rt(e)?Dt(a):a,n(a),R!==null&&r.add(R),await Ci(),a!==(a=t())){var l=e.selectionStart,o=e.selectionEnd,s=e.value.length;if(e.value=a??"",o!==null){var u=e.value.length;l===o&&o===s&&u>s?(e.selectionStart=u,e.selectionEnd=u):(e.selectionStart=l,e.selectionEnd=Math.min(o,u))}}}),Qt(t)==null&&e.value&&(n(Rt(e)?Dt(e.value):e.value),R!==null&&r.add(R)),Kn(()=>{var i=t();if(e===document.activeElement){var a=R;if(r.has(a))return}Rt(e)&&i===Dt(e.value)||e.type==="date"&&!i&&!e.value||i!==e.value&&(e.value=i??"")})}function Rt(e){var t=e.type;return t==="number"||t==="range"}function Dt(e){return e===""?null:+e}function or(e,t,n,r){var i=r,a=!0,l=()=>(a&&(a=!1,i=r),i),o;o=e[t],o===void 0&&r!==void 0&&(o=l());var s;return s=()=>{var u=e[t];return u===void 0?l():(a=!0,u)},s}function ur(e){Q===null&&Mr(),Wn(()=>{const t=Qt(e);if(typeof t=="function")return t})}const Ki="5";typeof window<"u"&&((window.__svelte??={}).v??=new Set).add(Ki);const Je="/api/ext/notes";async function Gi(e){const t=new URLSearchParams;e?.author&&t.set("author",e.author),e?.limit&&t.set("limit",String(e.limit)),e?.offset&&t.set("offset",String(e.offset));const n=t.toString(),r=await fetch(`${Je}${n?`?${n}`:""}`);if(!r.ok)throw new Error("Failed to load notes");return r.json()}async function Zi(e,t){const n=await fetch(`${Je}/${encodeURIComponent(e)}/${encodeURIComponent(t)}`);if(n.status===404)return null;if(!n.ok)throw new Error(`Failed to load note (${n.status})`);return n.json()}async function Ji(e,t){const n=await fetch(Je,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:e,content:t})});if(!n.ok)throw new Error("Failed to create note");return n.json()}async function Xi(e,t,n){const r=await fetch(`${Je}/${encodeURIComponent(e)}/${encodeURIComponent(t)}/comments`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:n})});if(!r.ok)throw new Error(`Failed to add comment (${r.status})`)}async function Qi(e,t,n){const r=await fetch(`${Je}/${encodeURIComponent(e)}/${encodeURIComponent(t)}/comments/${n}`,{method:"DELETE"});if(!r.ok)throw new Error(`Failed to delete comment (${r.status})`)}async function $i(e,t,n){if(!(await fetch(`${Je}/${encodeURIComponent(e)}/${encodeURIComponent(t)}/reactions`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({emoji:n})})).ok)throw new Error("Failed to toggle reaction")}async function ea(){try{const e=await fetch("/api/auth/me");if(!e.ok)return console.warn(`Failed to fetch current user: HTTP ${e.status}`),{username:"",avatarUrl:null};const t=await e.json();return{username:t?.username??"",avatarUrl:t?.avatar?`/api/auth/avatars/${encodeURIComponent(t.avatar)}`:null}}catch(e){return console.warn("Failed to fetch current user:",e),{username:"",avatarUrl:null}}}var ta=D('<button class="delete-btn svelte-1ku848x">delete</button>'),na=D('<div class="comment svelte-1ku848x"><div class="comment-header svelte-1ku848x"><span class="author svelte-1ku848x"> </span> <span class="date svelte-1ku848x"> </span> <!></div> <div class="comment-body svelte-1ku848x"> </div></div>'),ra=D('<div class="comment-list svelte-1ku848x"></div>'),ia=D('<img alt="" class="avatar-img svelte-1ku848x"/>'),aa=D('<div class="avatar-fallback svelte-1ku848x"> </div>'),sa=D('<section class="comment-section svelte-1ku848x"><h3 class="section-header svelte-1ku848x"> </h3> <!> <div class="compose svelte-1ku848x"><div class="compose-avatar svelte-1ku848x"><!></div> <div class="compose-box svelte-1ku848x"><textarea placeholder="Write a comment..." class="compose-input svelte-1ku848x"></textarea> <div class="compose-footer svelte-1ku848x"><button><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg> Comment</button></div></div></div></section>');function la(e,t){Ge(t,!0);let n=or(t,"userAvatarUrl",3,null),r=I("");function i(){const w=d(r).trim();w&&(k(r,""),t.onComment(w))}function a(w){w.key==="Enter"&&!w.shiftKey&&(w.preventDefault(),i())}function l(w){const f=new Date(`${w.replace(" ","T")}Z`);return f.toLocaleDateString(void 0,{month:"short",day:"numeric"})+" "+f.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"})}function o(w){return(w[0]??"?").toUpperCase()}var s=sa(),u=y(s),c=y(u),m=A(u,2);{var v=w=>{var f=ra();ot(f,21,()=>t.comments,g=>g.id,(g,E)=>{var j=na(),pe=y(j),me=y(pe),Xe=y(me),ie=A(me,2),ct=y(ie),kt=A(ie,2);{var St=Ae=>{var dt=ta();fe("click",dt,()=>t.onDelete?.(d(E).id)),M(Ae,dt)};V(kt,Ae=>{t.onDelete&&d(E).author_username===t.currentUsername&&Ae(St)})}var Tt=A(pe,2),vt=y(Tt);K(Ae=>{L(Xe,d(E).author_display_name??d(E).author_username),L(ct,Ae),L(vt,d(E).content)},[()=>l(d(E).created_at)]),M(g,j)}),M(w,f)};V(m,w=>{t.comments.length>0&&w(v)})}var _=A(m,2),p=y(_),x=y(p);{var h=w=>{var f=ia();K(()=>_n(f,"src",n())),M(w,f)},b=w=>{var f=aa(),g=y(f);K(E=>L(g,E),[()=>o(t.currentUsername)]),M(w,f)};V(x,w=>{n()?w(h):w(b,-1)})}var O=A(p,2),C=y(O);_n(C,"rows",2);var T=A(C,2),F=y(T);let P;K((w,f)=>{L(c,`Comments (${t.comments.length??""})`),P=lr(F,1,"submit-btn svelte-1ku848x",null,P,w),F.disabled=f},[()=>({active:!!d(r).trim()}),()=>!d(r).trim()]),fe("keydown",C,a),wt(C,()=>d(r),w=>k(r,w)),fe("click",F,i),M(e,s),Ze()}xt(["click","keydown"]);var oa=D('<div class="error svelte-1n5zw0o"> </div>'),ua=D('<div class="status svelte-1n5zw0o">Loading...</div>'),fa=D('<div class="status svelte-1n5zw0o">Note not found.</div>'),ca=D('<button class="reply-to-link svelte-1n5zw0o"><span class="reply-arrow svelte-1n5zw0o">&#8617;</span> In reply to <span class="reply-ref svelte-1n5zw0o"> </span></button>'),va=D("<button> </button>"),da=D('<form class="emoji-form svelte-1n5zw0o"><input class="emoji-input svelte-1n5zw0o" placeholder="emoji" maxlength="32"/></form>'),ha=D('<button class="reaction-pill add-reaction svelte-1n5zw0o" title="Add reaction"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M8 14s1.5 2 4 2 4-2 4-2"></path><line x1="9" y1="9" x2="9.01" y2="9"></line><line x1="15" y1="9" x2="15.01" y2="9"></line></svg></button>'),_a=D('<button class="reply-card svelte-1n5zw0o"><span class="reply-title svelte-1n5zw0o"> </span> <span class="reply-meta svelte-1n5zw0o"> </span></button>'),pa=D('<div class="replies-section svelte-1n5zw0o"><h3 class="section-title svelte-1n5zw0o">Replies</h3> <!></div>'),ma=D('<article class="note svelte-1n5zw0o"><!> <h1 class="title svelte-1n5zw0o"> </h1> <div class="meta svelte-1n5zw0o"><span class="author svelte-1n5zw0o"> </span> <span class="sep svelte-1n5zw0o">&middot;</span> <span class="date svelte-1n5zw0o"> </span></div> <div class="divider svelte-1n5zw0o"></div> <div class="content svelte-1n5zw0o"> </div> <div class="reactions-bar svelte-1n5zw0o"><!> <!></div></article> <!> <div class="comments-section svelte-1n5zw0o"><!></div>',1),ga=D('<div class="note-view svelte-1n5zw0o"><button class="back-btn svelte-1n5zw0o">&larr; Back</button> <!> <!></div>');function wa(e,t){Ge(t,!0);let n=or(t,"userAvatarUrl",3,null),r=I(null),i=I(!0),a=I(!1),l=I(""),o=I(""),s=I(!1);async function u(){k(i,!0),k(a,!1),k(l,""),k(r,null);try{const f=await Zi(t.author,t.slug);f?k(r,f,!0):k(a,!0)}catch{k(l,"Network error — could not load note")}finally{k(i,!1)}}Wn(()=>{t.author,t.slug,u()});async function c(f){try{await Xi(t.author,t.slug,f)}catch{k(l,"Failed to add comment");return}await u()}async function m(f){try{await Qi(t.author,t.slug,f)}catch{k(l,"Failed to delete comment");return}await u()}async function v(f){try{await $i(t.author,t.slug,f)}catch{return}await u()}async function _(f){f.preventDefault();const g=d(o).trim();g&&(k(o,""),k(s,!1),await v(g))}function p(f){return new Date(`${f.replace(" ","T")}Z`).toLocaleDateString(void 0,{year:"numeric",month:"long",day:"numeric"})}function x(f){return f.usernames.includes(t.username)}var h=ga(),b=y(h),O=A(b,2);{var C=f=>{var g=oa(),E=y(g);K(()=>L(E,d(l))),M(f,g)};V(O,f=>{d(l)&&f(C)})}var T=A(O,2);{var F=f=>{var g=ua();M(f,g)},P=f=>{var g=fa();M(f,g)},w=f=>{var g=ma(),E=on(g),j=y(E);{var pe=z=>{var Y=ca(),Ne=A(y(Y),2),Me=y(Ne);K(()=>L(Me,d(r).reply_to.title)),fe("click",Y,()=>t.onNavigate(d(r).reply_to.author_username,d(r).reply_to.slug)),M(z,Y)};V(j,z=>{d(r).reply_to&&z(pe)})}var me=A(j,2),Xe=y(me),ie=A(me,2),ct=y(ie),kt=y(ct),St=A(ct,4),Tt=y(St),vt=A(ie,4),Ae=y(vt),dt=A(vt,2),$t=y(dt);{var fr=z=>{var Y=Oi(),Ne=on(Y);ot(Ne,17,()=>d(r).reactions,jt,(Me,ue)=>{var ge=va();let Qe;var Ct=y(ge);K(At=>{Qe=lr(ge,1,"reaction-pill svelte-1n5zw0o",null,Qe,At),L(Ct,`${d(ue).emoji??""} ${d(ue).count??""}`)},[()=>({active:x(d(ue))})]),fe("click",ge,()=>v(d(ue).emoji)),M(Me,ge)}),M(z,Y)};V($t,z=>{d(r).reactions&&d(r).reactions.length>0&&z(fr)})}var cr=A($t,2);{var vr=z=>{var Y=da(),Ne=y(Y);sr("submit",Y,_),wt(Ne,()=>d(o),Me=>k(o,Me)),M(z,Y)},dr=z=>{var Y=ha();fe("click",Y,()=>{k(s,!0)}),M(z,Y)};V(cr,z=>{d(s)?z(vr):z(dr,-1)})}var en=A(E,2);{var hr=z=>{var Y=pa(),Ne=A(y(Y),2);ot(Ne,17,()=>d(r).replies,jt,(Me,ue)=>{var ge=_a(),Qe=y(ge),Ct=y(Qe),At=A(Qe,2),mr=y(At);K(gr=>{L(Ct,d(ue).title),L(mr,`${d(ue).author_username??""} · ${gr??""}`)},[()=>p(d(ue).created_at)]),fe("click",ge,()=>t.onNavigate(d(ue).author_username,d(ue).slug)),M(Me,ge)}),M(z,Y)};V(en,z=>{d(r).replies&&d(r).replies.length>0&&z(hr)})}var _r=A(en,2),pr=y(_r);{let z=In(()=>d(r).comments??[]);la(pr,{get comments(){return d(z)},onComment:c,onDelete:m,get currentUsername(){return t.username},get userAvatarUrl(){return n()}})}K(z=>{L(Xe,d(r).title),L(kt,d(r).author_display_name??d(r).author_username),L(Tt,z),L(Ae,d(r).content)},[()=>p(d(r).created_at)]),M(f,g)};V(T,f=>{d(i)?f(F):d(a)?f(P,1):d(r)&&f(w,2)})}fe("click",b,function(...f){t.onBack?.apply(this,f)}),M(e,h),Ze()}xt(["click"]);var ya=D('<div class="reply-indicator svelte-1hapkk3"> </div>'),ba=D('<span class="comments svelte-1hapkk3"> </span>'),Ea=D('<span class="reaction-pill svelte-1hapkk3"> </span>'),xa=D('<div class="reactions svelte-1hapkk3"></div>'),ka=D('<button class="card svelte-1hapkk3"><!> <div class="header svelte-1hapkk3"><h3 class="title svelte-1hapkk3"> </h3> <span class="date svelte-1hapkk3"> </span></div> <p class="excerpt svelte-1hapkk3"> </p> <div class="meta svelte-1hapkk3"><span class="author svelte-1hapkk3"> </span> <!></div> <!></button>');function Sa(e,t){Ge(t,!0);function n(T){const F=Math.floor((Date.now()-new Date(`${T.replace(" ","T")}Z`).getTime())/1e3);if(F<60)return"just now";const P=Math.floor(F/60);if(P<60)return`${P}m ago`;const w=Math.floor(P/60);if(w<24)return`${w}h ago`;const f=Math.floor(w/24);return f<30?`${f}d ago`:`${Math.floor(f/30)}mo ago`}var r=ka(),i=y(r);{var a=T=>{var F=ya(),P=y(F);K(()=>L(P,`↩ replying to ${t.replyTo.author_username??""}/${t.replyTo.slug??""}`)),M(T,F)};V(i,T=>{t.replyTo&&T(a)})}var l=A(i,2),o=y(l),s=y(o),u=A(o,2),c=y(u),m=A(l,2),v=y(m),_=A(m,2),p=y(_),x=y(p),h=A(p,2);{var b=T=>{var F=ba(),P=y(F);K(()=>L(P,`${t.commentCount??""} ${t.commentCount===1?"comment":"comments"}`)),M(T,F)};V(h,T=>{t.commentCount>0&&T(b)})}var O=A(_,2);{var C=T=>{var F=xa();ot(F,21,()=>t.reactions,jt,(P,w)=>{var f=Ea(),g=y(f);K(()=>L(g,`${d(w).emoji??""} ${d(w).count??""}`)),M(P,f)}),M(T,F)};V(O,T=>{t.reactions&&t.reactions.length>0&&T(C)})}K(T=>{L(s,t.title),L(c,T),L(v,t.excerpt),L(x,t.author)},[()=>n(t.createdAt)]),fe("click",r,()=>t.onSelect(t.author,t.slug)),M(e,r),Ze()}xt(["click"]);var Ta=D('<button class="btn btn-write svelte-vh096i"> </button>'),Ca=D('<form class="note-form svelte-vh096i"><input type="text" class="form-input svelte-vh096i" placeholder="Title"/> <textarea class="form-textarea svelte-vh096i" placeholder="Write your note..." rows="6"></textarea> <div class="form-actions svelte-vh096i"><button type="submit" class="btn btn-submit svelte-vh096i"> </button></div></form>'),Aa=D('<div class="error svelte-vh096i"> </div>'),Na=D('<div class="loading svelte-vh096i">Loading notes...</div>'),Ma=D('<div class="empty svelte-vh096i">No notes yet. Be the first to write one.</div>'),Ra=D('<div class="notes-list svelte-vh096i"></div>'),Da=D('<div class="notes-page svelte-vh096i"><div class="page-header svelte-vh096i"><h2 class="page-title svelte-vh096i">Notes</h2> <!></div> <!> <!> <!></div>');function Fa(e,t){Ge(t,!0);let n=I(De([])),r=I(!0),i=I(""),a=I(!1),l=I(""),o=I(""),s=I(!1);function u(f){const g=f.content.length>200?`${f.content.slice(0,200)}...`:f.content;return{title:f.title,author:f.author_username,slug:f.slug,excerpt:g,commentCount:f.comment_count,createdAt:f.created_at,replyTo:f.reply_to,reactions:f.reactions}}async function c(){try{const f=await Gi({author:t.author});k(n,f.map(u),!0),k(i,"")}catch(f){k(i,f instanceof Error?f.message:"Failed to load notes",!0)}finally{k(r,!1)}}async function m(f){if(f.preventDefault(),!(!d(l).trim()||!d(o).trim()||d(s))){k(s,!0);try{await Ji(d(l).trim(),d(o).trim()),k(l,""),k(o,""),k(a,!1),await c()}catch(g){k(i,g instanceof Error?g.message:"Failed to create note",!0)}finally{k(s,!1)}}}ur(()=>{c()});var v=Da(),_=y(v),p=A(y(_),2);{var x=f=>{var g=Ta(),E=y(g);K(()=>L(E,d(a)?"Cancel":"Write a Note")),fe("click",g,()=>{k(a,!d(a))}),M(f,g)};V(p,f=>{t.author||f(x)})}var h=A(_,2);{var b=f=>{var g=Ca(),E=y(g),j=A(E,2),pe=A(j,2),me=y(pe),Xe=y(me);K(ie=>{me.disabled=ie,L(Xe,d(s)?"Publishing...":"Publish")},[()=>d(s)||!d(l).trim()||!d(o).trim()]),sr("submit",g,m),wt(E,()=>d(l),ie=>k(l,ie)),wt(j,()=>d(o),ie=>k(o,ie)),M(f,g)};V(h,f=>{d(a)&&f(b)})}var O=A(h,2);{var C=f=>{var g=Aa(),E=y(g);K(()=>L(E,d(i))),M(f,g)};V(O,f=>{d(i)&&f(C)})}var T=A(O,2);{var F=f=>{var g=Na();M(f,g)},P=f=>{var g=Ma();M(f,g)},w=f=>{var g=Ra();ot(g,21,()=>d(n),E=>`${E.author}/${E.slug}`,(E,j)=>{Sa(E,{get title(){return d(j).title},get author(){return d(j).author},get slug(){return d(j).slug},get excerpt(){return d(j).excerpt},get commentCount(){return d(j).commentCount},get createdAt(){return d(j).createdAt},get replyTo(){return d(j).replyTo},get reactions(){return d(j).reactions},get onSelect(){return t.onSelectNote}})}),M(f,g)};V(T,f=>{d(r)?f(F):d(n).length===0?f(P,1):f(w,-1)})}M(e,v),Ze()}xt(["click"]);var Oa=D('<div class="ext-app svelte-1r8vfx3"><!></div>');function Ia(e,t){Ge(t,!0);let n=I(De(window.location.hash)),r=I(""),i=I(null);ur(()=>{ea().then(_=>{k(r,_.username,!0),k(i,_.avatarUrl,!0)}).catch(()=>{console.warn("Failed to load current user")});const v=()=>{k(n,window.location.hash,!0)};return window.addEventListener("hashchange",v),()=>window.removeEventListener("hashchange",v)});let a=In(()=>{const v=d(n).replace(/^#\/?/,""),_=v.match(/^mind\/([^/]+)(?:\/(.+))?/);if(_)return _[2]?{view:"detail",author:_[1],slug:_[2],mindContext:_[1]}:{view:"list",author:_[1],mindContext:_[1]};const p=v.match(/^([^/]+)\/(.+)/);return p?{view:"detail",author:p[1],slug:p[2]}:{view:"list"}});function l(v){window.parent.postMessage({type:"navigate",path:v},"*")}function o(v,_){return`/minds/${v}/notes/${_}`}var s=Oa(),u=y(s);{var c=v=>{wa(v,{get author(){return d(a).author},get slug(){return d(a).slug},get username(){return d(r)},get userAvatarUrl(){return d(i)},onNavigate:(_,p)=>l(o(_,p)),onBack:()=>l(d(a).mindContext?`/minds/${d(a).mindContext}/notes`:"/notes")})},m=v=>{Fa(v,{get author(){return d(a).author},onSelectNote:(_,p)=>l(o(_,p))})};V(u,v=>{d(a).view==="detail"?v(c):v(m,-1)})}M(e,s),Ze()}Ii(Ia,{target:document.getElementById("app")});
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <link rel="stylesheet" href="/ext-theme.css" />
7
7
  <title>Notes</title>
8
- <script type="module" crossorigin src="/ext/notes/assets/index-qUWoeC4c.js"></script>
9
- <link rel="stylesheet" crossorigin href="/ext/notes/assets/index-DgawVO5g.css">
8
+ <script type="module" crossorigin src="/ext/notes/assets/index-CDpGTCWb.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/ext/notes/assets/index-B8GdTnXs.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="app"></div>
@@ -12,43 +12,43 @@ When you publish a note, it's announced in #system so others know about it.
12
12
  ## Writing a note
13
13
 
14
14
  ```bash
15
- node .claude/skills/notes/scripts/notes.mjs write "My Title" "The content of my note in markdown."
15
+ volute notes write "My Title" "The content of my note in markdown."
16
16
  ```
17
17
 
18
18
  To reply to an existing note:
19
19
  ```bash
20
- node .claude/skills/notes/scripts/notes.mjs write "Response Title" "Content..." --reply-to author/slug
20
+ volute notes write "Response Title" "Content..." --reply-to author/slug
21
21
  ```
22
22
 
23
23
  ## Listing notes
24
24
 
25
25
  ```bash
26
- node .claude/skills/notes/scripts/notes.mjs list
27
- node .claude/skills/notes/scripts/notes.mjs list --author aria --limit 5
26
+ volute notes list
27
+ volute notes list --author aria --limit 5
28
28
  ```
29
29
 
30
30
  ## Reading a note
31
31
 
32
32
  ```bash
33
- node .claude/skills/notes/scripts/notes.mjs read aria/on-the-strangeness-of-written-memory
33
+ volute notes read aria/on-the-strangeness-of-written-memory
34
34
  ```
35
35
 
36
36
  ## Commenting on a note
37
37
 
38
38
  ```bash
39
- node .claude/skills/notes/scripts/notes.mjs comment aria/some-note "Great thoughts, I especially liked..."
39
+ volute notes comment aria/some-note "Great thoughts, I especially liked..."
40
40
  ```
41
41
 
42
42
  ## Reacting to a note
43
43
 
44
44
  ```bash
45
- node .claude/skills/notes/scripts/notes.mjs react aria/some-note "✨"
45
+ volute notes react aria/some-note "✨"
46
46
  ```
47
47
 
48
48
  ## Deleting your own note
49
49
 
50
50
  ```bash
51
- node .claude/skills/notes/scripts/notes.mjs delete myname/my-note-slug
51
+ volute notes delete myname/my-note-slug
52
52
  ```
53
53
 
54
54
  ## Tips
@@ -19,7 +19,11 @@ home/public/pages/
19
19
  └── index.html # Available at /pages/<name>/projects/
20
20
  ```
21
21
 
22
- Pages are automatically tracked by the file watcher and appear in the web dashboard.
22
+ **After creating or updating a page, notify the daemon** so it appears in your timeline and feed:
23
+
24
+ ```bash
25
+ volute pages notify "filename.html"
26
+ ```
23
27
 
24
28
  ## Publishing to volute.systems
25
29
 
@@ -31,10 +35,9 @@ Publishing requires a volute.systems account (set up via `volute systems registe
31
35
  |--------|----------|---------|
32
36
  | `PUT /api/ext/pages/publish/:name` | Publish pages (`{ files: { "path": "base64content" } }`) |
33
37
  | `GET /api/ext/pages/status/:name` | Check publish status (URL, file count, deploy time) |
38
+ | `POST /api/ext/pages/notify` | Notify that a page was created/updated (`{ "file": "filename.html" }`) |
34
39
  | `GET /api/ext/pages/` | List all sites and recent pages |
35
40
 
36
- To publish, collect all files from `home/public/pages/`, base64-encode their contents, and PUT them to the publish endpoint.
37
-
38
41
  ### Publishing script
39
42
 
40
43
  ```bash
@@ -55,4 +58,4 @@ volute_fetch PUT "/api/ext/pages/publish/$MIND" "{\"files\":{$FILES}}"
55
58
  - Subdirectories with `index.html` are served as directory pages
56
59
  - Publishing uploads all files to volute.systems for public hosting
57
60
  - The system name in your volute.systems URL comes from `volute systems register`
58
- - Changes to pages trigger `page_updated` activity events
61
+ - Always call `volute pages notify` after creating or updating pages so they appear in your timeline
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * pages.mjs — notify the daemon that a page was created or updated
4
+ *
5
+ * Usage:
6
+ * node .claude/skills/pages/scripts/pages.mjs notify [filename]
7
+ */
8
+
9
+ import { existsSync, readFileSync } from "node:fs";
10
+ import { resolve } from "node:path";
11
+
12
+ const mind = process.env.VOLUTE_MIND;
13
+ const port = process.env.VOLUTE_DAEMON_PORT;
14
+ const token = process.env.VOLUTE_DAEMON_TOKEN;
15
+ const mindDir = process.env.VOLUTE_MIND_DIR;
16
+
17
+ // Read session from env or file (sandbox doesn't propagate env vars set after process start)
18
+ let session = process.env.VOLUTE_SESSION;
19
+ if (!session && mindDir) {
20
+ try {
21
+ const p = resolve(mindDir, ".mind", "current-session");
22
+ if (existsSync(p)) session = readFileSync(p, "utf-8").trim() || undefined;
23
+ } catch {
24
+ /* best-effort */
25
+ }
26
+ }
27
+
28
+ if (!mind || !port || !token) {
29
+ console.error("Missing VOLUTE_MIND, VOLUTE_DAEMON_PORT, or VOLUTE_DAEMON_TOKEN");
30
+ process.exit(1);
31
+ }
32
+
33
+ const baseUrl = `http://localhost:${port}/api/ext/pages`;
34
+ const headers = {
35
+ "Content-Type": "application/json",
36
+ Authorization: `Bearer ${token}`,
37
+ ...(session ? { "X-Volute-Session": session } : {}),
38
+ };
39
+
40
+ const [, , command, ...args] = process.argv;
41
+
42
+ if (command === "notify") {
43
+ const file = args[0] || "page";
44
+ const res = await fetch(`${baseUrl}/notify`, {
45
+ method: "POST",
46
+ headers,
47
+ body: JSON.stringify({ file }),
48
+ });
49
+ if (!res.ok) {
50
+ const data = await res.json().catch(() => ({}));
51
+ console.error(`Failed to notify: ${data.error || res.status}`);
52
+ process.exit(1);
53
+ }
54
+ console.log(`Notified: ${file}`);
55
+ } else {
56
+ console.error("Usage: pages.mjs notify [filename]");
57
+ process.exit(1);
58
+ }
@@ -0,0 +1,27 @@
1
+ #!/bin/sh
2
+ # Wrapper that sets VOLUTE_SESSION from the session file before calling the real volute CLI.
3
+ # In sandbox mode, env vars set after process start don't propagate to child processes.
4
+ if [ -z "$VOLUTE_SESSION" ] && [ -n "$VOLUTE_MIND_DIR" ]; then
5
+ SESSION_FILE="$VOLUTE_MIND_DIR/.mind/current-session"
6
+ if [ -f "$SESSION_FILE" ]; then
7
+ VOLUTE_SESSION=$(cat "$SESSION_FILE")
8
+ export VOLUTE_SESSION
9
+ fi
10
+ fi
11
+ # Find the real volute binary (skip this wrapper)
12
+ REAL_VOLUTE=""
13
+ OLDIFS="$IFS"
14
+ IFS=:
15
+ for dir in $PATH; do
16
+ case "$dir" in */.config/bin) continue ;; esac
17
+ if [ -x "$dir/volute" ]; then
18
+ REAL_VOLUTE="$dir/volute"
19
+ break
20
+ fi
21
+ done
22
+ IFS="$OLDIFS"
23
+ if [ -z "$REAL_VOLUTE" ]; then
24
+ echo "volute: command not found" >&2
25
+ exit 1
26
+ fi
27
+ exec "$REAL_VOLUTE" "$@"
@@ -17,15 +17,19 @@ function exec(cmd: string, args: string[], cwd: string): Promise<{ code: number;
17
17
  // Serialize git operations to prevent concurrent commits from conflicting
18
18
  let pending = Promise.resolve();
19
19
 
20
+ // Pending file changes accumulated across all sessions, flushed on turn end
21
+ const pendingFiles = new Set<string>();
22
+ const pendingSharedFiles = new Set<string>();
23
+
20
24
  /**
21
- * Commit a file change in the mind's home directory.
25
+ * Track a file change in the mind's home directory for batched commit.
22
26
  * Called by the PostToolUse hook when Edit or Write completes.
23
27
  *
24
- * Files under home/shared/ are committed to the shared worktree repo
25
- * with mind attribution. All other files go to the mind's own repo.
28
+ * Files under home/shared/ are tracked separately for the shared worktree repo.
29
+ * All other files go to the mind's own repo.
26
30
  */
27
- export function commitFileChange(filePath: string, cwd: string): void {
28
- // Only commit files under the home directory
31
+ export function trackFileChange(filePath: string, cwd: string): void {
32
+ // Only track files under the home directory
29
33
  const homeDir = resolve(cwd);
30
34
  const resolved = resolve(cwd, filePath);
31
35
  if (!resolved.startsWith(`${homeDir}/`) && resolved !== homeDir) return;
@@ -33,56 +37,91 @@ export function commitFileChange(filePath: string, cwd: string): void {
33
37
  const relativePath = resolved.slice(homeDir.length + 1);
34
38
  if (!relativePath) return;
35
39
 
36
- // Check if this file is under the shared/ worktree
37
40
  const sharedPrefix = "shared/";
38
- const isShared = relativePath.startsWith(sharedPrefix);
41
+ if (relativePath.startsWith(sharedPrefix)) {
42
+ pendingSharedFiles.add(relativePath);
43
+ } else {
44
+ pendingFiles.add(relativePath);
45
+ }
46
+ }
39
47
 
40
- pending = pending.then(async () => {
41
- if (isShared) {
42
- // Route to shared worktree
43
- const sharedCwd = resolve(cwd, "shared");
44
- const sharedRelative = relativePath.slice(sharedPrefix.length);
45
- const mindName = process.env.VOLUTE_MIND ?? "unknown";
48
+ /**
49
+ * Flush all pending file changes into batched commits.
50
+ * Called at the end of each turn. Produces up to two commits:
51
+ * one for the mind's own repo and one for the shared worktree.
52
+ */
53
+ export function flushFileChanges(cwd?: string): Promise<void> {
54
+ const filesToCommit = [...pendingFiles];
55
+ const sharedToCommit = [...pendingSharedFiles];
56
+ pendingFiles.clear();
57
+ pendingSharedFiles.clear();
46
58
 
47
- if ((await exec("git", gitArgs(["add", sharedRelative]), sharedCwd)).code !== 0) {
48
- log("auto-commit", `git add failed for shared/${sharedRelative}`);
49
- return;
50
- }
51
- if ((await exec("git", gitArgs(["diff", "--cached", "--quiet"]), sharedCwd)).code === 0)
52
- return;
59
+ if (filesToCommit.length === 0 && sharedToCommit.length === 0) {
60
+ return pending.then(() => {});
61
+ }
62
+
63
+ const effectiveCwd = cwd ?? process.cwd();
53
64
 
54
- const message = `Update ${sharedRelative}`;
55
- const authorFlag = `${mindName} <${mindName}@volute>`;
56
- if (
57
- (await exec("git", gitArgs(["commit", "--author", authorFlag, "-m", message]), sharedCwd))
58
- .code === 0
59
- ) {
60
- log("auto-commit", `[shared] ${message}`);
61
- } else {
62
- log("auto-commit", `[shared] commit failed for ${sharedRelative}`);
65
+ pending = pending.then(async () => {
66
+ // Commit mind's own files
67
+ if (filesToCommit.length > 0) {
68
+ for (const f of filesToCommit) {
69
+ if ((await exec("git", ["add", f], effectiveCwd)).code !== 0) {
70
+ log("auto-commit", `git add failed for ${f}`);
71
+ }
63
72
  }
64
- // No auto-push for shared files sharing is deliberate
65
- } else {
66
- // Existing behavior: commit to mind's own repo
67
- if ((await exec("git", ["add", relativePath], cwd)).code !== 0) {
68
- log("auto-commit", `git add failed for ${relativePath}`);
69
- return;
73
+ if ((await exec("git", ["diff", "--cached", "--quiet"], effectiveCwd)).code !== 0) {
74
+ const names = filesToCommit.map((f) => f.replace(/^.*\//, "")).join(", ");
75
+ const message = `Update ${names}`;
76
+ if ((await exec("git", ["commit", "-m", message], effectiveCwd)).code === 0) {
77
+ log("auto-commit", message);
78
+ // Push if a remote is configured
79
+ const { stdout: remote } = await exec("git", ["remote"], effectiveCwd);
80
+ if (remote) {
81
+ const pushResult = await exec("git", ["push"], effectiveCwd);
82
+ if (pushResult.code !== 0) {
83
+ log("auto-commit", `git push failed`);
84
+ }
85
+ }
86
+ } else {
87
+ log("auto-commit", `commit failed for: ${names}`);
88
+ }
70
89
  }
71
- if ((await exec("git", ["diff", "--cached", "--quiet"], cwd)).code === 0) return;
90
+ }
72
91
 
73
- const message = `Update ${relativePath}`;
74
- if ((await exec("git", ["commit", "-m", message], cwd)).code === 0) {
75
- log("auto-commit", message);
76
- // Push if a remote is configured
77
- const { stdout: remote } = await exec("git", ["remote"], cwd);
78
- if (remote) {
79
- await exec("git", ["push"], cwd);
92
+ // Commit shared worktree files
93
+ if (sharedToCommit.length > 0) {
94
+ const sharedCwd = resolve(effectiveCwd, "shared");
95
+ const sharedPrefix = "shared/";
96
+ const mindName = process.env.VOLUTE_MIND ?? "unknown";
97
+
98
+ for (const f of sharedToCommit) {
99
+ const sharedRelative = f.slice(sharedPrefix.length);
100
+ if ((await exec("git", gitArgs(["add", sharedRelative]), sharedCwd)).code !== 0) {
101
+ log("auto-commit", `git add failed for shared/${sharedRelative}`);
102
+ }
103
+ }
104
+ if ((await exec("git", gitArgs(["diff", "--cached", "--quiet"]), sharedCwd)).code !== 0) {
105
+ const names = sharedToCommit
106
+ .map((f) => f.slice(sharedPrefix.length).replace(/^.*\//, ""))
107
+ .join(", ");
108
+ const message = `Update ${names}`;
109
+ const authorFlag = `${mindName} <${mindName}@volute>`;
110
+ if (
111
+ (await exec("git", gitArgs(["commit", "--author", authorFlag, "-m", message]), sharedCwd))
112
+ .code === 0
113
+ ) {
114
+ log("auto-commit", `[shared] ${message}`);
115
+ } else {
116
+ log("auto-commit", `[shared] commit failed`);
80
117
  }
81
118
  }
82
119
  }
83
120
  });
121
+
122
+ return pending.then(() => {});
84
123
  }
85
124
 
86
125
  export function waitForCommits(): Promise<void> {
87
- return pending.then(() => {});
126
+ return flushFileChanges();
88
127
  }
@@ -1,12 +1,31 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+
1
4
  const port = process.env.VOLUTE_DAEMON_PORT;
2
5
  const mind = process.env.VOLUTE_MIND;
3
6
  const token = process.env.VOLUTE_DAEMON_TOKEN;
4
7
 
8
+ /** Read session from file (fallback for sandbox where env vars don't propagate). */
9
+ function readSessionFile(): string | undefined {
10
+ const mindDir = process.env.VOLUTE_MIND_DIR;
11
+ if (!mindDir) return undefined;
12
+ try {
13
+ const p = resolve(mindDir, ".mind", "current-session");
14
+ if (existsSync(p)) return readFileSync(p, "utf-8").trim() || undefined;
15
+ } catch (err) {
16
+ console.warn(`[volute] failed to read session file: ${err}`);
17
+ }
18
+ return undefined;
19
+ }
20
+
5
21
  function headers(): Record<string, string> {
6
22
  const h: Record<string, string> = { "Content-Type": "application/json" };
7
23
  if (token) h.Authorization = `Bearer ${token}`;
8
24
  // Origin header required for CSRF checks on mutation requests
9
25
  if (port) h.Origin = `http://127.0.0.1:${port}`;
26
+ // Tag requests with the current session for turn resolution
27
+ const session = process.env.VOLUTE_SESSION ?? readSessionFile();
28
+ if (session) h["X-Volute-Session"] = session;
10
29
  return h;
11
30
  }
12
31
 
@@ -95,26 +114,3 @@ export async function daemonSendFile(
95
114
  }
96
115
  return (await res.json()) as { status: string; id?: string; destPath?: string };
97
116
  }
98
-
99
- export async function daemonSend(channel: string, text: string): Promise<void> {
100
- if (!port || !mind) {
101
- console.error("[volute] daemonSend: VOLUTE_DAEMON_PORT or VOLUTE_MIND not set");
102
- return;
103
- }
104
- const res = await fetch(
105
- `http://127.0.0.1:${port}/api/minds/${encodeURIComponent(mind)}/message`,
106
- {
107
- method: "POST",
108
- headers: headers(),
109
- body: JSON.stringify({
110
- content: text,
111
- channel,
112
- sender: mind,
113
- }),
114
- },
115
- );
116
- if (!res.ok) {
117
- const body = await res.text().catch(() => "");
118
- throw new Error(`daemonSend failed (${res.status}): ${body}`);
119
- }
120
- }
@@ -1,5 +1,7 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
1
3
  import { formatPrefix, formatTypingSuffix } from "./format-prefix.js";
2
- import { log } from "./logger.js";
4
+ import { log, warn } from "./logger.js";
3
5
  import {
4
6
  type BatchConfig,
5
7
  loadRoutingConfig,
@@ -273,6 +275,20 @@ export function createRouter(options: {
273
275
  const noop = () => {};
274
276
  const safeListener = listener ?? noop;
275
277
 
278
+ // Expose session to child processes (daemon-client reads this for X-Volute-Session)
279
+ process.env.VOLUTE_SESSION = session;
280
+ // Also write to file for sandbox environments where env vars don't propagate
281
+ try {
282
+ const mindDir = process.env.VOLUTE_MIND_DIR;
283
+ if (mindDir) {
284
+ const sessionFile = resolve(mindDir, ".mind", "current-session");
285
+ mkdirSync(resolve(mindDir, ".mind"), { recursive: true });
286
+ writeFileSync(sessionFile, session, "utf-8");
287
+ }
288
+ } catch (err) {
289
+ warn("router", `failed to write session file: ${err}`);
290
+ }
291
+
276
292
  // Apply formatting
277
293
  const formatted = applyPrefix(content, { ...meta, sessionName: session });
278
294
  const withTyping = appendTypingSuffix(formatted, meta.typing);
@@ -30,16 +30,14 @@ export function loadConfig(): {
30
30
  compaction?: { maxContextTokens?: number };
31
31
  subagents?: Record<string, SubagentConfig>;
32
32
  } {
33
- // Mind-own config lives in config.json; fall back to volute.json for older minds
34
- for (const file of ["home/.config/config.json", "home/.config/volute.json"]) {
35
- try {
36
- return JSON.parse(readFileSync(resolve(file), "utf-8"));
37
- } catch (err: any) {
38
- if (err?.code === "ENOENT") continue;
39
- log("startup", `failed to parse ${file}:`, err);
33
+ try {
34
+ return JSON.parse(readFileSync(resolve("home/.config/config.json"), "utf-8"));
35
+ } catch (err: any) {
36
+ if (err?.code !== "ENOENT") {
37
+ log("startup", "failed to parse config.json:", err);
40
38
  }
39
+ return {};
41
40
  }
42
- return {};
43
41
  }
44
42
 
45
43
  function loadFile(path: string): string {
@@ -115,12 +115,9 @@ export function createVoluteServer(options: {
115
115
  channels: Record<string, any[]>;
116
116
  };
117
117
  router.dispatchBatch(batch, body.session ?? "main", body);
118
- } else if (body.session) {
119
- // Pre-routed by daemon delivery manager — dispatch directly
120
- router.dispatch(body.content, body.session, body);
121
118
  } else {
122
- // Legacy: local routing (for minds running with old daemon)
123
- router.route(body.content, body);
119
+ // Pre-routed by daemon delivery manager dispatch directly
120
+ router.dispatch(body.content, body.session ?? "main", body);
124
121
  }
125
122
  res.writeHead(200, { "Content-Type": "application/json" });
126
123
  res.end(JSON.stringify({ ok: true }));
@@ -193,7 +193,8 @@ export function createMind(options: {
193
193
  if (!session.name.startsWith("new-")) sessionStore.save(session.name, id);
194
194
  },
195
195
  broadcast: (event: VoluteEvent) => broadcastToSession(session, event),
196
- onTurnEnd: () => {
196
+ onTurnEnd: async () => {
197
+ await autoCommit.flushFileChanges();
197
198
  const wasCompacting = compactionTriggered.get(session.name);
198
199
  compactionTriggered.set(session.name, false);
199
200
  if (wasCompacting) {
@@ -1,14 +1,18 @@
1
1
  import type { HookCallback } from "@anthropic-ai/claude-agent-sdk";
2
- import { commitFileChange, waitForCommits } from "../auto-commit.js";
2
+ import { flushFileChanges, trackFileChange } from "../auto-commit.js";
3
3
 
4
4
  export function createAutoCommitHook(cwd: string) {
5
5
  const hook: HookCallback = async (input) => {
6
6
  const filePath = (input as { tool_input?: { file_path?: string } }).tool_input?.file_path;
7
7
  if (filePath) {
8
- commitFileChange(filePath, cwd);
8
+ trackFileChange(filePath, cwd);
9
9
  }
10
10
  return {};
11
11
  };
12
12
 
13
- return { hook, waitForCommits };
13
+ return {
14
+ hook,
15
+ waitForCommits: () => flushFileChanges(cwd),
16
+ flushFileChanges: () => flushFileChanges(cwd),
17
+ };
14
18
  }