claude-task-viewer 1.5.0 → 1.6.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/README.md CHANGED
@@ -26,6 +26,9 @@ Tasks can block other tasks. The viewer shows these relationships clearly — bl
26
26
  ### Notes
27
27
  Add context to any task. Your notes are appended to the task description, so Claude sees them when it reads the task. Use this to clarify requirements, add constraints, or redirect work — all without interrupting Claude's flow.
28
28
 
29
+ ### Search
30
+ Find tasks instantly. Type in the search box to filter across all columns by subject or description. Case-insensitive, real-time results.
31
+
29
32
  ### Project Filtering
30
33
  Filter tasks by project using the dropdown. Working on multiple codebases? See only what's relevant. Combine with the session filter to show just active sessions for a specific project.
31
34
 
@@ -90,6 +93,9 @@ PORT=8080 npx claude-task-viewer
90
93
 
91
94
  # Open browser automatically
92
95
  npx claude-task-viewer --open
96
+
97
+ # Use a different Claude config directory (for multiple accounts)
98
+ npx claude-task-viewer --dir=~/.claude-work
93
99
  ```
94
100
 
95
101
  ## API
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-task-viewer",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "A web-based Kanban board for viewing Claude Code tasks",
5
5
  "main": "server.js",
6
6
  "bin": {
package/public/index.html CHANGED
@@ -469,26 +469,6 @@
469
469
  color: var(--accent);
470
470
  }
471
471
 
472
- .search-input {
473
- background: var(--bg-elevated);
474
- border: 1px solid var(--border);
475
- border-radius: 6px;
476
- padding: 8px 12px;
477
- font-family: var(--mono);
478
- font-size: 12px;
479
- color: var(--text-primary);
480
- width: 200px;
481
- }
482
-
483
- .search-input:focus {
484
- outline: none;
485
- border-color: var(--accent);
486
- }
487
-
488
- .search-input::placeholder {
489
- color: var(--text-muted);
490
- }
491
-
492
472
  .icon-btn {
493
473
  width: 32px;
494
474
  height: 32px;
@@ -1039,8 +1019,6 @@
1039
1019
  <p id="session-meta" class="view-meta"></p>
1040
1020
  </div>
1041
1021
  <div class="view-actions">
1042
- <input type="text" id="task-search" class="search-input"
1043
- placeholder="Search tasks..." oninput="searchTasks(this.value)">
1044
1022
  <div class="view-progress">
1045
1023
  <div class="progress-bar">
1046
1024
  <div id="progress-bar" class="progress-fill" style="width: 0%"></div>
@@ -1112,7 +1090,6 @@
1112
1090
  let viewMode = 'session';
1113
1091
  let sessionFilter = localStorage.getItem('sessionFilter') || 'all'; // 'all' or 'active'
1114
1092
  let filterProject = null; // null = all projects, or project path to filter
1115
- let searchQuery = '';
1116
1093
 
1117
1094
  // DOM
1118
1095
  const sessionsList = document.getElementById('sessions-list');
@@ -1184,7 +1161,6 @@
1184
1161
  async function fetchTasks(sessionId) {
1185
1162
  try {
1186
1163
  viewMode = 'session';
1187
- clearSearch();
1188
1164
  const res = await fetch(`/api/sessions/${sessionId}`);
1189
1165
  currentTasks = await res.json();
1190
1166
  currentSessionId = sessionId;
@@ -1198,7 +1174,6 @@
1198
1174
  try {
1199
1175
  viewMode = 'all';
1200
1176
  currentSessionId = null;
1201
- clearSearch();
1202
1177
  const res = await fetch('/api/tasks/all');
1203
1178
  let tasks = await res.json();
1204
1179
  if (filterProject) {
@@ -1336,17 +1311,9 @@
1336
1311
  }
1337
1312
 
1338
1313
  function renderKanban() {
1339
- let filteredTasks = currentTasks;
1340
- if (searchQuery) {
1341
- filteredTasks = currentTasks.filter(t =>
1342
- t.subject.toLowerCase().includes(searchQuery) ||
1343
- (t.description && t.description.toLowerCase().includes(searchQuery))
1344
- );
1345
- }
1346
-
1347
- const pending = filteredTasks.filter(t => t.status === 'pending');
1348
- const inProgress = filteredTasks.filter(t => t.status === 'in_progress');
1349
- const completed = filteredTasks.filter(t => t.status === 'completed');
1314
+ const pending = currentTasks.filter(t => t.status === 'pending');
1315
+ const inProgress = currentTasks.filter(t => t.status === 'in_progress');
1316
+ const completed = currentTasks.filter(t => t.status === 'completed');
1350
1317
 
1351
1318
  pendingCount.textContent = pending.length;
1352
1319
  inProgressCount.textContent = inProgress.length;
@@ -1538,17 +1505,6 @@
1538
1505
  showAllTasks();
1539
1506
  }
1540
1507
 
1541
- function searchTasks(query) {
1542
- searchQuery = query.toLowerCase();
1543
- renderKanban();
1544
- }
1545
-
1546
- function clearSearch() {
1547
- searchQuery = '';
1548
- const searchInput = document.getElementById('task-search');
1549
- if (searchInput) searchInput.value = '';
1550
- }
1551
-
1552
1508
  function updateProjectDropdown() {
1553
1509
  const dropdown = document.getElementById('project-filter');
1554
1510
  const projects = [...new Set(sessions.map(s => s.project).filter(Boolean))].sort();
package/server.js CHANGED
@@ -10,7 +10,24 @@ const os = require('os');
10
10
 
11
11
  const app = express();
12
12
  const PORT = process.env.PORT || 3456;
13
- const CLAUDE_DIR = process.env.CLAUDE_DIR || path.join(os.homedir(), '.claude');
13
+
14
+ // Parse --dir flag for custom Claude directory
15
+ function getClaudeDir() {
16
+ const dirIndex = process.argv.findIndex(arg => arg.startsWith('--dir'));
17
+ if (dirIndex !== -1) {
18
+ const arg = process.argv[dirIndex];
19
+ if (arg.includes('=')) {
20
+ const dir = arg.split('=')[1];
21
+ return dir.startsWith('~') ? dir.replace('~', os.homedir()) : dir;
22
+ } else if (process.argv[dirIndex + 1]) {
23
+ const dir = process.argv[dirIndex + 1];
24
+ return dir.startsWith('~') ? dir.replace('~', os.homedir()) : dir;
25
+ }
26
+ }
27
+ return process.env.CLAUDE_DIR || path.join(os.homedir(), '.claude');
28
+ }
29
+
30
+ const CLAUDE_DIR = getClaudeDir();
14
31
  const TASKS_DIR = path.join(CLAUDE_DIR, 'tasks');
15
32
  const PROJECTS_DIR = path.join(CLAUDE_DIR, 'projects');
16
33