mcp-memory-bucket 0.8.5 → 0.8.7

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.
@@ -1745,7 +1745,7 @@ This removes the doc's key, tags, and status — it drops out of key-based looku
1745
1745
  cursor: pointer;
1746
1746
  }
1747
1747
  .bulk-bar button.danger { border-color: var(--danger); color: var(--danger); }
1748
- `}#e=Ui();#t=new u(this.#e.query??"");#s=new u(this.#e.typeFilter??"all");#n=new u(this.#e.activeTags??[]);#r=new u(this.#e.activeFolders??[]);#g=new u([]);#a=new u(Oi);#i=new u(null);#l=new u(Di);#u=new u(!1);#h=new u("");#d=new u(!1);#o=new u(Mi());#f=new u("");#b=new u(!1);#k=new u(this.#e.sort??"mtime_desc");#x=new u(this.#e.deprecatedFilter??"all");#y=new u(this.#e.pausedFilter??"all");#v=new u(this.#e.dateFrom??"");#m=new u(this.#e.dateTo??"");#p=new u(new Set);#$=new u(qi());#w=new u(!1);#_=new u("entries");#P=new u([]);#A=new u(null);#R=new u(null);#T=new u(!1);#z=e=>this.#N(e);#L=()=>this.#q();constructor(){super(),new ce(this),pt(this.#$.value)}#F(e){this.#$.set(e),localStorage.setItem(Dt,e),pt(e)}#I(){const e=ge[(ge.indexOf(this.#$.value)+1)%ge.length];this.#F(e)}async#O(){if(!this.#w.value){this.#w.set(!0);try{await fetch("/api/rebuild-cache",{method:"POST"}),await Promise.all([this.#C(),this.#S(),this.#c()])}finally{this.#w.set(!1)}}}#D(e){e.preventDefault(),this.#b.set(!0),document.addEventListener("pointermove",this.#z),document.addEventListener("pointerup",this.#L)}#N(e){const t=this.renderRoot.querySelector(".body-region");if(!t)return;const s=t.getBoundingClientRect(),i=(e.clientX-s.left)/s.width*100;this.#o.set(Math.min(Ot,Math.max(It,i)))}#q(){this.#b.set(!1),document.removeEventListener("pointermove",this.#z),document.removeEventListener("pointerup",this.#L),localStorage.setItem(Lt,String(this.#o.value))}#U=new us(()=>{const e=new URLSearchParams;this.#s.value!=="all"&&e.set("type",this.#s.value),this.#t.value.trim()&&e.set("q",this.#t.value.trim());for(const t of this.#n.value)e.append("tag",t);for(const t of this.#r.value)e.append("folder",t);return this.#k.value!=="mtime_desc"&&e.set("sort",this.#k.value),this.#x.value==="hide"?e.set("deprecated","0"):this.#x.value==="only"&&e.set("deprecated","1"),this.#y.value==="hide"?e.set("paused","0"):this.#y.value==="only"&&e.set("paused","1"),this.#v.value&&e.set("date_from",this.#v.value),this.#m.value&&e.set("date_to",this.#m.value),e.toString()});#E=()=>this.#ne();#M=e=>this.#se(e);#K=e=>this.#ie(e);#Z=()=>this.#V();#W;connectedCallback(){super.connectedCallback(),this.#c(),this.#S(),this.#C(),window.addEventListener("focus",this.#E),document.addEventListener("visibilitychange",this.#E),document.addEventListener("folderfoo-file-open",this.#M),document.addEventListener("folderfoo-folder-changed",this.#K),window.addEventListener("folderfoo-auth-change",this.#Z),this.#re(),this.#V(),Li(),this.#W=zt.subscribe(()=>this.#C())}async#se(e){const t=e.detail?.name;if(!t)return;const s=zi(t);if(s.owner){this.#f.set(`"${s.name}" is from a shared folder — opening shared files here isn't supported yet.`);return}const{folderfooMode:i,folderfooHost:n}=await W();if(!(i==="off"||!n))try{const o=await fetch("/api/folderfoo/resolve-open",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({server:n,tenantId:oe,folderPath:s.folderPath,name:s.name})}),a=await o.json();if(!o.ok){this.#f.set(a.error??`couldn't open "${s.name}"`);return}this.#f.set(""),this.#i.set({table:a.table,id:a.id})}catch(o){this.#f.set(o.message)}}async#ie(e){const{path:t,action:s,newPath:i}=e.detail??{};if(!(t===void 0||!s)){if((s==="rename"||s==="move")&&i){const{folderfooHost:n}=await W();if(!n)return;try{await fetch("/api/folders/renamed",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({server:n,oldPath:t,newPath:i})})}catch{}}this.#C()}}async#re(){if(this.shadowRoot?.querySelector("folderfoo-profile-circle"))return;const{folderfooMode:e,folderfooHost:t}=await W();e==="off"||!t||ut(()=>import(`${t}/elements/folderfoo-profile-circle.js`),[]).then(async()=>{await this.updateComplete;const s=document.createElement("folderfoo-profile-circle");s.setAttribute("app-name","Memory Bucket"),s.setAttribute("tenant-id",oe),s.style.zoom="0.875",this.shadowRoot?.querySelector(".folderfoo-slot")?.appendChild(s)}).catch(s=>{console.warn("folderfoo-profile-circle unavailable:",s.message)})}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("focus",this.#E),document.removeEventListener("visibilitychange",this.#E),document.removeEventListener("folderfoo-file-open",this.#M),document.removeEventListener("folderfoo-folder-changed",this.#K),window.removeEventListener("folderfoo-auth-change",this.#Z),this.#W?.()}async#V(){let e=null;try{e=localStorage.getItem("folderfoo_token")}catch{return}if(!e){fetch("/api/folderfoo/logout",{method:"POST"}).catch(()=>{});return}const{folderfooMode:t,folderfooHost:s}=await W();t==="off"||!s||fetch("/api/folderfoo/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({server:s,token:e})}).catch(()=>{})}#j=!1;async#ne(){if(document.visibilityState==="visible"){if(this.#G().some(e=>e.remote)&&!this.#j){this.#j=!0;try{await fetch("/api/remote-folders/resync-all",{method:"POST"})}catch{}finally{this.#j=!1}}this.#c(),this.#S(),this.#C(),this.renderRoot.querySelector("detail-panel")?.refresh?.()}}async#c(){const e=this.#U.value;history.replaceState(null,"",e?`#${e}`:location.pathname+location.search);const t=await fetch(`/api/entries?${e}`);this.#g.set(await t.json()),this.renderRoot.querySelector("result-list")?.scrollTo(0,0)}async#S(){const e=this.#s.value==="all"?"":`?type=${this.#s.value}`,t=await fetch(`/api/facets${e}`);this.#a.set(await t.json())}async#C(){const t=await(await fetch("/api/folders")).json();this.#l.set(t),this.#d.set(!0);const s=new Set([...t.skill,...t.memory].map(n=>n.name)),i=this.#r.value.filter(n=>s.has(n));i.length!==this.#r.value.length&&(this.#r.set(i),this.#c())}#oe(e){this.#_.set(e),e==="channels"&&this.#Q()}async#Q(){const e=await fetch("/api/channels");this.#P.set(await e.json()),this.#A.value&&this.#J(this.#A.value)}async#J(e){this.#A.set(e),this.#T.set(!0);try{const t=await fetch(`/api/channels/${encodeURIComponent(e)}`);this.#R.set(t.ok?await t.json():null)}finally{this.#T.set(!1)}}#ae(e){const t=this.#r.value;this.#r.set(t.includes(e)?t.filter(s=>s!==e):[...t,e]),this.#c()}async#le(e,t){if(t.stopPropagation(),window.prompt(`Type "${e.name}" to remove this ${e.kind} folder (files on disk are untouched):`)===e.name){this.#h.set(e.name);try{await fetch(`/api/folders/${e.kind}/${encodeURIComponent(e.name)}`,{method:"DELETE"}),this.#r.set(this.#r.value.filter(i=>i!==e.name)),await Promise.all([this.#C(),this.#S(),this.#c()])}finally{this.#h.set("")}}}#Y(){this.#u.set(!1),this.#C(),this.#S(),this.#c()}#G(){return[...this.#l.value.skill,...this.#l.value.memory].sort((e,t)=>Number(e.remote)-Number(t.remote))}#ce(e){this.#s.set(e),this.#n.set([]),this.#S(),this.#c()}#he(e){const t=this.#n.value;this.#n.set(t.includes(e)?t.filter(s=>s!==e):[...t,e]),this.#c()}#de(e){this.#n.value.includes(e)||this.#n.set([...this.#n.value,e]),this.#c()}#pe(e){this.#r.value.includes(e)||this.#r.set([...this.#r.value,e]),this.#c()}#ue(e){this.#v.set(e),this.#m.set(e),this.#c()}#fe(e){this.#t.set(e.target.value),this.#c()}#X(e){this.#t.set(e),this.#c()}#ge(){this.#t.set(""),this.#c()}#be(e){this.#i.set({table:e._table,id:e.id})}#me(e){this.#k.set(e.target.value),this.#c()}#xe(e){this.#x.set(e.target.value),this.#c()}#ve(e){this.#y.set(e.target.value),this.#c()}#ye(e){this.#v.set(e.target.value),this.#c()}#ke(e){this.#m.set(e.target.value),this.#c()}#$e(){this.#v.set(""),this.#m.set(""),this.#c()}#we(e){const t=new Set(this.#p.value);t.has(e.id)?t.delete(e.id):t.add(e.id),this.#p.set(t)}#_e(){return new Map(this.#g.value.map(e=>[e.id,e]))}#H(){const e=new Map,t=this.#_e();for(const s of this.#p.value){const i=t.get(s);if(!i)continue;const n=e.get(i._table)??[];n.push(s),e.set(i._table,n)}return e}async#ee(e){const t=this.#H();await Promise.all([...t.entries()].map(([s,i])=>fetch(`/api/entries/${s}/bulk/deprecated`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({ids:i,deprecated:e})}))),this.#p.set(new Set),await this.#c()}async#te(e){const t=this.#H();await Promise.all([...t.entries()].map(([s,i])=>fetch(`/api/entries/${s}/bulk/paused`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({ids:i,paused:e})}))),this.#p.set(new Set),await this.#c()}async#Se(){if(!window.confirm(`Delete ${this.#p.value.size} doc(s)? This can't be undone.`))return;const e=this.#H();await Promise.all([...e.entries()].map(([t,s])=>fetch(`/api/entries/${t}/bulk/delete`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({ids:s})}))),this.#p.set(new Set),await this.#c()}#Ce(){const e=this.#$.value;return c`
1748
+ `}#e=Ui();#t=new u(this.#e.query??"");#s=new u(this.#e.typeFilter??"all");#n=new u(this.#e.activeTags??[]);#r=new u(this.#e.activeFolders??[]);#g=new u([]);#a=new u(Oi);#i=new u(null);#l=new u(Di);#u=new u(!1);#h=new u("");#d=new u(!1);#o=new u(Mi());#f=new u("");#b=new u(!1);#k=new u(this.#e.sort??"mtime_desc");#x=new u(this.#e.deprecatedFilter??"all");#y=new u(this.#e.pausedFilter??"all");#v=new u(this.#e.dateFrom??"");#m=new u(this.#e.dateTo??"");#p=new u(new Set);#$=new u(qi());#w=new u(!1);#_=new u("entries");#P=new u([]);#A=new u(null);#R=new u(null);#T=new u(!1);#z=e=>this.#N(e);#L=()=>this.#q();constructor(){super(),new ce(this),pt(this.#$.value)}#F(e){this.#$.set(e),localStorage.setItem(Dt,e),pt(e)}#I(){const e=ge[(ge.indexOf(this.#$.value)+1)%ge.length];this.#F(e)}async#O(){if(!this.#w.value){this.#w.set(!0);try{await fetch("/api/rebuild-cache",{method:"POST"}),await Promise.all([this.#C(),this.#S(),this.#c()])}finally{this.#w.set(!1)}}}#D(e){e.preventDefault(),this.#b.set(!0),document.addEventListener("pointermove",this.#z),document.addEventListener("pointerup",this.#L)}#N(e){const t=this.renderRoot.querySelector(".body-region");if(!t)return;const s=t.getBoundingClientRect(),i=(e.clientX-s.left)/s.width*100;this.#o.set(Math.min(Ot,Math.max(It,i)))}#q(){this.#b.set(!1),document.removeEventListener("pointermove",this.#z),document.removeEventListener("pointerup",this.#L),localStorage.setItem(Lt,String(this.#o.value))}#U=new us(()=>{const e=new URLSearchParams;this.#s.value!=="all"&&e.set("type",this.#s.value),this.#t.value.trim()&&e.set("q",this.#t.value.trim());for(const t of this.#n.value)e.append("tag",t);for(const t of this.#r.value)e.append("folder",t);return this.#k.value!=="mtime_desc"&&e.set("sort",this.#k.value),this.#x.value==="hide"?e.set("deprecated","0"):this.#x.value==="only"&&e.set("deprecated","1"),this.#y.value==="hide"?e.set("paused","0"):this.#y.value==="only"&&e.set("paused","1"),this.#v.value&&e.set("date_from",this.#v.value),this.#m.value&&e.set("date_to",this.#m.value),e.toString()});#E=()=>this.#Q();#M=e=>this.#ie(e);#K=e=>this.#re(e);#Z=()=>this.#V();#W;connectedCallback(){super.connectedCallback(),this.#c(),this.#S(),this.#C().then(()=>this.#Q()),window.addEventListener("focus",this.#E),document.addEventListener("visibilitychange",this.#E),document.addEventListener("folderfoo-file-open",this.#M),document.addEventListener("folderfoo-folder-changed",this.#K),window.addEventListener("folderfoo-auth-change",this.#Z),this.#ne(),this.#V(),Li(),this.#W=zt.subscribe(()=>this.#C())}async#ie(e){const t=e.detail?.name;if(!t)return;const s=zi(t);if(s.owner){this.#f.set(`"${s.name}" is from a shared folder — opening shared files here isn't supported yet.`);return}const{folderfooMode:i,folderfooHost:n}=await W();if(!(i==="off"||!n))try{const o=await fetch("/api/folderfoo/resolve-open",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({server:n,tenantId:oe,folderPath:s.folderPath,name:s.name})}),a=await o.json();if(!o.ok){this.#f.set(a.error??`couldn't open "${s.name}"`);return}this.#f.set(""),this.#i.set({table:a.table,id:a.id})}catch(o){this.#f.set(o.message)}}async#re(e){const{path:t,action:s,newPath:i}=e.detail??{};if(!(t===void 0||!s)){if((s==="rename"||s==="move")&&i){const{folderfooHost:n}=await W();if(!n)return;try{await fetch("/api/folders/renamed",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({server:n,oldPath:t,newPath:i})})}catch{}}this.#C()}}async#ne(){if(this.shadowRoot?.querySelector("folderfoo-profile-circle"))return;const{folderfooMode:e,folderfooHost:t}=await W();e==="off"||!t||ut(()=>import(`${t}/elements/folderfoo-profile-circle.js`),[]).then(async()=>{await this.updateComplete;const s=document.createElement("folderfoo-profile-circle");s.setAttribute("app-name","Memory Bucket"),s.setAttribute("tenant-id",oe),s.style.zoom="0.875",this.shadowRoot?.querySelector(".folderfoo-slot")?.appendChild(s)}).catch(s=>{console.warn("folderfoo-profile-circle unavailable:",s.message)})}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("focus",this.#E),document.removeEventListener("visibilitychange",this.#E),document.removeEventListener("folderfoo-file-open",this.#M),document.removeEventListener("folderfoo-folder-changed",this.#K),window.removeEventListener("folderfoo-auth-change",this.#Z),this.#W?.()}async#V(){let e=null;try{e=localStorage.getItem("folderfoo_token")}catch{return}if(!e){fetch("/api/folderfoo/logout",{method:"POST"}).catch(()=>{});return}const{folderfooMode:t,folderfooHost:s}=await W();t==="off"||!s||fetch("/api/folderfoo/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({server:s,token:e})}).catch(()=>{})}#j=!1;async#Q(){if(document.visibilityState==="visible"){if(this.#X().some(e=>e.remote)&&!this.#j){this.#j=!0;try{await fetch("/api/remote-folders/resync-all",{method:"POST"})}catch{}finally{this.#j=!1}}this.#c(),this.#S(),this.#C(),this.renderRoot.querySelector("detail-panel")?.refresh?.()}}async#c(){const e=this.#U.value;history.replaceState(null,"",e?`#${e}`:location.pathname+location.search);const t=await fetch(`/api/entries?${e}`);this.#g.set(await t.json()),this.renderRoot.querySelector("result-list")?.scrollTo(0,0)}async#S(){const e=this.#s.value==="all"?"":`?type=${this.#s.value}`,t=await fetch(`/api/facets${e}`);this.#a.set(await t.json())}async#C(){const t=await(await fetch("/api/folders")).json();this.#l.set(t),this.#d.set(!0);const s=new Set([...t.skill,...t.memory].map(n=>n.name)),i=this.#r.value.filter(n=>s.has(n));i.length!==this.#r.value.length&&(this.#r.set(i),this.#c())}#oe(e){this.#_.set(e),e==="channels"&&this.#J()}async#J(){const e=await fetch("/api/channels");this.#P.set(await e.json()),this.#A.value&&this.#Y(this.#A.value)}async#Y(e){this.#A.set(e),this.#T.set(!0);try{const t=await fetch(`/api/channels/${encodeURIComponent(e)}`);this.#R.set(t.ok?await t.json():null)}finally{this.#T.set(!1)}}#ae(e){const t=this.#r.value;this.#r.set(t.includes(e)?t.filter(s=>s!==e):[...t,e]),this.#c()}async#le(e,t){if(t.stopPropagation(),window.prompt(`Type "${e.name}" to remove this ${e.kind} folder (files on disk are untouched):`)===e.name){this.#h.set(e.name);try{await fetch(`/api/folders/${e.kind}/${encodeURIComponent(e.name)}`,{method:"DELETE"}),this.#r.set(this.#r.value.filter(i=>i!==e.name)),await Promise.all([this.#C(),this.#S(),this.#c()])}finally{this.#h.set("")}}}#G(){this.#u.set(!1),this.#C(),this.#S(),this.#c()}#X(){return[...this.#l.value.skill,...this.#l.value.memory].sort((e,t)=>Number(e.remote)-Number(t.remote))}#ce(e){this.#s.set(e),this.#n.set([]),this.#S(),this.#c()}#he(e){const t=this.#n.value;this.#n.set(t.includes(e)?t.filter(s=>s!==e):[...t,e]),this.#c()}#de(e){this.#n.value.includes(e)||this.#n.set([...this.#n.value,e]),this.#c()}#pe(e){this.#r.value.includes(e)||this.#r.set([...this.#r.value,e]),this.#c()}#ue(e){this.#v.set(e),this.#m.set(e),this.#c()}#fe(e){this.#t.set(e.target.value),this.#c()}#ee(e){this.#t.set(e),this.#c()}#ge(){this.#t.set(""),this.#c()}#be(e){this.#i.set({table:e._table,id:e.id})}#me(e){this.#k.set(e.target.value),this.#c()}#xe(e){this.#x.set(e.target.value),this.#c()}#ve(e){this.#y.set(e.target.value),this.#c()}#ye(e){this.#v.set(e.target.value),this.#c()}#ke(e){this.#m.set(e.target.value),this.#c()}#$e(){this.#v.set(""),this.#m.set(""),this.#c()}#we(e){const t=new Set(this.#p.value);t.has(e.id)?t.delete(e.id):t.add(e.id),this.#p.set(t)}#_e(){return new Map(this.#g.value.map(e=>[e.id,e]))}#H(){const e=new Map,t=this.#_e();for(const s of this.#p.value){const i=t.get(s);if(!i)continue;const n=e.get(i._table)??[];n.push(s),e.set(i._table,n)}return e}async#te(e){const t=this.#H();await Promise.all([...t.entries()].map(([s,i])=>fetch(`/api/entries/${s}/bulk/deprecated`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({ids:i,deprecated:e})}))),this.#p.set(new Set),await this.#c()}async#se(e){const t=this.#H();await Promise.all([...t.entries()].map(([s,i])=>fetch(`/api/entries/${s}/bulk/paused`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({ids:i,paused:e})}))),this.#p.set(new Set),await this.#c()}async#Se(){if(!window.confirm(`Delete ${this.#p.value.size} doc(s)? This can't be undone.`))return;const e=this.#H();await Promise.all([...e.entries()].map(([t,s])=>fetch(`/api/entries/${t}/bulk/delete`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({ids:s})}))),this.#p.set(new Set),await this.#c()}#Ce(){const e=this.#$.value;return c`
1749
1749
  <button
