@masslessai/push-todo 3.6.5 → 3.6.7

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 (3) hide show
  1. package/SKILL.md +25 -43
  2. package/lib/daemon.js +7 -4
  3. package/package.json +1 -1
package/SKILL.md CHANGED
@@ -213,74 +213,56 @@ If no CLAUDE.md or README.md exists, generate minimal keywords from:
213
213
  - Git repo name
214
214
  - Primary file extensions (`.swift` -> iOS, `.py` -> Python, `.rs` -> Rust)
215
215
 
216
- ## Auto-Resume from Session Transcript
216
+ ## Auto-Resume from Daemon Session
217
217
 
218
- When a task has a resumable daemon session, automatically load the session context instead of starting from scratch. The daemon's session transcript contains every file read, edit, and decision — use it to continue intelligently.
218
+ When a task has a resumable daemon session, use the git worktree branch directly instead of starting from scratch. The daemon commits its changes to a worktree branch — use that branch to see exactly what was done.
219
219
 
220
- ### Step 1: Locate the Session File
220
+ ### Step 1: Find the Worktree Branch
221
221
 
222
- The daemon runs in a git worktree. Find the session transcript:
222
+ The daemon creates a branch named `push-{number}-{suffix}`:
223
223
 
224
224
  ```bash
225
- # Get machine ID suffix for worktree name
225
+ # Get machine ID suffix
226
226
  MACHINE_ID=$(cat ~/.config/push/machine_id 2>/dev/null)
227
227
  SUFFIX=$(echo "$MACHINE_ID" | rev | cut -d'-' -f1 | rev | cut -c1-8)
228
228
  TASK_NUM=<display_number>
229
+ BRANCH="push-${TASK_NUM}-${SUFFIX}"
229
230
 
230
- # Session files are stored under ~/.claude/projects/ with path-encoded directory names
231
- SESSION_DIR="$HOME/.claude/projects/-Users-$(whoami)-projects-push-${TASK_NUM}-${SUFFIX}"
232
- SESSION_ID=<session_id_from_task>
233
-
234
- # Check if transcript exists
235
- ls "${SESSION_DIR}/${SESSION_ID}.jsonl" 2>/dev/null
231
+ # Check if branch exists and has commits
232
+ git log master..${BRANCH} --oneline 2>/dev/null
236
233
  ```
237
234
 
238
- ### Step 2: Extract Session Context
235
+ ### Step 2: Get Semantic Summary from Session Transcript
239
236
 
240
- Read the JSONL transcript and extract what the daemon did:
237
+ Read the session transcript for context on *what* and *why* (reasoning, decisions):
241
238
 
242
239
  ```bash
243
- cat "${SESSION_DIR}/${SESSION_ID}.jsonl" | node -e "
240
+ SESSION_DIR="$HOME/.claude/projects/-Users-$(whoami)-projects-push-${TASK_NUM}-${SUFFIX}"
241
+ SESSION_ID=<session_id_from_task>
242
+
243
+ # Extract just the text reasoning (not file edits — we get those from git)
244
+ cat "${SESSION_DIR}/${SESSION_ID}.jsonl" 2>/dev/null | node -e "
244
245
  const lines = [];
245
246
  process.stdin.on('data', d => lines.push(d));
246
247
  process.stdin.on('end', () => {
247
248
  const entries = Buffer.concat(lines).toString().split('\n')
248
249
  .filter(Boolean).map(l => { try { return JSON.parse(l); } catch { return null; } }).filter(Boolean);
249
-
250
- const assistantMsgs = entries.filter(e => e.type === 'assistant');
251
- const edits = [];
252
- const texts = [];
253
-
254
- assistantMsgs.forEach(a => {
255
- (a.message?.content || []).forEach(b => {
256
- if (b.type === 'text' && b.text.trim()) texts.push(b.text.trim());
257
- if (b.type === 'tool_use' && (b.name === 'Edit' || b.name === 'Write'))
258
- edits.push(b.input?.file_path);
259
- });
260
- });
261
-
262
- console.log('FILES_EDITED:', JSON.stringify(edits));
263
- console.log('---TRANSCRIPT_START---');
250
+ const texts = entries.filter(e => e.type === 'assistant')
251
+ .flatMap(a => (a.message?.content || []).filter(b => b.type === 'text' && b.text.trim()).map(b => b.text.trim()));
264
252
  texts.forEach(t => console.log(t));
265
- console.log('---TRANSCRIPT_END---');
266
253
  });
267
254
  "
268
255
  ```
269
256
 
270
- ### Step 3: Present Context and Continue
271
-
272
- 1. Tell the user what the daemon did (root cause found, files edited, commits made)
273
- 2. Check if the daemon's changes are already in the main branch (it may have committed to a worktree branch)
274
- 3. If the daemon's work is complete but not merged, help merge/cherry-pick the changes
275
- 4. If the daemon's work is incomplete, continue from where it left off using the context
276
-
277
- ### Fallback: Terminal Resume
257
+ ### Step 3: Review Changes and Act
278
258
 
279
- If the session transcript can't be read (file not found, parse error), tell the user they can also resume interactively in a **new terminal**:
280
- ```
281
- push-todo resume <number>
282
- ```
283
- This launches a full interactive Claude Code session with the daemon's complete conversation history.
259
+ 1. **Show the user** what the daemon did: semantic summary + `git diff master...${BRANCH}`
260
+ 2. **If the branch has commits** (daemon committed):
261
+ - Show the diff and ask if user wants to cherry-pick/merge to current branch
262
+ - Use `git cherry-pick <commit>` or `git merge ${BRANCH}` as appropriate
263
+ 3. **If the branch has NO commits** (daemon didn't commit older daemon versions):
264
+ - Fall back to reading edits from the session transcript JSONL
265
+ 4. **If work is incomplete**, continue from where the daemon left off using the context from the transcript and the branch state
284
266
 
285
267
  ## Live Session Status
286
268
 
package/lib/daemon.js CHANGED
@@ -780,9 +780,10 @@ function executeTask(task) {
780
780
 
781
781
  ${content}
782
782
 
783
- IMPORTANT: When you're done, the SessionEnd hook will automatically report completion to Supabase.
784
-
785
- If you need to understand the codebase, start by reading the CLAUDE.md file if it exists.`;
783
+ IMPORTANT:
784
+ 1. If you need to understand the codebase, start by reading the CLAUDE.md file if it exists.
785
+ 2. ALWAYS commit your changes before finishing. Use a descriptive commit message summarizing what you did. This is critical uncommitted changes will be lost when the worktree is cleaned up.
786
+ 3. When you're done, the SessionEnd hook will automatically report completion to Supabase.`;
786
787
 
787
788
  // Update status to running
788
789
  updateTaskStatus(displayNumber, 'running');
@@ -960,12 +961,14 @@ function handleTaskCompletion(displayNumber, exitCode) {
960
961
  });
961
962
  }
962
963
 
963
- // Cleanup
964
+ // Cleanup internal tracking
964
965
  taskDetails.delete(displayNumber);
965
966
  taskLastOutput.delete(displayNumber);
966
967
  taskStdoutBuffer.delete(displayNumber);
967
968
  taskProjectPaths.delete(displayNumber);
968
969
 
970
+ // Always clean up worktree — the branch preserves all committed work.
971
+ // On re-run, createWorktree() recreates from the existing branch.
969
972
  cleanupWorktree(displayNumber, projectPath);
970
973
  updateStatusFile();
971
974
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masslessai/push-todo",
3
- "version": "3.6.5",
3
+ "version": "3.6.7",
4
4
  "description": "Voice tasks from Push iOS app for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {