@masslessai/push-todo 3.1.0 → 3.2.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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "push-todo",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "Voice tasks from Push iOS app"
5
5
  }
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.0';
18
+ const VERSION = '3.2.0';
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masslessai/push-todo",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "Voice tasks from Push iOS app for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,11 +2,14 @@
2
2
  /**
3
3
  * Post-install script for Push CLI.
4
4
  *
5
- * 1. Sets up Claude Code plugin symlink
6
- * 2. Downloads the native keychain helper binary for macOS
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,22 @@ 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 plugin locations
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_AGENTS_FILE = join(CODEX_DIR, 'AGENTS.md');
35
+
36
+ // Clawdbot locations
37
+ const CLAWDBOT_DIR = join(homedir(), '.clawdbot');
38
+ const CLAWDBOT_SKILL_DIR = join(CLAWDBOT_DIR, 'skills', 'push-todo');
39
+ const CLAWDBOT_SKILL_FILE = join(CLAWDBOT_SKILL_DIR, 'SKILL.md');
40
+
31
41
  const BINARY_NAME = 'push-keychain-helper';
32
42
  const BINARY_DIR = join(__dirname, '../bin');
33
43
  const BINARY_PATH = join(BINARY_DIR, BINARY_NAME);
@@ -130,6 +140,135 @@ function migrateFromPython() {
130
140
  }
131
141
  }
132
142
 
143
+ /**
144
+ * Set up OpenAI Codex integration.
145
+ * Adds Push Tasks section to ~/.codex/AGENTS.md
146
+ *
147
+ * @returns {boolean} True if Codex was detected and set up
148
+ */
149
+ function setupCodex() {
150
+ // Only set up if Codex directory exists (user has Codex installed)
151
+ if (!existsSync(CODEX_DIR)) {
152
+ return false;
153
+ }
154
+
155
+ console.log('[push-todo] Detected OpenAI Codex installation');
156
+
157
+ const PUSH_SECTION = `
158
+ ## Push Tasks Integration
159
+
160
+ Voice tasks captured on iPhone via the Push app.
161
+
162
+ ### Commands
163
+
164
+ | Command | Description |
165
+ |---------|-------------|
166
+ | \`push-todo\` | List active tasks |
167
+ | \`push-todo 427\` | Show task #427 |
168
+ | \`push-todo connect\` | Connect/fix issues |
169
+ | \`push-todo search "query"\` | Search tasks |
170
+
171
+ ### Session Start
172
+
173
+ At the start of each session, check for pending tasks:
174
+ \`\`\`bash
175
+ push-todo --json 2>/dev/null | head -1
176
+ \`\`\`
177
+ If tasks exist, inform: "You have X task(s) from Push. Type $push-todo to see them."
178
+ `;
179
+
180
+ try {
181
+ if (existsSync(CODEX_AGENTS_FILE)) {
182
+ const content = readFileSync(CODEX_AGENTS_FILE, 'utf8');
183
+ if (content.includes('Push Tasks Integration')) {
184
+ console.log('[push-todo] Codex: Push section already exists in AGENTS.md');
185
+ return true;
186
+ }
187
+ appendFileSync(CODEX_AGENTS_FILE, PUSH_SECTION);
188
+ console.log('[push-todo] Codex: Added Push section to AGENTS.md');
189
+ } else {
190
+ writeFileSync(CODEX_AGENTS_FILE, PUSH_SECTION.trim() + '\n');
191
+ console.log('[push-todo] Codex: Created AGENTS.md with Push section');
192
+ }
193
+ return true;
194
+ } catch (error) {
195
+ console.log(`[push-todo] Codex: Could not set up AGENTS.md: ${error.message}`);
196
+ return false;
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Set up Clawdbot integration.
202
+ * Creates ~/.clawdbot/skills/push-todo/SKILL.md
203
+ *
204
+ * @returns {boolean} True if Clawdbot was detected and set up
205
+ */
206
+ function setupClawdbot() {
207
+ // Only set up if Clawdbot directory exists (user has Clawdbot installed)
208
+ if (!existsSync(CLAWDBOT_DIR)) {
209
+ return false;
210
+ }
211
+
212
+ console.log('[push-todo] Detected Clawdbot installation');
213
+
214
+ const SKILL_CONTENT = `# Push Tasks
215
+
216
+ Voice tasks captured on iPhone, ready to work on.
217
+
218
+ ## Commands
219
+
220
+ Run these in the terminal:
221
+
222
+ | Command | Description |
223
+ |---------|-------------|
224
+ | \`push-todo\` | List active tasks |
225
+ | \`push-todo 427\` | Show task #427 |
226
+ | \`push-todo connect\` | Connect/fix issues |
227
+ | \`push-todo search "query"\` | Search tasks |
228
+ | \`push-todo --help\` | All options |
229
+
230
+ ## Quick Start
231
+
232
+ If not connected yet, run:
233
+ \`\`\`bash
234
+ push-todo connect
235
+ \`\`\`
236
+
237
+ To see tasks:
238
+ \`\`\`bash
239
+ push-todo
240
+ \`\`\`
241
+
242
+ To work on a specific task:
243
+ \`\`\`bash
244
+ push-todo 427
245
+ \`\`\`
246
+
247
+ ## Session Start
248
+
249
+ At the start of each session, check for tasks:
250
+ \`\`\`bash
251
+ push-todo --json 2>/dev/null | head -1
252
+ \`\`\`
253
+ If tasks exist, inform the user.
254
+ `;
255
+
256
+ try {
257
+ mkdirSync(CLAWDBOT_SKILL_DIR, { recursive: true });
258
+
259
+ if (existsSync(CLAWDBOT_SKILL_FILE)) {
260
+ console.log('[push-todo] Clawdbot: SKILL.md already exists, updating...');
261
+ }
262
+
263
+ writeFileSync(CLAWDBOT_SKILL_FILE, SKILL_CONTENT);
264
+ console.log('[push-todo] Clawdbot: Created skills/push-todo/SKILL.md');
265
+ return true;
266
+ } catch (error) {
267
+ console.log(`[push-todo] Clawdbot: Could not set up SKILL.md: ${error.message}`);
268
+ return false;
269
+ }
270
+ }
271
+
133
272
  /**
134
273
  * Download a file from URL to destination.
135
274
  *
@@ -184,35 +323,66 @@ async function main() {
184
323
 
185
324
  // Step 3: Set up Claude Code plugin symlink
186
325
  console.log('[push-todo] Setting up Claude Code plugin...');
187
- const pluginSuccess = setupClaudePlugin();
326
+ const claudeSuccess = setupClaudePlugin();
188
327
  console.log('');
189
328
 
190
- // Step 4: Download native binary (macOS only)
329
+ // Step 4: Set up OpenAI Codex (if installed)
330
+ const codexSuccess = setupCodex();
331
+ if (codexSuccess) console.log('');
332
+
333
+ // Step 5: Set up Clawdbot (if installed)
334
+ const clawdbotSuccess = setupClawdbot();
335
+ if (clawdbotSuccess) console.log('');
336
+
337
+ // Track which clients were set up
338
+ const clients = [];
339
+ if (claudeSuccess) clients.push('Claude Code');
340
+ if (codexSuccess) clients.push('OpenAI Codex');
341
+ if (clawdbotSuccess) clients.push('Clawdbot');
342
+
343
+ // Step 6: Download native binary (macOS only)
191
344
  if (platform() !== 'darwin') {
192
345
  console.log('[push-todo] Skipping native binary (macOS only)');
193
346
  console.log('[push-todo] E2EE features will not be available.');
194
347
  console.log('');
195
- console.log('[push-todo] Installation complete.');
196
- if (pluginSuccess) {
197
- console.log('[push-todo] You can now use /push-todo in Claude Code!');
348
+ console.log('[push-todo] Installation complete!');
349
+ if (clients.length > 0) {
350
+ console.log(`[push-todo] Configured for: ${clients.join(', ')}`);
198
351
  }
199
352
  return;
200
353
  }
201
354
 
202
355
  // Check if binary already exists and is valid
356
+ let binaryExists = false;
203
357
  if (existsSync(BINARY_PATH)) {
204
358
  try {
205
359
  const stats = await stat(BINARY_PATH);
206
360
  if (stats.size > 0) {
207
361
  console.log('[push-todo] Native binary already installed.');
208
- console.log('[push-todo] Installation complete.');
209
- return;
362
+ binaryExists = true;
210
363
  }
211
364
  } catch {
212
365
  // Continue to download
213
366
  }
214
367
  }
215
368
 
369
+ if (binaryExists) {
370
+ // Skip download, show summary
371
+ console.log('');
372
+ console.log('[push-todo] Installation complete!');
373
+ if (clients.length > 0) {
374
+ console.log(`[push-todo] Configured for: ${clients.join(', ')}`);
375
+ }
376
+ console.log('');
377
+ console.log('[push-todo] Quick start:');
378
+ console.log('[push-todo] push-todo connect Set up authentication');
379
+ console.log('[push-todo] push-todo List your tasks');
380
+ if (claudeSuccess) console.log('[push-todo] /push-todo Use in Claude Code');
381
+ if (codexSuccess) console.log('[push-todo] $push-todo Use in OpenAI Codex');
382
+ if (clawdbotSuccess) console.log('[push-todo] /push-todo Use in Clawdbot');
383
+ return;
384
+ }
385
+
216
386
  // Determine architecture
217
387
  const archType = arch();
218
388
  const url = archType === 'arm64' ? BINARY_URL : BINARY_URL_X64;
@@ -233,11 +403,22 @@ async function main() {
233
403
 
234
404
  console.log('');
235
405
  console.log('[push-todo] Installation complete!');
406
+ if (clients.length > 0) {
407
+ console.log(`[push-todo] Configured for: ${clients.join(', ')}`);
408
+ }
236
409
  console.log('');
237
410
  console.log('[push-todo] Quick start:');
238
411
  console.log('[push-todo] push-todo connect Set up authentication');
239
412
  console.log('[push-todo] push-todo List your tasks');
240
- console.log('[push-todo] /push-todo Use in Claude Code');
413
+ if (claudeSuccess) {
414
+ console.log('[push-todo] /push-todo Use in Claude Code');
415
+ }
416
+ if (codexSuccess) {
417
+ console.log('[push-todo] $push-todo Use in OpenAI Codex');
418
+ }
419
+ if (clawdbotSuccess) {
420
+ console.log('[push-todo] /push-todo Use in Clawdbot');
421
+ }
241
422
  }
242
423
 
243
424
  main().catch(error => {