@masslessai/push-todo 4.0.1 → 4.0.2

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.
Files changed (2) hide show
  1. package/lib/daemon.js +48 -9
  2. package/package.json +1 -1
package/lib/daemon.js CHANGED
@@ -1011,6 +1011,24 @@ async function markTaskAsCompleted(displayNumber, taskId, comment) {
1011
1011
  }
1012
1012
  }
1013
1013
 
1014
+ async function hasApprovedConfirmation(displayNumber) {
1015
+ try {
1016
+ const response = await apiRequest(`synced-todos?display_number=${displayNumber}`);
1017
+ if (!response.ok) return false;
1018
+ const data = await response.json();
1019
+ const todos = data.todos || [];
1020
+ if (todos.length === 0) return false;
1021
+ const events = parseJsonField(todos[0].executionEventsJson);
1022
+ for (let i = events.length - 1; i >= 0; i--) {
1023
+ if (events[i].type === 'confirmation_approved') return true;
1024
+ if (events[i].type === 'confirmation_rejected') return false;
1025
+ }
1026
+ return false;
1027
+ } catch {
1028
+ return false;
1029
+ }
1030
+ }
1031
+
1014
1032
  /**
1015
1033
  * Auto-heal: detect if a previous execution already completed work for this task.
1016
1034
  * Checks for existing branch commits and PRs to avoid redundant re-execution.
@@ -1653,15 +1671,36 @@ async function handleTaskCompletion(displayNumber, exitCode) {
1653
1671
  }
1654
1672
  }
1655
1673
 
1656
- // Auto-complete task after successful merge (configurable, default ON)
1674
+ // Auto-complete task (configurable, default ON)
1657
1675
  const taskId = info.taskId;
1658
- if (getAutoCompleteEnabled() && merged && taskId) {
1659
- const comment = semanticSummary
1660
- ? `${semanticSummary} (${durationStr} on ${machineName})`
1661
- : `Completed in ${durationStr} on ${machineName}`;
1662
- const completed = await markTaskAsCompleted(displayNumber, taskId, comment);
1663
- if (!completed) {
1664
- logError(`Task #${displayNumber}: Failed to mark as completed — status is session_finished but not completed`);
1676
+ let autoCompleted = false;
1677
+
1678
+ if (getAutoCompleteEnabled() && taskId) {
1679
+ // Path 1: PR merge (code tasks)
1680
+ if (merged) {
1681
+ const comment = semanticSummary
1682
+ ? `${semanticSummary} (${durationStr} on ${machineName})`
1683
+ : `Completed in ${durationStr} on ${machineName}`;
1684
+ autoCompleted = await markTaskAsCompleted(displayNumber, taskId, comment);
1685
+ if (!autoCompleted) {
1686
+ logError(`Task #${displayNumber}: Failed to mark as completed after merge`);
1687
+ }
1688
+ }
1689
+
1690
+ // Path 2: Confirmation approval (content tasks — tweets, emails, etc.)
1691
+ // If user approved a confirmation AND Claude exited cleanly, the task is done.
1692
+ if (!autoCompleted && !merged) {
1693
+ const approved = await hasApprovedConfirmation(displayNumber);
1694
+ if (approved) {
1695
+ log(`Task #${displayNumber}: user-approved confirmation detected, auto-completing`);
1696
+ const comment = semanticSummary
1697
+ ? `${semanticSummary} (${durationStr} on ${machineName})`
1698
+ : `Confirmed and completed in ${durationStr} on ${machineName}`;
1699
+ autoCompleted = await markTaskAsCompleted(displayNumber, taskId, comment);
1700
+ if (!autoCompleted) {
1701
+ logError(`Task #${displayNumber}: Failed to mark as completed after confirmation`);
1702
+ }
1703
+ }
1665
1704
  }
1666
1705
  }
1667
1706
 
@@ -1670,7 +1709,7 @@ async function handleTaskCompletion(displayNumber, exitCode) {
1670
1709
  summary,
1671
1710
  completedAt: new Date().toISOString(),
1672
1711
  duration,
1673
- status: merged ? 'completed' : 'session_finished',
1712
+ status: autoCompleted ? 'completed' : 'session_finished',
1674
1713
  prUrl,
1675
1714
  sessionId
1676
1715
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masslessai/push-todo",
3
- "version": "4.0.1",
3
+ "version": "4.0.2",
4
4
  "description": "Voice tasks from Push iOS app for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {