@delt/claude-alarm 0.6.10 → 0.6.11

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.
@@ -1398,22 +1398,21 @@
1398
1398
  return toolName;
1399
1399
  }
1400
1400
 
1401
- // Returns { text, truncated } — truncated=true when input_preview was cut off
1401
+ // Returns { text } — dashboard shows full content, no truncation
1402
1402
  function formatPermPreview(toolName, raw) {
1403
- if (!raw) return { text: '', truncated: false };
1403
+ if (!raw) return { text: '' };
1404
1404
  let p = null;
1405
- let truncated = false;
1406
1405
  try { p = JSON.parse(raw); } catch {
1407
- truncated = true; // JSON parse failed = likely truncated by Claude Code
1406
+ // Truncated JSON - extract known fields with regex
1408
1407
  const cmdMatch = raw.match(/"command"\s*:\s*"((?:[^"\\]|\\.)*)"/);
1409
1408
  const fileMatch = raw.match(/"file_path"\s*:\s*"((?:[^"\\]|\\.)*)"/);
1410
1409
  const patternMatch = raw.match(/"pattern"\s*:\s*"((?:[^"\\]|\\.)*)"/);
1411
1410
  const contentMatch = raw.match(/"content"\s*:\s*"((?:[^"\\]|\\.)*)"/);
1412
- if (cmdMatch) return { text: '$ ' + cmdMatch[1], truncated };
1413
- if (fileMatch) return { text: fileMatch[1], truncated };
1414
- if (patternMatch) return { text: patternMatch[1], truncated };
1415
- if (contentMatch) return { text: contentMatch[1].slice(0, 200), truncated };
1416
- return { text: raw.slice(0, 300), truncated };
1411
+ if (cmdMatch) return { text: '$ ' + cmdMatch[1] };
1412
+ if (fileMatch) return { text: fileMatch[1] };
1413
+ if (patternMatch) return { text: patternMatch[1] };
1414
+ if (contentMatch) return { text: contentMatch[1] };
1415
+ return { text: raw };
1417
1416
  }
1418
1417
  let text;
1419
1418
  switch (toolName) {
@@ -1423,8 +1422,8 @@
1423
1422
  case 'Edit':
1424
1423
  if (p.file_path) {
1425
1424
  text = p.file_path;
1426
- if (p.new_string) { text += '\n+ ' + p.new_string.slice(0, 200); if (p.new_string.length > 200) truncated = true; }
1427
- else if (p.content) { text += '\n' + p.content.slice(0, 200); if (p.content.length > 200) truncated = true; }
1425
+ if (p.new_string) text += '\n+ ' + p.new_string;
1426
+ else if (p.content) text += '\n' + p.content;
1428
1427
  } else { text = raw; }
1429
1428
  break;
1430
1429
  case 'Read':
@@ -1435,18 +1434,16 @@
1435
1434
  text = (p.pattern || '') + (p.path ? ' in ' + p.path : ''); break;
1436
1435
  default:
1437
1436
  if (p.title && p.message) {
1438
- // Tools like notify: title is already shown in tool name, show message only
1439
1437
  text = p.message;
1440
1438
  } else if (p.content && typeof p.content === 'string') {
1441
- text = p.content.slice(0, 300);
1442
- if (p.content.length > 300) truncated = true;
1439
+ text = p.content;
1443
1440
  } else {
1444
1441
  const entries = Object.entries(p);
1445
- if (entries.length <= 3) text = entries.map(([k, v]) => k + ': ' + String(v).slice(0, 150)).join('\n');
1446
- else { text = JSON.stringify(p, null, 1).slice(0, 300); truncated = true; }
1442
+ if (entries.length <= 3) text = entries.map(([k, v]) => k + ': ' + String(v)).join('\n');
1443
+ else text = JSON.stringify(p, null, 1);
1447
1444
  }
1448
1445
  }
1449
- return { text: text || '', truncated };
1446
+ return { text: text || '' };
1450
1447
  }
1451
1448
 
1452
1449
  function sendPermissionVerdict(sessionId, requestId, behavior) {
@@ -1470,8 +1467,7 @@
1470
1467
  if (!reqs.length) { bar.classList.remove('active'); bar.innerHTML = ''; return; }
1471
1468
  bar.classList.add('active');
1472
1469
  bar.innerHTML = reqs.map(r => {
1473
- const { text: previewText, truncated } = formatPermPreview(r.toolName, r.inputPreview);
1474
- const truncLabel = truncated ? '<span style="color:var(--text-dim);font-size:10px;font-style:italic"> ...truncated</span>' : '';
1470
+ const { text: previewText } = formatPermPreview(r.toolName, r.inputPreview);
1475
1471
  const displayName = formatToolName(r.toolName, r.inputPreview);
1476
1472
  return `<div class="perm-item">
1477
1473
  <div class="perm-icon">&#9888;</div>
@@ -1479,7 +1475,7 @@
1479
1475
  <div class="perm-header">
1480
1476
  <span class="perm-tool">${esc(displayName)}</span>
1481
1477
  </div>
1482
- ${previewText ? `<div class="perm-preview">${esc(previewText)}${truncLabel}</div>` : ''}
1478
+ ${previewText ? `<div class="perm-preview">${esc(previewText)}</div>` : ''}
1483
1479
  </div>
1484
1480
  <div class="perm-actions">
1485
1481
  <button class="perm-allow" data-req-id="${esc(r.requestId)}" data-session-id="${esc(sid)}">Allow <span class="perm-kbd">(Enter)</span></button>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delt/claude-alarm",
3
- "version": "0.6.10",
3
+ "version": "0.6.11",
4
4
  "description": "Monitor and get notifications from multiple Claude Code sessions via MCP Channels",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1398,22 +1398,21 @@
1398
1398
  return toolName;
1399
1399
  }
1400
1400
 
1401
- // Returns { text, truncated } — truncated=true when input_preview was cut off
1401
+ // Returns { text } — dashboard shows full content, no truncation
1402
1402
  function formatPermPreview(toolName, raw) {
1403
- if (!raw) return { text: '', truncated: false };
1403
+ if (!raw) return { text: '' };
1404
1404
  let p = null;
1405
- let truncated = false;
1406
1405
  try { p = JSON.parse(raw); } catch {
1407
- truncated = true; // JSON parse failed = likely truncated by Claude Code
1406
+ // Truncated JSON - extract known fields with regex
1408
1407
  const cmdMatch = raw.match(/"command"\s*:\s*"((?:[^"\\]|\\.)*)"/);
1409
1408
  const fileMatch = raw.match(/"file_path"\s*:\s*"((?:[^"\\]|\\.)*)"/);
1410
1409
  const patternMatch = raw.match(/"pattern"\s*:\s*"((?:[^"\\]|\\.)*)"/);
1411
1410
  const contentMatch = raw.match(/"content"\s*:\s*"((?:[^"\\]|\\.)*)"/);
1412
- if (cmdMatch) return { text: '$ ' + cmdMatch[1], truncated };
1413
- if (fileMatch) return { text: fileMatch[1], truncated };
1414
- if (patternMatch) return { text: patternMatch[1], truncated };
1415
- if (contentMatch) return { text: contentMatch[1].slice(0, 200), truncated };
1416
- return { text: raw.slice(0, 300), truncated };
1411
+ if (cmdMatch) return { text: '$ ' + cmdMatch[1] };
1412
+ if (fileMatch) return { text: fileMatch[1] };
1413
+ if (patternMatch) return { text: patternMatch[1] };
1414
+ if (contentMatch) return { text: contentMatch[1] };
1415
+ return { text: raw };
1417
1416
  }
1418
1417
  let text;
1419
1418
  switch (toolName) {
@@ -1423,8 +1422,8 @@
1423
1422
  case 'Edit':
1424
1423
  if (p.file_path) {
1425
1424
  text = p.file_path;
1426
- if (p.new_string) { text += '\n+ ' + p.new_string.slice(0, 200); if (p.new_string.length > 200) truncated = true; }
1427
- else if (p.content) { text += '\n' + p.content.slice(0, 200); if (p.content.length > 200) truncated = true; }
1425
+ if (p.new_string) text += '\n+ ' + p.new_string;
1426
+ else if (p.content) text += '\n' + p.content;
1428
1427
  } else { text = raw; }
1429
1428
  break;
1430
1429
  case 'Read':
@@ -1435,18 +1434,16 @@
1435
1434
  text = (p.pattern || '') + (p.path ? ' in ' + p.path : ''); break;
1436
1435
  default:
1437
1436
  if (p.title && p.message) {
1438
- // Tools like notify: title is already shown in tool name, show message only
1439
1437
  text = p.message;
1440
1438
  } else if (p.content && typeof p.content === 'string') {
1441
- text = p.content.slice(0, 300);
1442
- if (p.content.length > 300) truncated = true;
1439
+ text = p.content;
1443
1440
  } else {
1444
1441
  const entries = Object.entries(p);
1445
- if (entries.length <= 3) text = entries.map(([k, v]) => k + ': ' + String(v).slice(0, 150)).join('\n');
1446
- else { text = JSON.stringify(p, null, 1).slice(0, 300); truncated = true; }
1442
+ if (entries.length <= 3) text = entries.map(([k, v]) => k + ': ' + String(v)).join('\n');
1443
+ else text = JSON.stringify(p, null, 1);
1447
1444
  }
1448
1445
  }
1449
- return { text: text || '', truncated };
1446
+ return { text: text || '' };
1450
1447
  }
1451
1448
 
1452
1449
  function sendPermissionVerdict(sessionId, requestId, behavior) {
@@ -1470,8 +1467,7 @@
1470
1467
  if (!reqs.length) { bar.classList.remove('active'); bar.innerHTML = ''; return; }
1471
1468
  bar.classList.add('active');
1472
1469
  bar.innerHTML = reqs.map(r => {
1473
- const { text: previewText, truncated } = formatPermPreview(r.toolName, r.inputPreview);
1474
- const truncLabel = truncated ? '<span style="color:var(--text-dim);font-size:10px;font-style:italic"> ...truncated</span>' : '';
1470
+ const { text: previewText } = formatPermPreview(r.toolName, r.inputPreview);
1475
1471
  const displayName = formatToolName(r.toolName, r.inputPreview);
1476
1472
  return `<div class="perm-item">
1477
1473
  <div class="perm-icon">&#9888;</div>
@@ -1479,7 +1475,7 @@
1479
1475
  <div class="perm-header">
1480
1476
  <span class="perm-tool">${esc(displayName)}</span>
1481
1477
  </div>
1482
- ${previewText ? `<div class="perm-preview">${esc(previewText)}${truncLabel}</div>` : ''}
1478
+ ${previewText ? `<div class="perm-preview">${esc(previewText)}</div>` : ''}
1483
1479
  </div>
1484
1480
  <div class="perm-actions">
1485
1481
  <button class="perm-allow" data-req-id="${esc(r.requestId)}" data-session-id="${esc(sid)}">Allow <span class="perm-kbd">(Enter)</span></button>