@masslessai/push-todo 4.2.2 → 4.2.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/README.md +68 -47
- package/lib/daemon.js +4 -0
- package/lib/launchagent.js +9 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,69 +1,94 @@
|
|
|
1
1
|
# @masslessai/push-todo
|
|
2
2
|
|
|
3
|
-
Voice tasks from the [Push iOS app](https://pushto.do) for Claude Code.
|
|
3
|
+
Voice tasks from the [Push iOS app](https://pushto.do) for Claude Code, Codex, and OpenClaw.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install -g @masslessai/push-todo
|
|
9
|
+
push-todo connect --auto
|
|
9
10
|
```
|
|
10
11
|
|
|
12
|
+
The install sets up skill integrations for all detected agents (Claude Code, Codex, OpenClaw). The `connect --auto` command handles authentication, project discovery, and LaunchAgent installation in one step.
|
|
13
|
+
|
|
11
14
|
## Quick Start
|
|
12
15
|
|
|
13
16
|
```bash
|
|
14
|
-
# Authenticate and set up
|
|
15
|
-
push-todo connect
|
|
16
|
-
|
|
17
17
|
# List your tasks
|
|
18
18
|
push-todo
|
|
19
19
|
|
|
20
20
|
# Work on a specific task
|
|
21
21
|
push-todo 427
|
|
22
|
+
|
|
23
|
+
# Create a task from the terminal
|
|
24
|
+
push-todo create "Fix the auth redirect bug"
|
|
25
|
+
|
|
26
|
+
# Queue tasks for background execution
|
|
27
|
+
push-todo --queue 1,2,3
|
|
22
28
|
```
|
|
23
29
|
|
|
24
30
|
## Features
|
|
25
31
|
|
|
26
32
|
- **Voice Tasks**: Tasks captured by voice on your iPhone sync to your terminal
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
33
|
+
- **Background Daemon**: Executes tasks automatically via Claude Code (or Codex/OpenClaw) in git worktrees
|
|
34
|
+
- **LaunchAgent**: Daemon starts on login and restarts on crash — no manual babysitting
|
|
35
|
+
- **Multi-Agent**: Same CLI works with Claude Code, OpenAI Codex, and OpenClaw
|
|
36
|
+
- **Project Routing**: AI routes voice tasks to the right project using learned vocabulary
|
|
37
|
+
- **E2EE Support**: End-to-end encrypted tasks decrypted via iCloud Keychain
|
|
38
|
+
- **Cron Jobs**: Schedule recurring notifications and health checks
|
|
31
39
|
|
|
32
40
|
## Commands
|
|
33
41
|
|
|
34
42
|
| Command | Description |
|
|
35
43
|
|---------|-------------|
|
|
36
|
-
| `push-todo` | List active tasks |
|
|
44
|
+
| `push-todo` | List active tasks for current project |
|
|
37
45
|
| `push-todo <number>` | View specific task |
|
|
38
|
-
| `push-todo
|
|
46
|
+
| `push-todo create <title>` | Create a new todo |
|
|
47
|
+
| `push-todo connect --auto` | One-command setup (auth + projects + daemon) |
|
|
48
|
+
| `push-todo connect` | Run connection diagnostics |
|
|
39
49
|
| `push-todo search <query>` | Search tasks |
|
|
40
|
-
| `push-todo
|
|
50
|
+
| `push-todo review` | Review and mark completed tasks |
|
|
51
|
+
| `push-todo update` | Update CLI and check agent versions |
|
|
41
52
|
| `push-todo --watch` | Live monitoring UI |
|
|
53
|
+
| `push-todo --queue 1,2,3` | Queue tasks for daemon execution |
|
|
54
|
+
| `push-todo --queue-batch` | Auto-queue a batch of tasks |
|
|
55
|
+
| `push-todo --resume <number>` | Resume daemon's Claude session for a task |
|
|
56
|
+
| `push-todo --all-projects` | Tasks from all projects |
|
|
57
|
+
| `push-todo --backlog` | Show backlog items |
|
|
58
|
+
| `push-todo --completed` | Show completed items |
|
|
59
|
+
| `push-todo --json` | Output as JSON |
|
|
42
60
|
|
|
43
|
-
##
|
|
44
|
-
|
|
45
|
-
This package works as a Claude Code plugin:
|
|
61
|
+
## Daemon Management
|
|
46
62
|
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
63
|
+
```bash
|
|
64
|
+
push-todo --daemon-status # Show daemon + LaunchAgent status
|
|
65
|
+
push-todo --daemon-install # Install LaunchAgent (auto-start on login)
|
|
66
|
+
push-todo --daemon-uninstall # Remove LaunchAgent
|
|
67
|
+
push-todo --daemon-start # Start daemon manually
|
|
68
|
+
push-todo --daemon-stop # Stop daemon
|
|
51
69
|
```
|
|
52
70
|
|
|
53
|
-
|
|
71
|
+
The daemon self-updates hourly when idle. Two-layer reliability: LaunchAgent for OS-level lifecycle, self-healing for edge cases.
|
|
54
72
|
|
|
55
|
-
|
|
56
|
-
- **Session End**: Reports session completion
|
|
57
|
-
|
|
58
|
-
## Options
|
|
73
|
+
## Cron Jobs
|
|
59
74
|
|
|
60
75
|
```bash
|
|
61
|
-
push-todo --
|
|
62
|
-
push-todo --
|
|
63
|
-
push-todo --
|
|
64
|
-
push-todo
|
|
65
|
-
push-todo
|
|
66
|
-
|
|
76
|
+
push-todo cron add --name "standup" --every 24h --notify "Time for standup"
|
|
77
|
+
push-todo cron add --name "weekly-review" --cron "0 9 * * 1" --create-todo "Weekly code review"
|
|
78
|
+
push-todo cron add --name "check-deps" --every 7d --health-check /path/to/project --scope deps
|
|
79
|
+
push-todo cron list
|
|
80
|
+
push-todo cron remove <id>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Claude Code Integration
|
|
84
|
+
|
|
85
|
+
This package installs as a Claude Code skill (not plugin) for a clean `/push-todo` command:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
/push-todo List your voice tasks
|
|
89
|
+
/push-todo 427 Work on task #427
|
|
90
|
+
/push-todo review Review completed tasks
|
|
91
|
+
/push-todo setup Configure connection
|
|
67
92
|
```
|
|
68
93
|
|
|
69
94
|
## Configuration
|
|
@@ -71,37 +96,33 @@ push-todo --queue 1,2,3 # Queue tasks for daemon
|
|
|
71
96
|
Config stored at `~/.config/push/config`:
|
|
72
97
|
|
|
73
98
|
```bash
|
|
74
|
-
push-todo setting
|
|
75
|
-
push-todo setting auto-commit
|
|
99
|
+
push-todo setting # Show all settings
|
|
100
|
+
push-todo setting auto-commit # Toggle auto-commit
|
|
101
|
+
push-todo setting auto-update # Toggle daemon self-update
|
|
76
102
|
```
|
|
77
103
|
|
|
78
|
-
##
|
|
79
|
-
|
|
80
|
-
- Node.js 18+
|
|
81
|
-
- macOS (for E2EE features)
|
|
82
|
-
- [Push iOS app](https://apps.apple.com/app/push-todo/id6738972839)
|
|
83
|
-
|
|
84
|
-
## API
|
|
104
|
+
## Programmatic API
|
|
85
105
|
|
|
86
106
|
```javascript
|
|
87
107
|
import { listTasks, showTask, searchTasks } from '@masslessai/push-todo';
|
|
88
108
|
|
|
89
|
-
// List tasks
|
|
90
109
|
const tasks = await listTasks({ allProjects: true });
|
|
91
|
-
|
|
92
|
-
// Get specific task
|
|
93
110
|
const task = await showTask(427);
|
|
94
|
-
|
|
95
|
-
// Search
|
|
96
|
-
const results = await searchTasks('bug');
|
|
111
|
+
const results = await searchTasks('auth bug');
|
|
97
112
|
```
|
|
98
113
|
|
|
114
|
+
## Requirements
|
|
115
|
+
|
|
116
|
+
- Node.js 18+
|
|
117
|
+
- macOS (for LaunchAgent and E2EE)
|
|
118
|
+
- [Push iOS app](https://pushto.do)
|
|
119
|
+
|
|
99
120
|
## Documentation
|
|
100
121
|
|
|
101
|
-
- [Skill
|
|
122
|
+
- [Skill Instructions](./SKILL.md) — how the AI agent uses push-todo
|
|
102
123
|
- [Push Website](https://pushto.do)
|
|
103
|
-
- [
|
|
124
|
+
- [GitHub Issues](https://github.com/MasslessAI/push-todo-cli/issues)
|
|
104
125
|
|
|
105
126
|
## License
|
|
106
127
|
|
|
107
|
-
MIT
|
|
128
|
+
MIT
|
package/lib/daemon.js
CHANGED
|
@@ -1666,6 +1666,7 @@ function respawnWithInjectedMessage(displayNumber) {
|
|
|
1666
1666
|
const claudeArgs = [
|
|
1667
1667
|
'--continue', sessionId,
|
|
1668
1668
|
'-p', injectionPrompt,
|
|
1669
|
+
'--verbose',
|
|
1669
1670
|
'--allowedTools', allowedTools,
|
|
1670
1671
|
'--output-format', 'stream-json',
|
|
1671
1672
|
'--permission-mode', 'bypassPermissions',
|
|
@@ -2330,6 +2331,7 @@ async function executeTask(task) {
|
|
|
2330
2331
|
? [
|
|
2331
2332
|
'--continue', previousSessionId,
|
|
2332
2333
|
'-p', prompt,
|
|
2334
|
+
'--verbose',
|
|
2333
2335
|
'--allowedTools', allowedTools,
|
|
2334
2336
|
'--output-format', 'stream-json',
|
|
2335
2337
|
'--permission-mode', 'bypassPermissions',
|
|
@@ -2337,6 +2339,7 @@ async function executeTask(task) {
|
|
|
2337
2339
|
]
|
|
2338
2340
|
: [
|
|
2339
2341
|
'-p', prompt,
|
|
2342
|
+
'--verbose',
|
|
2340
2343
|
'--allowedTools', allowedTools,
|
|
2341
2344
|
'--output-format', 'stream-json',
|
|
2342
2345
|
'--permission-mode', 'bypassPermissions',
|
|
@@ -3059,6 +3062,7 @@ If dependencies are current, say "All dependencies up to date."`,
|
|
|
3059
3062
|
|
|
3060
3063
|
const claudeArgs = [
|
|
3061
3064
|
'-p', prompt,
|
|
3065
|
+
'--verbose',
|
|
3062
3066
|
'--allowedTools', allowedTools,
|
|
3063
3067
|
'--output-format', 'stream-json',
|
|
3064
3068
|
'--permission-mode', 'bypassPermissions',
|
package/lib/launchagent.js
CHANGED
|
@@ -103,13 +103,13 @@ export function getStatus() {
|
|
|
103
103
|
|
|
104
104
|
if (installed) {
|
|
105
105
|
try {
|
|
106
|
-
|
|
107
|
-
encoding: 'utf8',
|
|
106
|
+
execFileSync('launchctl', ['list', LABEL], {
|
|
108
107
|
timeout: 5000,
|
|
108
|
+
stdio: ['ignore', 'pipe', 'ignore'], // capture stdout, suppress stderr
|
|
109
109
|
});
|
|
110
|
-
loaded =
|
|
110
|
+
loaded = true; // If no error thrown, service exists
|
|
111
111
|
} catch {
|
|
112
|
-
loaded = false;
|
|
112
|
+
loaded = false; // launchctl exits non-zero if service not found
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -135,11 +135,11 @@ export function install() {
|
|
|
135
135
|
if (existsSync(PLIST_PATH)) {
|
|
136
136
|
const existing = readFileSync(PLIST_PATH, 'utf8');
|
|
137
137
|
if (existing === newContent) {
|
|
138
|
-
// Ensure loaded
|
|
138
|
+
// Ensure loaded (suppress stderr — already-loaded plist emits noise)
|
|
139
139
|
try {
|
|
140
140
|
execFileSync('launchctl', ['load', '-w', PLIST_PATH], {
|
|
141
|
-
encoding: 'utf8',
|
|
142
141
|
timeout: 5000,
|
|
142
|
+
stdio: ['ignore', 'ignore', 'ignore'],
|
|
143
143
|
});
|
|
144
144
|
} catch {}
|
|
145
145
|
return { success: true, message: 'LaunchAgent already installed', alreadyInstalled: true };
|
|
@@ -148,8 +148,8 @@ export function install() {
|
|
|
148
148
|
// Content changed (e.g., node path updated) — unload old, write new
|
|
149
149
|
try {
|
|
150
150
|
execFileSync('launchctl', ['unload', PLIST_PATH], {
|
|
151
|
-
encoding: 'utf8',
|
|
152
151
|
timeout: 5000,
|
|
152
|
+
stdio: ['ignore', 'ignore', 'ignore'],
|
|
153
153
|
});
|
|
154
154
|
} catch {}
|
|
155
155
|
}
|
|
@@ -159,8 +159,8 @@ export function install() {
|
|
|
159
159
|
|
|
160
160
|
// Load it
|
|
161
161
|
execFileSync('launchctl', ['load', '-w', PLIST_PATH], {
|
|
162
|
-
encoding: 'utf8',
|
|
163
162
|
timeout: 5000,
|
|
163
|
+
stdio: ['ignore', 'ignore', 'ignore'],
|
|
164
164
|
});
|
|
165
165
|
|
|
166
166
|
return { success: true, message: 'LaunchAgent installed and loaded' };
|
|
@@ -183,8 +183,8 @@ export function uninstall() {
|
|
|
183
183
|
// Unload
|
|
184
184
|
try {
|
|
185
185
|
execFileSync('launchctl', ['unload', PLIST_PATH], {
|
|
186
|
-
encoding: 'utf8',
|
|
187
186
|
timeout: 5000,
|
|
187
|
+
stdio: ['ignore', 'ignore', 'ignore'],
|
|
188
188
|
});
|
|
189
189
|
} catch {}
|
|
190
190
|
|