@memtensor/memos-local-openclaw-plugin 0.3.17 → 0.3.19

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 (74) hide show
  1. package/README.md +21 -11
  2. package/dist/capture/index.d.ts +1 -1
  3. package/dist/capture/index.d.ts.map +1 -1
  4. package/dist/capture/index.js +7 -2
  5. package/dist/capture/index.js.map +1 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +2 -2
  9. package/dist/index.js.map +1 -1
  10. package/dist/ingest/dedup.d.ts +2 -2
  11. package/dist/ingest/dedup.d.ts.map +1 -1
  12. package/dist/ingest/dedup.js +4 -4
  13. package/dist/ingest/dedup.js.map +1 -1
  14. package/dist/ingest/task-processor.d.ts +1 -1
  15. package/dist/ingest/task-processor.d.ts.map +1 -1
  16. package/dist/ingest/task-processor.js +14 -13
  17. package/dist/ingest/task-processor.js.map +1 -1
  18. package/dist/ingest/worker.d.ts.map +1 -1
  19. package/dist/ingest/worker.js +7 -3
  20. package/dist/ingest/worker.js.map +1 -1
  21. package/dist/recall/engine.d.ts +5 -1
  22. package/dist/recall/engine.d.ts.map +1 -1
  23. package/dist/recall/engine.js +77 -2
  24. package/dist/recall/engine.js.map +1 -1
  25. package/dist/skill/evolver.d.ts +2 -1
  26. package/dist/skill/evolver.d.ts.map +1 -1
  27. package/dist/skill/evolver.js +2 -2
  28. package/dist/skill/evolver.js.map +1 -1
  29. package/dist/skill/generator.d.ts +3 -1
  30. package/dist/skill/generator.d.ts.map +1 -1
  31. package/dist/skill/generator.js +15 -1
  32. package/dist/skill/generator.js.map +1 -1
  33. package/dist/storage/sqlite.d.ts +24 -8
  34. package/dist/storage/sqlite.d.ts.map +1 -1
  35. package/dist/storage/sqlite.js +233 -28
  36. package/dist/storage/sqlite.js.map +1 -1
  37. package/dist/storage/vector.d.ts +1 -1
  38. package/dist/storage/vector.d.ts.map +1 -1
  39. package/dist/storage/vector.js +3 -3
  40. package/dist/storage/vector.js.map +1 -1
  41. package/dist/telemetry.d.ts.map +1 -1
  42. package/dist/telemetry.js +3 -3
  43. package/dist/telemetry.js.map +1 -1
  44. package/dist/types.d.ts +16 -0
  45. package/dist/types.d.ts.map +1 -1
  46. package/dist/types.js.map +1 -1
  47. package/dist/viewer/html.d.ts +1 -1
  48. package/dist/viewer/html.d.ts.map +1 -1
  49. package/dist/viewer/html.js +107 -1
  50. package/dist/viewer/html.js.map +1 -1
  51. package/dist/viewer/server.d.ts +1 -0
  52. package/dist/viewer/server.d.ts.map +1 -1
  53. package/dist/viewer/server.js +52 -3
  54. package/dist/viewer/server.js.map +1 -1
  55. package/index.ts +171 -7
  56. package/package.json +1 -1
  57. package/scripts/postinstall.cjs +31 -15
  58. package/skill/browserwing-admin/SKILL.md +521 -0
  59. package/skill/browserwing-executor/SKILL.md +510 -0
  60. package/skill/memos-memory-guide/SKILL.md +62 -36
  61. package/src/capture/index.ts +7 -1
  62. package/src/index.ts +3 -2
  63. package/src/ingest/dedup.ts +4 -2
  64. package/src/ingest/task-processor.ts +14 -13
  65. package/src/ingest/worker.ts +7 -3
  66. package/src/recall/engine.ts +94 -4
  67. package/src/skill/evolver.ts +3 -1
  68. package/src/skill/generator.ts +15 -0
  69. package/src/storage/sqlite.ts +262 -34
  70. package/src/storage/vector.ts +3 -2
  71. package/src/telemetry.ts +3 -3
  72. package/src/types.ts +18 -0
  73. package/src/viewer/html.ts +107 -1
  74. package/src/viewer/server.ts +48 -3
