claude-code-kanban 4.2.0 → 4.3.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": "4.2.0",
3
+ "version": "4.3.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
@@ -2509,16 +2509,25 @@ function renderSessions() {
2509
2509
  filteredSessions = filteredSessions.filter(matchesSearch);
2510
2510
 
2511
2511
  // Re-add pinned/sticky sessions that match the query but were excluded by active filter
2512
- if (activityFilter.size === 0 && (pinnedSessionIds.size > 0 || stickySessionIds.size > 0)) {
2512
+ if (
2513
+ sessionFilter === 'active' &&
2514
+ activityFilter.size === 0 &&
2515
+ (pinnedSessionIds.size > 0 || stickySessionIds.size > 0)
2516
+ ) {
2513
2517
  const filteredIds = new Set(filteredSessions.map((s) => s.id));
2514
2518
  const missingPinned = sessions.filter((s) => isAnyPinned(s.id) && !filteredIds.has(s.id) && matchesSearch(s));
2515
2519
  if (missingPinned.length) filteredSessions = [...missingPinned, ...filteredSessions];
2516
2520
  }
2517
2521
  }
2518
2522
 
2519
- // Include pinned/sticky sessions even if they don't match active/recent filter
2520
- // (skipped when an activity chip filter is on user explicitly asked for a slice)
2521
- if (activityFilter.size === 0 && !searchQuery && (pinnedSessionIds.size > 0 || stickySessionIds.size > 0)) {
2523
+ // Include pinned/sticky sessions even if they don't match the active filter.
2524
+ // Only in the "active" view the "all" view is a plain list with no pin prioritization.
2525
+ if (
2526
+ sessionFilter === 'active' &&
2527
+ activityFilter.size === 0 &&
2528
+ !searchQuery &&
2529
+ (pinnedSessionIds.size > 0 || stickySessionIds.size > 0)
2530
+ ) {
2522
2531
  const filteredIds = new Set(filteredSessions.map((s) => s.id));
2523
2532
  const missingPinned = sessions.filter((s) => isAnyPinned(s.id) && !filteredIds.has(s.id));
2524
2533
  if (missingPinned.length) filteredSessions = [...missingPinned, ...filteredSessions];
@@ -2737,31 +2746,7 @@ function renderSessions() {
2737
2746
 
2738
2747
  sessionsList.innerHTML = html;
2739
2748
  } else {
2740
- const sticky = filteredSessions.filter((s) => isPlacedSticky(s.id));
2741
- const idlePinned = filteredSessions.filter((s) => isPlacedPinned(s.id) && !isSessionActive(s));
2742
- const rest = filteredSessions.filter(
2743
- (s) => (!isPlacedPinned(s.id) && !isPlacedSticky(s.id)) || (isPlacedPinned(s.id) && isSessionActive(s)),
2744
- );
2745
- let html = '';
2746
- if (sticky.length > 0) {
2747
- html += sticky.map(renderSessionCard).join('');
2748
- }
2749
- const isCollapsed = collapsedProjectGroups.has('__pinned__');
2750
- const hasPinned = pinnedSessionIds.size > 0 && filteredSessions.some((s) => pinnedSessionIds.has(s.id));
2751
- if (idlePinned.length > 0 || (hasPinned && isCollapsed)) {
2752
- html += `
2753
- <div class="project-group-header${isCollapsed ? ' collapsed' : ''}" data-group-path="__pinned__">
2754
- <svg class="group-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg>
2755
- <span class="group-name">Pinned</span>
2756
- <span class="group-count">${idlePinned.length}</span>
2757
- </div>
2758
- <div class="project-group-sessions${isCollapsed ? ' collapsed' : ''}">
2759
- ${idlePinned.map(renderSessionCard).join('')}
2760
- </div>
2761
- `;
2762
- }
2763
- html += rest.map(renderSessionCard).join('');
2764
- sessionsList.innerHTML = html;
2749
+ sessionsList.innerHTML = filteredSessions.map(renderSessionCard).join('');
2765
2750
  }
2766
2751
 
2767
2752
  const navItems = getNavigableItems();
package/public/style.css CHANGED
@@ -153,14 +153,13 @@ body::before {
153
153
  }
154
154
 
155
155
  .activity-chip.activity-filter-on {
156
- background: color-mix(in srgb, var(--accent) 14%, var(--bg-deep));
157
- border-color: var(--accent);
158
- box-shadow: inset 0 0 0 1px var(--accent);
156
+ --chip-color: var(--accent);
157
+ background: color-mix(in srgb, var(--chip-color) 9%, var(--bg-deep));
158
+ border-color: color-mix(in srgb, var(--chip-color) 50%, var(--border));
159
+ color: color-mix(in srgb, var(--chip-color) 80%, var(--text-secondary));
159
160
  }
160
161
  .activity-chip.activity-waiting.activity-filter-on {
161
- border-color: var(--warning);
162
- box-shadow: inset 0 0 0 1px var(--warning);
163
- background: color-mix(in srgb, var(--warning) 14%, var(--bg-deep));
162
+ --chip-color: var(--warning);
164
163
  }
165
164
 
166
165
  .activity-dot {
@@ -188,22 +187,12 @@ body::before {
188
187
  opacity: 1;
189
188
  }
190
189
 
191
- .activity-chip.activity-waiting {
192
- color: var(--warning);
193
- border-color: color-mix(in srgb, var(--warning) 40%, var(--border));
194
- }
195
190
  .activity-chip.activity-waiting .activity-dot {
196
191
  background: var(--warning);
197
- box-shadow: 0 0 8px color-mix(in srgb, var(--warning) 60%, transparent);
198
192
  }
199
193
 
200
- .activity-chip.activity-active {
201
- color: color-mix(in srgb, var(--accent) 70%, var(--text-secondary));
202
- border-color: color-mix(in srgb, var(--accent) 18%, var(--border));
203
- }
204
194
  .activity-chip.activity-active .activity-dot {
205
- background: color-mix(in srgb, var(--accent) 75%, var(--text-secondary));
206
- box-shadow: 0 0 4px color-mix(in srgb, var(--accent) 30%, transparent);
195
+ background: color-mix(in srgb, var(--accent) 60%, var(--text-muted));
207
196
  animation: pulse 2.5s ease-in-out infinite;
208
197
  }
209
198