claude-code-kanban 3.6.0 → 3.7.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-kanban",
3
- "version": "3.6.0",
3
+ "version": "3.7.0",
4
4
  "description": "A web-based Kanban board for viewing Claude Code tasks with agent teams support",
5
5
  "main": "server.js",
6
6
  "bin": {
package/public/app.js CHANGED
@@ -59,7 +59,9 @@ function getUrlState() {
59
59
  project: params.get('project'),
60
60
  owner: params.get('owner'),
61
61
  search: params.get('search'),
62
- messages: params.get('messages') === '1',
62
+ messages: params.has('messages')
63
+ ? params.get('messages') === '1'
64
+ : localStorage.getItem('message-panel-open') === 'true',
63
65
  projectView: params.get('projectView'),
64
66
  };
65
67
  }
@@ -653,6 +655,7 @@ async function refreshProjectAgents() {
653
655
  function toggleMessagePanel() {
654
656
  const panel = document.getElementById('message-panel');
655
657
  messagePanelOpen = !messagePanelOpen;
658
+ localStorage.setItem('message-panel-open', messagePanelOpen);
656
659
  panel.classList.toggle('visible', messagePanelOpen);
657
660
  document.getElementById('message-toggle')?.classList.toggle('active', messagePanelOpen);
658
661
  if (messagePanelOpen && currentSessionId) {
@@ -667,10 +670,13 @@ async function openSessionWithBookmarks(sessionId) {
667
670
  if (!messagePanelOpen) {
668
671
  const panel = document.getElementById('message-panel');
669
672
  messagePanelOpen = true;
673
+ localStorage.setItem('message-panel-open', 'true');
670
674
  panel.classList.add('visible');
671
675
  document.getElementById('message-toggle')?.classList.add('active');
672
676
  }
673
677
  await fetchTasks(sessionId);
678
+ if (currentMessages.length) renderMessages(currentMessages);
679
+ fetchMessages(sessionId);
674
680
  }
675
681
 
676
682
  // biome-ignore lint/correctness/noUnusedVariables: used in HTML
@@ -1503,10 +1509,25 @@ function closeMsgDetailModal() {
1503
1509
  msgDetailFollowLatest = false;
1504
1510
  }
1505
1511
 
1512
+ function _setModalWidth(modal, slot, on, maxWidth, width) {
1513
+ const mwKey = `prev${slot}MaxWidth`;
1514
+ const wKey = `prev${slot}Width`;
1515
+ if (on) {
1516
+ modal.dataset[mwKey] = modal.style.maxWidth || '';
1517
+ modal.dataset[wKey] = modal.style.width || '';
1518
+ modal.style.maxWidth = maxWidth;
1519
+ modal.style.width = width;
1520
+ } else {
1521
+ modal.style.maxWidth = modal.dataset[mwKey] || '';
1522
+ modal.style.width = modal.dataset[wKey] || '';
1523
+ }
1524
+ }
1525
+
1506
1526
  // biome-ignore lint/correctness/noUnusedVariables: used in HTML
1507
1527
  function toggleModalFullscreen(modalId) {
1508
1528
  const modal = document.querySelector(`#${modalId} .modal`);
1509
1529
  const isFs = modal.classList.toggle('fullscreen');
1530
+ _setModalWidth(modal, 'Fs', isFs, '', '');
1510
1531
  updateFullscreenBtnIcon(`${modalId}-fullscreen-btn`, isFs);
1511
1532
  }
1512
1533
 
@@ -1737,17 +1758,30 @@ function highlightBash(escaped) {
1737
1758
  }
1738
1759
 
1739
1760
  let _expandIdCounter = 0;
1761
+ function _toggleExpand(btn) {
1762
+ const f = document.getElementById(btn.dataset.expandId);
1763
+ const t = btn.parentElement.nextElementSibling;
1764
+ const expand = f.style.display === 'none';
1765
+ f.style.display = expand ? 'block' : 'none';
1766
+ t.style.display = expand ? 'none' : 'block';
1767
+ btn.textContent = expand ? 'Show less' : 'Show more';
1768
+ const panel = btn.closest('.message-panel');
1769
+ if (panel) panel.classList.toggle('msg-expanded-wide', expand);
1770
+ const modal = btn.closest('.modal');
1771
+ if (modal) _setModalWidth(modal, 'Expand', expand, '60vw', '60vw');
1772
+ }
1740
1773
  function makeExpandToggle(_truncatedHtml, fullHtml, opts = {}) {
1741
1774
  const id = `expand-${++_expandIdCounter}`;
1742
1775
  const fontSize = opts.fontSize || '0.8rem';
1743
1776
  const maxHeight = opts.maxHeight || '';
1744
- const btn = `<button onclick="var f=document.getElementById('${id}'),t=this.parentElement.nextElementSibling,expand=f.style.display==='none';f.style.display=expand?'block':'none';t.style.display=expand?'none':'block';this.textContent=expand?'Show less':'Show more'" style="background:none;border:none;color:var(--accent);cursor:pointer;font-size:${fontSize};text-decoration:underline;margin-left:6px">Show more</button>`;
1777
+ const btn = `<button data-expand-id="${id}" onclick="_toggleExpand(this)" style="background:none;border:none;color:var(--accent);cursor:pointer;font-size:${fontSize};text-decoration:underline;margin-left:6px">Show more</button>`;
1745
1778
  const mhStyle = maxHeight ? `max-height:${maxHeight};` : '';
1746
1779
  const full = `<pre id="${id}" class="msg-detail-pre" style="${mhStyle}overflow:auto;display:none">${fullHtml}</pre>`;
1747
1780
  return { btn, full };
1748
1781
  }
1749
1782
 
1750
1783
  function autoSizeModal(modal, body) {
1784
+ if (modal.classList.contains('fullscreen')) return;
1751
1785
  modal.style.maxWidth = '';
1752
1786
  modal.classList.remove('has-mermaid');
1753
1787
  const hasMermaid = body.querySelector('pre.mermaid') !== null;
package/public/style.css CHANGED
@@ -1824,6 +1824,9 @@ body::before {
1824
1824
  .message-panel.visible {
1825
1825
  display: flex;
1826
1826
  }
1827
+ .message-panel.msg-expanded-wide {
1828
+ width: 60vw;
1829
+ }
1827
1830
  .message-panel-header {
1828
1831
  padding: 16px 20px;
1829
1832
  display: flex;
@@ -2787,8 +2790,8 @@ body.light .msg-assistant .msg-text {
2787
2790
  }
2788
2791
 
2789
2792
  .modal.fullscreen {
2790
- width: 90vw;
2791
- max-width: 90vw;
2793
+ width: 80vw;
2794
+ max-width: 80vw;
2792
2795
  height: 92vh;
2793
2796
  max-height: 92vh;
2794
2797
  }
@@ -2802,8 +2805,8 @@ body.light .msg-assistant .msg-text {
2802
2805
  }
2803
2806
 
2804
2807
  .modal.plan-modal.fullscreen {
2805
- width: 90vw;
2806
- max-width: 90vw;
2808
+ width: 80vw;
2809
+ max-width: 80vw;
2807
2810
  height: 92vh;
2808
2811
  max-height: 92vh;
2809
2812
  }
package/server.js CHANGED
@@ -119,18 +119,11 @@ function isAgentFresh(agent) {
119
119
  return (Date.now() - new Date(ts).getTime()) < AGENT_TTL_MS;
120
120
  }
121
121
 
122
- const sessionLogStatCache = new Map();
123
122
  function getSessionLogStat(meta) {
124
123
  if (!meta.jsonlPath) return { mtime: null, hasMessages: false };
125
124
  try {
126
125
  const st = statSync(meta.jsonlPath);
127
- const cached = sessionLogStatCache.get(meta.jsonlPath);
128
- if (cached && cached.mtime === st.mtimeMs) return cached;
129
- const content = readFileSync(meta.jsonlPath, 'utf8');
130
- const hasMessages = content.includes('"type":"assistant"');
131
- const data = { mtime: st.mtimeMs, hasMessages };
132
- sessionLogStatCache.set(meta.jsonlPath, data);
133
- return data;
126
+ return { mtime: st.mtimeMs, hasMessages: st.size > 1000 };
134
127
  } catch (e) { return { mtime: null, hasMessages: false }; }
135
128
  }
136
129