@masslessai/push-todo 3.1.0 → 3.2.1
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/.claude-plugin/plugin.json +1 -1
- package/lib/cli.js +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +251 -14
package/lib/cli.js
CHANGED
|
@@ -15,7 +15,7 @@ import { ensureDaemonRunning, getDaemonStatus, startDaemon, stopDaemon } from '.
|
|
|
15
15
|
import { getScreenshotPath, screenshotExists, openScreenshot } from './utils/screenshots.js';
|
|
16
16
|
import { bold, red, cyan, dim, green } from './utils/colors.js';
|
|
17
17
|
|
|
18
|
-
const VERSION = '3.1
|
|
18
|
+
const VERSION = '3.2.1';
|
|
19
19
|
|
|
20
20
|
const HELP_TEXT = `
|
|
21
21
|
${bold('push-todo')} - Voice tasks from Push iOS app for Claude Code
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Post-install script for Push CLI.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Sets up integrations for ALL detected AI coding clients:
|
|
6
|
+
* 1. Claude Code - symlink to ~/.claude/plugins/
|
|
7
|
+
* 2. OpenAI Codex - AGENTS.md in ~/.codex/
|
|
8
|
+
* 3. Clawdbot - SKILL.md in ~/.clawdbot/skills/
|
|
9
|
+
* 4. Downloads native keychain helper binary (macOS)
|
|
7
10
|
*/
|
|
8
11
|
|
|
9
|
-
import { createWriteStream, existsSync, mkdirSync, unlinkSync, readFileSync, symlinkSync, lstatSync, readlinkSync, rmSync } from 'fs';
|
|
12
|
+
import { createWriteStream, existsSync, mkdirSync, unlinkSync, readFileSync, writeFileSync, symlinkSync, lstatSync, readlinkSync, rmSync, appendFileSync } from 'fs';
|
|
10
13
|
import { chmod, stat } from 'fs/promises';
|
|
11
14
|
import { pipeline } from 'stream/promises';
|
|
12
15
|
import { join, dirname } from 'path';
|
|
@@ -19,15 +22,24 @@ const __dirname = dirname(__filename);
|
|
|
19
22
|
// Package root (one level up from scripts/)
|
|
20
23
|
const PACKAGE_ROOT = join(__dirname, '..');
|
|
21
24
|
|
|
22
|
-
// Claude Code
|
|
25
|
+
// Claude Code locations
|
|
23
26
|
const CLAUDE_DIR = join(homedir(), '.claude');
|
|
24
27
|
const PLUGIN_DIR = join(CLAUDE_DIR, 'plugins');
|
|
25
28
|
const PLUGIN_LINK = join(PLUGIN_DIR, 'push-todo');
|
|
26
|
-
|
|
27
|
-
// Legacy location (for migration)
|
|
28
29
|
const LEGACY_SKILL_DIR = join(CLAUDE_DIR, 'skills');
|
|
29
30
|
const LEGACY_SKILL_LINK = join(LEGACY_SKILL_DIR, 'push-todo');
|
|
30
31
|
|
|
32
|
+
// OpenAI Codex locations
|
|
33
|
+
const CODEX_DIR = join(homedir(), '.codex');
|
|
34
|
+
const CODEX_SKILL_DIR = join(CODEX_DIR, 'skills', 'push-todo');
|
|
35
|
+
const CODEX_SKILL_FILE = join(CODEX_SKILL_DIR, 'SKILL.md');
|
|
36
|
+
const CODEX_AGENTS_FILE = join(CODEX_DIR, 'AGENTS.md');
|
|
37
|
+
|
|
38
|
+
// Clawdbot locations
|
|
39
|
+
const CLAWDBOT_DIR = join(homedir(), '.clawdbot');
|
|
40
|
+
const CLAWDBOT_SKILL_DIR = join(CLAWDBOT_DIR, 'skills', 'push-todo');
|
|
41
|
+
const CLAWDBOT_SKILL_FILE = join(CLAWDBOT_SKILL_DIR, 'SKILL.md');
|
|
42
|
+
|
|
31
43
|
const BINARY_NAME = 'push-keychain-helper';
|
|
32
44
|
const BINARY_DIR = join(__dirname, '../bin');
|
|
33
45
|
const BINARY_PATH = join(BINARY_DIR, BINARY_NAME);
|
|
@@ -130,6 +142,189 @@ function migrateFromPython() {
|
|
|
130
142
|
}
|
|
131
143
|
}
|
|
132
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Set up OpenAI Codex integration.
|
|
147
|
+
* Creates ~/.codex/skills/push-todo/SKILL.md and updates AGENTS.md
|
|
148
|
+
*
|
|
149
|
+
* @returns {boolean} True if Codex was detected and set up
|
|
150
|
+
*/
|
|
151
|
+
function setupCodex() {
|
|
152
|
+
// Only set up if Codex directory exists (user has Codex installed)
|
|
153
|
+
if (!existsSync(CODEX_DIR)) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
console.log('[push-todo] Detected OpenAI Codex installation');
|
|
158
|
+
|
|
159
|
+
// Skill file content
|
|
160
|
+
const SKILL_CONTENT = `# Push Tasks Skill
|
|
161
|
+
|
|
162
|
+
This skill retrieves and processes tasks sent from the Push iOS app.
|
|
163
|
+
|
|
164
|
+
## Activation
|
|
165
|
+
|
|
166
|
+
This skill activates when the user:
|
|
167
|
+
- Says "push-todo", "push todo", "push tasks", or "tasks from push"
|
|
168
|
+
- Runs \`$push-todo\` command
|
|
169
|
+
- Mentions "tasks from iPhone" or "mobile tasks"
|
|
170
|
+
- Asks about "pending tasks" or "voice tasks"
|
|
171
|
+
|
|
172
|
+
## Commands
|
|
173
|
+
|
|
174
|
+
Run these in the terminal:
|
|
175
|
+
|
|
176
|
+
| Command | Description |
|
|
177
|
+
|---------|-------------|
|
|
178
|
+
| \`push-todo\` | List active tasks |
|
|
179
|
+
| \`push-todo 427\` | Show task #427 |
|
|
180
|
+
| \`push-todo connect\` | Connect/fix issues |
|
|
181
|
+
| \`push-todo search "query"\` | Search tasks |
|
|
182
|
+
| \`push-todo --help\` | All options |
|
|
183
|
+
|
|
184
|
+
## Instructions
|
|
185
|
+
|
|
186
|
+
When this skill is activated:
|
|
187
|
+
|
|
188
|
+
1. **Check connection** - If user hasn't set up, run:
|
|
189
|
+
\`\`\`bash
|
|
190
|
+
push-todo connect
|
|
191
|
+
\`\`\`
|
|
192
|
+
|
|
193
|
+
2. **Fetch tasks** - List available tasks:
|
|
194
|
+
\`\`\`bash
|
|
195
|
+
push-todo
|
|
196
|
+
\`\`\`
|
|
197
|
+
|
|
198
|
+
3. **Work on specific task** - Get task details:
|
|
199
|
+
\`\`\`bash
|
|
200
|
+
push-todo 427
|
|
201
|
+
\`\`\`
|
|
202
|
+
|
|
203
|
+
4. **Present the task** to the user with a brief summary and offer to help implement it.
|
|
204
|
+
`;
|
|
205
|
+
|
|
206
|
+
// AGENTS.md bootstrap content
|
|
207
|
+
const AGENTS_SECTION = `
|
|
208
|
+
## Push Tasks Integration
|
|
209
|
+
|
|
210
|
+
At the start of each session, check for pending tasks from the Push iOS app:
|
|
211
|
+
|
|
212
|
+
1. Run this command silently:
|
|
213
|
+
\`\`\`bash
|
|
214
|
+
push-todo --json 2>/dev/null | head -1
|
|
215
|
+
\`\`\`
|
|
216
|
+
|
|
217
|
+
2. If tasks exist, inform the user:
|
|
218
|
+
"You have X task(s) from Push. Type $push-todo to see them."
|
|
219
|
+
|
|
220
|
+
3. If no output or error, proceed normally without mentioning Push.
|
|
221
|
+
`;
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
// Create skill directory and SKILL.md
|
|
225
|
+
mkdirSync(CODEX_SKILL_DIR, { recursive: true });
|
|
226
|
+
writeFileSync(CODEX_SKILL_FILE, SKILL_CONTENT);
|
|
227
|
+
console.log('[push-todo] Codex: Created skills/push-todo/SKILL.md');
|
|
228
|
+
|
|
229
|
+
// Update AGENTS.md for session-start bootstrap
|
|
230
|
+
if (existsSync(CODEX_AGENTS_FILE)) {
|
|
231
|
+
const content = readFileSync(CODEX_AGENTS_FILE, 'utf8');
|
|
232
|
+
if (content.includes('Push Tasks Integration')) {
|
|
233
|
+
// Update existing section (replace old Python references)
|
|
234
|
+
const updated = content.replace(
|
|
235
|
+
/## Push Tasks Integration[\s\S]*?(?=\n## |$)/,
|
|
236
|
+
AGENTS_SECTION.trim() + '\n\n'
|
|
237
|
+
);
|
|
238
|
+
writeFileSync(CODEX_AGENTS_FILE, updated);
|
|
239
|
+
console.log('[push-todo] Codex: Updated AGENTS.md');
|
|
240
|
+
} else {
|
|
241
|
+
appendFileSync(CODEX_AGENTS_FILE, AGENTS_SECTION);
|
|
242
|
+
console.log('[push-todo] Codex: Added to AGENTS.md');
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
writeFileSync(CODEX_AGENTS_FILE, AGENTS_SECTION.trim() + '\n');
|
|
246
|
+
console.log('[push-todo] Codex: Created AGENTS.md');
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return true;
|
|
250
|
+
} catch (error) {
|
|
251
|
+
console.log(`[push-todo] Codex: Setup failed: ${error.message}`);
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Set up Clawdbot integration.
|
|
258
|
+
* Creates ~/.clawdbot/skills/push-todo/SKILL.md
|
|
259
|
+
*
|
|
260
|
+
* @returns {boolean} True if Clawdbot was detected and set up
|
|
261
|
+
*/
|
|
262
|
+
function setupClawdbot() {
|
|
263
|
+
// Only set up if Clawdbot directory exists (user has Clawdbot installed)
|
|
264
|
+
if (!existsSync(CLAWDBOT_DIR)) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
console.log('[push-todo] Detected Clawdbot installation');
|
|
269
|
+
|
|
270
|
+
const SKILL_CONTENT = `# Push Tasks
|
|
271
|
+
|
|
272
|
+
Voice tasks captured on iPhone, ready to work on.
|
|
273
|
+
|
|
274
|
+
## Commands
|
|
275
|
+
|
|
276
|
+
Run these in the terminal:
|
|
277
|
+
|
|
278
|
+
| Command | Description |
|
|
279
|
+
|---------|-------------|
|
|
280
|
+
| \`push-todo\` | List active tasks |
|
|
281
|
+
| \`push-todo 427\` | Show task #427 |
|
|
282
|
+
| \`push-todo connect\` | Connect/fix issues |
|
|
283
|
+
| \`push-todo search "query"\` | Search tasks |
|
|
284
|
+
| \`push-todo --help\` | All options |
|
|
285
|
+
|
|
286
|
+
## Quick Start
|
|
287
|
+
|
|
288
|
+
If not connected yet, run:
|
|
289
|
+
\`\`\`bash
|
|
290
|
+
push-todo connect
|
|
291
|
+
\`\`\`
|
|
292
|
+
|
|
293
|
+
To see tasks:
|
|
294
|
+
\`\`\`bash
|
|
295
|
+
push-todo
|
|
296
|
+
\`\`\`
|
|
297
|
+
|
|
298
|
+
To work on a specific task:
|
|
299
|
+
\`\`\`bash
|
|
300
|
+
push-todo 427
|
|
301
|
+
\`\`\`
|
|
302
|
+
|
|
303
|
+
## Session Start
|
|
304
|
+
|
|
305
|
+
At the start of each session, check for tasks:
|
|
306
|
+
\`\`\`bash
|
|
307
|
+
push-todo --json 2>/dev/null | head -1
|
|
308
|
+
\`\`\`
|
|
309
|
+
If tasks exist, inform the user.
|
|
310
|
+
`;
|
|
311
|
+
|
|
312
|
+
try {
|
|
313
|
+
mkdirSync(CLAWDBOT_SKILL_DIR, { recursive: true });
|
|
314
|
+
|
|
315
|
+
if (existsSync(CLAWDBOT_SKILL_FILE)) {
|
|
316
|
+
console.log('[push-todo] Clawdbot: SKILL.md already exists, updating...');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
writeFileSync(CLAWDBOT_SKILL_FILE, SKILL_CONTENT);
|
|
320
|
+
console.log('[push-todo] Clawdbot: Created skills/push-todo/SKILL.md');
|
|
321
|
+
return true;
|
|
322
|
+
} catch (error) {
|
|
323
|
+
console.log(`[push-todo] Clawdbot: Could not set up SKILL.md: ${error.message}`);
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
133
328
|
/**
|
|
134
329
|
* Download a file from URL to destination.
|
|
135
330
|
*
|
|
@@ -184,35 +379,66 @@ async function main() {
|
|
|
184
379
|
|
|
185
380
|
// Step 3: Set up Claude Code plugin symlink
|
|
186
381
|
console.log('[push-todo] Setting up Claude Code plugin...');
|
|
187
|
-
const
|
|
382
|
+
const claudeSuccess = setupClaudePlugin();
|
|
188
383
|
console.log('');
|
|
189
384
|
|
|
190
|
-
// Step 4:
|
|
385
|
+
// Step 4: Set up OpenAI Codex (if installed)
|
|
386
|
+
const codexSuccess = setupCodex();
|
|
387
|
+
if (codexSuccess) console.log('');
|
|
388
|
+
|
|
389
|
+
// Step 5: Set up Clawdbot (if installed)
|
|
390
|
+
const clawdbotSuccess = setupClawdbot();
|
|
391
|
+
if (clawdbotSuccess) console.log('');
|
|
392
|
+
|
|
393
|
+
// Track which clients were set up
|
|
394
|
+
const clients = [];
|
|
395
|
+
if (claudeSuccess) clients.push('Claude Code');
|
|
396
|
+
if (codexSuccess) clients.push('OpenAI Codex');
|
|
397
|
+
if (clawdbotSuccess) clients.push('Clawdbot');
|
|
398
|
+
|
|
399
|
+
// Step 6: Download native binary (macOS only)
|
|
191
400
|
if (platform() !== 'darwin') {
|
|
192
401
|
console.log('[push-todo] Skipping native binary (macOS only)');
|
|
193
402
|
console.log('[push-todo] E2EE features will not be available.');
|
|
194
403
|
console.log('');
|
|
195
|
-
console.log('[push-todo] Installation complete
|
|
196
|
-
if (
|
|
197
|
-
console.log(
|
|
404
|
+
console.log('[push-todo] Installation complete!');
|
|
405
|
+
if (clients.length > 0) {
|
|
406
|
+
console.log(`[push-todo] Configured for: ${clients.join(', ')}`);
|
|
198
407
|
}
|
|
199
408
|
return;
|
|
200
409
|
}
|
|
201
410
|
|
|
202
411
|
// Check if binary already exists and is valid
|
|
412
|
+
let binaryExists = false;
|
|
203
413
|
if (existsSync(BINARY_PATH)) {
|
|
204
414
|
try {
|
|
205
415
|
const stats = await stat(BINARY_PATH);
|
|
206
416
|
if (stats.size > 0) {
|
|
207
417
|
console.log('[push-todo] Native binary already installed.');
|
|
208
|
-
|
|
209
|
-
return;
|
|
418
|
+
binaryExists = true;
|
|
210
419
|
}
|
|
211
420
|
} catch {
|
|
212
421
|
// Continue to download
|
|
213
422
|
}
|
|
214
423
|
}
|
|
215
424
|
|
|
425
|
+
if (binaryExists) {
|
|
426
|
+
// Skip download, show summary
|
|
427
|
+
console.log('');
|
|
428
|
+
console.log('[push-todo] Installation complete!');
|
|
429
|
+
if (clients.length > 0) {
|
|
430
|
+
console.log(`[push-todo] Configured for: ${clients.join(', ')}`);
|
|
431
|
+
}
|
|
432
|
+
console.log('');
|
|
433
|
+
console.log('[push-todo] Quick start:');
|
|
434
|
+
console.log('[push-todo] push-todo connect Set up authentication');
|
|
435
|
+
console.log('[push-todo] push-todo List your tasks');
|
|
436
|
+
if (claudeSuccess) console.log('[push-todo] /push-todo Use in Claude Code');
|
|
437
|
+
if (codexSuccess) console.log('[push-todo] $push-todo Use in OpenAI Codex');
|
|
438
|
+
if (clawdbotSuccess) console.log('[push-todo] /push-todo Use in Clawdbot');
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
|
|
216
442
|
// Determine architecture
|
|
217
443
|
const archType = arch();
|
|
218
444
|
const url = archType === 'arm64' ? BINARY_URL : BINARY_URL_X64;
|
|
@@ -233,11 +459,22 @@ async function main() {
|
|
|
233
459
|
|
|
234
460
|
console.log('');
|
|
235
461
|
console.log('[push-todo] Installation complete!');
|
|
462
|
+
if (clients.length > 0) {
|
|
463
|
+
console.log(`[push-todo] Configured for: ${clients.join(', ')}`);
|
|
464
|
+
}
|
|
236
465
|
console.log('');
|
|
237
466
|
console.log('[push-todo] Quick start:');
|
|
238
467
|
console.log('[push-todo] push-todo connect Set up authentication');
|
|
239
468
|
console.log('[push-todo] push-todo List your tasks');
|
|
240
|
-
|
|
469
|
+
if (claudeSuccess) {
|
|
470
|
+
console.log('[push-todo] /push-todo Use in Claude Code');
|
|
471
|
+
}
|
|
472
|
+
if (codexSuccess) {
|
|
473
|
+
console.log('[push-todo] $push-todo Use in OpenAI Codex');
|
|
474
|
+
}
|
|
475
|
+
if (clawdbotSuccess) {
|
|
476
|
+
console.log('[push-todo] /push-todo Use in Clawdbot');
|
|
477
|
+
}
|
|
241
478
|
}
|
|
242
479
|
|
|
243
480
|
main().catch(error => {
|