clawforge-cli 1.5.4__tar.gz → 1.6.0__tar.gz
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.
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/CHANGELOG.md +29 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/Formula/clawforge.rb +3 -1
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/PKG-INFO +1 -1
- clawforge_cli-1.6.0/VERSION +1 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/clawforge +2 -0
- clawforge_cli-1.6.0/bin/quick-run.sh +204 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/spawn-agent.sh +6 -2
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/package.json +1 -1
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/pyproject.toml +1 -1
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/run-all-tests.sh +1 -1
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-dx.sh +3 -3
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-observability.sh +1 -1
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-power.sh +1 -1
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-practical.sh +1 -1
- clawforge_cli-1.6.0/tests/test-quick-run.sh +105 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-reliability.sh +1 -1
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-web.sh +1 -1
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/agent.go +3 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/dashboard.go +8 -4
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/keybindings.go +83 -11
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/model.go +2 -1
- clawforge_cli-1.5.4/VERSION +0 -1
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/.github/workflows/ci.yml +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/.github/workflows/publish-npm.yml +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/.github/workflows/publish-pypi.yml +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/.github/workflows/update-homebrew.yml +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/.github/workflows/version-sync.yml +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/.gitignore +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/LICENSE +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/PRD-v05.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/PRD-v06.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/PRD-v07.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/README.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/SKILL.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/attach.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/check-agents.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/clawforge-web +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/clean.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/completions.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/config.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/conflicts.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/cost.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/dashboard.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/deps.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/diff.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/doctor.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/eval.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/export.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/history.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/init.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/learn.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/logs.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/memory.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/merge-helper.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/multi-review.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/notify.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/on-complete.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/parse-cost.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/pr.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/profile.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/replay.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/resume.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/review-mode.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/review-pr.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/routing.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/scope-task.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/sprint.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/steer.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/stop.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/summary.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/swarm.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/templates.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/bin/web.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/clawforge/__init__.py +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/clawforge/cli.py +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/completions/_clawforge +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/completions/clawforge.bash +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/completions/clawforge.fish +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/config/defaults.json +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/config/prompt-templates/default.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/config/routing-defaults.json +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/IMPLEMENTATION-v04.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/PRD-v04.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/PUBLISHING-CHECKLIST.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/README.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/RELEASE.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/architecture.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/command-reference.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/configuration.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/dashboard.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/evaluation.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/faq.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/fleet-ops.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/getting-started.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/scenarios.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/troubleshooting.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/docs/workflow-modes.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/evals/run-log.example.jsonl +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/evals/run-log.schema.json +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/evals/scorecard.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/install.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/lib/common.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/lib/templates/bugfix.json +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/lib/templates/migration.json +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/lib/templates/refactor.json +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/lib/templates/security-audit.json +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/lib/templates/test-coverage.json +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/registry/conflicts.jsonl +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/registry/costs.jsonl +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-ci-loop.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-clean.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-cli.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-conflicts.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-cost.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-dashboard.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-deps.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-eval.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-foundation.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-history.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-init.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-learn.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-management.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-memory.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-merge.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-modes.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-multi-repo.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-notify.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-openclaw.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-registry.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-review.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-routing.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-scope.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-spawn.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-templates.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-tui.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tests/test-watch.sh +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/PRD.md +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/animation.go +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/filter.go +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/go.mod +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/go.sum +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/main.go +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/steer.go +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/tui/styles.go +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/web/go.mod +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/web/index.html +0 -0
- {clawforge_cli-1.5.4 → clawforge_cli-1.6.0}/web/main.go +0 -0
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.6.0 — quick-run: Zero-Overhead Direct Execution
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- New `clawforge quick-run "<task>"` command
|
|
7
|
+
- Runs agent directly in current directory (or `--dir <path>`)
|
|
8
|
+
- No worktree, no branch, no tmux — streams output to terminal
|
|
9
|
+
- Flags: `--agent`, `--model`, `--save`, `--budget`, `--no-track`, `--dir`, `--dry-run`
|
|
10
|
+
- Output teed to log file (`~/.clawforge/registry/logs/`) and registered in task history
|
|
11
|
+
- Appears in `clawforge status` unless `--no-track` used
|
|
12
|
+
- 34 test suites (new: `test-quick-run`)
|
|
13
|
+
|
|
14
|
+
### Use case
|
|
15
|
+
For quick questions, codebase exploration, or small fixes that don't need a branch/PR workflow.
|
|
16
|
+
Use `clawforge sprint` when you need a branch, worktree, CI loop, and PR.
|
|
17
|
+
|
|
18
|
+
## v1.5.5 — TUI Observability: Logs + Diff Keys
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- `l` key in TUI dashboard: show last 50 lines of agent log in preview pane (reads log file; falls back to tmux capture for live sessions)
|
|
22
|
+
- `d` key in TUI dashboard: show `git diff --stat HEAD` for selected agent's worktree
|
|
23
|
+
- `Enter` now falls back to showing log file in preview when session is gone (instead of silent no-op)
|
|
24
|
+
- Agent log files auto-captured to `~/.clawforge/registry/logs/<branch>.log` via `tee` on spawn
|
|
25
|
+
- `log_path` stored in registry and surfaced to TUI
|
|
26
|
+
- `Esc` closes preview/log panel
|
|
27
|
+
- Navigation clears stale static preview content
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- `Enter` on finished/dead sessions silently did nothing — now shows log output
|
|
31
|
+
|
|
3
32
|
## v1.5.4 — TUI Attach + Agent Session Persistence
|
|
4
33
|
|
|
5
34
|
### Fixed
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
class Clawforge < Formula
|
|
2
2
|
desc "Multi-mode coding workflow CLI for orchestrating AI coding agents"
|
|
3
3
|
homepage "https://github.com/cyperx84/clawforge"
|
|
4
|
-
url "https://github.com/cyperx84/clawforge/archive/refs/tags/v1.5.
|
|
4
|
+
url "https://github.com/cyperx84/clawforge/archive/refs/tags/v1.5.5.tar.gz"
|
|
5
|
+
sha256 "b2d483778e83b9007b22bb4c421c90b71e7343cc4f244d116b99eaa2810dc433"
|
|
6
|
+
sha256 "549b3ebf95c953cd4f366b5a251786c994726761c9d4ed6255b996b6458cf695"
|
|
5
7
|
sha256 "2730fca0066fda9d3c864802c4346ab7c39d0daee39a254cc5cebd2694d4a1db"
|
|
6
8
|
sha256 "a026cb0df5b7c3efae439a9ca912e728843deb56c70441591c9064f81a1041ae"
|
|
7
9
|
sha256 "27cca187828366d138dbde81f99f313e065c656be7073452ccc016eb5dba16db"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clawforge-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.0
|
|
4
4
|
Summary: Multi-mode coding workflow CLI for orchestrating AI coding agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/cyperx84/clawforge
|
|
6
6
|
Project-URL: Repository, https://github.com/cyperx84/clawforge
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.6.0
|
|
@@ -43,6 +43,7 @@ Multi-mode coding workflow CLI — from quick patches to parallel agent orchestr
|
|
|
43
43
|
Usage: clawforge <command> [options]
|
|
44
44
|
|
|
45
45
|
Workflow Modes:
|
|
46
|
+
quick-run Direct agent execution in cwd (no branch/worktree overhead)
|
|
46
47
|
sprint Single agent, full dev cycle (the workhorse)
|
|
47
48
|
review Quality gate on an existing PR (analysis only)
|
|
48
49
|
swarm Parallel multi-agent orchestration
|
|
@@ -260,6 +261,7 @@ doctor) exec "${BIN_DIR}/doctor.sh" "$@" ;;
|
|
|
260
261
|
spawn) exec "${BIN_DIR}/spawn-agent.sh" "$@" ;;
|
|
261
262
|
notify) exec "${BIN_DIR}/notify.sh" "$@" ;;
|
|
262
263
|
merge) exec "${BIN_DIR}/merge-helper.sh" "$@" ;;
|
|
264
|
+
quick-run) exec "${BIN_DIR}/quick-run.sh" "$@" ;;
|
|
263
265
|
run) run_combined "$@" ;;
|
|
264
266
|
|
|
265
267
|
# Meta
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# quick-run.sh — Zero-overhead direct agent execution in current directory.
|
|
3
|
+
# No worktree, no branch, no tmux. Just runs the agent and streams output.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
7
|
+
source "${SCRIPT_DIR}/../lib/common.sh"
|
|
8
|
+
|
|
9
|
+
usage() {
|
|
10
|
+
cat <<EOF
|
|
11
|
+
Usage: clawforge quick-run "<task>" [options]
|
|
12
|
+
|
|
13
|
+
Run an agent directly in the current (or specified) directory.
|
|
14
|
+
No worktree, no branch, no tmux overhead — just streams output to your terminal.
|
|
15
|
+
|
|
16
|
+
Arguments:
|
|
17
|
+
<task> Task description (required)
|
|
18
|
+
|
|
19
|
+
Options:
|
|
20
|
+
--dir <path> Directory to run in (default: current working directory)
|
|
21
|
+
--agent <name> Agent to use: claude or codex (default: auto-detect)
|
|
22
|
+
--model <model> Model override
|
|
23
|
+
--no-track Don't register in task registry
|
|
24
|
+
--save <file> Save output to file (in addition to stdout)
|
|
25
|
+
--budget <usd> Max spend cap (passed to agent if supported)
|
|
26
|
+
--dry-run Show what would run without executing
|
|
27
|
+
--help Show this help
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
clawforge quick-run "Explain what this codebase does"
|
|
31
|
+
clawforge quick-run "Add docstrings to all exported functions" --dir ~/github/mylib
|
|
32
|
+
clawforge quick-run "Fix the failing test" --agent codex --model gpt-5.3-codex
|
|
33
|
+
clawforge quick-run "Summarize recent git changes" --no-track
|
|
34
|
+
clawforge quick-run "Refactor auth.ts" --save /tmp/agent-output.log
|
|
35
|
+
|
|
36
|
+
Notes:
|
|
37
|
+
- Output streams directly to your terminal (and optionally a file).
|
|
38
|
+
- The agent runs in the target directory with full file access.
|
|
39
|
+
- Results are tracked in the registry (use --no-track to skip).
|
|
40
|
+
- For tasks requiring a branch/PR, use: clawforge sprint "<task>"
|
|
41
|
+
EOF
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# ── Parse args ─────────────────────────────────────────────────────────
|
|
45
|
+
TASK="" DIR="" AGENT="" MODEL="" NO_TRACK=false SAVE_PATH="" BUDGET="" DRY_RUN=false
|
|
46
|
+
|
|
47
|
+
while [[ $# -gt 0 ]]; do
|
|
48
|
+
case "$1" in
|
|
49
|
+
--dir) DIR="$2"; shift 2 ;;
|
|
50
|
+
--agent) AGENT="$2"; shift 2 ;;
|
|
51
|
+
--model) MODEL="$2"; shift 2 ;;
|
|
52
|
+
--no-track) NO_TRACK=true; shift ;;
|
|
53
|
+
--save) SAVE_PATH="$2"; shift 2 ;;
|
|
54
|
+
--budget) BUDGET="$2"; shift 2 ;;
|
|
55
|
+
--dry-run) DRY_RUN=true; shift ;;
|
|
56
|
+
--help|-h) usage; exit 0 ;;
|
|
57
|
+
-*) log_error "Unknown option: $1"; usage; exit 1 ;;
|
|
58
|
+
*)
|
|
59
|
+
if [[ -z "$TASK" ]]; then
|
|
60
|
+
TASK="$1"; shift
|
|
61
|
+
else
|
|
62
|
+
log_error "Unexpected argument: $1"; usage; exit 1
|
|
63
|
+
fi
|
|
64
|
+
;;
|
|
65
|
+
esac
|
|
66
|
+
done
|
|
67
|
+
|
|
68
|
+
[[ -z "$TASK" ]] && { log_error "Task description is required"; usage; exit 1; }
|
|
69
|
+
|
|
70
|
+
# ── Resolve directory ──────────────────────────────────────────────────
|
|
71
|
+
if [[ -n "$DIR" ]]; then
|
|
72
|
+
[[ -d "$DIR" ]] || { log_error "Directory not found: $DIR"; exit 1; }
|
|
73
|
+
TARGET_DIR="$(cd "$DIR" && pwd)"
|
|
74
|
+
else
|
|
75
|
+
TARGET_DIR="$(pwd)"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# ── Resolve agent ──────────────────────────────────────────────────────
|
|
79
|
+
RESOLVED_AGENT=$(detect_agent "${AGENT:-}")
|
|
80
|
+
[[ -z "$RESOLVED_AGENT" ]] && { log_error "No agent (claude/codex) found in PATH"; exit 1; }
|
|
81
|
+
|
|
82
|
+
# ── Resolve model ──────────────────────────────────────────────────────
|
|
83
|
+
if [[ -z "$MODEL" ]]; then
|
|
84
|
+
if [[ "$RESOLVED_AGENT" == "claude" ]]; then
|
|
85
|
+
MODEL=$(config_get default_model_claude "claude-sonnet-4-5")
|
|
86
|
+
else
|
|
87
|
+
MODEL=$(config_get default_model_codex "gpt-5.3-codex")
|
|
88
|
+
fi
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# ── Build task ID ──────────────────────────────────────────────────────
|
|
92
|
+
SAFE_SLUG=$(slugify_task "$TASK" 32)
|
|
93
|
+
TASK_ID="qr-${SAFE_SLUG}"
|
|
94
|
+
NOW=$(epoch_ms)
|
|
95
|
+
|
|
96
|
+
# ── Dry-run ────────────────────────────────────────────────────────────
|
|
97
|
+
if $DRY_RUN; then
|
|
98
|
+
echo "──────────────────────────────────────────"
|
|
99
|
+
echo " clawforge quick-run [dry-run]"
|
|
100
|
+
echo "──────────────────────────────────────────"
|
|
101
|
+
echo " task: $TASK"
|
|
102
|
+
echo " dir: $TARGET_DIR"
|
|
103
|
+
echo " agent: $RESOLVED_AGENT"
|
|
104
|
+
echo " model: $MODEL"
|
|
105
|
+
echo " track: $( $NO_TRACK && echo no || echo yes)"
|
|
106
|
+
[[ -n "$SAVE_PATH" ]] && echo " Save to: $SAVE_PATH"
|
|
107
|
+
[[ -n "$BUDGET" ]] && echo " Budget: \$$BUDGET"
|
|
108
|
+
echo "──────────────────────────────────────────"
|
|
109
|
+
exit 0
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# ── Register task ──────────────────────────────────────────────────────
|
|
113
|
+
SHORT_ID=""
|
|
114
|
+
if ! $NO_TRACK; then
|
|
115
|
+
_ensure_registry
|
|
116
|
+
TASK_JSON=$(jq -n \
|
|
117
|
+
--arg id "$TASK_ID" \
|
|
118
|
+
--arg agent "$RESOLVED_AGENT" \
|
|
119
|
+
--arg model "$MODEL" \
|
|
120
|
+
--arg desc "$TASK" \
|
|
121
|
+
--arg dir "$TARGET_DIR" \
|
|
122
|
+
--argjson started "$NOW" \
|
|
123
|
+
'{
|
|
124
|
+
id: $id,
|
|
125
|
+
agent: $agent,
|
|
126
|
+
model: $model,
|
|
127
|
+
description: $desc,
|
|
128
|
+
repo: $dir,
|
|
129
|
+
worktree: $dir,
|
|
130
|
+
branch: "",
|
|
131
|
+
mode: "quick-run",
|
|
132
|
+
status: "running",
|
|
133
|
+
started_at: $started,
|
|
134
|
+
files_touched: [],
|
|
135
|
+
ci_retries: 0
|
|
136
|
+
}')
|
|
137
|
+
registry_add "$TASK_JSON"
|
|
138
|
+
SHORT_ID=$(registry_get "$TASK_ID" | jq -r '.short_id // empty')
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# ── Set up output capture ──────────────────────────────────────────────
|
|
142
|
+
LOG_DIR="${CLAWFORGE_DIR}/registry/logs"
|
|
143
|
+
mkdir -p "$LOG_DIR"
|
|
144
|
+
LOG_FILE="${LOG_DIR}/${TASK_ID}.log"
|
|
145
|
+
|
|
146
|
+
if ! $NO_TRACK; then
|
|
147
|
+
registry_update "$TASK_ID" "log_path" "\"$LOG_FILE\""
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
# ── Build agent command ────────────────────────────────────────────────
|
|
151
|
+
ESCAPED_TASK=$(printf '%s' "$TASK" | sed "s/'/'\\''/g")
|
|
152
|
+
|
|
153
|
+
if [[ "$RESOLVED_AGENT" == "claude" ]]; then
|
|
154
|
+
BUDGET_FLAG=""
|
|
155
|
+
[[ -n "$BUDGET" ]] && BUDGET_FLAG="--max-budget-usd $BUDGET"
|
|
156
|
+
AGENT_CMD=(claude --model "$MODEL" --dangerously-skip-permissions -p "$TASK" $BUDGET_FLAG)
|
|
157
|
+
elif [[ "$RESOLVED_AGENT" == "codex" ]]; then
|
|
158
|
+
AGENT_CMD=(codex --model "$MODEL" --dangerously-bypass-approvals-and-sandbox "$TASK")
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
# ── Run ────────────────────────────────────────────────────────────────
|
|
162
|
+
ID_LABEL=""
|
|
163
|
+
[[ -n "$SHORT_ID" ]] && ID_LABEL=" [#${SHORT_ID}]"
|
|
164
|
+
|
|
165
|
+
echo "──────────────────────────────────────────"
|
|
166
|
+
echo " ⚡ clawforge quick-run${ID_LABEL}"
|
|
167
|
+
echo "──────────────────────────────────────────"
|
|
168
|
+
echo " Task: $TASK"
|
|
169
|
+
echo " Dir: $TARGET_DIR"
|
|
170
|
+
echo " Agent: $RESOLVED_AGENT ($MODEL)"
|
|
171
|
+
echo "──────────────────────────────────────────"
|
|
172
|
+
echo ""
|
|
173
|
+
|
|
174
|
+
EXIT_CODE=0
|
|
175
|
+
START_MS=$NOW
|
|
176
|
+
|
|
177
|
+
if [[ -n "$SAVE_PATH" ]]; then
|
|
178
|
+
(cd "$TARGET_DIR" && "${AGENT_CMD[@]}" 2>&1) | tee "$LOG_FILE" "$SAVE_PATH" || EXIT_CODE=$?
|
|
179
|
+
else
|
|
180
|
+
(cd "$TARGET_DIR" && "${AGENT_CMD[@]}" 2>&1) | tee "$LOG_FILE" || EXIT_CODE=$?
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
END_MS=$(epoch_ms)
|
|
184
|
+
DURATION_S=$(( (END_MS - START_MS) / 1000 ))
|
|
185
|
+
|
|
186
|
+
echo ""
|
|
187
|
+
echo "──────────────────────────────────────────"
|
|
188
|
+
if [[ $EXIT_CODE -eq 0 ]]; then
|
|
189
|
+
echo " ✅ Done in ${DURATION_S}s"
|
|
190
|
+
else
|
|
191
|
+
echo " ❌ Agent exited with code $EXIT_CODE (${DURATION_S}s)"
|
|
192
|
+
fi
|
|
193
|
+
[[ -n "$SAVE_PATH" ]] && echo " 📄 Saved to: $SAVE_PATH"
|
|
194
|
+
echo "──────────────────────────────────────────"
|
|
195
|
+
|
|
196
|
+
# ── Update registry ────────────────────────────────────────────────────
|
|
197
|
+
if ! $NO_TRACK; then
|
|
198
|
+
FINAL_STATUS="done"
|
|
199
|
+
[[ $EXIT_CODE -ne 0 ]] && FINAL_STATUS="failed"
|
|
200
|
+
registry_update "$TASK_ID" "status" "\"$FINAL_STATUS\""
|
|
201
|
+
registry_update "$TASK_ID" "finished_at" "$(epoch_ms)"
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
exit $EXIT_CODE
|
|
@@ -114,6 +114,8 @@ else
|
|
|
114
114
|
fi
|
|
115
115
|
|
|
116
116
|
TMUX_SESSION="agent-${SAFE_BRANCH}"
|
|
117
|
+
LOGFILE="${CLAWFORGE_DIR}/registry/logs/${SAFE_BRANCH}.log"
|
|
118
|
+
mkdir -p "$(dirname "$LOGFILE")"
|
|
117
119
|
MAX_RETRIES=$(config_get max_retries 3)
|
|
118
120
|
|
|
119
121
|
log_info "Spawning agent: $RESOLVED_AGENT ($MODEL)"
|
|
@@ -183,6 +185,7 @@ TASK_JSON=$(jq -n \
|
|
|
183
185
|
--arg desc "$TASK" \
|
|
184
186
|
--arg repo "$REPO_ABS" \
|
|
185
187
|
--arg wt "$WORKTREE_DIR" \
|
|
188
|
+
--arg log "$LOGFILE" \
|
|
186
189
|
--arg branch "$BRANCH" \
|
|
187
190
|
--argjson started "$NOW" \
|
|
188
191
|
--argjson maxRetries "$MAX_RETRIES" \
|
|
@@ -194,6 +197,7 @@ TASK_JSON=$(jq -n \
|
|
|
194
197
|
description: $desc,
|
|
195
198
|
repo: $repo,
|
|
196
199
|
worktree: $wt,
|
|
200
|
+
log_path: $log,
|
|
197
201
|
branch: $branch,
|
|
198
202
|
startedAt: $started,
|
|
199
203
|
status: "spawned",
|
|
@@ -223,9 +227,9 @@ tmux kill-session -t "$TMUX_SESSION" 2>/dev/null || true
|
|
|
223
227
|
# Build agent command — interactive mode so tmux attach works
|
|
224
228
|
ESCAPED_PROMPT=$(echo "$FULL_PROMPT" | sed 's/"/\\"/g')
|
|
225
229
|
if [[ "$RESOLVED_AGENT" == "claude" ]]; then
|
|
226
|
-
AGENT_CMD="claude --model ${MODEL} --dangerously-skip-permissions --verbose -p \"${ESCAPED_PROMPT}\"; echo; echo \"[ClawForge] Agent finished. Press Enter to close.\"; read"
|
|
230
|
+
AGENT_CMD="claude --model ${MODEL} --dangerously-skip-permissions --verbose -p \"${ESCAPED_PROMPT}\" 2>&1 | tee \"${LOGFILE}\"; echo; echo \"[ClawForge] Agent finished. Press Enter to close.\"; read"
|
|
227
231
|
elif [[ "$RESOLVED_AGENT" == "codex" ]]; then
|
|
228
|
-
AGENT_CMD="codex --model ${MODEL} --dangerously-bypass-approvals-and-sandbox \"${ESCAPED_PROMPT}\"; echo; echo \"[ClawForge] Agent finished. Press Enter to close.\"; read"
|
|
232
|
+
AGENT_CMD="codex --model ${MODEL} --dangerously-bypass-approvals-and-sandbox \"${ESCAPED_PROMPT}\" 2>&1 | tee \"${LOGFILE}\"; echo; echo \"[ClawForge] Agent finished. Press Enter to close.\"; read"
|
|
229
233
|
fi
|
|
230
234
|
|
|
231
235
|
# Create tmux session and launch
|
|
@@ -11,7 +11,7 @@ echo ""
|
|
|
11
11
|
|
|
12
12
|
TOTAL_PASS=0
|
|
13
13
|
TOTAL_FAIL=0
|
|
14
|
-
TESTS=(test-cli test-registry test-spawn test-watch test-review test-scope test-notify test-merge test-clean test-learn test-foundation test-modes test-management test-dashboard test-tui test-cost test-templates test-conflicts test-ci-loop test-openclaw test-multi-repo test-routing test-memory test-init test-history test-eval test-reliability test-observability test-practical test-power test-dx test-web test-deps)
|
|
14
|
+
TESTS=(test-cli test-registry test-spawn test-watch test-review test-scope test-notify test-merge test-clean test-learn test-foundation test-modes test-management test-dashboard test-tui test-cost test-templates test-conflicts test-ci-loop test-openclaw test-multi-repo test-routing test-memory test-init test-history test-eval test-reliability test-observability test-practical test-power test-dx test-web test-deps test-quick-run)
|
|
15
15
|
|
|
16
16
|
for test in "${TESTS[@]}"; do
|
|
17
17
|
echo "────────────────────────────────────────"
|
|
@@ -134,10 +134,10 @@ assert_contains "help shows Developer Experience" "Developer Experience" "$cli_h
|
|
|
134
134
|
# Test 11: version
|
|
135
135
|
echo "Test 11: version"
|
|
136
136
|
version=$(cat "${SCRIPT_DIR}/../VERSION")
|
|
137
|
-
if [[ "$version" == "1.
|
|
138
|
-
echo " ✅ version is 1.
|
|
137
|
+
if [[ "$version" == "1.6.0" ]]; then
|
|
138
|
+
echo " ✅ version is 1.6.0"; PASS=$((PASS+1))
|
|
139
139
|
else
|
|
140
|
-
echo " ❌ version is $version, expected 1.
|
|
140
|
+
echo " ❌ version is $version, expected 1.6.0"; FAIL=$((FAIL+1))
|
|
141
141
|
fi
|
|
142
142
|
|
|
143
143
|
echo ""
|
|
@@ -77,7 +77,7 @@ assert_contains "dashboard help shows p key" "preview" "$tui_help"
|
|
|
77
77
|
# Test 7: version
|
|
78
78
|
echo "Test 7: version"
|
|
79
79
|
version=$(cat "${SCRIPT_DIR}/../VERSION")
|
|
80
|
-
assert_eq "version is 1.
|
|
80
|
+
assert_eq "version is 1.6.0" "1.6.0" "$version"
|
|
81
81
|
|
|
82
82
|
echo ""
|
|
83
83
|
echo "Results: $PASS passed, $FAIL failed"
|
|
@@ -121,7 +121,7 @@ assert_contains "help shows Power Features" "Power Features" "$cli_help"
|
|
|
121
121
|
# Test 13: version
|
|
122
122
|
echo "Test 13: version"
|
|
123
123
|
version=$(cat "${SCRIPT_DIR}/../VERSION")
|
|
124
|
-
assert_eq "version is 1.
|
|
124
|
+
assert_eq "version is 1.6.0" "1.6.0" "$version"
|
|
125
125
|
|
|
126
126
|
echo ""
|
|
127
127
|
echo "Results: $PASS passed, $FAIL failed"
|
|
@@ -96,7 +96,7 @@ assert_contains "watch checks terminal states" "done|failed|timeout|cancelled" "
|
|
|
96
96
|
# Test 9: version
|
|
97
97
|
echo "Test 9: version"
|
|
98
98
|
version=$(cat "${SCRIPT_DIR}/../VERSION")
|
|
99
|
-
assert_eq "version is 1.
|
|
99
|
+
assert_eq "version is 1.6.0" "1.6.0" "$version"
|
|
100
100
|
|
|
101
101
|
echo ""
|
|
102
102
|
echo "Results: $PASS passed, $FAIL failed"
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# test-quick-run.sh — Tests for clawforge quick-run
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
6
|
+
CLI="${SCRIPT_DIR}/../bin/clawforge"
|
|
7
|
+
QR="${SCRIPT_DIR}/../bin/quick-run.sh"
|
|
8
|
+
|
|
9
|
+
PASS=0 FAIL=0
|
|
10
|
+
|
|
11
|
+
assert_ok() {
|
|
12
|
+
local desc="$1"; shift
|
|
13
|
+
if "$@" >/dev/null 2>&1; then
|
|
14
|
+
echo " ✅ $desc"; ((PASS++)) || true
|
|
15
|
+
else
|
|
16
|
+
echo " ❌ $desc"; ((FAIL++)) || true
|
|
17
|
+
fi
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
assert_fail() {
|
|
21
|
+
local desc="$1"; shift
|
|
22
|
+
if ! "$@" >/dev/null 2>&1; then
|
|
23
|
+
echo " ✅ $desc"; ((PASS++)) || true
|
|
24
|
+
else
|
|
25
|
+
echo " ❌ $desc"; ((FAIL++)) || true
|
|
26
|
+
fi
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
assert_contains() {
|
|
30
|
+
local desc="$1" needle="$2"; shift 2
|
|
31
|
+
local output
|
|
32
|
+
output=$("$@" 2>&1 || true)
|
|
33
|
+
if grep -q "$needle" <<< "$output"; then
|
|
34
|
+
echo " ✅ $desc"; ((PASS++)) || true
|
|
35
|
+
else
|
|
36
|
+
echo " ❌ $desc (expected '$needle' in output)"; ((FAIL++)) || true
|
|
37
|
+
fi
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
echo "=== test-quick-run.sh ==="
|
|
41
|
+
|
|
42
|
+
# Test 1: script exists and is executable
|
|
43
|
+
echo "Test 1: script exists"
|
|
44
|
+
assert_ok "quick-run.sh exists" test -f "$QR"
|
|
45
|
+
assert_ok "quick-run.sh is executable" test -x "$QR"
|
|
46
|
+
|
|
47
|
+
# Test 2: --help
|
|
48
|
+
echo "Test 2: --help"
|
|
49
|
+
assert_ok "help exits 0" "$QR" --help
|
|
50
|
+
assert_contains "help shows usage" "Usage:" "$QR" --help
|
|
51
|
+
assert_contains "help shows --dir" "\-\-dir" "$QR" --help
|
|
52
|
+
assert_contains "help shows --agent" "\-\-agent" "$QR" --help
|
|
53
|
+
assert_contains "help shows --model" "\-\-model" "$QR" --help
|
|
54
|
+
assert_contains "help shows --save" "\-\-save" "$QR" --help
|
|
55
|
+
assert_contains "help shows --budget" "\-\-budget" "$QR" --help
|
|
56
|
+
assert_contains "help shows --no-track" "\-\-no-track" "$QR" --help
|
|
57
|
+
assert_contains "help shows --dry-run" "\-\-dry-run" "$QR" --help
|
|
58
|
+
|
|
59
|
+
# Test 3: missing task fails
|
|
60
|
+
echo "Test 3: missing task"
|
|
61
|
+
assert_fail "no task fails" "$QR"
|
|
62
|
+
|
|
63
|
+
# Test 4: bad dir fails
|
|
64
|
+
echo "Test 4: bad dir"
|
|
65
|
+
assert_fail "nonexistent dir fails" "$QR" "task" --dir /nonexistent/path
|
|
66
|
+
|
|
67
|
+
# Test 5: dry-run
|
|
68
|
+
echo "Test 5: dry-run"
|
|
69
|
+
TMPDIR_TEST=$(mktemp -d)
|
|
70
|
+
assert_contains "dry-run shows task" "task" "$QR" "Explain the code" --dir "$TMPDIR_TEST" --dry-run
|
|
71
|
+
assert_contains "dry-run shows agent" "agent\|claude\|codex" "$QR" "Explain the code" --dir "$TMPDIR_TEST" --dry-run
|
|
72
|
+
assert_contains "dry-run shows dir" "$TMPDIR_TEST" "$QR" "Explain the code" --dir "$TMPDIR_TEST" --dry-run
|
|
73
|
+
assert_contains "dry-run shows model" "model" "$QR" "Explain the code" --dir "$TMPDIR_TEST" --dry-run
|
|
74
|
+
assert_contains "dry-run no-track shows no" "no" "$QR" "Explain the code" --dir "$TMPDIR_TEST" --dry-run --no-track
|
|
75
|
+
rm -rf "$TMPDIR_TEST"
|
|
76
|
+
|
|
77
|
+
# Test 6: CLI routes quick-run
|
|
78
|
+
echo "Test 6: CLI routing"
|
|
79
|
+
assert_contains "CLI help shows quick-run" "quick-run" "$CLI" help
|
|
80
|
+
assert_contains "CLI routes to script" "Usage:" "$CLI" quick-run --help
|
|
81
|
+
|
|
82
|
+
# Test 7: dry-run with options
|
|
83
|
+
echo "Test 7: dry-run with budget + save"
|
|
84
|
+
TMPDIR_TEST=$(mktemp -d)
|
|
85
|
+
assert_contains "dry-run shows budget" "Budget" \
|
|
86
|
+
"$QR" "Fix the bug" --dir "$TMPDIR_TEST" --dry-run --budget 1.50
|
|
87
|
+
assert_contains "dry-run shows save path" "/tmp" \
|
|
88
|
+
"$QR" "Fix the bug" --dir "$TMPDIR_TEST" --dry-run --save /tmp/out.log
|
|
89
|
+
rm -rf "$TMPDIR_TEST"
|
|
90
|
+
|
|
91
|
+
# Test 8: registry + log setup (with --no-track, no agent needed)
|
|
92
|
+
echo "Test 8: source inspection"
|
|
93
|
+
assert_contains "has epoch_ms" "epoch_ms" cat "$QR"
|
|
94
|
+
assert_contains "has registry_add" "registry_add" cat "$QR"
|
|
95
|
+
assert_contains "has log_path" "log_path" cat "$QR"
|
|
96
|
+
assert_contains "has tee" "tee" cat "$QR"
|
|
97
|
+
assert_contains "has quick-run mode" "quick-run" cat "$QR"
|
|
98
|
+
assert_contains "has detect_agent" "detect_agent" cat "$QR"
|
|
99
|
+
assert_contains "has no-track flag" "NO_TRACK" cat "$QR"
|
|
100
|
+
assert_contains "has budget flag" "BUDGET" cat "$QR"
|
|
101
|
+
assert_contains "has save flag" "SAVE_PATH" cat "$QR"
|
|
102
|
+
|
|
103
|
+
echo ""
|
|
104
|
+
echo "Results: $PASS passed, $FAIL failed"
|
|
105
|
+
[[ $FAIL -eq 0 ]] && exit 0 || exit 1
|
|
@@ -96,7 +96,7 @@ assert_contains "help shows Reliability" "Reliability" "$cli_help"
|
|
|
96
96
|
# Test 11: version bump
|
|
97
97
|
echo "Test 11: version"
|
|
98
98
|
version=$(cat "${SCRIPT_DIR}/../VERSION")
|
|
99
|
-
assert_eq "version is 1.
|
|
99
|
+
assert_eq "version is 1.6.0" "1.6.0" "$version"
|
|
100
100
|
|
|
101
101
|
# Test 12: doctor --fix runs without errors
|
|
102
102
|
echo "Test 12: doctor --fix"
|
|
@@ -107,7 +107,7 @@ assert_contains "help shows Web Dashboard" "Web Dashboard" "$cli_help"
|
|
|
107
107
|
# Test 7: version
|
|
108
108
|
echo "Test 7: version"
|
|
109
109
|
version=$(cat "${SCRIPT_DIR}/../VERSION")
|
|
110
|
-
assert_eq "version is 1.
|
|
110
|
+
assert_eq "version is 1.6.0" "1.6.0" "$version"
|
|
111
111
|
|
|
112
112
|
echo ""
|
|
113
113
|
echo "Results: $PASS passed, $FAIL failed"
|
|
@@ -25,6 +25,7 @@ type Agent struct {
|
|
|
25
25
|
Conflicts int
|
|
26
26
|
Description string
|
|
27
27
|
Worktree string
|
|
28
|
+
LogPath string
|
|
28
29
|
TmuxSession string
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -42,6 +43,7 @@ type registryTask struct {
|
|
|
42
43
|
Model string `json:"model"`
|
|
43
44
|
Repo string `json:"repo"`
|
|
44
45
|
CIStatus string `json:"ci_status"`
|
|
46
|
+
LogPath string `json:"log_path"`
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
type registryFile struct {
|
|
@@ -122,6 +124,7 @@ func LoadAgents() []Agent {
|
|
|
122
124
|
Description: t.Description,
|
|
123
125
|
Task: t.Description,
|
|
124
126
|
Worktree: t.Worktree,
|
|
127
|
+
LogPath: t.LogPath,
|
|
125
128
|
TmuxSession: t.TmuxSession,
|
|
126
129
|
CI: ciIndicator(t.CIStatus),
|
|
127
130
|
Cost: costs[t.ID],
|
|
@@ -114,11 +114,15 @@ func renderDashboard(m Model) string {
|
|
|
114
114
|
fmt.Sprintf("── Preview: %s ──", selAgent.ID))
|
|
115
115
|
b.WriteString(previewHeader)
|
|
116
116
|
b.WriteString("\n")
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
// Static content (from l/d keys) takes priority over live tmux preview.
|
|
118
|
+
content := m.previewContent
|
|
119
|
+
if content == "" {
|
|
120
|
+
content = selAgent.Preview
|
|
121
121
|
}
|
|
122
|
+
if content == "" {
|
|
123
|
+
content = "(no output / not running)"
|
|
124
|
+
}
|
|
125
|
+
b.WriteString(lipgloss.NewStyle().Faint(true).Render(content))
|
|
122
126
|
b.WriteString("\n")
|
|
123
127
|
}
|
|
124
128
|
}
|