deepflow 0.1.39 → 0.1.41

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepflow",
3
- "version": "0.1.39",
3
+ "version": "0.1.41",
4
4
  "description": "Stay in flow state - lightweight spec-driven task orchestration for Claude Code",
5
5
  "keywords": [
6
6
  "claude",
@@ -4,9 +4,9 @@
4
4
 
5
5
  You are a coordinator. Spawn agents, wait for results, update PLAN.md. Never implement code yourself.
6
6
 
7
- **NEVER:** Read source files, edit code, run tests, run git commands (except status), use TaskOutput, use run_in_background
7
+ **NEVER:** Read source files, edit code, run tests, run git commands (except status), use TaskOutput
8
8
 
9
- **ONLY:** Read PLAN.md, read specs/doing-*.md, spawn agents (non-background), read `.deepflow/results/*.yaml` for outcomes, update PLAN.md
9
+ **ONLY:** Read PLAN.md, read specs/doing-*.md, spawn background agents, read `.deepflow/results/*.yaml` on completion notifications, update PLAN.md
10
10
 
11
11
  ---
12
12
 
@@ -43,29 +43,56 @@ Statusline writes to `.deepflow/context.json`: `{"percentage": 45}`
43
43
 
44
44
  ## Agent Protocol
45
45
 
46
- Each task = one agent. Spawn ALL wave tasks in ONE message as non-background parallel Task calls.
47
-
48
- **NEVER use `run_in_background`** — causes late "Agent completed" notifications after orchestrator finishes, polluting output and duplicating summaries.
46
+ Each task = one background agent. Use agent completion notifications as the feedback loop.
49
47
 
50
48
  **NEVER use TaskOutput** — returns full agent transcripts (100KB+) that explode context.
51
49
 
50
+ ### Notification-Driven Execution
51
+
52
+ ```
53
+ 1. Spawn ALL wave agents with run_in_background=true in ONE message
54
+ 2. STOP. End your turn. Do NOT run Bash monitors or poll for results.
55
+ 3. Wait for "Agent X completed" notifications (they arrive automatically)
56
+ 4. On EACH notification:
57
+ a. Read the result file: Read("{worktree}/.deepflow/results/{task_id}.yaml")
58
+ b. Report: "✓ T1: success (abc123)" or "✗ T1: failed"
59
+ c. Update PLAN.md for that task
60
+ d. Check: all wave agents done?
61
+ - No → end turn, wait for next notification
62
+ - Yes → proceed to next wave or write final summary
63
+ ```
64
+
65
+ **CRITICAL: After spawning agents, your turn ENDS. Do NOT:**
66
+ - Run Bash commands to poll/monitor
67
+ - Try to read result files before notifications arrive
68
+ - Write summaries before all wave agents complete
69
+
70
+ **On notification, respond briefly:**
71
+ - ONE line per completed agent: "✓ T1: success (abc123)"
72
+ - Only write full summary after ALL wave agents complete
73
+ - Do NOT repeat the full execution status on every notification
74
+
52
75
  ```python
53
- # 1. Spawn agents in parallel (single message, NON-background)
54
- Task(subagent_type="general-purpose", prompt="T1: ... Final message: one line only.")
55
- Task(subagent_type="general-purpose", prompt="T2: ... Final message: one line only.")
56
- Task(subagent_type="general-purpose", prompt="T3: ... Final message: one line only.")
57
- # All run in parallel, block until ALL complete — no late notifications
76
+ # Step 1: Spawn wave (ONE message, then STOP)
77
+ Task(subagent_type="general-purpose", model="sonnet", run_in_background=True, prompt="T1: ...")
78
+ Task(subagent_type="general-purpose", model="sonnet", run_in_background=True, prompt="T2: ...")
79
+ Task(subagent_type="general-purpose", model="sonnet", run_in_background=True, prompt="T3: ...")
80
+ # Turn ends here. Wait for notifications.
58
81
 
59
- # 2. Read structured results (minimal context)
82
+ # Step 2: On "Agent T1 completed" notification:
60
83
  Read("{worktree}/.deepflow/results/T1.yaml")
84
+ # Output: "✓ T1: success (abc123)" — then STOP, wait for next
85
+
86
+ # Step 3: On "Agent T2 completed" notification:
61
87
  Read("{worktree}/.deepflow/results/T2.yaml")
88
+ # Output: "✓ T2: success (def456)" — then STOP, wait for next
89
+
90
+ # Step 4: On "Agent T3 completed" notification (last one):
62
91
  Read("{worktree}/.deepflow/results/T3.yaml")
92
+ # Output: "✓ T3: success (ghi789)"
93
+ # All done → proceed to next wave or final summary
63
94
  ```
64
95
 
65
- **Agent final message rule:** Agents MUST end with exactly one line:
66
- `Done: {task_id} {status} ({commit_hash})`
67
- Detailed results go in the YAML file, not the message.
68
-
69
96
  Result file `.deepflow/results/{task_id}.yaml`:
70
97
  ```yaml
71
98
  task: T3
@@ -230,15 +257,15 @@ DO NOT spawn one task, wait, then spawn another. Instead, call Task tool multipl
230
257
  Example: If T1, T2, T3 are ready, send ONE message containing THREE Task tool invocations:
231
258
 
232
259
  ```
233
- // In a SINGLE assistant message, invoke Task THREE times (NON-background):
234
- Task(subagent_type="general-purpose", model="sonnet", prompt="T1: ...")
235
- Task(subagent_type="general-purpose", model="sonnet", prompt="T2: ...")
236
- Task(subagent_type="general-purpose", model="sonnet", prompt="T3: ...")
237
- // All run in parallel, block until complete — no late notifications
260
+ // In a SINGLE assistant message, invoke Task with run_in_background=true:
261
+ Task(subagent_type="general-purpose", model="sonnet", run_in_background=true, prompt="T1: ...")
262
+ Task(subagent_type="general-purpose", model="sonnet", run_in_background=true, prompt="T2: ...")
263
+ Task(subagent_type="general-purpose", model="sonnet", run_in_background=true, prompt="T3: ...")
264
+ // Turn ends here. Wait for completion notifications.
238
265
  ```
239
266
 
240
267
  **WRONG (sequential):** Send message with Task for T1 → wait → send message with Task for T2 → wait → ...
241
- **RIGHT (parallel):** Send ONE message with Task for T1, T2, T3 all together
268
+ **RIGHT (parallel):** Send ONE message with Task for T1, T2, T3 all together, then STOP
242
269
 
243
270
  Same-file conflicts: spawn sequentially instead.
244
271
 
@@ -391,24 +418,21 @@ When all tasks done for a `doing-*` spec:
391
418
  2. Rename: `doing-upload.md` → `done-upload.md`
392
419
  3. Remove section from PLAN.md
393
420
 
394
- ### 10. ITERATE
421
+ ### 10. ITERATE (Notification-Driven)
395
422
 
396
- After spawning wave agents (non-background, parallel), they block until all complete. Then read results.
423
+ After spawning wave agents, your turn ENDS. Completion notifications drive the loop.
397
424
 
398
425
  **NEVER use TaskOutput** — it explodes context.
399
- **NEVER use run_in_background** — causes late notifications and duplicate summaries.
400
426
 
401
- ```python
402
- # After spawning T1, T2, T3 in parallel (non-background):
403
- # They already completed read structured results:
404
- Read("{worktree}/.deepflow/results/T1.yaml")
405
- Read("{worktree}/.deepflow/results/T2.yaml")
406
- Read("{worktree}/.deepflow/results/T3.yaml")
407
- ```
427
+ **Per notification:**
428
+ 1. Read result file for the completed agent
429
+ 2. Report ONE line: "✓ Tx: status (commit)"
430
+ 3. If NOT all wave agents done → end turn, wait
431
+ 4. If ALL wave agents done → check context, update PLAN.md, spawn next wave or finish
408
432
 
409
- Then check which tasks completed, update PLAN.md, identify newly unblocked tasks, spawn next wave.
433
+ **Between waves:** Check context %. If ≥50%, checkpoint and exit.
410
434
 
411
- Repeat until: all done, all blocked, or context ≥50% (checkpoint).
435
+ **Repeat** until: all done, all blocked, or context ≥50% (checkpoint).
412
436
 
413
437
  ## Rules
414
438
 
@@ -424,13 +448,18 @@ Repeat until: all done, all blocked, or context ≥50% (checkpoint).
424
448
 
425
449
  ```
426
450
  /df:execute (context: 12%)
451
+ Spawning Wave 1: T1, T2, T3 parallel...
427
452
 
428
- Wave 1: T1, T2 parallel (context: 25%)
429
- T1: success (abc1234)
430
- T2: success (def5678)
453
+ [Agent "T1" completed]
454
+ T1: success (abc1234)
431
455
 
432
- Wave 2: T3 (context: 48%)
433
- T3: success (ghi9012)
456
+ [Agent "T2" completed]
457
+ ✓ T2: success (def5678)
458
+
459
+ [Agent "T3" completed]
460
+ ✓ T3: success (ghi9012)
461
+
462
+ Wave 1 complete (3/3). Context: 35%
434
463
 
435
464
  ✓ doing-upload → done-upload
436
465
  ✓ Complete: 3/3 tasks
@@ -448,16 +477,24 @@ Checking experiment status...
448
477
  T2: Blocked by T1 (spike not validated)
449
478
  T3: Blocked by T1 (spike not validated)
450
479
 
451
- Wave 1: T1 [SPIKE] (context: 15%)
452
- T1: complete, verifying...
480
+ Spawning Wave 1: T1 [SPIKE]...
481
+
482
+ [Agent "T1 SPIKE" completed]
483
+ ✓ T1: complete, verifying...
453
484
 
454
485
  Verifying T1...
455
486
  ✓ Spike T1 verified (throughput 8500 >= 7000)
456
487
  → upload--streaming--passed.md
457
488
 
458
- Wave 2: T2, T3 parallel (context: 40%)
459
- T2: success (def5678)
460
- T3: success (ghi9012)
489
+ Spawning Wave 2: T2, T3 parallel...
490
+
491
+ [Agent "T2" completed]
492
+ ✓ T2: success (def5678)
493
+
494
+ [Agent "T3" completed]
495
+ ✓ T3: success (ghi9012)
496
+
497
+ Wave 2 complete (2/2). Context: 40%
461
498
 
462
499
  ✓ doing-upload → done-upload
463
500
  ✓ Complete: 3/3 tasks
@@ -128,12 +128,35 @@ Learnings captured:
128
128
 
129
129
  After all verification passes:
130
130
 
131
- ### 1. MERGE TO MAIN
131
+ ### 1. DISCOVER WORKTREE
132
+
133
+ Find worktree info using two strategies (checkpoint → fallback to git):
132
134
 
133
135
  ```bash
134
- # Get worktree info from checkpoint
135
- WORKTREE_BRANCH=$(cat .deepflow/checkpoint.json | jq -r '.worktree_branch')
136
+ # Strategy 1: checkpoint.json (from interrupted executions)
137
+ if [ -f .deepflow/checkpoint.json ]; then
138
+ WORKTREE_BRANCH=$(cat .deepflow/checkpoint.json | jq -r '.worktree_branch')
139
+ WORKTREE_PATH=$(cat .deepflow/checkpoint.json | jq -r '.worktree_path')
140
+ fi
141
+
142
+ # Strategy 2: Infer from doing-* spec + git worktree list (no checkpoint needed)
143
+ if [ -z "${WORKTREE_BRANCH}" ]; then
144
+ SPEC_NAME=$(basename specs/doing-*.md .md | sed 's/doing-//')
145
+ WORKTREE_PATH=".deepflow/worktrees/${SPEC_NAME}"
146
+ # Get branch from git worktree list
147
+ WORKTREE_BRANCH=$(git worktree list --porcelain | grep -A2 "${WORKTREE_PATH}" | grep 'branch' | sed 's|branch refs/heads/||')
148
+ fi
149
+
150
+ # No worktree found — nothing to merge
151
+ if [ -z "${WORKTREE_BRANCH}" ]; then
152
+ echo "No worktree found — nothing to merge. Workflow may already be on main."
153
+ exit 0
154
+ fi
155
+ ```
156
+
157
+ ### 2. MERGE TO MAIN
136
158
 
159
+ ```bash
137
160
  # Switch to main and merge
138
161
  git checkout main
139
162
  git merge "${WORKTREE_BRANCH}" --no-ff -m "feat({spec}): merge verified changes"
@@ -144,20 +167,17 @@ git merge "${WORKTREE_BRANCH}" --no-ff -m "feat({spec}): merge verified changes"
144
167
  - Output: "Merge conflict detected. Resolve manually, then run /df:verify --merge-only"
145
168
  - Exit without cleanup
146
169
 
147
- ### 2. CLEANUP WORKTREE
170
+ ### 3. CLEANUP WORKTREE
148
171
 
149
172
  After successful merge:
150
173
 
151
174
  ```bash
152
- # Get worktree path from checkpoint
153
- WORKTREE_PATH=$(cat .deepflow/checkpoint.json | jq -r '.worktree_path')
154
-
155
175
  # Remove worktree and branch
156
176
  git worktree remove --force "${WORKTREE_PATH}"
157
177
  git branch -d "${WORKTREE_BRANCH}"
158
178
 
159
- # Remove checkpoint
160
- rm .deepflow/checkpoint.json
179
+ # Remove checkpoint if it exists
180
+ rm -f .deepflow/checkpoint.json
161
181
  ```
162
182
 
163
183
  **Output on success:**