@monoes/monomindcli 1.11.13 → 1.11.14

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.
@@ -202,7 +202,7 @@ async function checkMcpServers() {
202
202
  }
203
203
  }
204
204
  }
205
- return { name: 'MCP Servers', status: 'warn', message: 'No MCP config found', fix: 'claude mcp add monomind npx @monomind/cli@v1alpha mcp start' };
205
+ return { name: 'MCP Servers', status: 'warn', message: 'No MCP config found', fix: 'claude mcp add monomind -- npx -y monomind@latest mcp start' };
206
206
  }
207
207
  // Check disk space (async with proper env inheritance)
208
208
  async function checkDiskSpace() {
@@ -264,7 +264,7 @@ async function checkVersionFreshness() {
264
264
  const pkg = JSON.parse(readFileSync(candidate, 'utf8'));
265
265
  if (pkg.version &&
266
266
  typeof pkg.name === 'string' &&
267
- (pkg.name === '@monomind/cli' || pkg.name === 'monomind')) {
267
+ (pkg.name === '@monomind/cli' || pkg.name === 'monomind' || pkg.name === '@monoes/monomindcli')) {
268
268
  currentVersion = pkg.version;
269
269
  break;
270
270
  }
@@ -287,10 +287,10 @@ async function checkVersionFreshness() {
287
287
  const isNpx = process.argv[1]?.includes('_npx') ||
288
288
  process.env.npm_execpath?.includes('npx') ||
289
289
  process.cwd().includes('_npx');
290
- // Query npm for latest version (using alpha tag since that's what we publish to)
290
+ // Query npm for latest version of the published umbrella package
291
291
  let latestVersion = currentVersion;
292
292
  try {
293
- const npmInfo = await runCommand('npm view @monomind/cli@alpha version', 5000);
293
+ const npmInfo = await runCommand('npm view monomind version', 5000);
294
294
  latestVersion = npmInfo.trim();
295
295
  }
296
296
  catch {
@@ -322,8 +322,8 @@ async function checkVersionFreshness() {
322
322
  (latest.major === current.major && latest.minor === current.minor && latest.patch === current.patch && latest.prerelease > current.prerelease));
323
323
  if (isOutdated) {
324
324
  const fix = isNpx
325
- ? 'rm -rf ~/.npm/_npx/* && npx -y @monomind/cli@latest'
326
- : 'npm update @monomind/cli';
325
+ ? 'rm -rf ~/.npm/_npx/* && npx -y monomind@latest doctor'
326
+ : 'npm update -g monomind';
327
327
  return {
328
328
  name: 'Version Freshness',
329
329
  status: 'warn',
@@ -387,18 +387,34 @@ async function installClaudeCode() {
387
387
  async function checkMonograph() {
388
388
  try {
389
389
  const __filename = fileURLToPath(import.meta.url);
390
+ const _base = dirname(__filename);
391
+ let _globalRoot = '';
392
+ try { _globalRoot = execSync('npm root -g', { encoding: 'utf8', timeout: 3000 }).trim(); } catch { /* no npm */ }
390
393
  const candidates = [
391
- join(dirname(__filename), '..', '..', 'node_modules', '@monomind', 'monograph', 'package.json'),
392
- join(dirname(__filename), '..', '..', '..', '..', 'node_modules', '@monomind', 'monograph', 'package.json'),
394
+ join(_base, '..', '..', 'node_modules', '@monomind', 'monograph', 'package.json'),
395
+ join(_base, '..', '..', '..', '..', 'node_modules', '@monomind', 'monograph', 'package.json'),
396
+ join(_base, '..', '..', 'node_modules', '@monoes', 'monograph', 'package.json'),
397
+ join(_base, '..', '..', '..', '..', 'node_modules', '@monoes', 'monograph', 'package.json'),
398
+ ...(_globalRoot ? [
399
+ join(_globalRoot, '@monomind', 'monograph', 'package.json'),
400
+ join(_globalRoot, '@monoes', 'monograph', 'package.json'),
401
+ ] : []),
393
402
  ];
394
- if (candidates.some(p => existsSync(p))) {
395
- return { name: 'Monograph', status: 'pass', message: 'available (knowledge graph engine)' };
403
+ const found = candidates.find(p => existsSync(p));
404
+ if (found) {
405
+ try {
406
+ const pkg = JSON.parse(readFileSync(found, 'utf-8'));
407
+ return { name: 'Monograph', status: 'pass', message: `v${pkg.version || '?'} available (knowledge graph engine)` };
408
+ }
409
+ catch {
410
+ return { name: 'Monograph', status: 'pass', message: 'available (knowledge graph engine)' };
411
+ }
396
412
  }
397
413
  return {
398
414
  name: 'Monograph',
399
415
  status: 'warn',
400
416
  message: 'Package not found (knowledge graph disabled)',
401
- fix: 'npm install in project root'
417
+ fix: 'npm install -g monomind@latest # reinstall to get @monoes/monograph'
402
418
  };
403
419
  }
404
420
  catch {
@@ -406,9 +422,42 @@ async function checkMonograph() {
406
422
  name: 'Monograph',
407
423
  status: 'warn',
408
424
  message: 'Package check failed (knowledge graph may be unavailable)',
409
- fix: 'npm install in project root'
425
+ fix: 'npm install -g monomind@latest'
426
+ };
427
+ }
428
+ }
429
+ // Check @monoes/memory (optional HNSW vector search package)
430
+ async function checkMonoesMemory() {
431
+ try {
432
+ const __filename = fileURLToPath(import.meta.url);
433
+ const _base = dirname(__filename);
434
+ let _globalRoot = '';
435
+ try { _globalRoot = execSync('npm root -g', { encoding: 'utf8', timeout: 3000 }).trim(); } catch { /* no npm */ }
436
+ const candidates = [
437
+ join(_base, '..', '..', 'node_modules', '@monoes', 'memory', 'package.json'),
438
+ join(_base, '..', '..', '..', '..', 'node_modules', '@monoes', 'memory', 'package.json'),
439
+ ...(_globalRoot ? [join(_globalRoot, '@monoes', 'memory', 'package.json')] : []),
440
+ ];
441
+ const found = candidates.find(p => existsSync(p));
442
+ if (found) {
443
+ try {
444
+ const pkg = JSON.parse(readFileSync(found, 'utf-8'));
445
+ return { name: 'Vector Memory', status: 'pass', message: `@monoes/memory v${pkg.version || '?'} (HNSW search enabled)` };
446
+ }
447
+ catch {
448
+ return { name: 'Vector Memory', status: 'pass', message: '@monoes/memory available (HNSW search enabled)' };
449
+ }
450
+ }
451
+ return {
452
+ name: 'Vector Memory',
453
+ status: 'warn',
454
+ message: '@monoes/memory not installed (vector search disabled — using fallback)',
455
+ fix: 'npm install @monoes/memory'
410
456
  };
411
457
  }
458
+ catch {
459
+ return { name: 'Vector Memory', status: 'warn', message: 'Vector memory check failed' };
460
+ }
412
461
  }
413
462
  // Check agentic-flow v1 integration (filesystem-based to avoid slow WASM/DB init)
414
463
  // Resolve the path to the bundled (npm-installed) copy of a helper file.
@@ -766,6 +815,7 @@ export const doctorCommand = {
766
815
  checkDiskSpace,
767
816
  checkBuildTools,
768
817
  checkMonograph,
818
+ checkMonoesMemory,
769
819
  checkHelpersFresh,
770
820
  checkAgenticFlow,
771
821
  checkMonoesIntegration,
@@ -787,6 +837,7 @@ export const doctorCommand = {
787
837
  'disk': checkDiskSpace,
788
838
  'typescript': checkBuildTools,
789
839
  'monograph': checkMonograph,
840
+ 'memory-pkg': checkMonoesMemory,
790
841
  'helpers': checkHelpersFresh,
791
842
  'agentic-flow': checkAgenticFlow,
792
843
  'monoes': checkMonoesIntegration,
@@ -2593,7 +2593,9 @@ function renderGroupRow(g) {
2593
2593
  }
2594
2594
 
2595
2595
  function expandGroup(el) {
2596
- const items = JSON.parse(el.dataset.items);
2596
+ let items;
2597
+ try { items = JSON.parse(el.dataset.items); } catch { return; }
2598
+ if (!Array.isArray(items)) return;
2597
2599
  const html = items.map(renderFeedEntry).join('');
2598
2600
  el.outerHTML = html;
2599
2601
  // re-apply active feed search to newly injected entries
@@ -2653,7 +2655,9 @@ function setFeedContent(html) {
2653
2655
 
2654
2656
  // ── detail panel ───────────────────────────────────────────
2655
2657
  function openDetail(evJson) {
2656
- const ev = JSON.parse(evJson);
2658
+ let ev;
2659
+ try { ev = JSON.parse(evJson); } catch { return; }
2660
+ if (!ev) return;
2657
2661
  selectedEntryId = ev.id || ev.uuid || '';
2658
2662
 
2659
2663
  const panel = document.getElementById('detail-panel');
@@ -3686,7 +3690,7 @@ function buildTagFilterBar(sessions) {
3686
3690
  if (!allTags.common.size) return '';
3687
3691
  const sorted = [...allTags.common].sort();
3688
3692
  const chips = sorted.map(t =>
3689
- `<button class="tag-chip${activeTagFilter === t ? ' active' : ''}" title="Filter sessions by tag: ${esc(t)}" onclick="setTagFilter('${esc(t)}')">${esc(t)}</button>`
3693
+ `<button class="tag-chip${activeTagFilter === t ? ' active' : ''}" title="Filter sessions by tag: ${esc(t)}" data-tag="${esc(t)}" onclick="setTagFilter(this.dataset.tag)">${esc(t)}</button>`
3690
3694
  ).join('');
3691
3695
  return `<div class="tag-filter-bar">${chips}</div>`;
3692
3696
  }
@@ -3910,9 +3914,9 @@ async function renderGlobalLoops() {
3910
3914
  ${stopBtn}
3911
3915
  </div>
3912
3916
  <div class="loop-expand">
3913
- ${userPrompt ? `<div class="le-row"><div class="le-lbl">Prompt</div><div class="le-val mono" style="display:flex;align-items:flex-start;gap:8px"><span title="${esc(userPrompt)}">${esc(userPrompt.slice(0, 300))}${userPrompt.length > 300 ? '…' : ''}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy prompt" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(userPrompt)}).then(()=>showToast('Copied','Prompt copied','ok'))">⎘</button></div></div>` : ''}
3914
- ${cmdStr ? `<div class="le-row"><div class="le-lbl">Command</div><div class="le-val mono" style="display:flex;align-items:center;gap:8px"><span>${esc(cmdStr)}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy command" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(cmdStr)}).then(()=>showToast('Copied','Command copied','ok'))">⎘</button></div></div>` : ''}
3915
- ${flagsStr ? `<div class="le-row"><div class="le-lbl">Flags</div><div class="le-val mono" style="display:flex;align-items:flex-start;gap:8px"><span title="${esc(flagsStr)}">${esc(flagsStr.slice(0, 300))}${flagsStr.length > 300 ? '…' : ''}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy flags" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(flagsStr)}).then(()=>showToast('Copied','Flags copied','ok'))">⎘</button></div></div>` : ''}
3917
+ ${userPrompt ? `<div class="le-row"><div class="le-lbl">Prompt</div><div class="le-val mono" style="display:flex;align-items:flex-start;gap:8px"><span title="${esc(userPrompt)}">${esc(userPrompt.slice(0, 300))}${userPrompt.length > 300 ? '…' : ''}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy prompt" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(userPrompt).replace(/"/g, '&quot;')}).then(()=>showToast('Copied','Prompt copied','ok'))">⎘</button></div></div>` : ''}
3918
+ ${cmdStr ? `<div class="le-row"><div class="le-lbl">Command</div><div class="le-val mono" style="display:flex;align-items:center;gap:8px"><span>${esc(cmdStr)}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy command" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(cmdStr).replace(/"/g, '&quot;')}).then(()=>showToast('Copied','Command copied','ok'))">⎘</button></div></div>` : ''}
3919
+ ${flagsStr ? `<div class="le-row"><div class="le-lbl">Flags</div><div class="le-val mono" style="display:flex;align-items:flex-start;gap:8px"><span title="${esc(flagsStr)}">${esc(flagsStr.slice(0, 300))}${flagsStr.length > 300 ? '…' : ''}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy flags" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(flagsStr).replace(/"/g, '&quot;')}).then(()=>showToast('Copied','Flags copied','ok'))">⎘</button></div></div>` : ''}
3916
3920
  <div class="le-row"><div class="le-lbl">Project</div><div class="le-val"><span class="gf-proj-tag">${esc(projName)}</span></div></div>
3917
3921
  <div class="le-row"><div class="le-lbl">Type</div><div class="le-val">${esc(l.type || 'repeat')}</div></div>
3918
3922
  <div class="le-row"><div class="le-lbl">Interval</div><div class="le-val">${esc(intervalStr || '—')}</div></div>
@@ -4776,9 +4780,9 @@ async function renderLoops() {
4776
4780
  ${stopBtn}
4777
4781
  </div>
4778
4782
  <div class="loop-expand">
4779
- ${userPrompt ? `<div class="le-row"><div class="le-lbl">Prompt</div><div class="le-val mono" style="display:flex;align-items:flex-start;gap:8px"><span title="${esc(userPrompt)}">${esc(userPrompt.slice(0, 300))}${userPrompt.length > 300 ? '…' : ''}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy prompt" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(userPrompt)}).then(()=>showToast('Copied','Prompt copied','ok'))">⎘</button></div></div>` : ''}
4780
- ${cmdStr ? `<div class="le-row"><div class="le-lbl">Command</div><div class="le-val mono" style="display:flex;align-items:center;gap:8px"><span>${esc(cmdStr)}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy command" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(cmdStr)}).then(()=>showToast('Copied','Command copied','ok'))">⎘</button></div></div>` : ''}
4781
- ${flagsStr ? `<div class="le-row"><div class="le-lbl">Flags</div><div class="le-val mono" style="display:flex;align-items:flex-start;gap:8px"><span title="${esc(flagsStr)}">${esc(flagsStr.slice(0, 300))}${flagsStr.length > 300 ? '…' : ''}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy flags" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(flagsStr)}).then(()=>showToast('Copied','Flags copied','ok'))">⎘</button></div></div>` : ''}
4783
+ ${userPrompt ? `<div class="le-row"><div class="le-lbl">Prompt</div><div class="le-val mono" style="display:flex;align-items:flex-start;gap:8px"><span title="${esc(userPrompt)}">${esc(userPrompt.slice(0, 300))}${userPrompt.length > 300 ? '…' : ''}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy prompt" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(userPrompt).replace(/"/g, '&quot;')}).then(()=>showToast('Copied','Prompt copied','ok'))">⎘</button></div></div>` : ''}
4784
+ ${cmdStr ? `<div class="le-row"><div class="le-lbl">Command</div><div class="le-val mono" style="display:flex;align-items:center;gap:8px"><span>${esc(cmdStr)}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy command" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(cmdStr).replace(/"/g, '&quot;')}).then(()=>showToast('Copied','Command copied','ok'))">⎘</button></div></div>` : ''}
4785
+ ${flagsStr ? `<div class="le-row"><div class="le-lbl">Flags</div><div class="le-val mono" style="display:flex;align-items:flex-start;gap:8px"><span title="${esc(flagsStr)}">${esc(flagsStr.slice(0, 300))}${flagsStr.length > 300 ? '…' : ''}</span><button class="btn" style="flex-shrink:0;font-size:10px;padding:1px 6px" title="Copy flags" onclick="event.stopPropagation();navigator.clipboard.writeText(${JSON.stringify(flagsStr).replace(/"/g, '&quot;')}).then(()=>showToast('Copied','Flags copied','ok'))">⎘</button></div></div>` : ''}
4782
4786
  <div class="le-row"><div class="le-lbl">Type</div><div class="le-val">${esc(l.type || 'repeat')}</div></div>
4783
4787
  <div class="le-row"><div class="le-lbl">Interval</div><div class="le-val">${esc(intervalStr || '—')}</div></div>
4784
4788
  <div class="le-row"><div class="le-lbl">Status</div><div class="le-val">${isHil ? '⚠ hil:pending' : (running ? '● running' : (isFinished ? '✓ done' : '○ stopped'))}</div></div>
@@ -7168,9 +7172,11 @@ document.addEventListener('keydown', e => {
7168
7172
  else cur = cur < 0 ? 0 : Math.max(cur - 1, 0);
7169
7173
  entries.forEach((el, i) => el.classList.toggle('selected', i === cur));
7170
7174
  entries[cur].scrollIntoView({ block: 'nearest' });
7171
- selectedEntryId = entries[cur].dataset.ev
7172
- ? (JSON.parse(entries[cur].dataset.ev).id || '')
7173
- : '';
7175
+ try {
7176
+ selectedEntryId = entries[cur].dataset.ev
7177
+ ? (JSON.parse(entries[cur].dataset.ev).id || '')
7178
+ : '';
7179
+ } catch { selectedEntryId = ''; }
7174
7180
  }
7175
7181
 
7176
7182
  if (e.key === 'Enter') {
@@ -8055,11 +8061,11 @@ function showCustomTagInput(sessId, event) {
8055
8061
 
8056
8062
  function renderCustomTagsInline(sessId, tags) {
8057
8063
  const tagHtml = tags.map(t =>
8058
- `<span class="sr-ctag">${esc(t)}<span class="ctag-del" onclick="removeCustomTag('${esc(sessId)}','${esc(t)}',event)" title="Remove tag">✕</span></span>`
8064
+ `<span class="sr-ctag">${esc(t)}<span class="ctag-del" data-sess="${esc(sessId)}" data-tag="${esc(t)}" onclick="removeCustomTag(this.dataset.sess,this.dataset.tag,event)" title="Remove tag">✕</span></span>`
8059
8065
  ).join('');
8060
8066
  return `<div class="sr-custom-tags" data-sess="${esc(sessId)}" onclick="event.stopPropagation()">
8061
8067
  ${tagHtml}
8062
- <button class="ctag-add-btn" onclick="showCustomTagInput('${esc(sessId)}',event)" title="Add tag">+ tag</button>
8068
+ <button class="ctag-add-btn" data-sess="${esc(sessId)}" onclick="showCustomTagInput(this.dataset.sess,event)" title="Add tag">+ tag</button>
8063
8069
  </div>`;
8064
8070
  }
8065
8071
 
@@ -9676,7 +9682,7 @@ function mgWikiFindRelated(nodeId) {
9676
9682
  const n = (_mgGraph.nodes || []).find(x => (x.id || x.name || x.label || '') === k);
9677
9683
  const lbl = n ? (n.label || n.name || k) : k;
9678
9684
  const typeIcon = n ? mgNodeIcon(n.type || n.kind) : '◈';
9679
- return `<li style="cursor:pointer;display:flex;align-items:center;gap:6px;padding:2px 0" onclick="mgWikiJumpToNode(${JSON.stringify(k)})" title="Open ${esc(lbl)}"><span style="opacity:0.6">${typeIcon}</span>${esc(lbl)}</li>`;
9685
+ return `<li style="cursor:pointer;display:flex;align-items:center;gap:6px;padding:2px 0" onclick="mgWikiJumpToNode(${JSON.stringify(k).replace(/"/g, '&quot;')})" title="Open ${esc(lbl)}"><span style="opacity:0.6">${typeIcon}</span>${esc(lbl)}</li>`;
9680
9686
  }).join('') + `</ul>`;
9681
9687
  el.style.display = 'block';
9682
9688
  }
@@ -9821,8 +9827,8 @@ function selectMem(filename) {
9821
9827
  const actions = (f.readonly || f.source === 'backend')
9822
9828
  ? '<div class="mem-actions"><span style="font-size:11px;color:var(--text-lo)">Read-only — stored in the backend memory store (not a file)</span></div>'
9823
9829
  : '<div class="mem-actions">' +
9824
- '<button class="btn" title="Edit this memory entry" onclick="openEditMemModal(' + JSON.stringify(filename) + ')">&#x270E; Edit</button>' +
9825
- '<button class="btn" title="Delete this memory entry" style="color:var(--red);border-color:var(--red)" onclick="deleteMem(' + JSON.stringify(filename) + ')">&#x2715; Delete</button>' +
9830
+ '<button class="btn" title="Edit this memory entry" onclick="openEditMemModal(' + JSON.stringify(filename).replace(/"/g, '&quot;') + ')">&#x270E; Edit</button>' +
9831
+ '<button class="btn" title="Delete this memory entry" style="color:var(--red);border-color:var(--red)" onclick="deleteMem(' + JSON.stringify(filename).replace(/"/g, '&quot;') + ')">&#x2715; Delete</button>' +
9826
9832
  '</div>';
9827
9833
  detail.innerHTML =
9828
9834
  '<span class="mem-badge" style="background:' + col + '22;color:' + col + '">' + esc(f.type || '?') + '</span>' + srcBadge +
@@ -10440,7 +10446,7 @@ function mmRenderOrgs(body) {
10440
10446
  if (!orgs.length) { body.innerHTML = '<div class="empty">No orgs found. Run /mastermind:createorg to create one.</div>'; return; }
10441
10447
  body.innerHTML = orgs.map(o => {
10442
10448
  const running = o.running;
10443
- return `<div class="mm-skill-item" onclick="closeMastermind();v2SelectOrg(${JSON.stringify(o.name)});switchView('orgs')">
10449
+ return `<div class="mm-skill-item" onclick="closeMastermind();v2SelectOrg(${JSON.stringify(o.name).replace(/"/g, '&quot;')});switchView('orgs')">
10444
10450
  <span class="mm-skill-name">${esc(o.name)}</span>
10445
10451
  <span class="mm-skill-desc" title="${esc(o.goal || '')}">${esc((o.goal || '').slice(0, 60))}${(o.goal || '').length > 60 ? '…' : ''} ${running ? '⬤ LIVE' : ''}</span>
10446
10452
  </div>`;
@@ -10452,7 +10458,7 @@ function mmRenderSkills(body) {
10452
10458
  const q = _mmSkillFilter.toLowerCase();
10453
10459
  const filtered = q ? _MM_SKILLS_CATALOG.filter(s => s.name.toLowerCase().includes(q) || s.desc.toLowerCase().includes(q)) : _MM_SKILLS_CATALOG;
10454
10460
  body.innerHTML = `<div class="filter-bar" style="margin-bottom:12px"><input class="filter-input" id="mm-skill-filter-input" type="text" placeholder="Search skills…" value="${esc(_mmSkillFilter)}" oninput="_mmSkillFilter=this.value;mmRenderSkills(document.getElementById('mm-body'))"></div>` +
10455
- filtered.map(s => `<div class="mm-skill-item" title="Click to copy: /${esc(s.name)}" onclick="navigator.clipboard.writeText(${JSON.stringify(s.name)}).then(()=>showToast('Copied',${JSON.stringify(s.name)},'ok'))">
10461
+ filtered.map(s => `<div class="mm-skill-item" title="Click to copy: /${esc(s.name)}" onclick="navigator.clipboard.writeText(${JSON.stringify(s.name).replace(/"/g, '&quot;')}).then(()=>showToast('Copied',${JSON.stringify(s.name).replace(/"/g, '&quot;')},'ok'))">
10456
10462
  <span class="mm-skill-name">${esc(s.name)}</span>
10457
10463
  <span class="mm-skill-desc">${esc(s.desc)}</span>
10458
10464
  </div>`).join('');
@@ -10520,7 +10526,7 @@ async function mmRenderLoops(body) {
10520
10526
  <div style="display:flex;align-items:center;gap:8px">
10521
10527
  <span style="font-size:13px;color:var(--text-hi);flex:1">${typeIco}${esc(name)}</span>
10522
10528
  <span class="ss-pill ${running && !isHilMm ? 'on' : ''}" style="${statusColor ? 'color:'+statusColor+';background:oklch(65% 0.15 60 / 0.15);border:none' : ''}">${statusLabel}</span>
10523
- ${running ? `<button class="btn" title="Stop this automation loop" style="font-size:10px;color:var(--red);border-color:var(--red)" onclick="stopLoop(event,${JSON.stringify(l.id||l.name||'')});mmSwitchTab('loops')">■ Stop</button>` : ''}
10529
+ ${running ? `<button class="btn" title="Stop this automation loop" style="font-size:10px;color:var(--red);border-color:var(--red)" onclick="stopLoop(event,${JSON.stringify(l.id||l.name||'').replace(/"/g, '&quot;')});mmSwitchTab('loops')">■ Stop</button>` : ''}
10524
10530
  </div>
10525
10531
  <div style="font-size:11px;color:var(--text-lo);margin-top:4px;font-family:var(--mono)">${esc(metaParts)}</div>
10526
10532
  ${isHilMm ? `<div style="font-size:10px;color:oklch(75% 0.16 60);margin-top:4px">⚠ Waiting for human response — check HIL file to resume</div>` : ''}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monoes/monomindcli",
3
- "version": "1.11.13",
3
+ "version": "1.11.14",
4
4
  "type": "module",
5
5
  "description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
6
6
  "main": "dist/src/index.js",