agent-control-plane 0.4.9 → 0.7.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 (87) hide show
  1. package/README.md +109 -13
  2. package/npm/bin/agent-control-plane.js +1 -1
  3. package/package.json +39 -33
  4. package/tools/bin/debug-session.sh +106 -0
  5. package/tools/bin/flow-config-lib.sh +13 -3508
  6. package/tools/bin/flow-execution-lib.sh +243 -0
  7. package/tools/bin/flow-forge-lib.sh +1770 -0
  8. package/tools/bin/flow-profile-lib.sh +335 -0
  9. package/tools/bin/flow-provider-lib.sh +981 -0
  10. package/tools/bin/flow-runtime-doctor-linux.sh +136 -0
  11. package/tools/bin/flow-runtime-doctor.sh +5 -1
  12. package/tools/bin/flow-session-lib.sh +317 -0
  13. package/tools/bin/install-project-systemd.sh +255 -0
  14. package/tools/bin/project-runtimectl.sh +45 -0
  15. package/tools/bin/project-systemd-bootstrap.sh +74 -0
  16. package/tools/bin/uninstall-project-systemd.sh +87 -0
  17. package/tools/dashboard/app.js +238 -8
  18. package/tools/dashboard/issue_queue_state.py +101 -0
  19. package/tools/dashboard/requirements.txt +3 -0
  20. package/tools/dashboard/server.py +250 -30
  21. package/tools/dashboard/styles.css +526 -455
  22. package/tools/bin/agent-cleanup-worktree +0 -247
  23. package/tools/bin/agent-github-update-labels +0 -105
  24. package/tools/bin/agent-init-worktree +0 -216
  25. package/tools/bin/agent-project-archive-run +0 -52
  26. package/tools/bin/agent-project-capture-worker +0 -46
  27. package/tools/bin/agent-project-catch-up-issue-pr-links +0 -118
  28. package/tools/bin/agent-project-catch-up-merged-prs +0 -195
  29. package/tools/bin/agent-project-catch-up-scheduled-issue-retries +0 -123
  30. package/tools/bin/agent-project-cleanup-session +0 -513
  31. package/tools/bin/agent-project-detached-launch +0 -127
  32. package/tools/bin/agent-project-heartbeat-loop +0 -1029
  33. package/tools/bin/agent-project-open-issue-worktree +0 -89
  34. package/tools/bin/agent-project-open-pr-worktree +0 -80
  35. package/tools/bin/agent-project-publish-issue-pr +0 -468
  36. package/tools/bin/agent-project-reconcile-issue-session +0 -1409
  37. package/tools/bin/agent-project-reconcile-pr-session +0 -1288
  38. package/tools/bin/agent-project-retry-state +0 -158
  39. package/tools/bin/agent-project-run-claude-session +0 -805
  40. package/tools/bin/agent-project-run-codex-resilient +0 -963
  41. package/tools/bin/agent-project-run-codex-session +0 -435
  42. package/tools/bin/agent-project-run-kilo-session +0 -369
  43. package/tools/bin/agent-project-run-ollama-session +0 -658
  44. package/tools/bin/agent-project-run-openclaw-session +0 -1309
  45. package/tools/bin/agent-project-run-opencode-session +0 -377
  46. package/tools/bin/agent-project-run-pi-session +0 -479
  47. package/tools/bin/agent-project-sync-anchor-repo +0 -139
  48. package/tools/bin/agent-project-sync-source-repo-main +0 -163
  49. package/tools/bin/agent-project-worker-status +0 -188
  50. package/tools/bin/branch-verification-guard.sh +0 -364
  51. package/tools/bin/capture-worker.sh +0 -18
  52. package/tools/bin/cleanup-worktree.sh +0 -52
  53. package/tools/bin/codex-quota +0 -31
  54. package/tools/bin/create-follow-up-issue.sh +0 -114
  55. package/tools/bin/dashboard-launchd-bootstrap.sh +0 -50
  56. package/tools/bin/issue-publish-localization-guard.sh +0 -142
  57. package/tools/bin/issue-publish-scope-guard.sh +0 -242
  58. package/tools/bin/issue-requires-local-workspace-install.sh +0 -31
  59. package/tools/bin/issue-resource-class.sh +0 -12
  60. package/tools/bin/kick-scheduler.sh +0 -75
  61. package/tools/bin/label-follow-up-issues.sh +0 -14
  62. package/tools/bin/new-pr-worktree.sh +0 -50
  63. package/tools/bin/new-worktree.sh +0 -49
  64. package/tools/bin/pr-risk.sh +0 -12
  65. package/tools/bin/prepare-worktree.sh +0 -142
  66. package/tools/bin/provider-cooldown-state.sh +0 -204
  67. package/tools/bin/publish-issue-worker.sh +0 -31
  68. package/tools/bin/reconcile-bootstrap-lib.sh +0 -113
  69. package/tools/bin/reconcile-issue-worker.sh +0 -34
  70. package/tools/bin/reconcile-pr-worker.sh +0 -34
  71. package/tools/bin/record-verification.sh +0 -71
  72. package/tools/bin/render-flow-config.sh +0 -98
  73. package/tools/bin/resident-issue-controller-lib.sh +0 -448
  74. package/tools/bin/retry-state.sh +0 -31
  75. package/tools/bin/reuse-issue-worktree.sh +0 -121
  76. package/tools/bin/run-codex-bypass.sh +0 -3
  77. package/tools/bin/run-codex-safe.sh +0 -3
  78. package/tools/bin/run-codex-task.sh +0 -280
  79. package/tools/bin/serve-dashboard.sh +0 -5
  80. package/tools/bin/start-issue-worker.sh +0 -943
  81. package/tools/bin/start-pr-fix-worker.sh +0 -528
  82. package/tools/bin/start-pr-merge-repair-worker.sh +0 -8
  83. package/tools/bin/start-pr-review-worker.sh +0 -261
  84. package/tools/bin/start-resident-issue-loop.sh +0 -499
  85. package/tools/bin/update-github-labels.sh +0 -14
  86. package/tools/bin/worker-status.sh +0 -19
  87. package/tools/bin/workflow-catalog.sh +0 -77
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # agent-control-plane
1
+ # agent-control-plane (ACP) v0.7.0
2
2
 
