claude-code-watch 0.0.21 → 0.0.22

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 (2) hide show
  1. package/package.json +1 -1
  2. package/public/index.html +33 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-watch",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "description": "Web-based real-time monitor for Claude Code.",
5
5
  "main": "./src/server/server.js",
6
6
  "bin": {
package/public/index.html CHANGED
@@ -92,9 +92,8 @@ body {
92
92
  .btn[data-tooltip]:hover::after {
93
93
  content: attr(data-tooltip);
94
94
  position: absolute;
95
- bottom: calc(100% + 5px);
96
- left: 50%;
97
- transform: translateX(-50%);
95
+ top: calc(100% + 5px);
96
+ left: 0;
98
97
  background: var(--bg2); color: var(--white);
99
98
  padding: 2px 8px; border-radius: 4px;
100
99
  font-size: 10px; white-space: nowrap; z-index: 9999;
@@ -185,6 +184,7 @@ body {
185
184
  .tree-node .active-dot { flex-shrink: 0; }
186
185
  .tree-node .active-dot.on { color: var(--green); text-shadow: 0 0 6px var(--green); }
187
186
  .tree-node .active-dot.off { color: #555; opacity: 1; }
187
+ .tree-node .tree-agent-id { font-size: 10px; color: var(--dim); margin-left: 2px; font-family: monospace; }
188
188
 
189
189
  .tree-node .session-prefix {
190
190
  background: rgba(255,255,255,0.08);
@@ -313,10 +313,9 @@ body {
313
313
  <div id="tree-panel">
314
314
  <div id="tree-resize-handle"></div>
315
315
  <div id="tree-toolbar">
316
- <button class="btn btn-icon" onclick="selectAll()" data-tooltip="Show all sessions/agents">⊞</button>
317
- <button class="btn btn-icon accent" onclick="soloSelected()" data-tooltip="Solo selected">⊙</button>
318
- <button class="btn btn-icon danger" onclick="removeSelectedSession()" data-tooltip="Remove session">✕</button>
319
- <button class="btn btn-icon on" id="btn-activity" onclick="toggleActivity()" data-tooltip="Toggle activity info">💬</button>
316
+ <button class="btn btn-icon accent" onclick="soloSelected()" data-tooltip="独显:只看选中项,再点恢复全显">⊙</button>
317
+ <button class="btn btn-icon danger" onclick="removeSelectedSession()" data-tooltip="移除:隐藏选中会话(24h)">✕</button>
318
+ <button class="btn btn-icon on" id="btn-activity" onclick="toggleActivity()" data-tooltip="活动:显示/隐藏操作摘要">💬</button>
320
319
  <span style="flex:1"></span>
321
320
  <span id="tree-cursor-info" style="font-size:10px;color:var(--dim)"></span>
322
321
  </div>
@@ -783,6 +782,8 @@ function rebuildNodes() {
783
782
  sessions.sort((a, b) => (b.birthtimeMs || 0) - (a.birthtimeMs || 0));
784
783
  for (let i = 0; i < sessions.length; i++) sessions[i].colorRank = i;
785
784
 
785
+ computeAgentIdDisplayLengths();
786
+
786
787
  const today = new Date();
787
788
  const todayStr = `${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
788
789
 
@@ -960,7 +961,7 @@ function getNodeHTML(node, idx) {
960
961
  return `<div class="tree-row${selClass ? ' selected' : ''}">
961
962
  <div class="tree-content${enabled ? '' : ' dim'}" onclick="treeClick(${idx})" data-idx="${idx}">
962
963
  <div class="tree-node">
963
- <span class="tree-prefix">${treePrefix(node)}</span>${activeDot} ${icon} ${esc(node.name || '')}${ctxPct}
964
+ <span class="tree-prefix">${treePrefix(node)}</span>${activeDot} ${icon} ${esc(node.name || '')}${node.type === 'agent' && node.id ? '<span class="tree-agent-id">(' + esc(node.id.slice(0, agentIdDisplayLen.get(node.sessionID + ':' + node.id) || 7)) + ')</span>' : ''}${ctxPct}
964
965
  </div>
965
966
  ${activityHTML}
966
967
  </div>
@@ -1158,7 +1159,8 @@ function renderItem(item) {
1158
1159
  const agentName = item.agentName || 'Main';
1159
1160
  const sForColor = sessionsMap.get(item.sessionID);
1160
1161
  const prefixTag = `<span class="session-prefix" style="color:${idColor(sForColor ? sForColor.colorRank : 0)}">[${esc(item.sessionID.split('-')[0].toUpperCase())}]</span>`;
1161
- const agentLabel = prefixTag + ' ' + esc(agentName);
1162
+ const agentIdTag = item.agentID ? `<span class="session-prefix" style="color:var(--dim)">(</span><span class="session-prefix" style="color:var(--magenta)">${esc(item.agentID.slice(0, agentIdDisplayLen.get(item.sessionID + ':' + item.agentID) || 7))}</span><span class="session-prefix" style="color:var(--dim)">)</span>` : '';
1163
+ const agentLabel = prefixTag + agentIdTag + ' ' + esc(agentName);
1162
1164
  const tsHtml = item.timestamp ? `<span class="timestamp">${fmtTimestamp(item.timestamp)}</span>` : '';
1163
1165
 
1164
1166
  switch (item.type) {
@@ -1540,6 +1542,28 @@ function agentDisplayName(id, type) {
1540
1542
  return 'Agent-' + id.slice(0, 7);
1541
1543
  }
1542
1544
 
1545
+ // Compute the minimum display length per agentID so that within each session,
1546
+ // no two agent IDs share the same truncated prefix. Minimum 7 chars.
1547
+ const agentIdDisplayLen = new Map();
1548
+ function computeAgentIdDisplayLengths() {
1549
+ agentIdDisplayLen.clear();
1550
+ for (const s of sessions) {
1551
+ const agentIds = s.agents.filter(a => a.id).map(a => a.id);
1552
+ if (agentIds.length === 0) continue;
1553
+ // Find minimum length that makes all prefixes unique
1554
+ let minLen = 7;
1555
+ while (minLen < 21) {
1556
+ const prefixes = agentIds.map(id => id.slice(0, minLen));
1557
+ const unique = new Set(prefixes);
1558
+ if (unique.size === agentIds.length) break;
1559
+ minLen++;
1560
+ }
1561
+ for (const id of agentIds) {
1562
+ agentIdDisplayLen.set(s.id + ':' + id, minLen);
1563
+ }
1564
+ }
1565
+ }
1566
+
1543
1567
  function folderName(projectPath) {
1544
1568
  if (!projectPath) return '';
1545
1569
  const parts = projectPath.split('/');