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.
- package/README.md +109 -13
- package/npm/bin/agent-control-plane.js +1 -1
- package/package.json +39 -33
- package/tools/bin/debug-session.sh +106 -0
- package/tools/bin/flow-config-lib.sh +13 -3508
- package/tools/bin/flow-execution-lib.sh +243 -0
- package/tools/bin/flow-forge-lib.sh +1770 -0
- package/tools/bin/flow-profile-lib.sh +335 -0
- package/tools/bin/flow-provider-lib.sh +981 -0
- package/tools/bin/flow-runtime-doctor-linux.sh +136 -0
- package/tools/bin/flow-runtime-doctor.sh +5 -1
- package/tools/bin/flow-session-lib.sh +317 -0
- package/tools/bin/install-project-systemd.sh +255 -0
- package/tools/bin/project-runtimectl.sh +45 -0
- package/tools/bin/project-systemd-bootstrap.sh +74 -0
- package/tools/bin/uninstall-project-systemd.sh +87 -0
- package/tools/dashboard/app.js +238 -8
- package/tools/dashboard/issue_queue_state.py +101 -0
- package/tools/dashboard/requirements.txt +3 -0
- package/tools/dashboard/server.py +250 -30
- package/tools/dashboard/styles.css +526 -455
- package/tools/bin/agent-cleanup-worktree +0 -247
- package/tools/bin/agent-github-update-labels +0 -105
- 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 -195
- 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 -468
- package/tools/bin/agent-project-reconcile-issue-session +0 -1409
- package/tools/bin/agent-project-reconcile-pr-session +0 -1288
- package/tools/bin/agent-project-retry-state +0 -158
- package/tools/bin/agent-project-run-claude-session +0 -805
- package/tools/bin/agent-project-run-codex-resilient +0 -963
- 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-sync-source-repo-main +0 -163
- 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/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/start-issue-worker.sh +0 -943
- package/tools/bin/start-pr-fix-worker.sh +0 -528
- 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
|
@@ -1,163 +0,0 @@
|
|
|
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
|
-
CONFIG_YAML="${ACP_SOURCE_REPO_SYNC_CONFIG_YAML:-$(resolve_flow_config_yaml "${BASH_SOURCE[0]}")}"
|
|
9
|
-
REPO_SLUG="$(flow_resolve_repo_slug "${CONFIG_YAML}")"
|
|
10
|
-
SOURCE_REPO_ROOT="$(flow_resolve_source_repo_root "${CONFIG_YAML}")"
|
|
11
|
-
DEFAULT_BRANCH="$(flow_resolve_default_branch "${CONFIG_YAML}")"
|
|
12
|
-
STATE_ROOT="$(flow_resolve_state_root "${CONFIG_YAML}")"
|
|
13
|
-
SYNC_STATE_FILE="${STATE_ROOT}/source-repo-main-sync.env"
|
|
14
|
-
FORGE_PROVIDER="$(flow_forge_provider)"
|
|
15
|
-
REMOTE_OVERRIDE="${ACP_SOURCE_SYNC_REMOTE:-${F_LOSNING_SOURCE_SYNC_REMOTE:-}}"
|
|
16
|
-
|
|
17
|
-
write_state() {
|
|
18
|
-
local status="${1:-}"
|
|
19
|
-
local remote_name="${2:-}"
|
|
20
|
-
local remote_sha="${3:-}"
|
|
21
|
-
local local_sha="${4:-}"
|
|
22
|
-
local detail="${5:-}"
|
|
23
|
-
|
|
24
|
-
mkdir -p "$(dirname "${SYNC_STATE_FILE}")"
|
|
25
|
-
{
|
|
26
|
-
printf 'STATUS=%s\n' "${status}"
|
|
27
|
-
printf 'UPDATED_AT=%s\n' "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
28
|
-
printf 'SOURCE_REPO_ROOT=%s\n' "${SOURCE_REPO_ROOT}"
|
|
29
|
-
printf 'DEFAULT_BRANCH=%s\n' "${DEFAULT_BRANCH}"
|
|
30
|
-
printf 'REMOTE_NAME=%s\n' "${remote_name}"
|
|
31
|
-
printf 'REMOTE_SHA=%s\n' "${remote_sha}"
|
|
32
|
-
printf 'LOCAL_SHA=%s\n' "${local_sha}"
|
|
33
|
-
printf 'DETAIL=%s\n' "${detail}"
|
|
34
|
-
} >"${SYNC_STATE_FILE}"
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
git_ref_sha() {
|
|
38
|
-
local repo_root="${1:?repo root required}"
|
|
39
|
-
local ref_name="${2:?ref required}"
|
|
40
|
-
git -C "${repo_root}" rev-parse --verify --quiet "${ref_name}" 2>/dev/null || true
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
git_has_remote() {
|
|
44
|
-
local repo_root="${1:?repo root required}"
|
|
45
|
-
local remote_name="${2:?remote required}"
|
|
46
|
-
git -C "${repo_root}" remote get-url "${remote_name}" >/dev/null 2>&1
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
discover_remote_name() {
|
|
50
|
-
local remote_name=""
|
|
51
|
-
|
|
52
|
-
if [[ -n "${REMOTE_OVERRIDE}" ]] && git_has_remote "${SOURCE_REPO_ROOT}" "${REMOTE_OVERRIDE}"; then
|
|
53
|
-
printf '%s\n' "${REMOTE_OVERRIDE}"
|
|
54
|
-
return 0
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
case "${FORGE_PROVIDER}" in
|
|
58
|
-
gitea)
|
|
59
|
-
if git_has_remote "${SOURCE_REPO_ROOT}" "gitea"; then
|
|
60
|
-
printf 'gitea\n'
|
|
61
|
-
return 0
|
|
62
|
-
fi
|
|
63
|
-
;;
|
|
64
|
-
github)
|
|
65
|
-
if git_has_remote "${SOURCE_REPO_ROOT}" "origin"; then
|
|
66
|
-
printf 'origin\n'
|
|
67
|
-
return 0
|
|
68
|
-
fi
|
|
69
|
-
;;
|
|
70
|
-
esac
|
|
71
|
-
|
|
72
|
-
while IFS= read -r remote_name; do
|
|
73
|
-
[[ -n "${remote_name}" ]] || continue
|
|
74
|
-
if [[ "$(flow_git_remote_repo_slug "${SOURCE_REPO_ROOT}" "${remote_name}" 2>/dev/null || true)" == "${REPO_SLUG}" ]]; then
|
|
75
|
-
printf '%s\n' "${remote_name}"
|
|
76
|
-
return 0
|
|
77
|
-
fi
|
|
78
|
-
done < <(git -C "${SOURCE_REPO_ROOT}" remote)
|
|
79
|
-
|
|
80
|
-
return 1
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if [[ -z "${SOURCE_REPO_ROOT}" ]]; then
|
|
84
|
-
write_state "skipped" "" "" "" "source-repo-root-unset"
|
|
85
|
-
printf 'SOURCE_REPO_SYNC_STATUS=skipped\nSOURCE_REPO_SYNC_REASON=source-repo-root-unset\n'
|
|
86
|
-
exit 0
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
|
-
if [[ ! -d "${SOURCE_REPO_ROOT}/.git" && ! -f "${SOURCE_REPO_ROOT}/.git" ]]; then
|
|
90
|
-
write_state "skipped" "" "" "" "source-repo-not-git"
|
|
91
|
-
printf 'SOURCE_REPO_SYNC_STATUS=skipped\nSOURCE_REPO_SYNC_REASON=source-repo-not-git\nSOURCE_REPO_ROOT=%s\n' "${SOURCE_REPO_ROOT}"
|
|
92
|
-
exit 0
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
REMOTE_NAME="$(discover_remote_name || true)"
|
|
96
|
-
if [[ -z "${REMOTE_NAME}" ]]; then
|
|
97
|
-
write_state "skipped" "" "" "" "remote-not-found"
|
|
98
|
-
printf 'SOURCE_REPO_SYNC_STATUS=skipped\nSOURCE_REPO_SYNC_REASON=remote-not-found\nSOURCE_REPO_ROOT=%s\n' "${SOURCE_REPO_ROOT}"
|
|
99
|
-
exit 0
|
|
100
|
-
fi
|
|
101
|
-
|
|
102
|
-
if ! git -C "${SOURCE_REPO_ROOT}" fetch "${REMOTE_NAME}" "+refs/heads/${DEFAULT_BRANCH}:refs/remotes/${REMOTE_NAME}/${DEFAULT_BRANCH}" --prune >/dev/null 2>&1; then
|
|
103
|
-
write_state "failed" "${REMOTE_NAME}" "" "" "fetch-failed"
|
|
104
|
-
printf 'SOURCE_REPO_SYNC_STATUS=failed\nSOURCE_REPO_SYNC_REASON=fetch-failed\nSOURCE_REPO_ROOT=%s\nREMOTE_NAME=%s\n' "${SOURCE_REPO_ROOT}" "${REMOTE_NAME}"
|
|
105
|
-
exit 1
|
|
106
|
-
fi
|
|
107
|
-
|
|
108
|
-
remote_sha="$(git_ref_sha "${SOURCE_REPO_ROOT}" "refs/remotes/${REMOTE_NAME}/${DEFAULT_BRANCH}")"
|
|
109
|
-
local_branch_sha="$(git_ref_sha "${SOURCE_REPO_ROOT}" "refs/heads/${DEFAULT_BRANCH}")"
|
|
110
|
-
current_branch="$(git -C "${SOURCE_REPO_ROOT}" symbolic-ref --quiet --short HEAD 2>/dev/null || true)"
|
|
111
|
-
|
|
112
|
-
if [[ -z "${remote_sha}" || -z "${local_branch_sha}" ]]; then
|
|
113
|
-
write_state "failed" "${REMOTE_NAME}" "${remote_sha}" "${local_branch_sha}" "missing-branch-ref"
|
|
114
|
-
printf 'SOURCE_REPO_SYNC_STATUS=failed\nSOURCE_REPO_SYNC_REASON=missing-branch-ref\nSOURCE_REPO_ROOT=%s\nREMOTE_NAME=%s\n' "${SOURCE_REPO_ROOT}" "${REMOTE_NAME}"
|
|
115
|
-
exit 1
|
|
116
|
-
fi
|
|
117
|
-
|
|
118
|
-
if [[ "${remote_sha}" == "${local_branch_sha}" ]]; then
|
|
119
|
-
write_state "unchanged" "${REMOTE_NAME}" "${remote_sha}" "${local_branch_sha}" "already-current"
|
|
120
|
-
printf 'SOURCE_REPO_SYNC_STATUS=unchanged\nSOURCE_REPO_ROOT=%s\nREMOTE_NAME=%s\nSOURCE_REPO_SYNC_SHA=%s\n' "${SOURCE_REPO_ROOT}" "${REMOTE_NAME}" "${remote_sha}"
|
|
121
|
-
exit 0
|
|
122
|
-
fi
|
|
123
|
-
|
|
124
|
-
if [[ "${current_branch}" == "${DEFAULT_BRANCH}" ]]; then
|
|
125
|
-
if [[ -n "$(git -C "${SOURCE_REPO_ROOT}" status --porcelain 2>/dev/null || true)" ]]; then
|
|
126
|
-
write_state "blocked" "${REMOTE_NAME}" "${remote_sha}" "${local_branch_sha}" "working-tree-dirty"
|
|
127
|
-
printf 'SOURCE_REPO_SYNC_STATUS=blocked\nSOURCE_REPO_SYNC_REASON=working-tree-dirty\nSOURCE_REPO_ROOT=%s\nREMOTE_NAME=%s\nLOCAL_SHA=%s\nREMOTE_SHA=%s\n' \
|
|
128
|
-
"${SOURCE_REPO_ROOT}" "${REMOTE_NAME}" "${local_branch_sha}" "${remote_sha}"
|
|
129
|
-
exit 0
|
|
130
|
-
fi
|
|
131
|
-
|
|
132
|
-
if git -C "${SOURCE_REPO_ROOT}" merge-base --is-ancestor "${local_branch_sha}" "${remote_sha}" >/dev/null 2>&1; then
|
|
133
|
-
git -C "${SOURCE_REPO_ROOT}" merge --ff-only "refs/remotes/${REMOTE_NAME}/${DEFAULT_BRANCH}" >/dev/null
|
|
134
|
-
updated_sha="$(git_ref_sha "${SOURCE_REPO_ROOT}" "refs/heads/${DEFAULT_BRANCH}")"
|
|
135
|
-
write_state "updated" "${REMOTE_NAME}" "${remote_sha}" "${updated_sha}" "fast-forward-checked-out-branch"
|
|
136
|
-
printf 'SOURCE_REPO_SYNC_STATUS=updated\nSOURCE_REPO_ROOT=%s\nREMOTE_NAME=%s\nSOURCE_REPO_SYNC_SHA=%s\n' "${SOURCE_REPO_ROOT}" "${REMOTE_NAME}" "${updated_sha}"
|
|
137
|
-
exit 0
|
|
138
|
-
fi
|
|
139
|
-
|
|
140
|
-
if git -C "${SOURCE_REPO_ROOT}" merge --no-edit "refs/remotes/${REMOTE_NAME}/${DEFAULT_BRANCH}" >/dev/null 2>&1; then
|
|
141
|
-
updated_sha="$(git_ref_sha "${SOURCE_REPO_ROOT}" "refs/heads/${DEFAULT_BRANCH}")"
|
|
142
|
-
write_state "updated" "${REMOTE_NAME}" "${remote_sha}" "${updated_sha}" "merge-checked-out-branch"
|
|
143
|
-
printf 'SOURCE_REPO_SYNC_STATUS=updated\nSOURCE_REPO_ROOT=%s\nREMOTE_NAME=%s\nSOURCE_REPO_SYNC_SHA=%s\n' "${SOURCE_REPO_ROOT}" "${REMOTE_NAME}" "${updated_sha}"
|
|
144
|
-
exit 0
|
|
145
|
-
fi
|
|
146
|
-
|
|
147
|
-
git -C "${SOURCE_REPO_ROOT}" merge --abort >/dev/null 2>&1 || true
|
|
148
|
-
write_state "blocked" "${REMOTE_NAME}" "${remote_sha}" "${local_branch_sha}" "merge-conflict"
|
|
149
|
-
printf 'SOURCE_REPO_SYNC_STATUS=blocked\nSOURCE_REPO_SYNC_REASON=merge-conflict\nSOURCE_REPO_ROOT=%s\nREMOTE_NAME=%s\nLOCAL_SHA=%s\nREMOTE_SHA=%s\n' \
|
|
150
|
-
"${SOURCE_REPO_ROOT}" "${REMOTE_NAME}" "${local_branch_sha}" "${remote_sha}"
|
|
151
|
-
exit 0
|
|
152
|
-
fi
|
|
153
|
-
|
|
154
|
-
if ! git -C "${SOURCE_REPO_ROOT}" merge-base --is-ancestor "${local_branch_sha}" "${remote_sha}" >/dev/null 2>&1; then
|
|
155
|
-
write_state "blocked" "${REMOTE_NAME}" "${remote_sha}" "${local_branch_sha}" "local-main-diverged"
|
|
156
|
-
printf 'SOURCE_REPO_SYNC_STATUS=blocked\nSOURCE_REPO_SYNC_REASON=local-main-diverged\nSOURCE_REPO_ROOT=%s\nREMOTE_NAME=%s\nLOCAL_SHA=%s\nREMOTE_SHA=%s\n' \
|
|
157
|
-
"${SOURCE_REPO_ROOT}" "${REMOTE_NAME}" "${local_branch_sha}" "${remote_sha}"
|
|
158
|
-
exit 0
|
|
159
|
-
fi
|
|
160
|
-
|
|
161
|
-
git -C "${SOURCE_REPO_ROOT}" update-ref "refs/heads/${DEFAULT_BRANCH}" "${remote_sha}" "${local_branch_sha}"
|
|
162
|
-
write_state "updated" "${REMOTE_NAME}" "${remote_sha}" "${remote_sha}" "fast-forward-local-ref"
|
|
163
|
-
printf 'SOURCE_REPO_SYNC_STATUS=updated\nSOURCE_REPO_ROOT=%s\nREMOTE_NAME=%s\nSOURCE_REPO_SYNC_SHA=%s\n' "${SOURCE_REPO_ROOT}" "${REMOTE_NAME}" "${remote_sha}"
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
|
|
4
|
-
usage() {
|
|
5
|
-
cat <<'EOF'
|
|
6
|
-
Usage:
|
|
7
|
-
agent-project-worker-status --runs-root <path> --session <id> [--exit-marker <marker>]
|
|
8
|
-
|
|
9
|
-
Reads a project-lane run directory and reports session status using tmux plus the
|
|
10
|
-
worker log exit marker.
|
|
11
|
-
EOF
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
runs_root="${AGENT_PROJECT_RUNS_ROOT:-}"
|
|
15
|
-
session=""
|
|
16
|
-
exit_marker="__\\w+_EXIT__:"
|
|
17
|
-
|
|
18
|
-
while [[ $# -gt 0 ]]; do
|
|
19
|
-
case "$1" in
|
|
20
|
-
--runs-root) runs_root="${2:-}"; shift 2 ;;
|
|
21
|
-
--session) session="${2:-}"; shift 2 ;;
|
|
22
|
-
--exit-marker) exit_marker="${2:-}"; shift 2 ;;
|
|
23
|
-
--help|-h) usage; exit 0 ;;
|
|
24
|
-
*) echo "Unknown argument: $1" >&2; usage >&2; exit 1 ;;
|
|
25
|
-
esac
|
|
26
|
-
done
|
|
27
|
-
|
|
28
|
-
if [[ -z "$runs_root" || -z "$session" ]]; then
|
|
29
|
-
usage >&2
|
|
30
|
-
exit 1
|
|
31
|
-
fi
|
|
32
|
-
|
|
33
|
-
run_dir="${runs_root}/${session}"
|
|
34
|
-
meta_file="${run_dir}/run.env"
|
|
35
|
-
result_file="${run_dir}/result.env"
|
|
36
|
-
runner_state_file="${run_dir}/runner.env"
|
|
37
|
-
output_file="${run_dir}/${session}.log"
|
|
38
|
-
|
|
39
|
-
status="UNKNOWN"
|
|
40
|
-
exit_code=""
|
|
41
|
-
result_only_completion="no"
|
|
42
|
-
failure_reason=""
|
|
43
|
-
runner_state=""
|
|
44
|
-
thread_id=""
|
|
45
|
-
last_exit_code=""
|
|
46
|
-
|
|
47
|
-
failure_reason_from_output() {
|
|
48
|
-
[[ -f "$output_file" ]] || return 1
|
|
49
|
-
|
|
50
|
-
if rg -qi "You've hit your usage limit|You have reached your Codex usage limits|visit https://chatgpt.com/codex/settings/usage|Upgrade to Pro|rate limit exceeded|quota exceeded|usage cap (reached|exceeded)|usage quota (reached|exceeded)" "$output_file"; then
|
|
51
|
-
printf 'usage-limit\n'
|
|
52
|
-
return 0
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
if rg -qi 'stale-run no-codex-output-before-stall-threshold|no-codex-output-before-stall-threshold' "$output_file"; then
|
|
56
|
-
printf 'no-codex-output-before-stall-threshold\n'
|
|
57
|
-
return 0
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
if rg -qi 'stale-run no-codex-progress-before-stall-threshold|no-codex-progress-before-stall-threshold' "$output_file"; then
|
|
61
|
-
printf 'no-codex-progress-before-stall-threshold\n'
|
|
62
|
-
return 0
|
|
63
|
-
fi
|
|
64
|
-
|
|
65
|
-
# Recover Codex startup stalls when the wrapper was archived before it could
|
|
66
|
-
# flush a terminal runner.env state. This is intentionally narrow: the log
|
|
67
|
-
# must show a turn started, but no tool activity or turn completion.
|
|
68
|
-
if rg -q '"type":"turn.started"' "$output_file" \
|
|
69
|
-
&& ! rg -q '"type":"item.started"|"type":"item.completed"|"type":"turn.completed"' "$output_file"; then
|
|
70
|
-
printf 'no-codex-progress-before-stall-threshold\n'
|
|
71
|
-
return 0
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
return 1
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if tmux has-session -t "$session" 2>/dev/null; then
|
|
78
|
-
status="RUNNING"
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
if [[ -f "$runner_state_file" ]]; then
|
|
82
|
-
set -a
|
|
83
|
-
# shellcheck source=/dev/null
|
|
84
|
-
source "$runner_state_file"
|
|
85
|
-
set +a
|
|
86
|
-
runner_state="${RUNNER_STATE:-}"
|
|
87
|
-
thread_id="${THREAD_ID:-}"
|
|
88
|
-
last_exit_code="${LAST_EXIT_CODE:-}"
|
|
89
|
-
if [[ -z "$failure_reason" ]]; then
|
|
90
|
-
failure_reason="${LAST_FAILURE_REASON:-}"
|
|
91
|
-
fi
|
|
92
|
-
fi
|
|
93
|
-
|
|
94
|
-
if [[ "$status" == "UNKNOWN" ]]; then
|
|
95
|
-
case "$runner_state" in
|
|
96
|
-
succeeded)
|
|
97
|
-
status="SUCCEEDED"
|
|
98
|
-
;;
|
|
99
|
-
failed)
|
|
100
|
-
status="FAILED"
|
|
101
|
-
if [[ -z "$exit_code" && -n "$last_exit_code" ]]; then
|
|
102
|
-
exit_code="$last_exit_code"
|
|
103
|
-
fi
|
|
104
|
-
;;
|
|
105
|
-
esac
|
|
106
|
-
fi
|
|
107
|
-
|
|
108
|
-
if [[ "$status" == "UNKNOWN" && -f "$output_file" ]]; then
|
|
109
|
-
exit_match="$(rg -o "${exit_marker}[0-9]+" "$output_file" | tail -n 1 || true)"
|
|
110
|
-
if [[ -n "$exit_match" ]]; then
|
|
111
|
-
exit_code="${exit_match##*:}"
|
|
112
|
-
if [[ "$exit_code" == "0" ]]; then
|
|
113
|
-
status="SUCCEEDED"
|
|
114
|
-
else
|
|
115
|
-
status="FAILED"
|
|
116
|
-
fi
|
|
117
|
-
fi
|
|
118
|
-
fi
|
|
119
|
-
|
|
120
|
-
if [[ "$status" == "UNKNOWN" && -n "$runner_state" ]]; then
|
|
121
|
-
case "$runner_state" in
|
|
122
|
-
running|waiting-auth-refresh|switching-account)
|
|
123
|
-
# Tmux session is gone and runner never reached a terminal state.
|
|
124
|
-
# This detects crashes where the worker process died before updating
|
|
125
|
-
# runner.env or writing an exit marker.
|
|
126
|
-
# Check BEFORE stale result.env to avoid false SUCCEEDED when a prior
|
|
127
|
-
# cycle's result.env happens to exist.
|
|
128
|
-
status="FAILED"
|
|
129
|
-
failure_reason="$(failure_reason_from_output || true)"
|
|
130
|
-
if [[ -z "$failure_reason" ]]; then
|
|
131
|
-
failure_reason="runner-aborted-before-completion"
|
|
132
|
-
fi
|
|
133
|
-
if [[ -z "$exit_code" && -n "$last_exit_code" ]]; then
|
|
134
|
-
exit_code="$last_exit_code"
|
|
135
|
-
fi
|
|
136
|
-
;;
|
|
137
|
-
esac
|
|
138
|
-
fi
|
|
139
|
-
|
|
140
|
-
if [[ "$status" == "UNKNOWN" && -f "$result_file" ]]; then
|
|
141
|
-
# A worker that managed to persist result.env already completed its contract,
|
|
142
|
-
# even if the tmux session disappeared before the exit marker was flushed.
|
|
143
|
-
# Check BEFORE failure_reason_from_output so that a completed result.env
|
|
144
|
-
# is not overridden by transient failure text in the log.
|
|
145
|
-
status="SUCCEEDED"
|
|
146
|
-
result_only_completion="yes"
|
|
147
|
-
fi
|
|
148
|
-
|
|
149
|
-
if [[ "$status" == "UNKNOWN" && -z "$failure_reason" ]]; then
|
|
150
|
-
failure_reason="$(failure_reason_from_output || true)"
|
|
151
|
-
if [[ -n "$failure_reason" ]]; then
|
|
152
|
-
status="FAILED"
|
|
153
|
-
fi
|
|
154
|
-
fi
|
|
155
|
-
|
|
156
|
-
if [[ "$status" == "UNKNOWN" && -f "$output_file" ]]; then
|
|
157
|
-
if rg -qi "You've hit your usage limit|You have reached your Codex usage limits|visit https://chatgpt.com/codex/settings/usage|Upgrade to Pro|rate limit exceeded|quota exceeded|usage cap (reached|exceeded)|usage quota (reached|exceeded)" "$output_file"; then
|
|
158
|
-
status="FAILED"
|
|
159
|
-
failure_reason="usage-limit"
|
|
160
|
-
fi
|
|
161
|
-
fi
|
|
162
|
-
|
|
163
|
-
printf 'SESSION=%s\n' "$session"
|
|
164
|
-
printf 'STATUS=%s\n' "$status"
|
|
165
|
-
if [[ -f "$meta_file" ]]; then
|
|
166
|
-
cat "$meta_file"
|
|
167
|
-
printf 'META_FILE=%s\n' "$meta_file"
|
|
168
|
-
fi
|
|
169
|
-
if [[ -f "$runner_state_file" ]]; then
|
|
170
|
-
cat "$runner_state_file"
|
|
171
|
-
printf 'RUNNER_STATE_FILE=%s\n' "$runner_state_file"
|
|
172
|
-
fi
|
|
173
|
-
if [[ -f "$result_file" ]]; then
|
|
174
|
-
cat "$result_file"
|
|
175
|
-
printf 'RESULT_FILE=%s\n' "$result_file"
|
|
176
|
-
fi
|
|
177
|
-
if [[ "$result_only_completion" == "yes" ]]; then
|
|
178
|
-
printf 'RESULT_ONLY_COMPLETION=yes\n'
|
|
179
|
-
fi
|
|
180
|
-
if [[ -n "$exit_code" ]]; then
|
|
181
|
-
printf 'EXIT_CODE=%s\n' "$exit_code"
|
|
182
|
-
fi
|
|
183
|
-
if [[ -n "$failure_reason" ]]; then
|
|
184
|
-
printf 'FAILURE_REASON=%s\n' "$failure_reason"
|
|
185
|
-
fi
|
|
186
|
-
if [[ -n "$thread_id" ]]; then
|
|
187
|
-
printf 'THREAD_ID=%s\n' "$thread_id"
|
|
188
|
-
fi
|