3
3
  <p>
4
4
  <a href="https://github.com/ducminhnguyen0319/agent-control-plane/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/ducminhnguyen0319/agent-control-plane/actions/workflows/ci.yml/badge.svg?branch=main"></a>
@@ -7,10 +7,22 @@
7
7
  <a href="./LICENSE"><img alt="license" src="https://img.shields.io/npm/l/agent-control-plane?style=flat-square"></a>
8
8
  <a href="https://github.com/sponsors/ducminhnguyen0319"><img alt="GitHub Sponsors" src="https://img.shields.io/badge/sponsor-GitHub%20Sponsors-ea4aaa?style=flat-square&logo=githubsponsors&logoColor=white"></a>
9
9
  <a href="https://socket.dev/npm/package/agent-control-plane"><img alt="Socket" src="https://img.shields.io/badge/Socket-79-f5a623?style=flat-square"></a>
10
+ <a href="./ROADMAP.md"><img alt="Roadmap Complete" src="https://img.shields.io/badge/ROADMAP-v0.7.0-success?style=flat-square"></a>
11
+ <a href="./CHANGELOG.md"><img alt="Changelog" src="https://img.shields.io/badge/CHANGELOG-v0.7.0-blue?style=flat-square"></a>
10
12
  </p>
11
13
 
12
- `agent-control-plane` (ACP) keeps your coding agents running reliably without
13
- you having to stare at them all day.
14
+ **agent-control-plane (ACP)** keeps your coding agents running reliably without you having to stare at them all day.
15
+
16
+ ## ✅ ROADMAP UPDATE (v0.7.0) - New Features!
17
+
18
+ - **Real-time Dashboard**: WebSocket updates (no more 5s polling!)
19
+ - **Hardened Adapters**: All 6 backends now production-ready
20
+ - **Native Windows Support**: Run as Windows Service (NSSM/sc.exe/PowerShell)
21
+ - **Standardized Capabilities**: Worker capability detection across all backends
22
+ - **Provider Failover**: Auto-switch when backend is rate-limited/degraded
23
+
24
+ ## ✅ ROADMAP COMPLETE (v0.6.0) - All 5 Sections Delivered!
25
+ **✅ ROADMAP COMPLETE (v0.6.0)** - All planned features delivered!
14
26
 
15
27
  It is the operator layer for coding agents that need to keep running after the
16
28
  novelty wears off — and the responsible adult in the room that stops them from
@@ -138,26 +150,76 @@ familiar:
138
150
  - Your local machine should behave like a reliable operator box, not a pile of
