@cyperx/clawforge 1.2.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.
- package/LICENSE +21 -0
- package/README.md +312 -0
- package/VERSION +1 -0
- package/bin/attach.sh +98 -0
- package/bin/check-agents.sh +343 -0
- package/bin/clawforge +257 -0
- package/bin/clawforge-dashboard +0 -0
- package/bin/clean.sh +257 -0
- package/bin/config.sh +111 -0
- package/bin/conflicts.sh +224 -0
- package/bin/cost.sh +273 -0
- package/bin/dashboard.sh +557 -0
- package/bin/diff.sh +109 -0
- package/bin/doctor.sh +196 -0
- package/bin/eval.sh +217 -0
- package/bin/history.sh +91 -0
- package/bin/init.sh +182 -0
- package/bin/learn.sh +230 -0
- package/bin/logs.sh +126 -0
- package/bin/memory.sh +207 -0
- package/bin/merge-helper.sh +174 -0
- package/bin/multi-review.sh +215 -0
- package/bin/notify.sh +93 -0
- package/bin/on-complete.sh +149 -0
- package/bin/parse-cost.sh +205 -0
- package/bin/pr.sh +167 -0
- package/bin/resume.sh +183 -0
- package/bin/review-mode.sh +163 -0
- package/bin/review-pr.sh +145 -0
- package/bin/routing.sh +88 -0
- package/bin/scope-task.sh +169 -0
- package/bin/spawn-agent.sh +190 -0
- package/bin/sprint.sh +320 -0
- package/bin/steer.sh +107 -0
- package/bin/stop.sh +136 -0
- package/bin/summary.sh +182 -0
- package/bin/swarm.sh +525 -0
- package/bin/templates.sh +244 -0
- package/lib/common.sh +302 -0
- package/lib/templates/bugfix.json +6 -0
- package/lib/templates/migration.json +7 -0
- package/lib/templates/refactor.json +6 -0
- package/lib/templates/security-audit.json +5 -0
- package/lib/templates/test-coverage.json +6 -0
- package/package.json +31 -0
- package/registry/conflicts.jsonl +0 -0
- package/registry/costs.jsonl +0 -0
- package/tui/PRD.md +106 -0
- package/tui/agent.go +266 -0
- package/tui/animation.go +192 -0
- package/tui/dashboard.go +219 -0
- package/tui/filter.go +68 -0
- package/tui/go.mod +25 -0
- package/tui/go.sum +46 -0
- package/tui/keybindings.go +229 -0
- package/tui/main.go +61 -0
- package/tui/model.go +166 -0
- package/tui/steer.go +69 -0
- package/tui/styles.go +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 cyperx84
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# ClawForge
|
|
2
|
+
|
|
3
|
+
```text
|
|
4
|
+
________ ______
|
|
5
|
+
/ ____/ /___ __ __ / ____/___ _________ ____
|
|
6
|
+
/ / / / __ `/ | /| / // /_ / __ \/ ___/ __ `/ _ \
|
|
7
|
+
/ /___/ / /_/ /| |/ |/ // __/ / /_/ / / / /_/ / __/
|
|
8
|
+
\____/_/\__,_/ |__/|__//_/ \____/_/ \__, /\___/
|
|
9
|
+
/____/
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
**Multi-mode coding workflow CLI** — from quick patches to parallel agent orchestration with Claude Code and Codex.
|
|
13
|
+
|
|
14
|
+
## Inspired By
|
|
15
|
+
|
|
16
|
+
This project was inspired by [Elvis's "OpenClaw + Codex/Claude Code Agent Swarm" workflow](https://x.com/elvissun/article/2025920521871716562) — a battle-tested system for managing a fleet of AI coding agents.
|
|
17
|
+
|
|
18
|
+
## What It Does
|
|
19
|
+
|
|
20
|
+
ClawForge manages coding agents running in tmux sessions on isolated git worktrees. Three workflow modes match task complexity:
|
|
21
|
+
|
|
22
|
+
| Mode | Use Case | Agents |
|
|
23
|
+
|------|----------|--------|
|
|
24
|
+
| **Sprint** | Single task, full dev cycle | 1 |
|
|
25
|
+
| **Review** | Quality gate on existing PR | 0 (analysis only) |
|
|
26
|
+
| **Swarm** | Parallel orchestration | N (decomposed) |
|
|
27
|
+
|
|
28
|
+
Plus management commands: `steer`, `attach`, `stop`, `watch --daemon`, `status`, `dashboard`.
|
|
29
|
+
|
|
30
|
+
## Architecture
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
clawforge CLI
|
|
34
|
+
│
|
|
35
|
+
┌───────────────┼───────────────┐
|
|
36
|
+
│ │ │
|
|
37
|
+
Workflow Modes Management Direct Access
|
|
38
|
+
┌───────────┐ ┌──────────┐ ┌──────────────┐
|
|
39
|
+
│ sprint │ │ status │ │ scope spawn │
|
|
40
|
+
│ review │ │ attach │ │ notify merge │
|
|
41
|
+
│ swarm │ │ steer │ │ clean learn │
|
|
42
|
+
└─────┬─────┘ │ stop │ └──────────────┘
|
|
43
|
+
│ │ watch │
|
|
44
|
+
│ │ dashboard│
|
|
45
|
+
│ └────┬─────┘
|
|
46
|
+
│ │
|
|
47
|
+
└──────┬───────┘
|
|
48
|
+
│
|
|
49
|
+
┌─────────┼─────────┐
|
|
50
|
+
│ │ │
|
|
51
|
+
tmux git worktree gh CLI
|
|
52
|
+
sessions (isolated) (PRs/CI)
|
|
53
|
+
│
|
|
54
|
+
coding agents
|
|
55
|
+
(claude / codex)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
| Method | Command | Best For |
|
|
61
|
+
|--------|---------|----------|
|
|
62
|
+
| Homebrew | `brew install cyperx84/tap/clawforge` | macOS users (recommended) |
|
|
63
|
+
| npm | `npm install -g @cyperx84/clawforge` | Node.js users |
|
|
64
|
+
| uv | `uv tool install clawforge` | Python users |
|
|
65
|
+
| bun | `bun install -g @cyperx84/clawforge` | Bun users |
|
|
66
|
+
| Source | See below | Development |
|
|
67
|
+
|
|
68
|
+
### Homebrew (recommended for macOS)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
brew tap cyperx84/tap
|
|
72
|
+
brew install cyperx84/tap/clawforge
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Upgrade later:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
brew update
|
|
79
|
+
brew upgrade clawforge
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### npm / bun
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# npm
|
|
86
|
+
npm install -g @cyperx84/clawforge
|
|
87
|
+
|
|
88
|
+
# bun
|
|
89
|
+
bun install -g @cyperx84/clawforge
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Upgrade later:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npm update -g @cyperx84/clawforge
|
|
96
|
+
# or
|
|
97
|
+
bun update -g @cyperx84/clawforge
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### uv (Python)
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
uv tool install clawforge
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Upgrade later:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv tool upgrade clawforge
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Source install
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
git clone https://github.com/cyperx84/clawforge.git
|
|
116
|
+
cd clawforge
|
|
117
|
+
./install.sh --openclaw
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
That command will:
|
|
121
|
+
- symlink `clawforge` into `~/.local/bin`
|
|
122
|
+
- wire up `SKILL.md` for OpenClaw
|
|
123
|
+
- create missing directories if needed
|
|
124
|
+
|
|
125
|
+
### Install modes
|
|
126
|
+
|
|
127
|
+
#### 1) OpenClaw skill mode
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
./install.sh --openclaw
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### 2) Standalone CLI mode
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
./install.sh --standalone
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### 3) Custom bin path
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
./install.sh --openclaw --bin-dir ~/.bin
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Manual install (if you prefer explicit symlinks)
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
mkdir -p ~/.local/bin
|
|
149
|
+
ln -sf "$(pwd)/bin/clawforge" ~/.local/bin/clawforge
|
|
150
|
+
|
|
151
|
+
# Optional OpenClaw skill wiring
|
|
152
|
+
mkdir -p ~/.openclaw/skills/clawforge/scripts
|
|
153
|
+
ln -sf "$(pwd)/SKILL.md" ~/.openclaw/skills/clawforge/SKILL.md
|
|
154
|
+
ln -sf "$(pwd)/bin/clawforge" ~/.openclaw/skills/clawforge/scripts/clawforge
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Verify install
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
clawforge version
|
|
161
|
+
clawforge help
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Prerequisites
|
|
165
|
+
|
|
166
|
+
- `bash` (4+), `jq`, `git`, `tmux`
|
|
167
|
+
- `gh` (GitHub CLI, authenticated)
|
|
168
|
+
- `claude` and/or `codex` CLI
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
## Documentation
|
|
172
|
+
|
|
173
|
+
Full docs live in [`docs/`](./docs/README.md):
|
|
174
|
+
|
|
175
|
+
- [Getting Started](./docs/getting-started.md)
|
|
176
|
+
- [Workflow Modes](./docs/workflow-modes.md)
|
|
177
|
+
- [Command Reference](./docs/command-reference.md)
|
|
178
|
+
- [Scenario Playbooks](./docs/scenarios.md)
|
|
179
|
+
- [Dashboard (Go TUI)](./docs/dashboard.md)
|
|
180
|
+
- [Architecture](./docs/architecture.md)
|
|
181
|
+
- [Fleet Ops](./docs/fleet-ops.md)
|
|
182
|
+
- [Evaluation Loop](./docs/evaluation.md)
|
|
183
|
+
- [Configuration](./docs/configuration.md)
|
|
184
|
+
- [Troubleshooting](./docs/troubleshooting.md)
|
|
185
|
+
- [FAQ](./docs/faq.md)
|
|
186
|
+
- [Changelog](./CHANGELOG.md)
|
|
187
|
+
|
|
188
|
+
## Quick Start
|
|
189
|
+
|
|
190
|
+
### Sprint — the workhorse
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Single agent, full dev cycle (auto-detects repo from cwd)
|
|
194
|
+
clawforge sprint "Add JWT authentication middleware"
|
|
195
|
+
|
|
196
|
+
# Quick patch mode — auto-merge, skip review
|
|
197
|
+
clawforge sprint "Fix typo in readme" --quick
|
|
198
|
+
|
|
199
|
+
# With explicit options
|
|
200
|
+
clawforge sprint ~/github/api "Fix null pointer" --branch fix/null-ptr --agent codex
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Review — quality gate
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
clawforge review --pr 42
|
|
207
|
+
clawforge review --pr 42 --fix # Spawn agent to fix issues
|
|
208
|
+
clawforge review --pr 42 --reviewers claude,gemini,codex
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Swarm — parallel agents
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
clawforge swarm "Migrate all tests from jest to vitest"
|
|
215
|
+
clawforge swarm "Add i18n to all strings" --max-agents 4
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Monitor & Manage
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
clawforge status # Short IDs: #1, #2, #3
|
|
222
|
+
clawforge attach 1 # Attach to agent tmux session
|
|
223
|
+
clawforge steer 1 "Use bcrypt" # Course-correct running agent
|
|
224
|
+
clawforge steer 3.2 "Skip legacy" # Steer sub-agent 2 of swarm task 3
|
|
225
|
+
clawforge stop 1 --yes # Stop agent
|
|
226
|
+
clawforge watch --daemon # Background monitoring + CI feedback
|
|
227
|
+
clawforge dashboard # Full overview + system health
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Commands
|
|
231
|
+
|
|
232
|
+
### Workflow Modes
|
|
233
|
+
|
|
234
|
+
| Command | Description | Key Flags |
|
|
235
|
+
|---------|-------------|-----------|
|
|
236
|
+
| `sprint` | Single agent, full dev cycle | `--quick`, `--branch`, `--agent`, `--auto-merge`, `--dry-run` |
|
|
237
|
+
| `review` | Quality gate on existing PR | `--pr`, `--fix`, `--reviewers`, `--dry-run` |
|
|
238
|
+
| `swarm` | Parallel multi-agent orchestration | `--max-agents`, `--agent`, `--auto-merge`, `--dry-run` |
|
|
239
|
+
|
|
240
|
+
### Management
|
|
241
|
+
|
|
242
|
+
| Command | Description | Key Flags |
|
|
243
|
+
|---------|-------------|-----------|
|
|
244
|
+
| `status` | Show tracked tasks with short IDs | `--status` |
|
|
245
|
+
| `attach` | Attach to agent tmux session | (task ID) |
|
|
246
|
+
| `steer` | Course-correct running agent | (task ID, message) |
|
|
247
|
+
| `stop` | Stop a running agent | `--yes`, `--clean` |
|
|
248
|
+
| `watch` | Monitor agent health | `--daemon`, `--stop`, `--json`, `--interval` |
|
|
249
|
+
| `dashboard` | Overview + system health | (none) |
|
|
250
|
+
| `clean` | Clean up completed tasks | `--all-done`, `--stale-days`, `--dry-run` |
|
|
251
|
+
| `learn` | Record learnings | `--auto`, `--notes`, `--memory` |
|
|
252
|
+
|
|
253
|
+
### Fleet Ops (v0.6)
|
|
254
|
+
|
|
255
|
+
| Command | Description | Key Flags |
|
|
256
|
+
|---------|-------------|-----------|
|
|
257
|
+
| `memory` | Per-repo agent memory | `show`, `add`, `search`, `forget`, `clear` |
|
|
258
|
+
| `init` | Scan project, generate initial memories | `--claude-md` |
|
|
259
|
+
| `history` | Show completed task history | `--repo`, `--mode`, `--limit`, `--all` |
|
|
260
|
+
|
|
261
|
+
### Direct Module Access (via `clawforge help --all`)
|
|
262
|
+
|
|
263
|
+
| Command | Description |
|
|
264
|
+
|---------|-------------|
|
|
265
|
+
| `scope` | Assemble prompt with context |
|
|
266
|
+
| `spawn` | Create worktree + launch agent |
|
|
267
|
+
| `notify` | Send Discord notification |
|
|
268
|
+
| `merge` | Merge PR with safety checks |
|
|
269
|
+
| `run` | Scope + spawn in one step (legacy) |
|
|
270
|
+
|
|
271
|
+
**Global flag:** `--verbose` enables debug logging for any command.
|
|
272
|
+
|
|
273
|
+
## Smart Behaviors
|
|
274
|
+
|
|
275
|
+
- **Auto-repo detection** — No `--repo` needed if you're in a git repo
|
|
276
|
+
- **Auto-branch naming** — `sprint/<slug>`, `quick/<slug>`, `swarm/<slug>` with collision detection
|
|
277
|
+
- **Short task IDs** — `#1`, `3.2` instead of full slugs
|
|
278
|
+
- **CI feedback loop** — Watch detects CI failure, auto-steers agent with error context (up to 2 retries)
|
|
279
|
+
- **Escalation suggestions** — Quick mode detects complex tasks, suggests full sprint
|
|
280
|
+
- **Conflict detection** — Dashboard warns when swarm agents touch overlapping files
|
|
281
|
+
- **RAM warnings** — Prompts when spawning >3 agents
|
|
282
|
+
- **Agent memory** — Per-repo knowledge base injected into agent prompts (max 20 entries)
|
|
283
|
+
- **Project init** — Auto-detect language, framework, test runner and seed memories
|
|
284
|
+
|
|
285
|
+
## Configuration
|
|
286
|
+
|
|
287
|
+
Edit `config/defaults.json`:
|
|
288
|
+
|
|
289
|
+
```json
|
|
290
|
+
{
|
|
291
|
+
"default_agent": "claude",
|
|
292
|
+
"default_model_claude": "claude-sonnet-4-5",
|
|
293
|
+
"default_model_codex": "gpt-5.3-codex",
|
|
294
|
+
"ci_retry_limit": 2,
|
|
295
|
+
"ram_warn_threshold": 3,
|
|
296
|
+
"reviewers": ["claude", "gemini"],
|
|
297
|
+
"auto_simplify": true,
|
|
298
|
+
"notify": {
|
|
299
|
+
"defaultChannel": "channel:..."
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Testing
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
./tests/run-all-tests.sh
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## License
|
|
311
|
+
|
|
312
|
+
MIT
|
package/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.2.0
|
package/bin/attach.sh
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# attach.sh — Attach to a running agent's tmux session
|
|
3
|
+
# Usage: clawforge attach <id>
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
7
|
+
source "${SCRIPT_DIR}/../lib/common.sh"
|
|
8
|
+
|
|
9
|
+
# ── Help ───────────────────────────────────────────────────────────────
|
|
10
|
+
usage() {
|
|
11
|
+
cat <<EOF
|
|
12
|
+
Usage: clawforge attach <id>
|
|
13
|
+
|
|
14
|
+
Attach to a running agent's tmux session.
|
|
15
|
+
|
|
16
|
+
Arguments:
|
|
17
|
+
<id> Task short ID (#1), full ID, or sub-agent ID (3.2)
|
|
18
|
+
|
|
19
|
+
For swarm tasks, use the parent ID to see a picker for which agent session.
|
|
20
|
+
|
|
21
|
+
Examples:
|
|
22
|
+
clawforge attach 1
|
|
23
|
+
clawforge attach 3.2
|
|
24
|
+
EOF
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# ── Parse args ────────────────────────────────────────────────────────
|
|
28
|
+
if [[ $# -lt 1 ]] || [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then
|
|
29
|
+
usage
|
|
30
|
+
[[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && exit 0 || exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
TASK_REF="$1"
|
|
34
|
+
|
|
35
|
+
# ── Resolve task ──────────────────────────────────────────────────────
|
|
36
|
+
TASK_ID=$(resolve_task_id "$TASK_REF")
|
|
37
|
+
if [[ -z "$TASK_ID" ]]; then
|
|
38
|
+
log_error "Could not resolve task: $TASK_REF"
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
TASK=$(registry_get "$TASK_ID")
|
|
43
|
+
if [[ -z "$TASK" ]]; then
|
|
44
|
+
log_error "Task not found: $TASK_ID"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
MODE=$(echo "$TASK" | jq -r '.mode // ""')
|
|
49
|
+
TMUX_SESSION=$(echo "$TASK" | jq -r '.tmuxSession')
|
|
50
|
+
|
|
51
|
+
# ── Swarm parent: show picker ─────────────────────────────────────────
|
|
52
|
+
if [[ "$MODE" == "swarm" ]] && [[ -z "$TMUX_SESSION" || "$TMUX_SESSION" == "" ]]; then
|
|
53
|
+
# This is a swarm parent — find sub-agents
|
|
54
|
+
SUB_TASKS=$(jq --arg pid "$TASK_ID" '[.tasks[] | select(.parent_id == $pid)]' "$REGISTRY_FILE" 2>/dev/null || echo "[]")
|
|
55
|
+
SUB_COUNT=$(echo "$SUB_TASKS" | jq 'length')
|
|
56
|
+
|
|
57
|
+
if [[ "$SUB_COUNT" == "0" ]]; then
|
|
58
|
+
log_error "No sub-agents found for swarm task $TASK_REF"
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
echo "Swarm task #$(echo "$TASK" | jq -r '.short_id') — select agent to attach:"
|
|
63
|
+
echo ""
|
|
64
|
+
echo "$SUB_TASKS" | jq -r '.[] | " \(.sub_index). [\(.status)] \(.description // .id)[0:50] (tmux: \(.tmuxSession))"'
|
|
65
|
+
echo ""
|
|
66
|
+
|
|
67
|
+
# Use fzf if available, otherwise prompt
|
|
68
|
+
if command -v fzf &>/dev/null; then
|
|
69
|
+
SELECTION=$(echo "$SUB_TASKS" | jq -r '.[].sub_index' | fzf --prompt="Select agent: ")
|
|
70
|
+
else
|
|
71
|
+
echo -n "Enter agent number: "
|
|
72
|
+
read -r SELECTION
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
if [[ -z "$SELECTION" ]]; then
|
|
76
|
+
echo "Cancelled."
|
|
77
|
+
exit 0
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
TMUX_SESSION=$(echo "$SUB_TASKS" | jq -r --argjson idx "$SELECTION" '.[] | select(.sub_index == $idx) | .tmuxSession')
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# ── Validate tmux session ─────────────────────────────────────────────
|
|
84
|
+
if [[ -z "$TMUX_SESSION" ]]; then
|
|
85
|
+
log_error "No tmux session for task $TASK_REF"
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
if ! tmux has-session -t "$TMUX_SESSION" 2>/dev/null; then
|
|
90
|
+
log_error "tmux session not found: $TMUX_SESSION"
|
|
91
|
+
echo " The agent may have finished or crashed."
|
|
92
|
+
echo " Use 'clawforge status' to check."
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# ── Attach ────────────────────────────────────────────────────────────
|
|
97
|
+
echo "Attaching to: $TMUX_SESSION"
|
|
98
|
+
exec tmux attach -t "$TMUX_SESSION"
|