1750
1750
  class="theme-toggle"
1751
1751
  title=${`Theme: ${Ni[e]} (click to change)`}
@@ -1779,15 +1779,15 @@ This removes the doc's key, tags, and status — it drops out of key-based looku
1779
1779
  ${this.#Ce()}
1780
1780
  <div class="folderfoo-slot"></div>
1781
1781
  </div>
1782
- `}render(){const e=this.#a.value,t=this.#G();return this.#_.value==="channels"?c`
1782
+ `}render(){const e=this.#a.value,t=this.#X();return this.#_.value==="channels"?c`
1783
1783
  <div class="toolbar-bar">${this.#B(!1)}</div>
1784
1784
  <channel-view
1785
1785
  .channels=${this.#P.value}
1786
1786
  .selected=${this.#A.value}
1787
1787
  .detail=${this.#R.value}
1788
1788
  .loading=${this.#T.value}
1789
- .onSelect=${s=>this.#J(s)}
1790
- .onRefresh=${()=>this.#Q()}
1789
+ .onSelect=${s=>this.#Y(s)}
1790
+ .onRefresh=${()=>this.#J()}
1791
1791
  ></channel-view>
1792
1792
  `:this.#d.value&&t.length===0&&!this.#u.value?c`
1793
1793
  <div class="toolbar-bar">${this.#B(!1)}</div>
@@ -1802,7 +1802,7 @@ This removes the doc's key, tags, and status — it drops out of key-based looku
1802
1802
  ${this.#u.value?c`<add-folder-modal
1803
1803
  .defaultKind=${"skill"}
1804
1804
  .lockKind=${!1}
1805
- .onAdded=${()=>this.#Y()}
1805
+ .onAdded=${()=>this.#G()}
1806
1806
  .onCancel=${()=>this.#u.set(!1)}
1807
1807
  ></add-folder-modal>`:""}
1808
1808
  `:c`
@@ -1919,10 +1919,10 @@ This removes the doc's key, tags, and status — it drops out of key-based looku
1919
1919
  ${this.#p.value.size>0?c`
1920
1920
  <div class="bulk-bar">
1921
1921
  <span>${this.#p.value.size} selected</span>
1922
- <button @click=${()=>this.#ee(!0)}>Mark deprecated</button>
1923
- <button @click=${()=>this.#ee(!1)}>Un-deprecate</button>
1924
- <button @click=${()=>this.#te(!0)}>Pause</button>
1925
- <button @click=${()=>this.#te(!1)}>Resume</button>
1922
+ <button @click=${()=>this.#te(!0)}>Mark deprecated</button>
1923
+ <button @click=${()=>this.#te(!1)}>Un-deprecate</button>
1924
+ <button @click=${()=>this.#se(!0)}>Pause</button>
1925
+ <button @click=${()=>this.#se(!1)}>Resume</button>
1926
1926
  <button class="danger" @click=${()=>this.#Se()}>Delete</button>
1927
1927
  <button @click=${()=>this.#p.set(new Set)}>Clear</button>
1928
1928
  </div>
@@ -1935,7 +1935,7 @@ This removes the doc's key, tags, and status — it drops out of key-based looku
1935
1935
  .onSelect=${s=>this.#be(s)}
1936
1936
  .selectedIds=${this.#p.value}
1937
1937
  .onToggleSelect=${s=>this.#we(s)}
1938
- .onKeyClick=${s=>this.#X(s)}
1938
+ .onKeyClick=${s=>this.#ee(s)}
1939
1939
  ></result-list>
1940
1940
  <div
1941
1941
  class="splitter ${this.#b.value?"dragging":""}"
@@ -1948,13 +1948,13 @@ This removes the doc's key, tags, and status — it drops out of key-based looku
1948
1948
  .onTagClick=${s=>this.#de(s)}
1949
1949
  .onFolderClick=${s=>this.#pe(s)}
1950
1950
  .onDateClick=${s=>this.#ue(s)}
1951
- .onKeyClick=${s=>this.#X(s)}
1951
+ .onKeyClick=${s=>this.#ee(s)}
1952
1952
  ></detail-panel>
1953
1953
  </div>
1954
1954
  ${this.#u.value?c`<add-folder-modal
1955
1955
  .defaultKind=${"skill"}
1956
1956
  .lockKind=${!1}
1957
- .onAdded=${()=>this.#Y()}
1957
+ .onAdded=${()=>this.#G()}
1958
1958
  .onCancel=${()=>this.#u.set(!1)}
1959
1959
  ></add-folder-modal>`:""}
1960
1960
  `}}customElements.define("mem-bucket-app",ji);
@@ -33,7 +33,7 @@
33
33
  z-index: 2147483000;
34
34
  }
35
35
  </style>
36
- <script type="module" crossorigin src="/assets/index-BuYlp268.js"></script>
36
+ <script type="module" crossorigin src="/assets/index-y6XKwUMi.js"></script>
37
37
  </head>
38
38
  <body>
39
39
  <mem-bucket-app></mem-bucket-app>
@@ -64,6 +64,14 @@ const attachmentRepo = new AttachmentRepository(memoryRepo, skillRepo);
64
64
  // same upsertFile/removeFile path a local file-watch event would.
65
65
  const remoteSkillPoller = config.remoteSkillFolders.length > 0 ? startRemotePolling(db, skillSpec, config.remoteSkillFolders, config.baseDir) : undefined;
66
66
  const remoteMemoryPoller = config.remoteMemoryFolders.length > 0 ? startRemotePolling(db, memorySpec, config.remoteMemoryFolders, config.baseDir) : undefined;
67
+ // Forces one immediate poll of every remote source at process start, instead
68
+ // of leaving the cache to show whatever was last synced until the first
69
+ // fixed interval tick (up to POLL_INTERVAL_MS later) - this is effectively
70
+ // "login" for a background server: a fresh process (laptop wake, editor
71
+ // reopened) is exactly when another device's writes are most likely to be
72
+ // unseen locally yet.
73
+ remoteSkillPoller?.resyncAll().catch((err) => console.error('[memory-bucket] initial remote skill resync failed:', err));
74
+ remoteMemoryPoller?.resyncAll().catch((err) => console.error('[memory-bucket] initial remote memory resync failed:', err));
67
75
  if (config.skillFolders.length === 0 && config.memoryFolders.length === 0) {
68
76
  console.error(`[memory-bucket] no folders configured — open http://localhost:${PORT} to add one`);
69
77
  }
@@ -840,6 +840,12 @@ export function buildWebRouter(db, config, skillRepo, memoryRepo, skillSpec, mem
840
840
  // already-stamped entries become visible.
841
841
  identity.setUsername(decodeUsername(token));
842
842
  res.json({ connected: true, server });
843
+ // Force-resyncs every remote source now that this identity's folders are
844
+ // visible again, rather than leaving them showing whatever was last
845
+ // synced until the next fixed poll tick or tab-focus resync. Fired after
846
+ // responding (best-effort, same posture as the rest of this route) so
847
+ // login doesn't wait on a round trip to every remote source.
848
+ Promise.all([remotePollers?.skill?.resyncAll(), remotePollers?.memory?.resyncAll()]).catch(() => { });
843
849
  });
844
850
  // Signals that the browser's folderfoo login session just ended (the page
845
851
  // detects folderfoo's own auth-change event going to logged-out) - clears
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-memory-bucket",
3
- "version": "0.8.5",
3
+ "version": "0.8.7",
4
4
  "type": "module",
5
5
  "description": "MCP server exposing skill_* (reusable coding patterns) and memory_* (point-in-time working context) tools over a markdown+frontmatter source, cached into SQLite at runtime.",
6
6
  "repository": {