okstra 0.177.0 → 0.178.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/dist/commands/execute/team.mjs +14 -4
- package/dist/commands/execute/team.mjs.map +1 -1
- package/dist/commands/lifecycle/install.mjs +0 -1
- package/dist/commands/lifecycle/install.mjs.map +1 -1
- package/docs/architecture.md +3 -3
- package/docs/cli.md +1 -1
- package/docs/project-structure-overview.md +2 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/report-writer-worker.md +1 -1
- package/runtime/bin/okstra-compact-reminder.sh +2 -2
- package/runtime/bin/okstra-render-report-views.py +13 -10
- package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
- package/runtime/prompts/lead/report-writer.md +5 -1
- package/runtime/prompts/profiles/_common-contract.md +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +5 -6
- package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +23 -1
- package/runtime/python/okstra_ctl/agent_invocation.py +17 -0
- package/runtime/python/okstra_ctl/agent_prompt_cli.py +13 -0
- package/runtime/python/okstra_ctl/dispatch_core.py +96 -17
- package/runtime/python/okstra_ctl/dispatch_state.py +57 -0
- package/runtime/python/okstra_ctl/model_cli.py +11 -2
- package/runtime/python/okstra_ctl/model_discovery.py +12 -0
- package/runtime/python/okstra_ctl/pane_reclaim.py +49 -43
- package/runtime/python/okstra_ctl/render.py +53 -0
- package/runtime/python/okstra_ctl/report_html/render.py +7 -4
- package/runtime/python/okstra_ctl/report_views.py +35 -0
- package/runtime/python/okstra_ctl/run.py +88 -2
- package/runtime/python/okstra_ctl/team.py +84 -14
- package/runtime/python/okstra_ctl/tmux.py +2 -3
- package/runtime/python/okstra_ctl/user_response.py +20 -4
- package/runtime/python/okstra_ctl/worker_runner.py +2 -2
- package/runtime/python/okstra_ctl/write_policy.py +9 -1
- package/runtime/schemas/final-report-v2.0.schema.json +24 -1
- package/runtime/skills/okstra-run/SKILL.md +3 -3
- package/runtime/templates/reports/final-report-v2.template.md +2 -1
- package/runtime/templates/reports/html/base.template.html +1 -2
- package/runtime/validators/validate-report-views.py +30 -17
- package/runtime/validators/validate-run.py +256 -78
- package/runtime/validators/validate_session_conformance.py +1 -1
- package/runtime/bin/okstra-trace-cleanup.sh +0 -185
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# okstra-trace-cleanup.sh — close the harness-owned worker panes of an okstra run.
|
|
4
|
-
#
|
|
5
|
-
# The panes this closes are the teammate panes the HARNESS splits for dispatched
|
|
6
|
-
# worker agents. okstra does not create them and cannot tag them, so they are
|
|
7
|
-
# found by a title allowlist scoped to the lead's window. They accumulate until
|
|
8
|
-
# the pane budget runs out, and `shutdown_request` only idles the agent without
|
|
9
|
-
# freeing its pane — this script is the only thing that closes them, which is why
|
|
10
|
-
# the lead calls it at every round boundary and before every user gate.
|
|
11
|
-
#
|
|
12
|
-
# Two tag-driven paths used to live here and both are gone:
|
|
13
|
-
#
|
|
14
|
-
# - Worker-compute panes of the `tmux-pane` dispatch backend, tagged
|
|
15
|
-
# `@okstra_worker_run`. That backend was removed — a worker now gets a cmux
|
|
16
|
-
# surface or a cli-wrapper subprocess, and neither is a tmux pane okstra owns.
|
|
17
|
-
# - Trace panes, tagged `@okstra_trace_run` / `@okstra_status`, which the
|
|
18
|
-
# provider wrappers used to split as `tail -F` siblings. The wrappers became
|
|
19
|
-
# four-line entrypoints and worker progress renders into the worker's own
|
|
20
|
-
# pane, so nothing had spawned a trace pane for some time.
|
|
21
|
-
#
|
|
22
|
-
# With both writers gone the tag scan matched nothing, so it was removed along
|
|
23
|
-
# with the two modes that existed only to drive it (`--reap`, which the SessionEnd
|
|
24
|
-
# hook called, and `--reclaim-completed`, which `okstra-subagent-reclaim.sh` drove
|
|
25
|
-
# from SubagentStop / TaskCompleted). Those hooks are gone from the seeded
|
|
26
|
-
# settings too.
|
|
27
|
-
#
|
|
28
|
-
# Invocation:
|
|
29
|
-
#
|
|
30
|
-
# --run-dir <RUN_DIR> Closes the run's worker-agent panes (`claude-worker` /
|
|
31
|
-
# `codex-worker` / `antigravity-worker` /
|
|
32
|
-
# `report-writer-worker` and the FleetView teammate
|
|
33
|
-
# prefixes), scoped to the LEAD's WINDOW. The lead pane is
|
|
34
|
-
# read from `<RUN_DIR>/state/lead-pane.id` (recorded once
|
|
35
|
-
# by the lead in its own foreground pane — reliable even
|
|
36
|
-
# though Claude Code's Bash tool strips `$TMUX` /
|
|
37
|
-
# `$TMUX_PANE`); it scopes the scan and is NEVER killed.
|
|
38
|
-
# Window scope keeps a second lead running in another
|
|
39
|
-
# window of the same session out of range.
|
|
40
|
-
#
|
|
41
|
-
# `--list` (alias `--dry-run`) prints `<pane_id>\t<pane_title>` per pane instead
|
|
42
|
-
# of killing.
|
|
43
|
-
#
|
|
44
|
-
# `--keep <substr>` (repeatable) spares any pane whose current title contains
|
|
45
|
-
# <substr>, in both the kill and the list set. Used to preserve an in-flight
|
|
46
|
-
# report-writer at a round boundary.
|
|
47
|
-
#
|
|
48
|
-
# Failures are tolerated silently — a stale pane id, no tmux, or a locked tmux
|
|
49
|
-
# client must never prevent Claude from exiting cleanly.
|
|
50
|
-
|
|
51
|
-
set -u
|
|
52
|
-
|
|
53
|
-
# Caller-pane resolution helper (okstra_resolve_caller_pane) — see
|
|
54
|
-
# lib/okstra/tmux-pane.sh. Used as the lead-pane fallback below so a missing /
|
|
55
|
-
# stale lead-pane.id resolves to the pane THIS process actually runs in (via
|
|
56
|
-
# ancestor-PID ↔ tmux pane_pid matching), never a foreign active-client pane.
|
|
57
|
-
# Bin-sibling path in repo + installed layouts; degrade silently if absent.
|
|
58
|
-
_clean_script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
59
|
-
[ -r "$_clean_script_dir/lib/okstra/tmux-pane.sh" ] && . "$_clean_script_dir/lib/okstra/tmux-pane.sh"
|
|
60
|
-
|
|
61
|
-
MODE="kill" # kill | list
|
|
62
|
-
run_dir=""
|
|
63
|
-
KEEP_PATTERNS=() # --keep <substr>: panes whose title contains substr are spared from kill/list
|
|
64
|
-
while [[ $# -gt 0 ]]; do
|
|
65
|
-
case "$1" in
|
|
66
|
-
--list|--dry-run) MODE="list" ;;
|
|
67
|
-
--run-dir) shift; run_dir="${1-}" ;;
|
|
68
|
-
--run-dir=*) run_dir="${1#--run-dir=}" ;;
|
|
69
|
-
--keep) shift; KEEP_PATTERNS+=("${1-}") ;;
|
|
70
|
-
--keep=*) KEEP_PATTERNS+=("${1#--keep=}") ;;
|
|
71
|
-
-h|--help)
|
|
72
|
-
cat <<'USAGE'
|
|
73
|
-
usage: okstra-trace-cleanup.sh --run-dir <RUN_DIR> [--list] [--keep <substr>]...
|
|
74
|
-
|
|
75
|
-
--run-dir okstra run directory; closes that run's worker-agent panes.
|
|
76
|
-
--list print "<pane_id>\t<pane_title>" per pane; no kill.
|
|
77
|
-
--dry-run alias for --list.
|
|
78
|
-
--keep <substr> exclude any pane whose title contains <substr> from the
|
|
79
|
-
kill/list set (repeatable). Used to spare an in-flight
|
|
80
|
-
report-writer at a round boundary.
|
|
81
|
-
USAGE
|
|
82
|
-
exit 0 ;;
|
|
83
|
-
*)
|
|
84
|
-
printf 'okstra-trace-cleanup.sh: unknown option: %s\n' "$1" >&2
|
|
85
|
-
exit 2 ;;
|
|
86
|
-
esac
|
|
87
|
-
shift
|
|
88
|
-
done
|
|
89
|
-
|
|
90
|
-
if [[ -z "$run_dir" ]]; then
|
|
91
|
-
printf 'okstra-trace-cleanup.sh: --run-dir <RUN_DIR> is required\n' >&2
|
|
92
|
-
exit 2
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
# Lead pane. Prefer the value the lead recorded in its own foreground pane; fall
|
|
96
|
-
# back to the active-pane probe. Rejected if the recorded pane is gone.
|
|
97
|
-
lead_pane=""
|
|
98
|
-
lead_pane_file="$run_dir/state/lead-pane.id"
|
|
99
|
-
[[ -r "$lead_pane_file" ]] && lead_pane="$(head -n1 "$lead_pane_file" 2>/dev/null || true)"
|
|
100
|
-
if [[ -z "$lead_pane" ]] || ! tmux display-message -p -t "$lead_pane" '#{pane_id}' >/dev/null 2>&1; then
|
|
101
|
-
if type okstra_resolve_caller_pane >/dev/null 2>&1; then
|
|
102
|
-
lead_pane="$(okstra_resolve_caller_pane 2>/dev/null || true)"
|
|
103
|
-
else
|
|
104
|
-
lead_pane="$(tmux display-message -p '#{pane_id}' 2>/dev/null || true)"
|
|
105
|
-
fi
|
|
106
|
-
fi
|
|
107
|
-
|
|
108
|
-
_title_in_okstra_scope() {
|
|
109
|
-
local title="$1"
|
|
110
|
-
case "$title" in
|
|
111
|
-
# Claude/FleetView teammate panes may carry the task title instead of the
|
|
112
|
-
# worker id. These glyph prefixes are the only stable tmux-side signal.
|
|
113
|
-
"✳ "*|"⠂ "*)
|
|
114
|
-
return 0 ;;
|
|
115
|
-
*claude-worker*|*claude-executor*|*claude-verifier*)
|
|
116
|
-
return 0 ;;
|
|
117
|
-
*codex-worker*|*codex-executor*|*codex-verifier*)
|
|
118
|
-
return 0 ;;
|
|
119
|
-
*agy-worker*|*agy-executor*|*agy-verifier*)
|
|
120
|
-
return 0 ;;
|
|
121
|
-
*antigravity-worker*|*antigravity-executor*|*antigravity-verifier*)
|
|
122
|
-
return 0 ;;
|
|
123
|
-
*report-writer-worker*|*report-writer*)
|
|
124
|
-
return 0 ;;
|
|
125
|
-
esac
|
|
126
|
-
return 1
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
# A collected pane whose current title contains any --keep substring is spared.
|
|
130
|
-
_keep_excluded() {
|
|
131
|
-
local pid="$1" title pat
|
|
132
|
-
(( ${#KEEP_PATTERNS[@]} )) || return 1
|
|
133
|
-
title=$(tmux display-message -p -t "$pid" '#{pane_title}' 2>/dev/null || true)
|
|
134
|
-
for pat in "${KEEP_PATTERNS[@]}"; do
|
|
135
|
-
[[ -n "$pat" && "$title" == *"$pat"* ]] && return 0
|
|
136
|
-
done
|
|
137
|
-
return 1
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
collect_okstra_panes() {
|
|
141
|
-
local -a panes=()
|
|
142
|
-
local pid title
|
|
143
|
-
|
|
144
|
-
# Title-allowlisted worker-agent panes in the lead's WINDOW. `list-panes -t
|
|
145
|
-
# <pane>` (no `-s`, no `-a`) resolves the window containing that pane and lists
|
|
146
|
-
# only that window's panes. Split-pane teammates always land in the lead's
|
|
147
|
-
# window, so this catches all of THIS run's worker panes while a second okstra
|
|
148
|
-
# lead in another window of the same tmux session is left untouched. Skipped
|
|
149
|
-
# when the lead pane is unknown.
|
|
150
|
-
[[ -n "$lead_pane" ]] || return 0
|
|
151
|
-
while IFS=$'\t' read -r pid title; do
|
|
152
|
-
[[ -n "$pid" ]] || continue
|
|
153
|
-
[[ "$pid" == "$lead_pane" ]] && continue
|
|
154
|
-
if _title_in_okstra_scope "$title"; then
|
|
155
|
-
panes+=("$pid")
|
|
156
|
-
fi
|
|
157
|
-
done < <(tmux list-panes -t "$lead_pane" \
|
|
158
|
-
-F '#{pane_id}'$'\t''#{pane_title}' 2>/dev/null || true)
|
|
159
|
-
|
|
160
|
-
# Drop any pane a --keep pattern spares (in-flight report-writer).
|
|
161
|
-
if (( ${#panes[@]} )); then
|
|
162
|
-
printf '%s\n' "${panes[@]}" | awk 'NF && !seen[$0]++' | while IFS= read -r _pid; do
|
|
163
|
-
_keep_excluded "$_pid" && continue
|
|
164
|
-
printf '%s\n' "$_pid"
|
|
165
|
-
done
|
|
166
|
-
fi
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if [[ "$MODE" == "list" ]]; then
|
|
170
|
-
while IFS= read -r pane_id; do
|
|
171
|
-
[[ -n "$pane_id" ]] || continue
|
|
172
|
-
# `display-message -p` resolves a *live* pane's title; for stale ids tmux
|
|
173
|
-
# exits non-zero — fall back to an empty title rather than failing.
|
|
174
|
-
title=$(tmux display-message -p -t "$pane_id" '#{pane_title}' 2>/dev/null || true)
|
|
175
|
-
printf '%s\t%s\n' "$pane_id" "$title"
|
|
176
|
-
done < <(collect_okstra_panes)
|
|
177
|
-
exit 0
|
|
178
|
-
fi
|
|
179
|
-
|
|
180
|
-
while IFS= read -r pane_id; do
|
|
181
|
-
[[ -n "$pane_id" ]] || continue
|
|
182
|
-
tmux kill-pane -t "$pane_id" 2>/dev/null || true
|
|
183
|
-
done < <(collect_okstra_panes)
|
|
184
|
-
|
|
185
|
-
exit 0
|