@masslessai/push-todo 3.5.2 → 3.5.4

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/daemon.js CHANGED
@@ -459,7 +459,7 @@ function getProjectPath(gitRemote) {
459
459
 
460
460
  try {
461
461
  const data = JSON.parse(readFileSync(REGISTRY_FILE, 'utf8'));
462
- return data.projects?.[gitRemote]?.path || null;
462
+ return data.projects?.[gitRemote]?.localPath || data.projects?.[gitRemote]?.local_path || null;
463
463
  } catch {
464
464
  return null;
465
465
  }
@@ -474,7 +474,7 @@ function getListedProjects() {
474
474
  const data = JSON.parse(readFileSync(REGISTRY_FILE, 'utf8'));
475
475
  const result = {};
476
476
  for (const [remote, info] of Object.entries(data.projects || {})) {
477
- result[remote] = info.path;
477
+ result[remote] = info.localPath || info.local_path;
478
478
  }
479
479
  return result;
480
480
  } catch {
package/lib/fetch.js CHANGED
@@ -88,8 +88,15 @@ export async function listTasks(options = {}) {
88
88
  }
89
89
 
90
90
  // Group by status for display
91
- const active = decryptedTasks.filter(t => !t.isCompleted && !t.is_completed && !t.isBacklog && !t.is_backlog);
92
- const backlog = decryptedTasks.filter(t => !t.isCompleted && !t.is_completed && (t.isBacklog || t.is_backlog));
91
+ // Execution status tasks (queued/running) are separated from regular active tasks
92
+ const getExecStatus = t => t.executionStatus || t.execution_status;
93
+ const isRunningOrQueued = t => {
94
+ const es = getExecStatus(t);
95
+ return es === 'queued' || es === 'running';
96
+ };
97
+ const running = decryptedTasks.filter(t => !t.isCompleted && !t.is_completed && isRunningOrQueued(t));
98
+ const active = decryptedTasks.filter(t => !t.isCompleted && !t.is_completed && !t.isBacklog && !t.is_backlog && !isRunningOrQueued(t));
99
+ const backlog = decryptedTasks.filter(t => !t.isCompleted && !t.is_completed && (t.isBacklog || t.is_backlog) && !isRunningOrQueued(t));
93
100
  const completed = decryptedTasks.filter(t => t.isCompleted || t.is_completed);
94
101
 
95
102
  // Build scope description
@@ -110,8 +117,20 @@ export async function listTasks(options = {}) {
110
117
  }
111
118
  }
112
119
 
120
+ // Show running/queued section first (always, unless viewing backlog/completed only)
121
+ if (!options.backlog && !options.completed && running.length > 0) {
122
+ console.log(`# ${running.length} Running/Queued Tasks (${scope})\n`);
123
+ for (const task of running) {
124
+ const displayNum = task.displayNumber || task.display_number;
125
+ console.log(`---\n### #${displayNum}\n`);
126
+ console.log(formatTaskForDisplay(task));
127
+ console.log('');
128
+ }
129
+ }
130
+
113
131
  // Header
114
- console.log(`# ${tasksToShow.length} Active Tasks (${scope}${backlogSuffix}${includeSuffix})\n`);
132
+ const totalCount = tasksToShow.length;
133
+ console.log(`# ${totalCount} Active Tasks (${scope}${backlogSuffix}${includeSuffix})\n`);
115
134
 
116
135
  // Show full details for each task (matching Python behavior)
117
136
  for (const task of tasksToShow) {
@@ -50,9 +50,18 @@ export function formatTaskForDisplay(task) {
50
50
  const displayNum = task.displayNumber || task.display_number;
51
51
 
52
52
  // Determine status prefix
53
+ const execStatus = task.executionStatus || task.execution_status;
53
54
  let statusPrefix = '';
54
55
  if (task.isCompleted || task.is_completed) {
55
56
  statusPrefix = '✅ '; // Completed
57
+ } else if (execStatus === 'running') {
58
+ statusPrefix = '🔄 '; // Running on Mac
59
+ } else if (execStatus === 'queued') {
60
+ statusPrefix = '⚡ '; // Queued for Mac
61
+ } else if (execStatus === 'failed') {
62
+ statusPrefix = '❌ '; // Failed
63
+ } else if (execStatus === 'needs_clarification') {
64
+ statusPrefix = '❓ '; // Needs clarification
56
65
  } else if (task.isBacklog || task.is_backlog) {
57
66
  statusPrefix = '📦 '; // Backlog
58
67
  }
@@ -127,6 +136,17 @@ export function formatTaskForDisplay(task) {
127
136
  if (sessionId) {
128
137
  lines.push(`**Session:** Available (\`push-todo resume ${displayNum}\`)`);
129
138
  }
139
+ } else if (execStatus === 'running') {
140
+ const machineName = task.executionMachineName || task.execution_machine_name;
141
+ const machineHint = machineName ? ` on ${machineName}` : '';
142
+ lines.push(`**Status:** 🔄 Running${machineHint}`);
143
+ } else if (execStatus === 'queued') {
144
+ lines.push('**Status:** ⚡ Queued for Mac execution');
145
+ } else if (execStatus === 'failed') {
146
+ const error = task.executionError || task.execution_error || 'Unknown error';
147
+ lines.push(`**Status:** ❌ Failed: ${error}`);
148
+ } else if (execStatus === 'needs_clarification') {
149
+ lines.push('**Status:** ❓ Needs clarification');
130
150
  } else if (task.isBacklog || task.is_backlog) {
131
151
  lines.push('**Status:** 📦 Backlog');
132
152
  } else {
@@ -198,9 +218,16 @@ export function formatTaskTable(tasks) {
198
218
  summary = summary.slice(0, 27) + '…';
199
219
  }
200
220
 
221
+ const taskExecStatus = task.executionStatus || task.execution_status;
201
222
  let status = 'Active';
202
223
  if (task.isCompleted || task.is_completed) {
203
224
  status = '✅ Done';
225
+ } else if (taskExecStatus === 'running') {
226
+ status = '🔄 Running';
227
+ } else if (taskExecStatus === 'queued') {
228
+ status = '⚡ Queued';
229
+ } else if (taskExecStatus === 'failed') {
230
+ status = '❌ Failed';
204
231
  } else if (task.isBacklog || task.is_backlog) {
205
232
  status = '📦 Later';
206
233
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masslessai/push-todo",
3
- "version": "3.5.2",
3
+ "version": "3.5.4",
4
4
  "description": "Voice tasks from Push iOS app for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {