@masslessai/push-todo 3.2.0 → 3.3.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.2.0",
3
+ "version": "3.3.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.2.0';
18
+ const VERSION = '3.3.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.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "Voice tasks from Push iOS app for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -31,6 +31,8 @@ const LEGACY_SKILL_LINK = join(LEGACY_SKILL_DIR, 'push-todo');
31
31
 
32
32
  // OpenAI Codex locations
33
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');
34
36
  const CODEX_AGENTS_FILE = join(CODEX_DIR, 'AGENTS.md');
35
37
 
36
38
  // Clawdbot locations
@@ -142,7 +144,8 @@ function migrateFromPython() {
142
144
 
143
145
  /**
144
146
  * Set up OpenAI Codex integration.
145
- * Adds Push Tasks section to ~/.codex/AGENTS.md
147
+ * Creates symlink ~/.codex/skills/push-todo -> npm package
148
+ * Updates AGENTS.md for session bootstrap
146
149
  *
147
150
  * @returns {boolean} True if Codex was detected and set up
148
151
  */
@@ -154,52 +157,81 @@ function setupCodex() {
154
157
 
155
158
  console.log('[push-todo] Detected OpenAI Codex installation');
156
159
 
157
- const PUSH_SECTION = `
160
+ // AGENTS.md bootstrap content (Codex-specific)
161
+ const AGENTS_SECTION = `
158
162
  ## Push Tasks Integration
159
163
 
160
- Voice tasks captured on iPhone via the Push app.
164
+ At the start of each session, check for pending tasks from the Push iOS app:
161
165
 
162
- ### Commands
166
+ 1. Run this command silently:
167
+ \`\`\`bash
168
+ push-todo --json 2>/dev/null | head -1
169
+ \`\`\`
163
170
 
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 |
171
+ 2. If tasks exist, inform the user:
172
+ "You have X task(s) from Push. Type $push-todo to see them."
170
173
 
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."
174
+ 3. If no output or error, proceed normally without mentioning Push.
178
175
  `;
179
176
 
180
177
  try {
178
+ // Ensure skills directory exists
179
+ const skillsDir = join(CODEX_DIR, 'skills');
180
+ mkdirSync(skillsDir, { recursive: true });
181
+
182
+ // Create symlink (same as Claude Code approach)
183
+ if (existsSync(CODEX_SKILL_DIR)) {
184
+ const stats = lstatSync(CODEX_SKILL_DIR);
185
+ if (stats.isSymbolicLink()) {
186
+ const target = readlinkSync(CODEX_SKILL_DIR);
187
+ if (target === PACKAGE_ROOT) {
188
+ console.log('[push-todo] Codex: Symlink already configured');
189
+ } else {
190
+ unlinkSync(CODEX_SKILL_DIR);
191
+ symlinkSync(PACKAGE_ROOT, CODEX_SKILL_DIR);
192
+ console.log('[push-todo] Codex: Updated symlink');
193
+ }
194
+ } else {
195
+ // It's a directory (old copy) - remove and replace with symlink
196
+ rmSync(CODEX_SKILL_DIR, { recursive: true });
197
+ symlinkSync(PACKAGE_ROOT, CODEX_SKILL_DIR);
198
+ console.log('[push-todo] Codex: Replaced copy with symlink');
199
+ }
200
+ } else {
201
+ symlinkSync(PACKAGE_ROOT, CODEX_SKILL_DIR);
202
+ console.log('[push-todo] Codex: Created symlink');
203
+ }
204
+
205
+ // Update AGENTS.md for session-start bootstrap
181
206
  if (existsSync(CODEX_AGENTS_FILE)) {
182
207
  const content = readFileSync(CODEX_AGENTS_FILE, 'utf8');
183
208
  if (content.includes('Push Tasks Integration')) {
184
- console.log('[push-todo] Codex: Push section already exists in AGENTS.md');
185
- return true;
209
+ // Update existing section
210
+ const updated = content.replace(
211
+ /## Push Tasks Integration[\s\S]*?(?=\n## |$)/,
212
+ AGENTS_SECTION.trim() + '\n\n'
213
+ );
214
+ writeFileSync(CODEX_AGENTS_FILE, updated);
215
+ console.log('[push-todo] Codex: Updated AGENTS.md');
216
+ } else {
217
+ appendFileSync(CODEX_AGENTS_FILE, AGENTS_SECTION);
218
+ console.log('[push-todo] Codex: Added to AGENTS.md');
186
219
  }
187
- appendFileSync(CODEX_AGENTS_FILE, PUSH_SECTION);
188
- console.log('[push-todo] Codex: Added Push section to AGENTS.md');
189
220
  } else {
190
- writeFileSync(CODEX_AGENTS_FILE, PUSH_SECTION.trim() + '\n');
191
- console.log('[push-todo] Codex: Created AGENTS.md with Push section');
221
+ writeFileSync(CODEX_AGENTS_FILE, AGENTS_SECTION.trim() + '\n');
222
+ console.log('[push-todo] Codex: Created AGENTS.md');
192
223
  }
224
+
193
225
  return true;
194
226
  } catch (error) {
195
- console.log(`[push-todo] Codex: Could not set up AGENTS.md: ${error.message}`);
227
+ console.log(`[push-todo] Codex: Setup failed: ${error.message}`);
196
228
  return false;
197
229
  }
198
230
  }
199
231
 
200
232
  /**
201
233
  * Set up Clawdbot integration.
202
- * Creates ~/.clawdbot/skills/push-todo/SKILL.md
234
+ * Creates symlink ~/.clawdbot/skills/push-todo -> npm package
203
235
  *
204
236
  * @returns {boolean} True if Clawdbot was detected and set up
205
237
  */
@@ -211,60 +243,37 @@ function setupClawdbot() {
211
243
 
212
244
  console.log('[push-todo] Detected Clawdbot installation');
213
245
 
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
246
  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...');
247
+ // Ensure skills directory exists
248
+ const skillsDir = join(CLAWDBOT_DIR, 'skills');
249
+ mkdirSync(skillsDir, { recursive: true });
250
+
251
+ // Create symlink (same as Claude Code approach)
252
+ if (existsSync(CLAWDBOT_SKILL_DIR)) {
253
+ const stats = lstatSync(CLAWDBOT_SKILL_DIR);
254
+ if (stats.isSymbolicLink()) {
255
+ const target = readlinkSync(CLAWDBOT_SKILL_DIR);
256
+ if (target === PACKAGE_ROOT) {
257
+ console.log('[push-todo] Clawdbot: Symlink already configured');
258
+ } else {
259
+ unlinkSync(CLAWDBOT_SKILL_DIR);
260
+ symlinkSync(PACKAGE_ROOT, CLAWDBOT_SKILL_DIR);
261
+ console.log('[push-todo] Clawdbot: Updated symlink');
262
+ }
263
+ } else {
264
+ // It's a directory (old copy) - remove and replace with symlink
265
+ rmSync(CLAWDBOT_SKILL_DIR, { recursive: true });
266
+ symlinkSync(PACKAGE_ROOT, CLAWDBOT_SKILL_DIR);
267
+ console.log('[push-todo] Clawdbot: Replaced copy with symlink');
268
+ }
269
+ } else {
270
+ symlinkSync(PACKAGE_ROOT, CLAWDBOT_SKILL_DIR);
271
+ console.log('[push-todo] Clawdbot: Created symlink');
261
272
  }
262
273
 
263
- writeFileSync(CLAWDBOT_SKILL_FILE, SKILL_CONTENT);
264
- console.log('[push-todo] Clawdbot: Created skills/push-todo/SKILL.md');
265
274
  return true;
266
275
  } catch (error) {
267
- console.log(`[push-todo] Clawdbot: Could not set up SKILL.md: ${error.message}`);
276
+ console.log(`[push-todo] Clawdbot: Setup failed: ${error.message}`);
268
277
  return false;
269
278
  }
270
279
  }