@@ -1 +1 @@
1
- {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/viewer/html.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,+9mOA8rHf,CAAC"}
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/viewer/html.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,i0zOAwyHf,CAAC"}
@@ -185,6 +185,13 @@ input,textarea,select{font-family:inherit;font-size:inherit}
185
185
  .dedup-badge.merged{background:rgba(59,130,246,.12);color:#60a5fa}
186
186
  .import-badge{display:inline-flex;align-items:center;gap:4px;background:rgba(236,72,153,.1);color:#ec4899;font-size:10px;font-weight:600;padding:3px 10px;border-radius:8px}
187
187
  [data-theme="light"] .import-badge{background:rgba(219,39,119,.08);color:#db2777}
188
+ .owner-badge{display:inline-flex;align-items:center;gap:3px;font-size:10px;font-weight:600;padding:3px 10px;border-radius:8px}
189
+ .owner-badge.public{background:rgba(52,211,153,.12);color:#34d399}
190
+ .owner-badge.agent{background:rgba(255,255,255,.06);color:var(--text-sec)}
191
+ [data-theme="light"] .owner-badge.public{background:rgba(16,185,129,.08);color:#059669}
192
+ [data-theme="light"] .owner-badge.agent{background:rgba(0,0,0,.04);color:var(--text-sec)}
193
+ .skill-badge.visibility-public{background:rgba(0,229,255,.12);color:#00bcd4}
194
+ [data-theme="light"] .skill-badge.visibility-public{background:rgba(0,172,193,.08);color:#00838f}
188
195
  .memory-card.dedup-inactive{opacity:.55;border-style:dashed}
189
196
  .memory-card.dedup-inactive:hover{opacity:.85}
190
197
  .dedup-target-link{font-size:11px;color:var(--pri);cursor:pointer;text-decoration:underline;margin-left:4px}
@@ -388,6 +395,11 @@ input,textarea,select{font-family:inherit;font-size:inherit}
388
395
  .skill-file-size{font-size:10px;color:var(--text-muted)}
389
396
  .skill-download-btn{display:inline-flex;align-items:center;gap:6px;padding:6px 14px;border-radius:8px;background:var(--pri-grad);color:#fff;font-size:12px;font-weight:600;border:none;cursor:pointer;transition:all .2s}
390
397
  .skill-download-btn:hover{opacity:.85;transform:translateY(-1px)}
398
+ .skill-vis-btn{display:inline-flex;align-items:center;gap:6px;padding:6px 14px;border-radius:8px;font-size:12px;font-weight:600;border:none;cursor:pointer;transition:all .2s}
399
+ .skill-vis-btn:hover{opacity:.85;transform:translateY(-1px)}
400
+ .skill-vis-btn.is-public{background:linear-gradient(135deg,#34d399,#10b981);color:#fff}
401
+ .skill-vis-btn.is-private{background:var(--pri-grad);color:#fff}
402
+ .mem-public-btn{color:var(--pri)!important}
391
403
  .task-skill-section{margin-bottom:16px;padding:14px 16px;border-radius:var(--radius);border:1px solid var(--border)}
392
404
  .task-skill-section.status-generated{border-color:var(--green);background:var(--green-bg)}
393
405
  .task-skill-section.status-generating{border-color:var(--amber);background:var(--amber-bg)}
@@ -763,6 +775,11 @@ input,textarea,select{font-family:inherit;font-size:inherit}
763
775
  <option value="newest" data-i18n="filter.newest">Newest first</option>
764
776
  <option value="oldest" data-i18n="filter.oldest">Oldest first</option>
765
777
  </select>
778
+ <span class="filter-sep"></span>
779
+ <select id="filterOwner" class="filter-select" onchange="applyFilters()">
780
+ <option value="" data-i18n="filter.allowners">All owners</option>
781
+ <option value="public" data-i18n="filter.public">Public</option>
782
+ </select>
766
783
  </div>
767
784
  <div class="date-filter">
768
785
  <label data-i18n="filter.from">From</label><input type="datetime-local" id="dateFrom" step="1" onchange="applyFilters()">
@@ -812,12 +829,19 @@ input,textarea,select{font-family:inherit;font-size:inherit}
812
829
  <div class="tasks-stat" style="border-left:3px solid var(--green)"><span class="tasks-stat-value" id="skillsActiveCount">-</span><span class="tasks-stat-label" data-i18n="skills.active">Active</span></div>
813
830
  <div class="tasks-stat" style="border-left:3px solid var(--amber)"><span class="tasks-stat-value" id="skillsDraftCount">-</span><span class="tasks-stat-label" data-i18n="skills.draft">Draft</span></div>
814
831
  <div class="tasks-stat" style="border-left:3px solid var(--violet)"><span class="tasks-stat-value" id="skillsInstalledCount">-</span><span class="tasks-stat-label" data-i18n="skills.installed">Installed</span></div>
832
+ <div class="tasks-stat" style="border-left:3px solid var(--cyan)"><span class="tasks-stat-value" id="skillsPublicCount">-</span><span class="tasks-stat-label" data-i18n="skills.public">Public</span></div>
815
833
  </div>
816
834
  <div class="tasks-filters">
817
835
  <button class="filter-chip active" data-skill-status="" onclick="setSkillStatusFilter(this,'')" data-i18n="filter.all">All</button>
818
836
  <button class="filter-chip" data-skill-status="active" onclick="setSkillStatusFilter(this,'active')" data-i18n="skills.filter.active">Active</button>
819
837
  <button class="filter-chip" data-skill-status="draft" onclick="setSkillStatusFilter(this,'draft')" data-i18n="skills.filter.draft">Draft</button>
820
838
  <button class="filter-chip" data-skill-status="archived" onclick="setSkillStatusFilter(this,'archived')" data-i18n="skills.filter.archived">Archived</button>
839
+ <span class="filter-sep"></span>
840
+ <select id="skillVisibilityFilter" class="filter-select" onchange="loadSkills()">
841
+ <option value="" data-i18n="filter.allvisibility">All visibility</option>
842
+ <option value="public" data-i18n="filter.public">Public</option>
843
+ <option value="private" data-i18n="filter.private">Private</option>
844
+ </select>
821
845
  <button class="btn btn-sm btn-ghost" onclick="loadSkills()" style="margin-left:auto" data-i18n="refresh">\u21BB Refresh</button>
822
846
  </div>
823
847
  </div>
@@ -828,6 +852,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
828
852
  <div class="task-detail-header">
829
853
  <h2 id="skillDetailTitle"></h2>
830
854
  <div style="display:flex;gap:8px;align-items:center">
855
+ <button class="skill-vis-btn" id="skillVisibilityBtn" onclick="toggleSkillVisibility()"></button>
831
856
  <button class="skill-download-btn" id="skillDownloadBtn" onclick="downloadSkill()" data-i18n="skills.download">\u2B07 Download</button>
832
857
  <button class="btn btn-icon" onclick="closeSkillDetail()" title="Close">\u2715</button>
833
858
  </div>
@@ -1272,6 +1297,11 @@ const I18N={
1272
1297
  'skills.total':'Total Skills',
1273
1298
  'skills.active':'Active',
1274
1299
  'skills.installed':'Installed',
1300
+ 'skills.public':'Public',
1301
+ 'skills.visibility.public':'Public',
1302
+ 'skills.visibility.private':'Private',
1303
+ 'skills.setPublic':'Set Public',
1304
+ 'skills.setPrivate':'Set Private',
1275
1305
  'tasks.total':'Total Tasks',
1276
1306
  'tasks.active':'Active',
1277
1307
  'tasks.completed':'Completed',
@@ -1310,6 +1340,10 @@ const I18N={
1310
1340
  'filter.command':'Command',
1311
1341
  'filter.newest':'Newest first',
1312
1342
  'filter.oldest':'Oldest first',
1343
+ 'filter.allowners':'All owners',
1344
+ 'filter.public':'Public',
1345
+ 'filter.private':'Private',
1346
+ 'filter.allvisibility':'All visibility',
1313
1347
  'filter.from':'From',
1314
1348
  'filter.to':'To',
1315
1349
  'filter.clear':'Clear',
@@ -1361,6 +1395,8 @@ const I18N={
1361
1395
  'toast.deleted':'Memory deleted',
1362
1396
  'toast.opfail':'Operation failed',
1363
1397
  'toast.delfail':'Delete failed',
1398
+ 'toast.setPublic':'Set to public',
1399
+ 'toast.setPrivate':'Set to private',
1364
1400
  'toast.cleared':'All memories cleared',
1365
1401
  'toast.clearfail':'Clear failed',
1366
1402
  'toast.notfound':'Memory not found in cache',
@@ -1532,6 +1568,11 @@ const I18N={
1532
1568
  'skills.total':'技能总数',
1533
1569
  'skills.active':'生效中',
1534
1570
  'skills.installed':'已安装',
1571
+ 'skills.public':'公开',
1572
+ 'skills.visibility.public':'公开',
1573
+ 'skills.visibility.private':'私有',
1574
+ 'skills.setPublic':'设为公开',
1575
+ 'skills.setPrivate':'设为私有',
1535
1576
  'tasks.total':'任务总数',
1536
1577
  'tasks.active':'进行中',
1537
1578
  'tasks.completed':'已完成',
@@ -1570,6 +1611,10 @@ const I18N={
1570
1611
  'filter.command':'命令',
1571
1612
  'filter.newest':'最新优先',
1572
1613
  'filter.oldest':'最早优先',
1614
+ 'filter.allowners':'所有归属',
1615
+ 'filter.public':'公开',
1616
+ 'filter.private':'私有',
1617
+ 'filter.allvisibility':'所有可见性',
1573
1618
  'filter.from':'起始',
1574
1619
  'filter.to':'截止',
1575
1620
  'filter.clear':'清除',
@@ -1621,6 +1666,8 @@ const I18N={
1621
1666
  'toast.deleted':'记忆已删除',
1622
1667
  'toast.opfail':'操作失败',
1623
1668
  'toast.delfail':'删除失败',
1669
+ 'toast.setPublic':'已设为公开',
1670
+ 'toast.setPrivate':'已设为私有',
1624
1671
  'toast.cleared':'所有记忆已清除',
1625
1672
  'toast.clearfail':'清除失败',
1626
1673
  'toast.notfound':'缓存中未找到此记忆',
@@ -2312,6 +2359,8 @@ async function loadSkills(){
2312
2359
  try{
2313
2360
  const params=new URLSearchParams();
2314
2361
  if(skillsStatusFilter) params.set('status',skillsStatusFilter);
2362
+ const visFilter=document.getElementById('skillVisibilityFilter')?.value;
2363
+ if(visFilter) params.set('visibility',visFilter);
2315
2364
  const r=await fetch('/api/skills?'+params);
2316
2365
  const data=await r.json();
2317
2366
 
@@ -2319,6 +2368,7 @@ async function loadSkills(){
2319
2368
  document.getElementById('skillsActiveCount').textContent=formatNum(data.skills.filter(s=>s.status==='active').length);
2320
2369
  document.getElementById('skillsDraftCount').textContent=formatNum(data.skills.filter(s=>s.status==='draft').length);
2321
2370
  document.getElementById('skillsInstalledCount').textContent=formatNum(data.skills.filter(s=>s.installed).length);
2371
+ document.getElementById('skillsPublicCount').textContent=formatNum(data.skills.filter(s=>s.visibility==='public').length);
2322
2372
 
2323
2373
  if(!data.skills||data.skills.length===0){
2324
2374
  list.innerHTML='<div style="text-align:center;padding:48px;color:var(--text-muted);font-size:14px">'+t('skills.empty')+'</div>';
@@ -2332,12 +2382,14 @@ async function loadSkills(){
2332
2382
  const statusClass=skill.status==='archived'?'archived':(skill.status==='draft'?'draft':'');
2333
2383
  const qs=skill.qualityScore;
2334
2384
  const qsBadge=qs!==null&&qs!==undefined?'<span class="skill-badge quality '+(qs>=7?'high':qs>=5?'mid':'low')+'">\\u2605 '+qs.toFixed(1)+'</span>':'';
2385
+ const visBadge=skill.visibility==='public'?'<span class="skill-badge visibility-public">\\u{1F310} '+t('skills.visibility.public')+'</span>':'';
2335
2386
  return '<div class="skill-card '+installedClass+' '+statusClass+'" onclick="openSkillDetail(\\''+skill.id+'\\')">'+
2336
2387
  '<div class="skill-card-top">'+
2337
2388
  '<div class="skill-card-name">\\u{1F9E0} '+esc(skill.name)+'</div>'+
2338
2389
  '<div class="skill-card-badges">'+
2339
2390
  qsBadge+
2340
2391
  '<span class="skill-badge version">v'+skill.version+'</span>'+
2392
+ visBadge+
2341
2393
  (skill.installed?'<span class="skill-badge installed">'+t('skills.installed.badge')+'</span>':'')+
2342
2394
  '<span class="skill-badge status-'+skill.status+'">'+t('skills.status.'+skill.status)+'</span>'+
2343
2395
  '</div>'+
@@ -2392,15 +2444,29 @@ async function openSkillDetail(skillId){
2392
2444
 
2393
2445
  const qs=skill.qualityScore;
2394
2446
  const qsBadge=qs!==null&&qs!==undefined?'<span class="meta-item"><span class="skill-badge quality '+(qs>=7?'high':qs>=5?'mid':'low')+'">\\u2605 '+qs.toFixed(1)+'/10</span></span>':'';
2447
+ const visMeta=skill.visibility==='public'?'<span class="meta-item"><span class="skill-badge visibility-public">\\u{1F310} '+t('skills.visibility.public')+'</span></span>':'<span class="meta-item"><span class="skill-badge">\\u{1F512} '+t('skills.visibility.private')+'</span></span>';
2395
2448
  document.getElementById('skillDetailMeta').innerHTML=[
2396
2449
  '<span class="meta-item"><span class="skill-badge version">v'+skill.version+'</span></span>',
2397
2450
  '<span class="meta-item"><span class="skill-badge status-'+skill.status+'">'+t('skills.status.'+skill.status)+'</span></span>',
2451
+ visMeta,
2398
2452
  qsBadge,
2399
2453
  skill.installed?'<span class="meta-item"><span class="skill-badge installed">'+t('skills.installed.badge')+'</span></span>':'',
2400
2454
  '<span class="meta-item">\\u{1F4C5} '+formatTime(skill.createdAt)+'</span>',
2401
2455
  '<span class="meta-item">\\u270F '+t('skills.updated')+formatTime(skill.updatedAt)+'</span>',
2402
2456
  ].filter(Boolean).join('');
2403
2457
 
2458
+ const visBtn=document.getElementById('skillVisibilityBtn');
2459
+ visBtn.className='skill-vis-btn';
2460
+ if(skill.visibility==='public'){
2461
+ visBtn.textContent='\\u{1F512} '+t('skills.setPrivate');
2462
+ visBtn.classList.add('is-public');
2463
+ visBtn.dataset.vis='public';
2464
+ } else {
2465
+ visBtn.textContent='\\u{1F310} '+t('skills.setPublic');
2466
+ visBtn.classList.add('is-private');
2467
+ visBtn.dataset.vis='private';
2468
+ }
2469
+
2404
2470
  document.getElementById('skillDetailDesc').textContent=skill.description;
2405
2471
 
2406
2472
  if(files.length>0){
@@ -2467,6 +2533,20 @@ function downloadSkill(){
2467
2533
  window.open('/api/skill/'+currentSkillId+'/download','_blank');
2468
2534
  }
2469
2535
 
2536
+ async function toggleSkillVisibility(){
2537
+ if(!currentSkillId) return;
2538
+ const btn=document.getElementById('skillVisibilityBtn');
2539
+ const newVis=btn.dataset.vis==='public'?'private':'public';
2540
+ try{
2541
+ const r=await fetch('/api/skill/'+currentSkillId+'/visibility',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify({visibility:newVis})});
2542
+ if(!r.ok) throw new Error('Failed: '+r.status);
2543
+ openSkillDetail(currentSkillId);
2544
+ loadSkills();
2545
+ }catch(e){
2546
+ alert('Error: '+e.message);
2547
+ }
2548
+ }
2549
+
2470
2550
  /* ─── Settings / Config ─── */
2471
2551
  async function loadConfig(){
2472
2552
  try{
@@ -2914,6 +2994,16 @@ async function loadStats(){
2914
2994
  const name=s.session_key.length>20?s.session_key.slice(0,8)+'...'+s.session_key.slice(-8):s.session_key;
2915
2995
  sl.innerHTML+='<div class="session-item'+(isActive?' active':'')+'" onclick="filterSession(\\''+s.session_key.replace(/'/g,"\\\\'")+'\\')"><span title="'+s.session_key+'">'+name+'</span><span class="count">'+s.count+'</span></div>';
2916
2996
  });
2997
+
2998
+ const ownerSel=document.getElementById('filterOwner');
2999
+ if(ownerSel && d.owners && d.owners.length>0){
3000
+ const curVal=ownerSel.value;
3001
+ ownerSel.innerHTML='<option value="">'+t('filter.allowners')+'</option>'+'<option value="public">'+t('filter.public')+'</option>';
3002
+ d.owners.filter(o=>o && o!=='public').forEach(o=>{
3003
+ ownerSel.innerHTML+='<option value="'+o+'">'+o+'</option>';
3004
+ });
3005
+ ownerSel.value=curVal;
3006
+ }
2917
3007
  }
2918
3008
 
2919
3009
  function getFilterParams(){
@@ -2928,6 +3018,8 @@ function getFilterParams(){
2928
3018
  if(dt) p.set('dateTo',dt);
2929
3019
  const sort=document.getElementById('filterSort').value;
2930
3020
  if(sort==='oldest') p.set('sort','oldest');
3021
+ const owner=document.getElementById('filterOwner').value;
3022
+ if(owner) p.set('owner',owner);
2931
3023
  return p;
2932
3024
  }
2933
3025
 
@@ -3031,6 +3123,9 @@ function renderMemories(items){
3031
3123
  const dedupBadge=ds==='duplicate'?'<span class="dedup-badge duplicate">'+t('card.dedupDuplicate')+'</span>':ds==='merged'?'<span class="dedup-badge merged">'+t('card.dedupMerged')+'</span>':'';
3032
3124
  const isImported=sid.startsWith('openclaw-import-')||sid.startsWith('openclaw-session-');
3033
3125
  const importBadge=isImported?'<span class="import-badge">\u{1F990} '+t('card.imported')+'</span>':'';
3126
+ const ownerVal=m.owner||'agent:main';
3127
+ const isPublicMem=ownerVal==='public';
3128
+ const ownerBadge=isPublicMem?'<span class="owner-badge public">\\u{1F310} '+t('filter.public')+'</span>':'<span class="owner-badge agent">\\u{1F512} '+t('filter.private')+'</span>';
3034
3129
  let dedupInfo='';
3035
3130
  if(isInactive){
3036
3131
  const reason=m.dedup_reason?'<span style="font-size:11px;color:var(--text-muted)">'+t('card.dedupReason')+esc(m.dedup_reason)+'</span>':'';
@@ -3055,7 +3150,7 @@ function renderMemories(items){
3055
3150
  }catch(e){}
3056
3151
  }
3057
3152
  return '<div class="memory-card'+(isInactive?' dedup-inactive':'')+'">'+
3058
- '<div class="card-header"><div class="meta"><span class="role-tag '+role+'">'+role+'</span><span class="kind-tag">'+kind+'</span>'+importBadge+dedupBadge+mergeBadge+'</div><span class="card-time"><span class="session-tag" title="'+esc(sid)+'">'+esc(sidShort)+'</span> '+time+updatedAt+'</span></div>'+
3153
+ '<div class="card-header"><div class="meta"><span class="role-tag '+role+'">'+role+'</span><span class="kind-tag">'+kind+'</span>'+ownerBadge+importBadge+dedupBadge+mergeBadge+'</div><span class="card-time"><span class="session-tag" title="'+esc(sid)+'">'+esc(sidShort)+'</span> '+time+updatedAt+'</span></div>'+
3059
3154
  '<div class="card-summary">'+summary+'</div>'+
3060
3155
  dedupInfo+
3061
3156
  '<div class="card-content" id="content-'+id+'"><pre>'+content+'</pre></div>'+
@@ -3064,6 +3159,7 @@ function renderMemories(items){
3064
3159
  '<button class="btn btn-sm btn-ghost" onclick="toggleContent(\\''+id+'\\')">'+t('card.expand')+'</button>'+
3065
3160
  (mc>0?'<button class="btn btn-sm btn-ghost" onclick="toggleHistory(\\''+id+'\\')">'+t('card.evolveHistory')+'</button>':'')+
3066
3161
  '<button class="btn btn-sm btn-ghost" onclick="openEditModal(\\''+id+'\\')">'+t('card.edit')+'</button>'+
3162
+ (isPublicMem?'<button class="btn btn-sm btn-ghost" onclick="toggleMemoryPublic(\\''+id+'\\',false)">\\u{1F512} '+t('skills.setPrivate')+'</button>':'<button class="btn btn-sm btn-ghost mem-public-btn" onclick="toggleMemoryPublic(\\''+id+'\\',true)">\\u{1F310} '+t('skills.setPublic')+'</button>')+
3067
3163
  '<button class="btn btn-sm btn-ghost" style="color:var(--accent)" onclick="deleteMemory(\\''+id+'\\')">'+t('card.delete')+'</button>'+
3068
3164
  vscore+
3069
3165
  '</div></div>';
@@ -3252,6 +3348,16 @@ async function deleteMemory(id){
3252
3348
  else{toast(t('toast.delfail'),'error')}
3253
3349
  }
3254
3350
 
3351
+ async function toggleMemoryPublic(id,setPublic){
3352
+ const newOwner=setPublic?'public':'agent:main';
3353
+ try{
3354
+ const r=await fetch('/api/memory/'+id,{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify({owner:newOwner})});
3355
+ const d=await r.json();
3356
+ if(d.ok){toast(setPublic?t('toast.setPublic'):t('toast.setPrivate'),'success');loadAll();}
3357
+ else{toast(d.error||t('toast.opfail'),'error')}
3358
+ }catch(e){toast('Error: '+e.message,'error')}
3359
+ }
3360
+
3255
3361
  async function clearAll(){
3256
3362
  if(!confirm(t('confirm.clearall')))return;
3257
3363
  if(!confirm(t('confirm.clearall2')))return;
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/viewer/html.ts"],"names":[],"mappings":";;;AAAa,QAAA,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA8rHlB,CAAC"}
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/viewer/html.ts"],"names":[],"mappings":";;;AAAa,QAAA,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAwyHlB,CAAC"}
@@ -57,6 +57,7 @@ export declare class ViewerServer {
57
57
  private serveSkillFiles;
58
58
  private walkDir;
59
59
  private serveSkillDownload;
60
+ private handleSkillVisibility;
60
61
  private handleCreate;
61
62
  private serveMemoryDetail;
62
63
  private handleUpdate;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/viewer/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/viewer/server.ts"],"names":[],"mappings":"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"}
@@ -176,6 +176,8 @@ class ViewerServer {
176
176
  this.serveSkillDownload(res, p);
177
177
  else if (p.match(/^\/api\/skill\/[^/]+\/files$/) && req.method === "GET")
178
178
  this.serveSkillFiles(res, p);
179
+ else if (p.match(/^\/api\/skill\/[^/]+\/visibility$/) && req.method === "PUT")
180
+ this.handleSkillVisibility(req, res, p);
179
181
  else if (p.startsWith("/api/skill/") && req.method === "GET")
180
182
  this.serveSkillDetail(res, p);
181
183
  else if (p === "/api/memory" && req.method === "POST")
@@ -339,6 +341,7 @@ class ViewerServer {
339
341
  const kind = url.searchParams.get("kind") ?? undefined;
340
342
  const dateFrom = url.searchParams.get("dateFrom") ?? undefined;
341
343
  const dateTo = url.searchParams.get("dateTo") ?? undefined;
344
+ const owner = url.searchParams.get("owner") ?? undefined;
342
345
  const sortBy = url.searchParams.get("sort") === "oldest" ? "ASC" : "DESC";
343
346
  const db = this.store.db;
344
347
  const conditions = [];
@@ -355,6 +358,10 @@ class ViewerServer {
355
358
  conditions.push("kind = ?");
356
359
  params.push(kind);
357
360
  }
361
+ if (owner) {
362
+ conditions.push("owner = ?");
363
+ params.push(owner);
364
+ }
358
365
  if (dateFrom) {
359
366
  conditions.push("created_at >= ?");
360
367
  params.push(new Date(dateFrom).getTime());
@@ -482,6 +489,12 @@ class ViewerServer {
482
489
  dedupBreakdown = Object.fromEntries(dedupRows.map((d) => [d.dedup_status ?? "active", d.count]));
483
490
  }
484
491
  catch { /* column may not exist yet */ }
492
+ let owners = [];
493
+ try {
494
+ const ownerRows = db.prepare("SELECT DISTINCT owner FROM chunks WHERE owner IS NOT NULL ORDER BY owner").all();
495
+ owners = ownerRows.map((o) => o.owner);
496
+ }
497
+ catch { /* column may not exist yet */ }
485
498
  this.jsonResponse(res, {
486
499
  totalMemories: total.count, totalSessions: sessions.count, totalEmbeddings: embCount,
487
500
  totalSkills: skillCount,
@@ -491,6 +504,7 @@ class ViewerServer {
491
504
  dedupBreakdown,
492
505
  timeRange: { earliest: timeRange.earliest, latest: timeRange.latest },
493
506
  sessions: sessionList,
507
+ owners,
494
508
  });
495
509
  }
496
510
  catch (e) {
@@ -570,7 +584,11 @@ class ViewerServer {
570
584
  // ─── Skills API ───
571
585
  serveSkills(res, url) {
572
586
  const status = url.searchParams.get("status") ?? undefined;
573
- const skills = this.store.listSkills({ status });
587
+ const visibility = url.searchParams.get("visibility") ?? undefined;
588
+ let skills = this.store.listSkills({ status });
589
+ if (visibility) {
590
+ skills = skills.filter(s => s.visibility === visibility);
591
+ }
574
592
  this.jsonResponse(res, { skills });
575
593
  }
576
594
  serveSkillDetail(res, urlPath) {
@@ -691,6 +709,34 @@ class ViewerServer {
691
709
  res.end(JSON.stringify({ error: `Failed to create zip: ${err}` }));
692
710
  }
693
711
  }
712
+ handleSkillVisibility(req, res, urlPath) {
713
+ const segments = urlPath.split("/");
714
+ const skillId = segments[segments.length - 2];
715
+ this.readBody(req, (body) => {
716
+ try {
717
+ const parsed = JSON.parse(body);
718
+ const visibility = parsed.visibility;
719
+ if (visibility !== "public" && visibility !== "private") {
720
+ res.writeHead(400, { "Content-Type": "application/json" });
721
+ res.end(JSON.stringify({ error: `visibility must be 'public' or 'private', got: '${visibility}'` }));
722
+ return;
723
+ }
724
+ const skill = this.store.getSkill(skillId);
725
+ if (!skill) {
726
+ res.writeHead(404, { "Content-Type": "application/json" });
727
+ res.end(JSON.stringify({ error: `Skill not found: ${skillId}` }));
728
+ return;
729
+ }
730
+ this.store.setSkillVisibility(skillId, visibility);
731
+ this.jsonResponse(res, { ok: true, skillId, visibility });
732
+ }
733
+ catch (err) {
734
+ this.log.error(`handleSkillVisibility error: skillId=${skillId}, body=${body}, err=${err}`);
735
+ res.writeHead(400, { "Content-Type": "application/json" });
736
+ res.end(JSON.stringify({ error: String(err) }));
737
+ }
738
+ });
739
+ }
694
740
  // ─── CRUD ───
695
741
  handleCreate(req, res) {
696
742
  this.readBody(req, (body) => {
@@ -703,7 +749,8 @@ class ViewerServer {
703
749
  id, sessionKey: data.session_key || "manual", turnId: `manual-${now}`, seq: 0,
704
750
  role: data.role || "user", content: data.content || "", kind: data.kind || "paragraph",
705
751
  summary: data.summary || data.content?.slice(0, 100) || "",
706
- taskId: null, skillId: null, dedupStatus: "active", dedupTarget: null, dedupReason: null,
752
+ taskId: null, skillId: null, owner: data.owner || "agent:main",
753
+ dedupStatus: "active", dedupTarget: null, dedupReason: null,
707
754
  mergeCount: 0, lastHitAt: null, mergeHistory: "[]",
708
755
  createdAt: now, updatedAt: now, embedding: null,
709
756
  });
@@ -733,7 +780,7 @@ class ViewerServer {
733
780
  this.readBody(req, (body) => {
734
781
  try {
735
782
  const data = JSON.parse(body);
736
- const ok = this.store.updateChunk(chunkId, { summary: data.summary, content: data.content, role: data.role, kind: data.kind });
783
+ const ok = this.store.updateChunk(chunkId, { summary: data.summary, content: data.content, role: data.role, kind: data.kind, owner: data.owner });
737
784
  if (ok)
738
785
  this.jsonResponse(res, { ok: true, message: "Memory updated" });
739
786
  else {
@@ -1231,6 +1278,7 @@ class ViewerServer {
1231
1278
  embedding: null,
1232
1279
  taskId: null,
1233
1280
  skillId: null,
1281
+ owner: `agent:${agentId}`,
1234
1282
  dedupStatus,
1235
1283
  dedupTarget,
1236
1284
  dedupReason,
@@ -1436,6 +1484,7 @@ class ViewerServer {
1436
1484
  embedding: null,
1437
1485
  taskId: null,
1438
1486
  skillId: null,
1487
+ owner: "agent:main",
1439
1488
  dedupStatus,
1440
1489
  dedupTarget,
1441
1490
  dedupReason,