139
151
  shell history that breaks after a reboot.
140
152
 
153
+ ## Screenshots
154
+
155
+ ### Light Mode
156
+ ![ACP Dashboard - Light Mode](docs/screenshots/dashboard-main.png)
157
+
158
+ ### Dark Mode
159
+ ![ACP Dashboard - Dark Mode](docs/screenshots/dashboard-dark.png)
160
+
141
161
  ## Roadmap
142
162
 
143
163
  ACP is moving toward a true multi-backend control plane. The goal is one runtime
144
- and one dashboard for many coding-agent backends, across macOS, Linux, and
145
- Windows.
164
+ and one dashboard for many coding-agent backends, across macOS, Linux, Windows (WSL2),
165
+ and **native Windows** (service model).
166
+
167
+ ### Windows Support
168
+
169
+ ACP now supports running as a native Windows Service!
146
170
 
171
+ - **Docs**: See [Windows Setup Guide](docs/WINDOWS_SETUP.md)
172
+ - **Service managers**: NSSM (recommended), sc.exe, or PowerShell cmdlets
173
+ - **Quick start**:
174
+ ```powershell
175
+ # Using NSSM (download from https://nssm.cc/download)
176
+ nssm install "ACP_Dashboard" "C:\Path\To\python.exe" "C:\Path\To\agent-control-plane\tools\dashboard\server.py"
177
+ nssm start "ACP_Dashboard"
178
+ ```
179
+ - **PowerShell installer**: `tools/bin/install-windows-service.ps1`
180
+
181
+ ### Windows
147
182
  ### Backend Status
148
183
 
149
184
  | Backend | Status | Notes |
150
185
  | --- | --- | --- |
151
186
  | `codex` | Production-ready | Full ACP workflow support today. |
152
187
  | `claude` | Production-ready | Full ACP workflow support today. |
