taskplane 0.0.1 → 0.1.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.
Files changed (38) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -20
  3. package/bin/taskplane.mjs +706 -0
  4. package/dashboard/public/app.js +900 -0
  5. package/dashboard/public/index.html +92 -0
  6. package/dashboard/public/style.css +924 -0
  7. package/dashboard/server.cjs +531 -0
  8. package/extensions/task-orchestrator.ts +28 -0
  9. package/extensions/task-runner.ts +1923 -0
  10. package/extensions/taskplane/abort.ts +466 -0
  11. package/extensions/taskplane/config.ts +102 -0
  12. package/extensions/taskplane/discovery.ts +988 -0
  13. package/extensions/taskplane/engine.ts +758 -0
  14. package/extensions/taskplane/execution.ts +1752 -0
  15. package/extensions/taskplane/extension.ts +577 -0
  16. package/extensions/taskplane/formatting.ts +718 -0
  17. package/extensions/taskplane/git.ts +38 -0
  18. package/extensions/taskplane/index.ts +22 -0
  19. package/extensions/taskplane/merge.ts +795 -0
  20. package/extensions/taskplane/messages.ts +134 -0
  21. package/extensions/taskplane/persistence.ts +1121 -0
  22. package/extensions/taskplane/resume.ts +1092 -0
  23. package/extensions/taskplane/sessions.ts +92 -0
  24. package/extensions/taskplane/types.ts +1514 -0
  25. package/extensions/taskplane/waves.ts +900 -0
  26. package/extensions/taskplane/worktree.ts +1624 -0
  27. package/package.json +48 -3
  28. package/skills/create-taskplane-task/SKILL.md +326 -0
  29. package/skills/create-taskplane-task/references/context-template.md +78 -0
  30. package/skills/create-taskplane-task/references/prompt-template.md +246 -0
  31. package/templates/agents/task-merger.md +256 -0
  32. package/templates/agents/task-reviewer.md +81 -0
  33. package/templates/agents/task-worker.md +140 -0
  34. package/templates/config/task-orchestrator.yaml +89 -0
  35. package/templates/config/task-runner.yaml +99 -0
  36. package/templates/tasks/CONTEXT.md +31 -0
  37. package/templates/tasks/EXAMPLE-001-hello-world/PROMPT.md +90 -0
  38. package/templates/tasks/EXAMPLE-001-hello-world/STATUS.md +73 -0
