claude-code-kanban 4.22.0 → 4.23.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/lib/file-url.js +2 -0
- package/package.json +1 -1
- package/public/app.js +11 -10
- package/public/style.css +92 -76
package/lib/file-url.js
CHANGED
|
@@ -24,6 +24,8 @@ function fileUrlToPath(value) {
|
|
|
24
24
|
if (typeof value !== 'string' || !/^file:/i.test(value)) return value;
|
|
25
25
|
// Backslashes are not legal in a URL, so this cannot corrupt a well-formed one.
|
|
26
26
|
let url = value.replace(/\\/g, '/');
|
|
27
|
+
// A scheme with no path body: POSIX Node resolves it to "/" rather than throwing.
|
|
28
|
+
if (/^file:\/*$/i.test(url)) return value;
|
|
27
29
|
const drive = DRIVE_URL.exec(url);
|
|
28
30
|
if (drive) url = `file:///${drive[1]}`;
|
|
29
31
|
try {
|
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -1460,8 +1460,8 @@ function getToolIcon(toolName) {
|
|
|
1460
1460
|
}
|
|
1461
1461
|
const AGENT_LOG_ICON =
|
|
1462
1462
|
'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>';
|
|
1463
|
-
function agentLogButton(agentId) {
|
|
1464
|
-
return `<button class="
|
|
1463
|
+
function agentLogButton(agentId, cls = 'msg-agent-log-btn') {
|
|
1464
|
+
return `<button class="${escapeHtml(cls)}" onclick="event.stopPropagation();viewAgentLog('${escAttrJs(agentId)}')" title="View agent log">${AGENT_LOG_ICON}</button>`;
|
|
1465
1465
|
}
|
|
1466
1466
|
|
|
1467
1467
|
function getPinId(m) {
|
|
@@ -2763,9 +2763,14 @@ function renderAgentFooter() {
|
|
|
2763
2763
|
const agentColor = resolveNamedColor(a.color);
|
|
2764
2764
|
const colorStyle = agentColor ? ` style="border-left:3px solid ${agentColor.color}"` : '';
|
|
2765
2765
|
const selectedClass = a.agentId === currentAgentModalId ? ' selected' : '';
|
|
2766
|
+
const cardModel = shortModelName(a.model);
|
|
2767
|
+
const modelChipHtml = cardModel
|
|
2768
|
+
? `<span class="agent-card-model" title="${escapeHtml(a.model)}">${escapeHtml(cardModel)}</span>`
|
|
2769
|
+
: '';
|
|
2766
2770
|
return `<div class="agent-card${selectedClass}" data-agent-id="${escapeHtml(a.agentId)}"${colorStyle} onclick="showAgentModal('${escAttrJs(a.agentId)}')">
|
|
2771
|
+
${agentLogButton(a.agentId, 'agent-card-log-btn')}
|
|
2767
2772
|
<div class="agent-type-row">${typeNs ? `<span class="agent-type-ns">${escapeHtml(typeNs)}</span>` : ''}<span class="agent-type-name">${escapeHtml(typeName)}</span>${nameBadgeHtml}</div>
|
|
2768
|
-
<div class="agent-status-row"><span class="agent-dot ${a.status}"></span><span class="agent-status">${statusText}</span
|
|
2773
|
+
<div class="agent-status-row"><span class="agent-dot ${a.status}"></span><span class="agent-status">${statusText}</span>${modelChipHtml}</div>
|
|
2769
2774
|
${msgHtml}
|
|
2770
2775
|
</div>`;
|
|
2771
2776
|
})
|
|
@@ -3137,9 +3142,9 @@ function renderSessions() {
|
|
|
3137
3142
|
const total = session.taskCount;
|
|
3138
3143
|
const percent = total > 0 ? Math.round((session.completed / total) * 100) : 0;
|
|
3139
3144
|
const isActive = session.id === currentSessionId && viewMode === 'session';
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3145
|
+
// hasRecentLog carries the server's registry-idle correction: an open-but-idle
|
|
3146
|
+
// terminal keeps touching its JSONL, so mtime alone is not proof of activity.
|
|
3147
|
+
const isLive = session.hasRecentLog && Date.now() - Date.parse(session.modifiedAt) <= LIVE_INDICATOR_MS;
|
|
3143
3148
|
const rawName = session.name || session.id;
|
|
3144
3149
|
const sessionName = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(rawName)
|
|
3145
3150
|
? rawName.slice(0, 8)
|
|
@@ -4612,8 +4617,6 @@ function activateSelectedSession(items) {
|
|
|
4612
4617
|
|
|
4613
4618
|
function setFocusZone(zone) {
|
|
4614
4619
|
const sidebar = document.querySelector('.sidebar');
|
|
4615
|
-
// Clear all zone visuals
|
|
4616
|
-
sidebar.classList.remove('sidebar-focused');
|
|
4617
4620
|
clearKbSelection();
|
|
4618
4621
|
clearTaskSelection();
|
|
4619
4622
|
|
|
@@ -4623,7 +4626,6 @@ function setFocusZone(zone) {
|
|
|
4623
4626
|
sidebar.classList.remove('collapsed');
|
|
4624
4627
|
localStorage.setItem('sidebar-collapsed', false);
|
|
4625
4628
|
}
|
|
4626
|
-
sidebar.classList.add('sidebar-focused');
|
|
4627
4629
|
const items = getNavigableItems();
|
|
4628
4630
|
if (items.length > 0) {
|
|
4629
4631
|
const activeIdx = items.findIndex((el) => el.classList.contains('active'));
|
|
@@ -5767,7 +5769,6 @@ document.addEventListener('keydown', (e) => {
|
|
|
5767
5769
|
}
|
|
5768
5770
|
if (e.key === 'Escape') {
|
|
5769
5771
|
// Plain unfocus — drop the keyboard cursor without jumping into the board
|
|
5770
|
-
document.querySelector('.sidebar').classList.remove('sidebar-focused');
|
|
5771
5772
|
clearKbSelection();
|
|
5772
5773
|
focusZone = 'board';
|
|
5773
5774
|
return;
|
package/public/style.css
CHANGED
|
@@ -562,6 +562,7 @@ body::before {
|
|
|
562
562
|
}
|
|
563
563
|
|
|
564
564
|
.session-item {
|
|
565
|
+
position: relative;
|
|
565
566
|
display: block;
|
|
566
567
|
width: 100%;
|
|
567
568
|
padding: 13px 15px;
|
|
@@ -574,11 +575,63 @@ body::before {
|
|
|
574
575
|
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
575
576
|
}
|
|
576
577
|
|
|
578
|
+
/* `.active` is the open session, `.kb-selected` the keyboard cursor. The cursor
|
|
579
|
+
must win when both land on one card, which is why it is ordered second. */
|
|
577
580
|
.session-item.active {
|
|
578
581
|
background: var(--bg-deep);
|
|
579
582
|
border-color: var(--accent);
|
|
580
583
|
}
|
|
581
584
|
|
|
585
|
+
.session-item.kb-selected {
|
|
586
|
+
background: var(--bg-elevated);
|
|
587
|
+
border-color: var(--accent);
|
|
588
|
+
box-shadow: 0 0 0 1px var(--accent-dim);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
.session-item.stale {
|
|
592
|
+
opacity: 0.85;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
.session-item.stale:hover,
|
|
596
|
+
.session-item.stale.active,
|
|
597
|
+
.session-item.stale.kb-selected,
|
|
598
|
+
.session-item.stale:has(.session-pin-btn.sticky) {
|
|
599
|
+
opacity: 1;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
.session-item.stale .session-time,
|
|
603
|
+
.session-item.warm .session-time {
|
|
604
|
+
display: inline-flex;
|
|
605
|
+
align-items: center;
|
|
606
|
+
gap: 6px;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.session-item.stale .session-time::before,
|
|
610
|
+
.session-item.warm .session-time::before {
|
|
611
|
+
content: '';
|
|
612
|
+
width: 6px;
|
|
613
|
+
height: 6px;
|
|
614
|
+
border-radius: 50%;
|
|
615
|
+
flex-shrink: 0;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.session-item.warm .session-time {
|
|
619
|
+
color: var(--success);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
.session-item.warm .session-time::before {
|
|
623
|
+
background: var(--success);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.session-item.stale .session-time {
|
|
627
|
+
color: var(--text-muted);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
.session-item.stale .session-time::before {
|
|
631
|
+
background: transparent;
|
|
632
|
+
border: 1px solid var(--text-muted);
|
|
633
|
+
}
|
|
634
|
+
|
|
582
635
|
.session-name {
|
|
583
636
|
font-size: 13px;
|
|
584
637
|
color: var(--text-primary);
|
|
@@ -590,12 +643,11 @@ body::before {
|
|
|
590
643
|
}
|
|
591
644
|
|
|
592
645
|
.session-indicators .pulse {
|
|
593
|
-
width:
|
|
594
|
-
height:
|
|
646
|
+
width: 6px;
|
|
647
|
+
height: 6px;
|
|
595
648
|
background: var(--accent);
|
|
596
649
|
border-radius: 50%;
|
|
597
650
|
animation: pulse 2s ease-in-out infinite;
|
|
598
|
-
box-shadow: 0 0 12px var(--accent-glow);
|
|
599
651
|
}
|
|
600
652
|
|
|
601
653
|
@keyframes pulse {
|
|
@@ -694,6 +746,10 @@ body::before {
|
|
|
694
746
|
transition: width 0.5s ease-out;
|
|
695
747
|
}
|
|
696
748
|
|
|
749
|
+
.session-item:not(.active) .progress-fill {
|
|
750
|
+
background: color-mix(in srgb, var(--text-tertiary) 55%, transparent);
|
|
751
|
+
}
|
|
752
|
+
|
|
697
753
|
.progress-text {
|
|
698
754
|
font-size: 11px;
|
|
699
755
|
font-weight: 500;
|
|
@@ -3597,6 +3653,25 @@ body::before {
|
|
|
3597
3653
|
.agent-card:hover {
|
|
3598
3654
|
border-color: color-mix(in srgb, var(--accent) 60%, var(--border));
|
|
3599
3655
|
}
|
|
3656
|
+
.agent-card-log-btn {
|
|
3657
|
+
position: absolute;
|
|
3658
|
+
top: 4px;
|
|
3659
|
+
right: 4px;
|
|
3660
|
+
display: flex;
|
|
3661
|
+
padding: 2px;
|
|
3662
|
+
background: none;
|
|
3663
|
+
border: none;
|
|
3664
|
+
color: var(--text-muted);
|
|
3665
|
+
cursor: pointer;
|
|
3666
|
+
opacity: 0.45;
|
|
3667
|
+
transition:
|
|
3668
|
+
opacity 0.15s,
|
|
3669
|
+
color 0.15s;
|
|
3670
|
+
}
|
|
3671
|
+
.agent-card-log-btn:hover {
|
|
3672
|
+
opacity: 1;
|
|
3673
|
+
color: var(--accent);
|
|
3674
|
+
}
|
|
3600
3675
|
.agent-card.selected,
|
|
3601
3676
|
.agent-card.selected:hover {
|
|
3602
3677
|
background: var(--bg-elevated);
|
|
@@ -3662,6 +3737,20 @@ body::before {
|
|
|
3662
3737
|
font-size: 11px;
|
|
3663
3738
|
color: var(--text-tertiary);
|
|
3664
3739
|
}
|
|
3740
|
+
.agent-card-model {
|
|
3741
|
+
margin-left: auto;
|
|
3742
|
+
padding: 1px 6px;
|
|
3743
|
+
font-family: var(--font-mono, monospace);
|
|
3744
|
+
font-size: 9.5px;
|
|
3745
|
+
line-height: 1.4;
|
|
3746
|
+
color: var(--text-tertiary);
|
|
3747
|
+
border: 1px solid var(--border);
|
|
3748
|
+
border-radius: 999px;
|
|
3749
|
+
white-space: nowrap;
|
|
3750
|
+
overflow: hidden;
|
|
3751
|
+
text-overflow: ellipsis;
|
|
3752
|
+
max-width: 45%;
|
|
3753
|
+
}
|
|
3665
3754
|
.agent-message {
|
|
3666
3755
|
font-size: 11px;
|
|
3667
3756
|
color: var(--text-muted);
|
|
@@ -5415,79 +5504,6 @@ pre.mermaid svg {
|
|
|
5415
5504
|
color: var(--accent);
|
|
5416
5505
|
}
|
|
5417
5506
|
|
|
5418
|
-
/* Session list hover accent bar */
|
|
5419
|
-
.session-item {
|
|
5420
|
-
position: relative;
|
|
5421
|
-
}
|
|
5422
|
-
|
|
5423
|
-
.session-item::before {
|
|
5424
|
-
content: '';
|
|
5425
|
-
position: absolute;
|
|
5426
|
-
left: 0;
|
|
5427
|
-
top: 50%;
|
|
5428
|
-
transform: translateY(-50%);
|
|
5429
|
-
width: 0;
|
|
5430
|
-
height: 60%;
|
|
5431
|
-
background: var(--accent);
|
|
5432
|
-
border-radius: 0 2px 2px 0;
|
|
5433
|
-
transition: width 0.15s ease;
|
|
5434
|
-
}
|
|
5435
|
-
|
|
5436
|
-
.session-item:hover::before {
|
|
5437
|
-
width: 0;
|
|
5438
|
-
}
|
|
5439
|
-
|
|
5440
|
-
.sidebar-focused .session-item.active::before {
|
|
5441
|
-
width: 0;
|
|
5442
|
-
}
|
|
5443
|
-
|
|
5444
|
-
.session-item.kb-selected,
|
|
5445
|
-
.session-item.kb-selected:hover,
|
|
5446
|
-
.session-item.active.kb-selected {
|
|
5447
|
-
background: var(--bg-elevated);
|
|
5448
|
-
border-color: var(--accent);
|
|
5449
|
-
box-shadow: 0 0 0 1px var(--accent-dim);
|
|
5450
|
-
}
|
|
5451
|
-
|
|
5452
|
-
.session-item.kb-selected::before {
|
|
5453
|
-
width: 0;
|
|
5454
|
-
}
|
|
5455
|
-
.session-item.stale .session-time,
|
|
5456
|
-
.session-item.warm .session-time {
|
|
5457
|
-
display: inline-flex;
|
|
5458
|
-
align-items: center;
|
|
5459
|
-
gap: 6px;
|
|
5460
|
-
}
|
|
5461
|
-
.session-item.stale .session-time::before,
|
|
5462
|
-
.session-item.warm .session-time::before {
|
|
5463
|
-
content: '';
|
|
5464
|
-
width: 6px;
|
|
5465
|
-
height: 6px;
|
|
5466
|
-
border-radius: 50%;
|
|
5467
|
-
flex-shrink: 0;
|
|
5468
|
-
}
|
|
5469
|
-
.session-item.warm .session-time {
|
|
5470
|
-
color: var(--success);
|
|
5471
|
-
}
|
|
5472
|
-
.session-item.warm .session-time::before {
|
|
5473
|
-
background: var(--success);
|
|
5474
|
-
}
|
|
5475
|
-
.session-item.stale {
|
|
5476
|
-
opacity: 0.85;
|
|
5477
|
-
}
|
|
5478
|
-
.session-item.stale:hover,
|
|
5479
|
-
.session-item.stale.active,
|
|
5480
|
-
.session-item.stale.kb-selected,
|
|
5481
|
-
.session-item.stale:has(.session-pin-btn.sticky) {
|
|
5482
|
-
opacity: 1;
|
|
5483
|
-
}
|
|
5484
|
-
.session-item.stale .session-time {
|
|
5485
|
-
color: var(--text-muted);
|
|
5486
|
-
}
|
|
5487
|
-
.session-item.stale .session-time::before {
|
|
5488
|
-
background: transparent;
|
|
5489
|
-
border: 1px solid var(--text-muted);
|
|
5490
|
-
}
|
|
5491
5507
|
/* #endregion */
|
|
5492
5508
|
|
|
5493
5509
|
/* #region SESSION_GROUPS */
|