agent-control-plane 0.3.0 → 0.6.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/README.md +141 -28
- package/assets/workflow-catalog.json +1 -1
- package/bin/pr-risk.sh +22 -7
- package/bin/sync-pr-labels.sh +1 -1
- package/hooks/heartbeat-hooks.sh +125 -12
- package/hooks/issue-reconcile-hooks.sh +1 -1
- package/hooks/pr-reconcile-hooks.sh +1 -1
- package/npm/bin/agent-control-plane.js +257 -59
- package/package.json +39 -32
- package/tools/bin/debug-session.sh +106 -0
- package/tools/bin/flow-config-lib.sh +1203 -60
- package/tools/bin/flow-runtime-doctor-linux.sh +136 -0
- package/tools/bin/flow-runtime-doctor.sh +5 -1
- package/tools/bin/flow-shell-lib.sh +32 -0
- package/tools/bin/github-core-rate-limit-state.sh +77 -0
- package/tools/bin/github-write-outbox.sh +470 -0
- package/tools/bin/heartbeat-loop-scheduling-lib.sh +7 -7
- package/tools/bin/heartbeat-safe-auto.sh +42 -0
- package/tools/bin/install-project-launchd.sh +17 -2
- package/tools/bin/install-project-systemd.sh +255 -0
- package/tools/bin/project-init.sh +21 -1
- package/tools/bin/project-launchd-bootstrap.sh +5 -1
- package/tools/bin/project-runtimectl.sh +91 -2
- package/tools/bin/project-systemd-bootstrap.sh +74 -0
- package/tools/bin/scaffold-profile.sh +61 -3
- package/tools/bin/uninstall-project-systemd.sh +87 -0
- package/tools/dashboard/app.js +228 -6
- package/tools/dashboard/dashboard_snapshot.py +55 -0
- package/tools/dashboard/issue_queue_state.py +101 -0
- package/tools/dashboard/server.py +123 -1
- package/tools/dashboard/styles.css +526 -455
- package/tools/templates/pr-fix-template.md +3 -1
- package/tools/templates/pr-merge-repair-template.md +2 -1
- package/references/architecture.md +0 -217
- package/references/commands.md +0 -128
- package/references/control-plane-map.md +0 -124
- package/references/docs-map.md +0 -73
- package/references/release-checklist.md +0 -65
- package/references/repo-map.md +0 -36
- package/tools/bin/agent-cleanup-worktree +0 -247
- package/tools/bin/agent-github-update-labels +0 -71
- package/tools/bin/agent-init-worktree +0 -216
- package/tools/bin/agent-project-archive-run +0 -52
- package/tools/bin/agent-project-capture-worker +0 -46
- package/tools/bin/agent-project-catch-up-issue-pr-links +0 -118
- package/tools/bin/agent-project-catch-up-merged-prs +0 -194
- package/tools/bin/agent-project-catch-up-scheduled-issue-retries +0 -123
- package/tools/bin/agent-project-cleanup-session +0 -513
- package/tools/bin/agent-project-detached-launch +0 -127
- package/tools/bin/agent-project-heartbeat-loop +0 -1029
- package/tools/bin/agent-project-open-issue-worktree +0 -89
- package/tools/bin/agent-project-open-pr-worktree +0 -80
- package/tools/bin/agent-project-publish-issue-pr +0 -465
- package/tools/bin/agent-project-reconcile-issue-session +0 -1398
- package/tools/bin/agent-project-reconcile-pr-session +0 -1230
- package/tools/bin/agent-project-retry-state +0 -147
- package/tools/bin/agent-project-run-claude-session +0 -805
- package/tools/bin/agent-project-run-codex-resilient +0 -955
- package/tools/bin/agent-project-run-codex-session +0 -435
- package/tools/bin/agent-project-run-kilo-session +0 -369
- package/tools/bin/agent-project-run-ollama-session +0 -658
- package/tools/bin/agent-project-run-openclaw-session +0 -1309
- package/tools/bin/agent-project-run-opencode-session +0 -377
- package/tools/bin/agent-project-run-pi-session +0 -479
- package/tools/bin/agent-project-sync-anchor-repo +0 -139
- package/tools/bin/agent-project-worker-status +0 -188
- package/tools/bin/branch-verification-guard.sh +0 -364
- package/tools/bin/capture-worker.sh +0 -18
- package/tools/bin/cleanup-worktree.sh +0 -52
- package/tools/bin/codex-quota +0 -31
- package/tools/bin/create-follow-up-issue.sh +0 -114
- package/tools/bin/dashboard-launchd-bootstrap.sh +0 -50
- package/tools/bin/issue-publish-localization-guard.sh +0 -142
- package/tools/bin/issue-publish-scope-guard.sh +0 -242
- package/tools/bin/issue-requires-local-workspace-install.sh +0 -31
- package/tools/bin/issue-resource-class.sh +0 -12
- package/tools/bin/kick-scheduler.sh +0 -75
- package/tools/bin/label-follow-up-issues.sh +0 -14
- package/tools/bin/new-pr-worktree.sh +0 -50
- package/tools/bin/new-worktree.sh +0 -49
- package/tools/bin/pr-risk.sh +0 -12
- package/tools/bin/prepare-worktree.sh +0 -142
- package/tools/bin/provider-cooldown-state.sh +0 -204
- package/tools/bin/publish-issue-worker.sh +0 -31
- package/tools/bin/reconcile-bootstrap-lib.sh +0 -113
- package/tools/bin/reconcile-issue-worker.sh +0 -34
- package/tools/bin/reconcile-pr-worker.sh +0 -34
- package/tools/bin/record-verification.sh +0 -71
- package/tools/bin/render-flow-config.sh +0 -98
- package/tools/bin/resident-issue-controller-lib.sh +0 -448
- package/tools/bin/resident-issue-queue-status.py +0 -35
- package/tools/bin/retry-state.sh +0 -31
- package/tools/bin/reuse-issue-worktree.sh +0 -121
- package/tools/bin/run-codex-bypass.sh +0 -3
- package/tools/bin/run-codex-safe.sh +0 -3
- package/tools/bin/run-codex-task.sh +0 -280
- package/tools/bin/serve-dashboard.sh +0 -5
- package/tools/bin/split-retained-slice.sh +0 -124
- package/tools/bin/start-issue-worker.sh +0 -943
- package/tools/bin/start-pr-fix-worker.sh +0 -491
- package/tools/bin/start-pr-merge-repair-worker.sh +0 -8
- package/tools/bin/start-pr-review-worker.sh +0 -261
- package/tools/bin/start-resident-issue-loop.sh +0 -499
- package/tools/bin/update-github-labels.sh +0 -14
- package/tools/bin/worker-status.sh +0 -19
- package/tools/bin/workflow-catalog.sh +0 -77
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# flow-runtime-doctor-linux.sh - Linux-specific runtime validation for ACP
|
|
3
|
+
# Checks systemd services, Linux paths, and runtime health
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
# shellcheck source=/dev/null
|
|
8
|
+
source "${SCRIPT_DIR}/flow-config-lib.sh"
|
|
9
|
+
|
|
10
|
+
FLOW_SKILL_DIR="$(resolve_flow_skill_dir "${BASH_SOURCE[0]}")"
|
|
11
|
+
CONTROL_PLANE_NAME="$(flow_canonical_skill_name)"
|
|
12
|
+
RUNTIME_HOME="$(resolve_runtime_home)"
|
|
13
|
+
|
|
14
|
+
echo "=== ACP Linux Runtime Doctor ==="
|
|
15
|
+
echo ""
|
|
16
|
+
|
|
17
|
+
# --- Systemd Checks ---
|
|
18
|
+
echo "--- Systemd Service Status ---"
|
|
19
|
+
if command -v systemctl &>/dev/null; then
|
|
20
|
+
echo "systemctl: available"
|
|
21
|
+
|
|
22
|
+
# Check user services (systemd --user)
|
|
23
|
+
if systemctl --user is-active --quiet "${CONTROL_PLANE_NAME}.service" 2>/dev/null; then
|
|
24
|
+
echo "service ${CONTROL_PLANE_NAME}: active (user)"
|
|
25
|
+
elif systemctl --user is-enabled --quiet "${CONTROL_PLANE_NAME}.service" 2>/dev/null; then
|
|
26
|
+
echo "service ${CONTROL_PLANE_NAME}: installed but not running (user)"
|
|
27
|
+
else
|
|
28
|
+
echo "service ${CONTROL_PLANE_NAME}: not installed (user)"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Check system services (if installed system-wide)
|
|
32
|
+
if systemctl is-active --quiet "${CONTROL_PLANE_NAME}.service" 2>/dev/null; then
|
|
33
|
+
echo "service ${CONTROL_PLANE_NAME}: active (system)"
|
|
34
|
+
fi
|
|
35
|
+
else
|
|
36
|
+
echo "systemctl: NOT available (not a systemd-based system?)"
|
|
37
|
+
fi
|
|
38
|
+
echo ""
|
|
39
|
+
|
|
40
|
+
# --- Linux Path Checks ---
|
|
41
|
+
echo "--- Linux Path Validation ---"
|
|
42
|
+
echo "RUNTIME_HOME=${RUNTIME_HOME}"
|
|
43
|
+
echo "FLOW_SKILL_DIR=${FLOW_SKILL_DIR}"
|
|
44
|
+
|
|
45
|
+
# Check XDG paths (Linux standard)
|
|
46
|
+
XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
|
|
47
|
+
XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
|
|
48
|
+
|
|
49
|
+
echo "XDG_CONFIG_HOME=${XDG_CONFIG_HOME}"
|
|
50
|
+
echo "XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}"
|
|
51
|
+
|
|
52
|
+
if [[ -d "${XDG_RUNTIME_DIR}" ]]; then
|
|
53
|
+
echo "XDG_RUNTIME_DIR: exists"
|
|
54
|
+
else
|
|
55
|
+
echo "XDG_RUNTIME_DIR: NOT FOUND (may cause issues with user services)"
|
|
56
|
+
fi
|
|
57
|
+
echo ""
|
|
58
|
+
|
|
59
|
+
# --- Process Checks ---
|
|
60
|
+
echo "--- Process Checks ---"
|
|
61
|
+
if command -v pgrep &>/dev/null; then
|
|
62
|
+
AGENT_PIDS=$(pgrep -f "agent-control-plane" 2>/dev/null || true)
|
|
63
|
+
if [[ -n "${AGENT_PIDS}" ]]; then
|
|
64
|
+
echo "agent-control-plane processes running: yes (PIDs: ${AGENT_PIDS})"
|
|
65
|
+
ps -p "${AGENT_PIDS}" -o pid,ppid,cmd 2>/dev/null || true
|
|
66
|
+
else
|
|
67
|
+
echo "agent-control-plane processes running: no"
|
|
68
|
+
fi
|
|
69
|
+
else
|
|
70
|
+
echo "pgrep: NOT available"
|
|
71
|
+
fi
|
|
72
|
+
echo ""
|
|
73
|
+
|
|
74
|
+
# --- tmux Checks ---
|
|
75
|
+
echo "--- tmux Session Checks ---"
|
|
76
|
+
if command -v tmux &>/dev/null; then
|
|
77
|
+
echo "tmux: available ($(tmux -V))"
|
|
78
|
+
TMUX_SESSIONS=$(tmux ls 2>/dev/null | grep -c "agent-" || true)
|
|
79
|
+
echo "agent- tmux sessions: ${TMUX_SESSIONS}"
|
|
80
|
+
if [[ ${TMUX_SESSIONS} -gt 0 ]]; then
|
|
81
|
+
tmux ls 2>/dev/null | grep "agent-" || true
|
|
82
|
+
fi
|
|
83
|
+
else
|
|
84
|
+
echo "tmux: NOT installed (required for ACP worker sessions)"
|
|
85
|
+
fi
|
|
86
|
+
echo ""
|
|
87
|
+
|
|
88
|
+
# --- Socket/Port Checks ---
|
|
89
|
+
echo "--- Socket/Port Checks ---"
|
|
90
|
+
if command -v ss &>/dev/null; then
|
|
91
|
+
echo "Checking for dashboard port (3180)..."
|
|
92
|
+
ss -tlnp 2>/dev/null | grep ":3180 " || echo "Port 3180: not in use"
|
|
93
|
+
elif command -v netstat &>/dev/null; then
|
|
94
|
+
netstat -tlnp 2>/dev/null | grep ":3180 " || echo "Port 3180: not in use"
|
|
95
|
+
else
|
|
96
|
+
echo "ss/netstat: NOT available, skipping port check"
|
|
97
|
+
fi
|
|
98
|
+
echo ""
|
|
99
|
+
|
|
100
|
+
# --- Log File Checks ---
|
|
101
|
+
echo "--- Log File Checks ---"
|
|
102
|
+
LOG_DIR="${RUNTIME_HOME}/logs"
|
|
103
|
+
if [[ -d "${LOG_DIR}" ]]; then
|
|
104
|
+
echo "LOG_DIR=${LOG_DIR}: exists"
|
|
105
|
+
LOG_COUNT=$(find "${LOG_DIR}" -name "*.log" 2>/dev/null | wc -l)
|
|
106
|
+
echo "Log files: ${LOG_COUNT}"
|
|
107
|
+
else
|
|
108
|
+
echo "LOG_DIR=${LOG_DIR}: NOT FOUND"
|
|
109
|
+
fi
|
|
110
|
+
echo ""
|
|
111
|
+
|
|
112
|
+
# --- Run Generic Doctor ---
|
|
113
|
+
echo "=== Generic Runtime Doctor ==="
|
|
114
|
+
if [[ -f "${SCRIPT_DIR}/flow-runtime-doctor.sh" ]]; then
|
|
115
|
+
bash "${SCRIPT_DIR}/flow-runtime-doctor.sh"
|
|
116
|
+
else
|
|
117
|
+
echo "flow-runtime-doctor.sh: NOT FOUND"
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
echo ""
|
|
121
|
+
echo "=== Linux Doctor Complete ==="
|
|
122
|
+
echo ""
|
|
123
|
+
echo "=== NEXT STEPS ==="
|
|
124
|
+
if ! command -v systemctl &>/dev/null; then
|
|
125
|
+
echo "NOT on systemd: Use macOS launchd or manual tmux for runtime."
|
|
126
|
+
elif ! systemctl --user is-active --quiet "${CONTROL_PLANE_NAME}.service" 2>/dev/null; then
|
|
127
|
+
echo "Service not running. Start with:"
|
|
128
|
+
echo " systemctl --user start ${CONTROL_PLANE_NAME}.service"
|
|
129
|
+
echo " systemctl --user enable ${CONTROL_PLANE_NAME}.service # autostart"
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
if ! command -v tmux &>/dev/null; then
|
|
133
|
+
echo "MISSING: tmux is required. Install:"
|
|
134
|
+
echo " Ubuntu/Debian: sudo apt install tmux"
|
|
135
|
+
echo " Alpine: apk add tmux"
|
|
136
|
+
fi
|
|
@@ -93,5 +93,9 @@ if [[ -n "${PROFILE_SELECTION_HINT}" ]]; then
|
|
|
93
93
|
fi
|
|
94
94
|
|
|
95
95
|
if [[ "${status}" != "ok" ]]; then
|
|
96
|
-
printf '
|
|
96
|
+
printf '\n=== ACTION REQUIRED ===\n'
|
|
97
|
+
printf 'Status: %s\n' "${status}"
|
|
98
|
+
printf 'Next step: Run sync to fix issues:\n'
|
|
99
|
+
printf ' bash %q %q %q\n' "${SYNC_SCRIPT}" "${SHARED_AGENT_HOME}" "${RUNTIME_HOME}"
|
|
100
|
+
printf '\nOr run: bash %s/tools/bin/setup.sh --resume\n' "${FLOW_SKILL_DIR}"
|
|
97
101
|
fi
|
|
@@ -29,6 +29,38 @@ flow_resolve_python_bin() {
|
|
|
29
29
|
return 1
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
flow_format_epoch_utc() {
|
|
33
|
+
local epoch="${1:-}"
|
|
34
|
+
local python_bin=""
|
|
35
|
+
|
|
36
|
+
if ! [[ "${epoch}" =~ ^[0-9]+$ ]] || [[ "${epoch}" == "0" ]]; then
|
|
37
|
+
return 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
if date -u -r "${epoch}" +"%Y-%m-%dT%H:%M:%SZ" >/dev/null 2>&1; then
|
|
41
|
+
date -u -r "${epoch}" +"%Y-%m-%dT%H:%M:%SZ"
|
|
42
|
+
return 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if date -u -d "@${epoch}" +"%Y-%m-%dT%H:%M:%SZ" >/dev/null 2>&1; then
|
|
46
|
+
date -u -d "@${epoch}" +"%Y-%m-%dT%H:%M:%SZ"
|
|
47
|
+
return 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
python_bin="$(flow_resolve_python_bin 2>/dev/null || true)"
|
|
51
|
+
if [[ -n "${python_bin}" ]]; then
|
|
52
|
+
"${python_bin}" - "${epoch}" <<'PY'
|
|
53
|
+
import datetime
|
|
54
|
+
import sys
|
|
55
|
+
|
|
56
|
+
print(datetime.datetime.fromtimestamp(int(sys.argv[1]), datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"))
|
|
57
|
+
PY
|
|
58
|
+
return 0
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
return 1
|
|
62
|
+
}
|
|
63
|
+
|
|
32
64
|
flow_compat_skill_alias() {
|
|
33
65
|
printf '%s\n' "${AGENT_CONTROL_PLANE_COMPAT_ALIAS:-}"
|
|
34
66
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
# shellcheck source=/dev/null
|
|
6
|
+
source "${SCRIPT_DIR}/flow-config-lib.sh"
|
|
7
|
+
|
|
8
|
+
usage() {
|
|
9
|
+
cat <<'EOF'
|
|
10
|
+
Usage:
|
|
11
|
+
github-core-rate-limit-state.sh get
|
|
12
|
+
github-core-rate-limit-state.sh schedule [reason] [--next-at-epoch <unix-seconds>]
|
|
13
|
+
github-core-rate-limit-state.sh clear
|
|
14
|
+
EOF
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
action="${1:-}"
|
|
18
|
+
reason="${2:-github-api-rate-limit}"
|
|
19
|
+
next_at_epoch=""
|
|
20
|
+
|
|
21
|
+
if [[ $# -lt 1 ]]; then
|
|
22
|
+
usage >&2
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
shift || true
|
|
27
|
+
if [[ $# -gt 0 ]]; then
|
|
28
|
+
reason="${1:-github-api-rate-limit}"
|
|
29
|
+
shift || true
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
while [[ $# -gt 0 ]]; do
|
|
33
|
+
case "$1" in
|
|
34
|
+
--next-at-epoch)
|
|
35
|
+
next_at_epoch="${2:-}"
|
|
36
|
+
shift 2
|
|
37
|
+
;;
|
|
38
|
+
--help|-h)
|
|
39
|
+
usage
|
|
40
|
+
exit 0
|
|
41
|
+
;;
|
|
42
|
+
*)
|
|
43
|
+
echo "unknown argument: $1" >&2
|
|
44
|
+
usage >&2
|
|
45
|
+
exit 1
|
|
46
|
+
;;
|
|
47
|
+
esac
|
|
48
|
+
done
|
|
49
|
+
|
|
50
|
+
case "${action}" in
|
|
51
|
+
get|schedule|clear) ;;
|
|
52
|
+
*)
|
|
53
|
+
usage >&2
|
|
54
|
+
exit 1
|
|
55
|
+
;;
|
|
56
|
+
esac
|
|
57
|
+
|
|
58
|
+
CONFIG_YAML="$(resolve_flow_config_yaml "${BASH_SOURCE[0]}")"
|
|
59
|
+
STATE_ROOT="$(flow_resolve_state_root "${CONFIG_YAML}")"
|
|
60
|
+
COOLDOWNS="$(flow_resolve_retry_cooldowns "${CONFIG_YAML}")"
|
|
61
|
+
|
|
62
|
+
exec_args=(
|
|
63
|
+
--state-root "${STATE_ROOT}"
|
|
64
|
+
--kind github
|
|
65
|
+
--item-id core-api
|
|
66
|
+
--action "${action}"
|
|
67
|
+
--reason "${reason}"
|
|
68
|
+
--cooldowns "${COOLDOWNS}"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if [[ "${action}" == "schedule" && "${next_at_epoch}" =~ ^[0-9]+$ ]]; then
|
|
72
|
+
exec_args+=(--next-at-epoch "${next_at_epoch}")
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
ACP_STATE_ROOT="${STATE_ROOT}" \
|
|
76
|
+
ACP_RETRY_COOLDOWNS="${COOLDOWNS}" \
|
|
77
|
+
exec bash "${SCRIPT_DIR}/agent-project-retry-state" "${exec_args[@]}"
|