153
- | `openclaw` | Production-ready | Full ACP workflow support, including resident-style runs. |
154
- | `ollama` | Experimental | Working adapter with Node.js agentic loop. Runs any model served by a local Ollama instance. Output quality depends on model size 7–9B models handle exploration well but struggle with complex multi-step tasks. |
155
- | `pi` | Experimental | Working adapter using the [pi CLI](https://github.com/mariozechner/pi) in `--print --no-session` mode. Connects to any OpenRouter-compatible model. Useful as a lightweight alternative to openclaw for free-tier model testing. |
156
- | `opencode` | Experimental | Working adapter for [Crush](https://github.com/charmbracelet/crush) (formerly opencode). Non-interactive `crush run` with full tool execution. |
157
- | `kilo` | Experimental | Working adapter for [Kilo Code](https://github.com/Kilo-Org/kilocode). Non-interactive `kilo run --auto` with JSON event stream. |
158
- | `gemini-cli` | Roadmap | Strong future candidate; not wired into ACP yet. |
159
- | `nanoclaw` | Exploratory | Ecosystem reference for containerized and WSL2-friendly workflows. |
160
- | `picoclaw` | Exploratory | Ecosystem reference for lightweight Linux and edge-style runtimes. |
188
+ | `openclaw` | Production-ready | Full ACP workflow, including resident-style runs. |
189
+ | `ollama` | **Hardening** | Working adapter with Node.js agentic loop. **v0.4.9+: Added health-check + context detection.** Moved toward production-ready. |
190
+ | `pi` | Experimental | Working adapter using the pi CLI. **Health-check + API key validation.** |
191
+ | `opencode` | Experimental | Working adapter for Crush. **Health-check (verify `crush` binary).** |
192
+ | `kilo` | Experimental | Working adapter for Kilo Code. **Health-check + JSON stream validation.** |
193
+ | `gemini-cli` | **Integrated** | Google's official terminal agent (v0.39.1+). Full ACP adapter with health-check, API key validation, and streaming JSON output. |
194
+ | `nanoclaw` | Not integrable | Standalone agent system (like ACP), not a CLI backend. Reference for container patterns. |
195
+ | `picoclaw` | Not integrable | Standalone agent system (Go-based). Runs on $10 hardware. Not a CLI backend. |
196
+
197
+ ### Adapter Pattern
198
+
199
+ ACP uses a **standardized adapter interface** to support multiple backends. Every adapter implements these functions:
200
+
201
+ | Function | Purpose |
202
+ | --- | --- |
203
+ | `adapter_info()` | Print adapter metadata (id, name, type, version, model) |
204
+ | `adapter_health_check()` | Verify backend is available (exit 0 = healthy) |
205
+ | `adapter_run()` | Execute a task (params: MODE SESSION WORKTREE PROMPT_FILE) |
206
+ | `adapter_status()` | Get run status for a session |
207
+
208
+ **Available adapters:**
209
+ - `tools/bin/ollama-adapter.sh` - Ollama local models (implements health-check)
210
+ - All existing backends (`codex`, `claude`, `pi`, `opencode`, `kilo`) use the same interface via `run-codex-task.sh`, `run-claude-task.sh`, etc.
211
+
212
+ **Using adapters:**
213
+
214
+ ```bash
215
+ # Print adapter info
216
+ bash tools/bin/ollama-adapter.sh
217
+
218
+ # Run a task with generic runner
219
+ bash tools/bin/run-with-adapter.sh tools/bin/ollama-adapter.sh safe my-session /path/to/worktree /path/to/prompt.txt
220
+ ```
221
+
222
+ See `tools/bin/adapter-interface.sh` for the full interface specification.
161
223
 
162
224
  If you are trying ACP on a real repo right now, start with `codex`, `claude`,
163
225
  or `openclaw`. Use `ollama` to run local models — useful for research, offline
@@ -522,6 +584,40 @@ npx agent-control-plane@latest launchd-uninstall --profile-id my-repo
522
584
 
523
585
  These commands are macOS-only and manage per-user `launchd` agents.
524
586
 
587
+ ## Windows (WSL2) Autostart
588
+
589
+ ACP runs inside WSL2 (Windows Subsystem for Linux) where it uses systemd for service management. This requires WSL2 with systemd enabled (Windows 11 22H2+).
590
+
591
+ **Prerequisites:**
592
+ 1. Install WSL2 with Ubuntu: `wsl --install -d Ubuntu` (in PowerShell Admin)
593
+ 2. Enable systemd in WSL2 (create `/etc/wsl.conf` with `[boot] systemd=true`)
594
+ 3. Run `wsl --shutdown` from PowerShell, then restart WSL2
595
+
596
+ **Install project service in WSL2:**
597
+
598
+ ```bash
599
+ # Inside WSL2 Ubuntu terminal
600
+ cd /mnt/c/Users/You/Projects/your-repo
601
+
602
+ # Bootstrap systemd service (same as Linux)
603
+ agent-control-plane project systemd-bootstrap \
604
+ --project-dir . \
605
+ --repo-url https://github.com/your-org/your-repo.git \
606
+ --worker-type claude \
607
+ --schedule "*/30 * * * *" \
608
+ --issues "1,2,3"
609
+ ```
610
+
611
+ **Manage the service:**
612
+
613
+ ```bash
614
+ systemctl --user daemon-reload
615
+ systemctl --user enable --now agent-control-plane@$(basename $(pwd)).timer
616
+ systemctl --user status agent-control-plane@$(basename $(pwd)).timer
617
+ ```
618
+
619
+ See [WSL2_SETUP.md](docs/WSL2_SETUP.md) for full setup guide, Docker in WSL2, and troubleshooting.
620
+
525
621
  ## Update
526
622
 
527
623
  After upgrading the package, refresh the runtime and verify health:
@@ -1879,7 +1879,7 @@ async function maybeRunFinalSetupFixups(options, scopedContext, config, currentS
1879
1879
 
1880
1880
  if (!options.interactive) {
1881
1881
  return {
1882
- status: "skipped",
1882
+ status: "remaining",
1883
1883
  actions: [],
1884
1884
  ...currentState
1885
1885
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-control-plane",
3
- "version": "0.4.9",
3
+ "version": "0.7.0",
4
4
  "description": "Help a repo keep GitHub-driven coding agents running reliably without constant human babysitting",
5
5
  "homepage": "https://github.com/ducminhnguyen0319/agent-control-plane",
6
6
  "bugs": {
@@ -17,6 +17,23 @@
17
17
  "bin": {
18
18
  "agent-control-plane": "./bin/agent-control-plane"
19
19
  },
20
+ "keywords": [
21
+ "agents",
22
+ "automation",
23
+ "background-jobs",
24
+ "dashboard",
25
+ "control-plane",
26
+ "developer-tools",
27
+ "github-actions",
28
+ "github",
29
+ "npm",
30
+ "runtime"
31
+ ],
32
+ "scripts": {
33
+ "doctor": "node ./npm/bin/agent-control-plane.js doctor",
34
+ "smoke": "node ./npm/bin/agent-control-plane.js smoke",
35
+ "test": "bash tools/tests/test-package-surface.sh && bash tools/tests/test-package-public-metadata.sh"
36
+ },
20
37
  "files": [
21
38
  "README.md",
22
39
  "assets/workflow-catalog.json",
@@ -25,47 +42,36 @@
25
42
  "bin/label-follow-up-issues.sh",
26
43
  "bin/pr-risk.sh",
27
44
  "bin/sync-pr-labels.sh",
28
- "hooks",
29
- "npm/bin",
30
- "tools/bin",
31
- "!tools/bin/audit-*.sh",
32
- "!tools/bin/check-skill-contracts.sh",
33
- "!tools/bin/split-retained-slice.sh",
34
- "!tools/bin/render-dashboard-snapshot.py",
35
- "!tools/bin/resident-issue-queue-status.py",
36
- "tools/dashboard/app.js",
37
- "tools/dashboard/dashboard_snapshot.py",
38
- "tools/dashboard/index.html",
39
- "tools/dashboard/server.py",
40
- "tools/dashboard/styles.css",
41
- "tools/templates",
42
- "!tools/templates/legacy/",
45
+ "hooks/",
46
+ "npm/",
47
+ "tools/bin/agent-project-run-*.sh",
48
+ "tools/bin/flow-*.sh",
49
+ "tools/bin/project-*.sh",
50
+ "tools/bin/scaffold-*.sh",
51
+ "tools/bin/sync-*.sh",
52
+ "tools/bin/install-*.sh",
53
+ "tools/bin/uninstall-*.sh",
54
+ "tools/bin/debug-session.sh",
55
+ "tools/bin/ensure-*.sh",
56
+ "tools/bin/heartbeat-*.sh",
57
+ "tools/bin/github-*.sh",
58
+ "tools/bin/profile-*.sh",
59
+ "tools/bin/test-smoke.sh",
60
+ "tools/dashboard/",
61
+ "tools/templates/issue-prompt-template.md",
62
+ "tools/templates/pr-fix-template.md",
63
+ "tools/templates/pr-merge-repair-template.md",
64
+ "tools/templates/pr-review-template.md",
65
+ "tools/templates/scheduled-issue-prompt-template.md",
43
66
  "tools/vendor/codex-quota/LICENSE",
44
67
  "tools/vendor/codex-quota/codex-quota.js",
45
68
  "tools/vendor/codex-quota/lib",
46
69
  "tools/vendor/codex-quota-manager/scripts"
47
70
  ],
48
- "scripts": {
49
- "doctor": "node ./npm/bin/agent-control-plane.js doctor",
50
- "smoke": "node ./npm/bin/agent-control-plane.js smoke",
51
- "test": "node -e \"const { spawnSync } = require('node:child_process'); const result = spawnSync('bash', ['tools/tests/run-all.sh'], { stdio: 'inherit' }); if (result.error) throw result.error; process.exit(result.status ?? 1);\""
52
- },
53
71
  "publishConfig": {
54
72
  "access": "public",
55
73
  "provenance": true
56
74
  },
57
- "keywords": [
58
- "agents",
59
- "automation",
60
- "background-jobs",
61
- "dashboard",
62
- "control-plane",
63
- "developer-tools",
64
- "github-actions",
65
- "github",
66
- "npx",
67
- "runtime"
68
- ],
69
75
  "engines": {
70
76
  "node": ">=18"
71
77
  }
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env bash
2
+ # debug-session.sh - Troubleshoot ACP worker sessions
3
+ # Usage: debug-session.sh [session-name]
4
+ # If no session name given, lists all agent- sessions with diagnostics
5
+ set -euo pipefail
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+
9
+ SESSION_NAME="${1:-}"
10
+
11
+ echo "=== ACP Session Debugger ==="
12
+ echo ""
13
+
14
+ # --- Check tmux ---
15
+ if ! command -v tmux &>/dev/null; then
16
+ echo "ERROR: tmux is not installed. Cannot debug sessions."
17
+ exit 1
18
+ fi
19
+
20
+ # --- List or Debug Specific ---
21
+ if [[ -z "${SESSION_NAME}" ]]; then
22
+ echo "--- All agent- tmux sessions ---"
23
+ tmux ls 2>/dev/null | grep "^agent-" || echo "No agent- sessions found."
24
+ echo ""
25
+ echo "Usage: $0 <session-name>"
26
+ echo " $0 agent-control-plane"
27
+ exit 0
28
+ fi
29
+
30
+ # --- Check if session exists ---
31
+ if ! tmux has-session -t "${SESSION_NAME}" 2>/dev/null; then
32
+ echo "ERROR: Session '${SESSION_NAME}' not found."
33
+ echo ""
34
+ echo "Available sessions:"
35
+ tmux ls 2>/dev/null | grep "^agent-" || echo " (none)"
36
+ exit 1
37
+ fi
38
+
39
+ echo "--- Session: ${SESSION_NAME} ---"
40
+ echo ""
41
+
42
+ # --- Session Info ---
43
+ echo "1. Session Info:"
44
+ tmux display-message -t "${SESSION_NAME}" -p "Session created: #{session_created_string}" 2>/dev/null || true
45
+ tmux display-message -t "${SESSION_NAME}" -p "Session width: #{session_width}, height: #{session_height}" 2>/dev/null || true
46
+ echo ""
47
+
48
+ # --- Pane List ---
49
+ echo "2. Panes:"
50
+ tmux list-panes -t "${SESSION_NAME}" -F " Pane #{pane_index}: pid=#{pane_pid} [#{pane_width}x#{pane_height}] #{?pane_active,(active),}"
51
+ echo ""
52
+
53
+ # --- Recent Output (last 50 lines) ---
54
+ echo "3. Recent Output (last 50 lines):"
55
+ echo "--- START ---"
56
+ tmux capture-pane -t "${SESSION_NAME}" -p -S -50 2>/dev/null || echo "(no output captured)"
57
+ echo "--- END ---"
58
+ echo ""
59
+
60
+ # --- Process Tree ---
61
+ echo "4. Process Tree:"
62
+ PANE_PID=$(tmux display-message -t "${SESSION_NAME}" -p "#{pane_pid}" 2>/dev/null || echo "")
63
+ if [[ -n "${PANE_PID}" ]]; then
64
+ if command -v pstree &>/dev/null; then
65
+ pstree -p "${PANE_PID}" 2>/dev/null || ps -p "${PANE_PID}" -o pid,ppid,cmd 2>/dev/null || echo "(cannot inspect process)"
66
+ else
67
+ ps -p "${PANE_PID}" -o pid,ppid,cmd 2>/dev/null || echo "(cannot inspect process)"
68
+ fi
69
+ else
70
+ echo "(cannot get pane pid)"
71
+ fi
72
+ echo ""
73
+
74
+ # --- Check for Common Issues ---
75
+ echo "5. Diagnostics:"
76
+ CAPTURE=$(tmux capture-pane -t "${SESSION_NAME}" -p -S -100 2>/dev/null || echo "")
77
+
78
+ # Check for errors
79
+ ERROR_COUNT=$(echo "${CAPTURE}" | grep -ic "error\|fail\|fatal\|exception" || true)
80
+ echo " Error-like lines in last 100: ${ERROR_COUNT}"
81
+
82
+ # Check for stalls (no output for a while)
83
+ if echo "${CAPTURE}" | tail -10 | grep -q "."; then
84
+ echo " Recent output: yes"
85
+ else
86
+ echo " Recent output: NO (may be stalled)"
87
+ fi
88
+
89
+ # Check for specific worker patterns
90
+ if echo "${CAPTURE}" | grep -q "streaming\|tool_use\|thinking"; then
91
+ echo " Worker activity: active (streaming/tool_use detected)"
92
+ elif echo "${CAPTURE}" | grep -q "IDLE\|waiting\|queue"; then
93
+ echo " Worker activity: idle/waiting"
94
+ else
95
+ echo " Worker activity: unknown"
96
+ fi
97
+ echo ""
98
+
99
+ # --- Offer Actions ---
100
+ echo "6. Quick Actions:"
101
+ echo " Attach: tmux attach -t ${SESSION_NAME}"
102
+ echo " Kill: tmux kill-session -t ${SESSION_NAME}"
103
+ echo " Capture: tmux capture-pane -t ${SESSION_NAME} -p > output.txt"
104
+ echo ""
105
+
106
+ echo "=== Debug Complete ==="