@@ -0,0 +1,134 @@
1
+ /**
2
+ * User-facing message templates (ORCH_MESSAGES)
3
+ * @module orch/messages
4
+ */
5
+ import type { AbortMode } from "./types.ts";
6
+
7
+ // ── Message Templates ────────────────────────────────────────────────
8
+
9
+ /**
10
+ * Deterministic message templates for user-facing /orch commands.
11
+ * Ensures consistent UX across invocations.
12
+ */
13
+ export const ORCH_MESSAGES = {
14
+ // /orch
15
+ orchStarting: (batchId: string, waves: number, tasks: number) =>
16
+ `🚀 Starting batch ${batchId}: ${waves} wave(s), ${tasks} task(s)`,
17
+ orchWaveStart: (waveNum: number, totalWaves: number, tasks: number, lanes: number) =>
18
+ `\n🌊 Wave ${waveNum}/${totalWaves}: ${tasks} task(s) across ${lanes} lane(s)`,
19
+ orchWaveComplete: (waveNum: number, succeeded: number, failed: number, skipped: number, elapsedSec: number) =>
20
+ `✅ Wave ${waveNum} complete: ${succeeded} succeeded, ${failed} failed, ${skipped} skipped (${elapsedSec}s)`,
21
+ orchMergeStart: (waveNum: number, laneCount: number) =>
22
+ `🔀 [Wave ${waveNum}] Merging ${laneCount} lane(s) into develop...`,
23
+ orchMergeLaneSuccess: (laneNum: number, commit: string, durationSec: number) =>
24
+ ` ✅ Lane ${laneNum} merged (${commit.slice(0, 8)}, ${durationSec}s)`,
25
+ orchMergeLaneConflictResolved: (laneNum: number, conflictCount: number, durationSec: number) =>
26
+ ` ⚡ Lane ${laneNum} merged with ${conflictCount} auto-resolved conflict(s) (${durationSec}s)`,
27
+ orchMergeLaneFailed: (laneNum: number, reason: string) =>
28
+ ` ❌ Lane ${laneNum} merge failed: ${reason}`,
29
+ orchMergeComplete: (waveNum: number, mergedCount: number, totalSec: number) =>
30
+ `🔀 [Wave ${waveNum}] Merge complete: ${mergedCount} lane(s) merged (${totalSec}s)`,
31
+ orchMergeFailed: (waveNum: number, laneNum: number, reason: string) =>
32
+ `❌ [Wave ${waveNum}] Merge failed at lane ${laneNum}: ${reason}`,
33
+ orchMergeSkipped: (waveNum: number) =>
34
+ `📝 [Wave ${waveNum}] No successful lanes to merge`,
35
+ orchMergePlaceholder: (waveNum: number) =>
36
+ `🔀 [Wave ${waveNum}] Merge: placeholder — Step 3 (TS-008) will replace with mergeWave()`,
37
+ orchWorktreeReset: (waveNum: number, lanes: number) =>
38
+ `🔄 Resetting ${lanes} worktree(s) to develop HEAD after wave ${waveNum}`,
39
+ orchBatchComplete: (batchId: string, succeeded: number, failed: number, skipped: number, blocked: number, elapsedSec: number) =>
40
+ `\n🏁 Batch ${batchId} complete: ${succeeded} succeeded, ${failed} failed, ${skipped} skipped, ${blocked} blocked (${elapsedSec}s)`,
41
+ orchBatchFailed: (batchId: string, reason: string) =>
42
+ `\n❌ Batch ${batchId} failed: ${reason}`,
43
+ orchBatchStopped: (batchId: string, policy: string) =>
44
+ `\n⛔ Batch ${batchId} stopped by ${policy} policy`,
45
+
46
+ // /orch-pause
47
+ pauseNoBatch: () => "No active batch is running. Use /orch <areas|all> to start.",
48
+ pauseAlreadyPaused: (batchId: string) => `Batch ${batchId} is already paused.`,
49
+ pauseActivated: (batchId: string) =>
50
+ `⏸️ Pausing batch ${batchId}... lanes will stop after their current tasks complete.`,
51
+
52
+ // /orch-sessions
53
+ sessionsNone: () => "No orchestrator TMUX sessions found.",
54
+ sessionsHeader: (count: number) => `🖥️ ${count} orchestrator session(s):`,
55
+
56
+ // /orch orphan detection
57
+ orphanDetectionResume: (batchId: string, sessionCount: number) =>
58
+ `🔄 Found ${sessionCount} running orchestrator session(s) from batch ${batchId}.\n` +
59
+ ` Use /orch-resume to continue, or /orch-abort to clean up.`,
60
+ orphanDetectionAbort: (sessionCount: number) =>
61
+ `⚠️ Found ${sessionCount} orphan orchestrator session(s) without usable state.\n` +
62
+ ` Use /orch-abort to clean up before starting a new batch.`,
63
+ orphanDetectionCleanup: () =>
64
+ `🧹 Cleaned up stale batch state file. Starting fresh.`,
65
+
66
+ // /orch-resume
67
+ resumeStarting: (batchId: string, phase: string) =>
68
+ `🔄 Resuming batch ${batchId} (was: ${phase})...`,
69
+ resumeReconciled: (batchId: string, completed: number, pending: number, failed: number, reconnecting: number, reExecuting: number = 0) =>
70
+ `📊 Batch ${batchId} reconciliation: ${completed} completed, ${pending} pending, ${failed} failed, ${reconnecting} reconnecting` +
71
+ (reExecuting > 0 ? `, ${reExecuting} re-executing` : ""),
72
+ resumeSkippedWaves: (skippedCount: number) =>
73
+ `⏭️ Skipping ${skippedCount} completed wave(s)`,
74
+ resumeReconnecting: (sessionCount: number) =>
75
+ `🔗 Reconnecting to ${sessionCount} alive session(s)...`,
76
+ resumeNoState: () =>
77
+ `❌ No batch to resume. No batch-state.json file found.\n` +
78
+ ` Use /orch <areas|all> to start a new batch.`,
79
+ resumeInvalidState: (error: string) =>
80
+ `❌ Cannot resume: batch state file is invalid.\n` +
81
+ ` Error: ${error}\n` +
82
+ ` Delete .pi/batch-state.json and start a new batch.`,
83
+ resumePhaseNotResumable: (batchId: string, phase: string, reason: string) =>
84
+ `❌ Cannot resume batch ${batchId} (phase: ${phase}).\n` +
85
+ ` ${reason}`,
86
+ resumeComplete: (batchId: string, succeeded: number, failed: number, skipped: number, blocked: number, elapsedSec: number) =>
87
+ `\n🏁 Resumed batch ${batchId} complete: ${succeeded} succeeded, ${failed} failed, ${skipped} skipped, ${blocked} blocked (${elapsedSec}s total)`,
88
+
89
+ // /orch-abort
90
+ abortGracefulStarting: (batchId: string, sessionCount: number) =>
91
+ `⏳ Graceful abort of batch ${batchId}: signaling ${sessionCount} session(s) to checkpoint and exit...`,
92
+ abortGracefulWaiting: (batchId: string, graceSec: number) =>
93
+ `⏳ Waiting up to ${graceSec}s for sessions to checkpoint and exit...`,
94
+ abortGracefulForceKill: (count: number) =>
95
+ `⚠️ Force-killing ${count} session(s) that did not exit within timeout`,
96
+ abortGracefulComplete: (batchId: string, graceful: number, forceKilled: number, durationSec: number) =>
97
+ `✅ Graceful abort complete for batch ${batchId}: ${graceful} exited gracefully, ${forceKilled} force-killed (${durationSec}s)`,
98
+ abortHardStarting: (batchId: string, sessionCount: number) =>
99
+ `⚡ Hard abort of batch ${batchId}: killing ${sessionCount} session(s) immediately...`,
100
+ abortHardComplete: (batchId: string, killed: number, durationSec: number) =>
101
+ `✅ Hard abort complete for batch ${batchId}: ${killed} session(s) killed (${durationSec}s)`,
102
+ abortPartialFailure: (failureCount: number) =>
103
+ `⚠️ ${failureCount} error(s) during abort (see details above)`,
104
+ abortNoBatch: () =>
105
+ `No active batch to abort. Use /orch <areas|all> to start a batch.`,
106
+ abortComplete: (mode: AbortMode, sessionsKilled: number) =>
107
+ `🏁 Abort (${mode}) complete: ${sessionsKilled} session(s) terminated. Worktrees and branches preserved.`,
108
+ } as const;
109
+
110
+
111
+ // ── Resume ORCH_MESSAGES ─────────────────────────────────────────────
112
+
113
+ // Note: These are added via extension to the ORCH_MESSAGES object below.
114
+
115
+ // ── Resume Orchestration ─────────────────────────────────────────────
116
+
117
+ /**
118
+ * Resume an interrupted batch from persisted state.
119
+ *
120
+ * Flow:
121
+ * 1. Load and validate batch-state.json
122
+ * 2. Check phase eligibility (paused/executing/merging only)
123
+ * 3. Check for alive TMUX sessions and .DONE files
124
+ * 4. Reconcile persisted state against live signals
125
+ * 5. Compute resume point (which wave to start from)
126
+ * 6. Reconstruct runtime state and continue execution
127
+ *
128
+ * @param orchConfig - Orchestrator configuration
129
+ * @param runnerConfig - Task runner configuration
130
+ * @param cwd - Repository root
131
+ * @param batchState - Mutable batch state (will be populated from persisted state)
132
+ * @param onNotify - Callback for user-facing messages
133
+ * @param onMonitorUpdate - Optional callback for dashboard updates
134
+ */