claude-code-kanban 3.4.0 → 3.5.1
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 +1 -1
- package/public/app.js +71 -24
- package/public/style.css +55 -0
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -78,11 +78,34 @@ function updateUrl() {
|
|
|
78
78
|
const qs = params.toString();
|
|
79
79
|
const url = qs ? `?${qs}` : window.location.pathname;
|
|
80
80
|
history.replaceState(null, '', url);
|
|
81
|
+
persistLastView();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const LAST_VIEW_KEY = 'lastView';
|
|
85
|
+
function persistLastView() {
|
|
86
|
+
try {
|
|
87
|
+
const data = {
|
|
88
|
+
view: viewMode,
|
|
89
|
+
session: currentSessionId,
|
|
90
|
+
projectPath: viewMode === 'project' ? currentProjectPath : null,
|
|
91
|
+
};
|
|
92
|
+
localStorage.setItem(LAST_VIEW_KEY, JSON.stringify(data));
|
|
93
|
+
} catch (_) {}
|
|
94
|
+
}
|
|
95
|
+
function loadLastView() {
|
|
96
|
+
try {
|
|
97
|
+
return JSON.parse(localStorage.getItem(LAST_VIEW_KEY)) || null;
|
|
98
|
+
} catch (_) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
81
101
|
}
|
|
82
102
|
|
|
83
103
|
// biome-ignore lint/correctness/noUnusedVariables: used in HTML
|
|
84
104
|
function resetState() {
|
|
85
105
|
history.replaceState(null, '', window.location.pathname);
|
|
106
|
+
try {
|
|
107
|
+
localStorage.removeItem(LAST_VIEW_KEY);
|
|
108
|
+
} catch (_) {}
|
|
86
109
|
sessionFilter = 'active';
|
|
87
110
|
sessionLimit = '20';
|
|
88
111
|
filterProject = '__recent__';
|
|
@@ -481,6 +504,7 @@ async function fetchTasks(sessionId) {
|
|
|
481
504
|
resetAgentState();
|
|
482
505
|
updateUrl();
|
|
483
506
|
renderSession();
|
|
507
|
+
renderSessions();
|
|
484
508
|
fetchAgents(sessionId);
|
|
485
509
|
if (!agentLogMode) fetchMessages(sessionId);
|
|
486
510
|
} catch (error) {
|
|
@@ -1999,34 +2023,35 @@ function showAgentModal(agentId) {
|
|
|
1999
2023
|
const modalNameLabel = agent.agentName ? ` · ${escapeHtml(agent.agentName)}` : '';
|
|
2000
2024
|
title.innerHTML = `${statusDot} ${escapeHtml(agent.type || 'unknown')}${modalNameLabel}`;
|
|
2001
2025
|
|
|
2002
|
-
const
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2026
|
+
const shortModel = agent.model ? agent.model.replace(/^claude-/, '').replace(/-\d{8}$/, '') : null;
|
|
2027
|
+
const shortId = agent.agentId ? agent.agentId.slice(0, 8) : '';
|
|
2028
|
+
const chip = (label, value, opts = {}) => {
|
|
2029
|
+
const cls = opts.cls ? ` ${opts.cls}` : '';
|
|
2030
|
+
const style = opts.style ? ` style="${opts.style}"` : '';
|
|
2031
|
+
const title = opts.title ? ` title="${escapeHtml(opts.title)}"` : '';
|
|
2032
|
+
const labelHtml = label ? `<span class="agent-chip-label">${label}</span>` : '';
|
|
2033
|
+
return `<span class="agent-chip${cls}"${style}${title}>${labelHtml}<span class="agent-chip-val">${value}</span></span>`;
|
|
2034
|
+
};
|
|
2035
|
+
|
|
2036
|
+
const chips = [];
|
|
2037
|
+
if (agent.agentId) chips.push(chip('id', escapeHtml(shortId), { cls: 'agent-chip-mono', title: agent.agentId }));
|
|
2038
|
+
chips.push(chip('', escapeHtml(agent.status), { cls: `agent-chip-status agent-chip-${agent.status}` }));
|
|
2039
|
+
chips.push(chip('⏱', formatDuration(elapsed)));
|
|
2040
|
+
if (shortModel) chips.push(chip('model', escapeHtml(shortModel), { cls: 'agent-chip-mono' }));
|
|
2007
2041
|
if (agent.agentName) {
|
|
2008
|
-
const
|
|
2009
|
-
|
|
2010
|
-
'
|
|
2011
|
-
|
|
2012
|
-
|
|
2042
|
+
const c = getOwnerColor(agent.agentName);
|
|
2043
|
+
chips.push(
|
|
2044
|
+
chip('owner', escapeHtml(agent.agentName), {
|
|
2045
|
+
style: `background:${c.bg};color:${c.color};border-color:transparent;`,
|
|
2046
|
+
}),
|
|
2047
|
+
);
|
|
2013
2048
|
}
|
|
2014
|
-
if (
|
|
2015
|
-
|
|
2016
|
-
if (started) rows.push(['Started', started.toLocaleTimeString()]);
|
|
2017
|
-
if (stopped) rows.push(['Stopped', stopped.toLocaleTimeString()]);
|
|
2049
|
+
if (started) chips.push(chip('started', started.toLocaleTimeString()));
|
|
2050
|
+
if (stopped) chips.push(chip('stopped', stopped.toLocaleTimeString()));
|
|
2018
2051
|
|
|
2019
2052
|
const agentMsg = currentMessages.find((m) => m.tool === 'Agent' && m.agentId === agentId);
|
|
2020
2053
|
|
|
2021
|
-
let html =
|
|
2022
|
-
`<table style="width:100%;border-collapse:collapse;">` +
|
|
2023
|
-
rows
|
|
2024
|
-
.map(
|
|
2025
|
-
([k, v]) =>
|
|
2026
|
-
`<tr><td style="padding:6px 12px 6px 0;color:var(--text-tertiary);white-space:nowrap;vertical-align:top;">${k}</td><td style="padding:6px 0;color:var(--text-primary);">${v}</td></tr>`,
|
|
2027
|
-
)
|
|
2028
|
-
.join('') +
|
|
2029
|
-
`</table>`;
|
|
2054
|
+
let html = `<div class="agent-chips">${chips.join('')}</div>`;
|
|
2030
2055
|
|
|
2031
2056
|
const promptText = stripTeammateWrapper(agentMsg?.agentPrompt || agent.prompt || null);
|
|
2032
2057
|
const responseText = agent.lastMessage ? stripAnsi(agent.lastMessage.trim()) : null;
|
|
@@ -4124,6 +4149,8 @@ document.addEventListener('keydown', (e) => {
|
|
|
4124
4149
|
e.preventDefault();
|
|
4125
4150
|
if (_manualRefreshing) return;
|
|
4126
4151
|
_manualRefreshing = true;
|
|
4152
|
+
lastSessionsHash = '';
|
|
4153
|
+
lastTasksHash = '';
|
|
4127
4154
|
const refreshes = [fetchSessions()];
|
|
4128
4155
|
if (currentSessionId) refreshes.push(fetchTasks(currentSessionId));
|
|
4129
4156
|
Promise.all(refreshes)
|
|
@@ -4955,11 +4982,18 @@ async function updateProjectDropdown() {
|
|
|
4955
4982
|
projectsCacheDirty = false;
|
|
4956
4983
|
|
|
4957
4984
|
const cutoff = Date.now() - 24 * 60 * 60 * 1000;
|
|
4985
|
+
const prevRecent = recentProjects;
|
|
4958
4986
|
recentProjects = new Set(
|
|
4959
4987
|
projects.filter((p) => p.modifiedAt && new Date(p.modifiedAt).getTime() > cutoff).map((p) => p.path),
|
|
4960
4988
|
);
|
|
4961
4989
|
|
|
4962
4990
|
renderProjectDropdown(dropdown, projects);
|
|
4991
|
+
|
|
4992
|
+
// recentProjects was empty before — sidebar rendered with __recent__ filter
|
|
4993
|
+
// dropping every session. Re-render now that we know which projects qualify.
|
|
4994
|
+
if (filterProject === '__recent__' && prevRecent.size === 0 && recentProjects.size > 0) {
|
|
4995
|
+
renderSessions();
|
|
4996
|
+
}
|
|
4963
4997
|
}
|
|
4964
4998
|
|
|
4965
4999
|
function renderProjectDropdown(dropdown, projects) {
|
|
@@ -5753,8 +5787,21 @@ Promise.all([
|
|
|
5753
5787
|
}
|
|
5754
5788
|
} else if (urlState.session) {
|
|
5755
5789
|
await fetchTasks(urlState.session);
|
|
5756
|
-
} else {
|
|
5790
|
+
} else if (urlState.view === 'all') {
|
|
5757
5791
|
showAllTasks();
|
|
5792
|
+
} else {
|
|
5793
|
+
const last = loadLastView();
|
|
5794
|
+
if (last?.view === 'project' && last.projectPath && sessions.some((s) => s.project === last.projectPath)) {
|
|
5795
|
+
try {
|
|
5796
|
+
await fetchProjectView(last.projectPath);
|
|
5797
|
+
} catch (_) {
|
|
5798
|
+
showAllTasks();
|
|
5799
|
+
}
|
|
5800
|
+
} else if (last?.view === 'session' && last.session && sessions.some((s) => s.id === last.session)) {
|
|
5801
|
+
await fetchTasks(last.session);
|
|
5802
|
+
} else {
|
|
5803
|
+
showAllTasks();
|
|
5804
|
+
}
|
|
5758
5805
|
}
|
|
5759
5806
|
if (urlState.messages && currentSessionId) {
|
|
5760
5807
|
toggleMessagePanel();
|
package/public/style.css
CHANGED
|
@@ -1707,6 +1707,61 @@ body::before {
|
|
|
1707
1707
|
flex-shrink: 0;
|
|
1708
1708
|
}
|
|
1709
1709
|
|
|
1710
|
+
.agent-chips {
|
|
1711
|
+
display: flex;
|
|
1712
|
+
flex-wrap: wrap;
|
|
1713
|
+
gap: 6px;
|
|
1714
|
+
margin-bottom: 10px;
|
|
1715
|
+
}
|
|
1716
|
+
.agent-chip {
|
|
1717
|
+
display: inline-flex;
|
|
1718
|
+
align-items: center;
|
|
1719
|
+
gap: 4px;
|
|
1720
|
+
padding: 3px 9px;
|
|
1721
|
+
font-size: 11px;
|
|
1722
|
+
font-weight: 500;
|
|
1723
|
+
border-radius: 999px;
|
|
1724
|
+
border: 1px solid var(--border-color, rgba(127, 127, 127, 0.25));
|
|
1725
|
+
background: var(--bg-secondary, rgba(127, 127, 127, 0.08));
|
|
1726
|
+
color: var(--text-secondary);
|
|
1727
|
+
white-space: nowrap;
|
|
1728
|
+
line-height: 1.4;
|
|
1729
|
+
}
|
|
1730
|
+
.agent-chip-label {
|
|
1731
|
+
color: var(--text-tertiary);
|
|
1732
|
+
text-transform: uppercase;
|
|
1733
|
+
font-size: 9.5px;
|
|
1734
|
+
font-weight: 600;
|
|
1735
|
+
letter-spacing: 0.5px;
|
|
1736
|
+
opacity: 0.75;
|
|
1737
|
+
}
|
|
1738
|
+
.agent-chip-val {
|
|
1739
|
+
color: inherit;
|
|
1740
|
+
}
|
|
1741
|
+
.agent-chip-mono .agent-chip-val {
|
|
1742
|
+
font-family: var(--font-mono, monospace);
|
|
1743
|
+
font-size: 10.5px;
|
|
1744
|
+
letter-spacing: 0.2px;
|
|
1745
|
+
}
|
|
1746
|
+
.agent-chip-status {
|
|
1747
|
+
text-transform: capitalize;
|
|
1748
|
+
}
|
|
1749
|
+
.agent-chip-running {
|
|
1750
|
+
background: rgba(34, 197, 94, 0.15);
|
|
1751
|
+
color: rgb(34, 160, 80);
|
|
1752
|
+
border-color: rgba(34, 197, 94, 0.3);
|
|
1753
|
+
}
|
|
1754
|
+
.agent-chip-stopped {
|
|
1755
|
+
background: rgba(127, 127, 127, 0.15);
|
|
1756
|
+
color: var(--text-tertiary);
|
|
1757
|
+
border-color: rgba(127, 127, 127, 0.3);
|
|
1758
|
+
}
|
|
1759
|
+
.agent-chip-error,
|
|
1760
|
+
.agent-chip-failed {
|
|
1761
|
+
background: rgba(239, 68, 68, 0.15);
|
|
1762
|
+
color: rgb(220, 60, 60);
|
|
1763
|
+
border-color: rgba(239, 68, 68, 0.3);
|
|
1764
|
+
}
|
|
1710
1765
|
.team-modal-desc {
|
|
1711
1766
|
font-size: 12px;
|
|
1712
1767
|
color: var(--text-secondary);
|