Skip to content

Commit f9a0aa3

Browse files
committed
sync: update 8 file(s) in core/
- .gaai/core/adapters/claude-code/runtime-routing-logger.js - .gaai/core/scripts/daemon-dispatch.sh - .gaai/core/scripts/daemon-monitor-tail.sh - .gaai/core/scripts/daemon-monitor-top.sh - .gaai/core/scripts/delivery-daemon.sh - .gaai/core/scripts/observe-secondary.sh - .gaai/core/scripts/tests/daemon-monitor.test.sh - .gaai/core/scripts/tests/daemon-state-machine.test.sh
1 parent 7bda975 commit f9a0aa3

8 files changed

Lines changed: 919 additions & 748 deletions

File tree

.gaai/core/adapters/claude-code/runtime-routing-logger.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export function logPhase(params) {
100100
};
101101

102102
// Append optional secondary-mode telemetry fields when present (integers/boolean, DEC-65)
103-
const TELEMETRY_FIELDS = ['context_size_at_spawn', 'compact_events_count', 'retry_429_count', 'nested_session_completed', 'pipeline'];
103+
const TELEMETRY_FIELDS = ['context_size_at_spawn', 'compact_events_count', 'retry_429_count', 'nested_session_completed', 'pipeline', 'pr_url', 'auto_merge_applied'];
104104
for (const f of TELEMETRY_FIELDS) {
105105
if (f in params) entry[f] = params[f];
106106
}
@@ -136,6 +136,8 @@ if (import.meta.url === pathToFileURL(process.argv[1]).href) {
136136
const implModelTag = argValue('--impl-model-tag');
137137
const pipelineArg = argValue('--pipeline');
138138
const logPathArg = argValue('--log-path');
139+
const prUrlArg = argValue('--pr-url');
140+
const autoMergeApplied = argValue('--auto-merge-applied');
139141

140142
// --log-path overrides default log path (useful for testing without internal _setLogPath)
141143
if (logPathArg) _setLogPath(logPathArg);
@@ -155,6 +157,8 @@ if (import.meta.url === pathToFileURL(process.argv[1]).href) {
155157
impl_model_tag: implModelTag,
156158
};
157159
if (pipelineArg !== undefined) phaseParams.pipeline = pipelineArg;
160+
if (prUrlArg !== undefined && prUrlArg !== '') phaseParams.pr_url = prUrlArg;
161+
if (autoMergeApplied !== undefined) phaseParams.auto_merge_applied = autoMergeApplied === 'true';
158162
logPhase(phaseParams);
159163
process.stdout.write(formatPhaseStdout(phase, provider, model, fallbackReason));
160164
} catch (err) {

.gaai/core/scripts/daemon-dispatch.sh

Lines changed: 369 additions & 50 deletions
Large diffs are not rendered by default.

.gaai/core/scripts/daemon-monitor-tail.sh

Lines changed: 9 additions & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
LOG_DIR="${1:-.gaai/project/contexts/backlog/.delivery-logs}"
66
PROJECT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
77
BACKLOG="$PROJECT_DIR/.gaai/project/contexts/backlog/active.backlog.yaml"
8-
LOCK_DIR="${PROJECT_DIR}/.gaai/project/contexts/backlog/.delivery-locks"
9-
WORKTREE_BASE="${PROJECT_DIR}/../.gaai-worktrees/$(basename "$PROJECT_DIR")"
108

119
HAS_JQ=false
1210
command -v jq &>/dev/null && HAS_JQ=true
@@ -52,157 +50,9 @@ format_model() {
5250

5351
PHASE_CACHE_DIR="${PROJECT_DIR}/.gaai/project/contexts/backlog/.delivery-locks/.phase-cache"
5452

55-
# Returns story IDs — one per line — for all currently active deliveries.
56-
# For legacy pipeline: active tmux sessions named gaai-deliver-{id}.
57-
# For 3phase pipeline: .lock files in LOCK_DIR where backlog status=in_progress.
58-
detect_active_stories() {
59-
local seen=()
60-
61-
# Legacy: tmux sessions
62-
local tmux_ids
63-
tmux_ids=$(tmux list-sessions -F '#{session_name}' 2>/dev/null \
64-
| grep '^gaai-deliver-' \
65-
| sed 's/gaai-deliver-//' || true)
66-
for _id in $tmux_ids; do
67-
local _dp
68-
_dp=$(awk -v id="$_id" '
69-
$0 == "- id: " id { found=1; next }
70-
found && /^- id:/ { exit }
71-
found && /^[[:space:]]+delivery_pipeline:/ {
72-
gsub(/^[[:space:]]+delivery_pipeline:[[:space:]]*/, "")
73-
gsub(/[[:space:]]*/, ""); print; exit
74-
}
75-
' "$BACKLOG" 2>/dev/null || true)
76-
[[ "$_dp" != "3phase" ]] && echo "$_id"
77-
seen+=("$_id")
78-
done
79-
80-
# 3phase: .lock files with in_progress status
81-
if [[ -d "$LOCK_DIR" ]]; then
82-
for _lf in "$LOCK_DIR"/*.lock; do
83-
[[ -f "$_lf" ]] || continue
84-
local _sid
85-
_sid=$(basename "$_lf" .lock)
86-
# Skip if already emitted via tmux path
87-
local _dup=0
88-
for _s in "${seen[@]:-}"; do [[ "$_s" == "$_sid" ]] && _dup=1 && break; done
89-
[[ $_dup -eq 1 ]] && continue
90-
local _status _dp2
91-
_status=$(awk -v id="$_sid" '
92-
$0 == "- id: " id { found=1; next }
93-
found && /^- id:/ { exit }
94-
found && /^[[:space:]]+status:/ {
95-
gsub(/^[[:space:]]+status:[[:space:]]*/, "")
96-
gsub(/[[:space:]]*/, ""); print; exit
97-
}
98-
' "$BACKLOG" 2>/dev/null || true)
99-
_dp2=$(awk -v id="$_sid" '
100-
$0 == "- id: " id { found=1; next }
101-
found && /^- id:/ { exit }
102-
found && /^[[:space:]]+delivery_pipeline:/ {
103-
gsub(/^[[:space:]]+delivery_pipeline:[[:space:]]*/, "")
104-
gsub(/[[:space:]]*/, ""); print; exit
105-
}
106-
' "$BACKLOG" 2>/dev/null || true)
107-
[[ "$_status" == "in_progress" && "$_dp2" == "3phase" ]] && echo "$_sid"
108-
done
109-
fi
110-
}
111-
112-
# Returns the canonical log path for the current active phase of a 3phase story.
113-
# AC2: per-phase log at {worktree}/.delivery-logs/{id}.{phase}.log
114-
# Falls back to [no log yet] sentinel string when log does not exist.
115-
resolve_3phase_log() {
116-
local story_id="$1"
117-
local worktree="${WORKTREE_BASE}/${story_id}-workspace"
118-
119-
# Determine active phase from markers (AC1 priority order)
120-
local active_phase=""
121-
for _ph in plan impl qa commit; do
122-
if [[ -f "${LOCK_DIR}/${story_id}.${_ph}.active" ]]; then
123-
active_phase="$_ph"
124-
break
125-
fi
126-
done
127-
128-
if [[ -z "$active_phase" ]]; then
129-
# No active marker: derive last relevant phase from phase_status
130-
local ps
131-
ps=$(awk -v id="$story_id" '
132-
$0 == "- id: " id { found=1; next }
133-
found && /^- id:/ { exit }
134-
found && /^[[:space:]]+phase_status:/ {
135-
gsub(/^[[:space:]]+phase_status:[[:space:]]*/, "")
136-
gsub(/[[:space:]]*/, ""); print; exit
137-
}
138-
' "$BACKLOG" 2>/dev/null || true)
139-
case "$ps" in
140-
not_started) active_phase="plan" ;;
141-
planned) active_phase="plan" ;;
142-
implemented) active_phase="impl" ;;
143-
qa_passed) active_phase="qa" ;;
144-
done) active_phase="commit" ;;
145-
qa_failed|qa_escalated) active_phase="qa" ;;
146-
failed|escalated) active_phase="impl" ;;
147-
"") echo "[?]"; return ;;
148-
*) echo "[?]"; return ;;
149-
esac
150-
fi
151-
152-
local log_path="${worktree}/.delivery-logs/${story_id}.${active_phase}.log"
153-
if [[ -f "$log_path" ]]; then
154-
echo "$log_path"
155-
else
156-
echo "[no log yet]"
157-
fi
158-
}
159-
160-
# Returns the display phase label for a 3phase story using authoritative markers.
161-
# AC1: markers take priority over phase_status for in-progress display.
162-
detect_phase_3phase() {
163-
local story_id="$1"
164-
165-
# Active marker check (highest priority)
166-
for _ph in plan impl qa commit; do
167-
if [[ -f "${LOCK_DIR}/${story_id}.${_ph}.active" ]]; then
168-
case "$_ph" in
169-
plan) echo "PLAN" ;;
170-
impl) echo "IMPL" ;;
171-
qa) echo "QA" ;;
172-
commit) echo "COMMIT" ;;
173-
esac
174-
return
175-
fi
176-
done
177-
178-
# No active marker: read phase_status for terminal / idle display
179-
local ps
180-
ps=$(awk -v id="$story_id" '
181-
$0 == "- id: " id { found=1; next }
182-
found && /^- id:/ { exit }
183-
found && /^[[:space:]]+phase_status:/ {
184-
gsub(/^[[:space:]]+phase_status:[[:space:]]*/, "")
185-
gsub(/[[:space:]]*/, ""); print; exit
186-
}
187-
' "$BACKLOG" 2>/dev/null || true)
188-
189-
case "$ps" in
190-
done) echo "DONE" ;;
191-
failed|escalated) echo "FAILED" ;;
192-
qa_failed) echo "QA_FAILED" ;;
193-
qa_escalated) echo "QA_ESCALATED" ;;
194-
not_started|planned|implemented|qa_passed)
195-
echo "IDLE @ ${ps}" ;;
196-
"") echo "[?]" ;;
197-
*) echo "[?]" ;;
198-
esac
199-
}
200-
20153
parse_log() {
20254
local log_file="$1"
20355
local story_id="$2"
204-
local pipeline="${3:-legacy}" # "3phase" or "legacy"
205-
local phase_override="${4:-}" # pre-computed phase label (3phase only)
20656

20757
if [[ ! -f "$log_file" ]]; then
20858
echo -e " ${DIM}(log not yet created)${NC}"
@@ -335,12 +185,6 @@ parse_log() {
335185
fi
336186

337187
# ── Phase detection ──
338-
if [[ "$pipeline" == "3phase" && -n "$phase_override" ]]; then
339-
# 3phase: use authoritative marker-derived label (AC1)
340-
phase_label="$phase_override"
341-
phase_origin=""
342-
else
343-
# Legacy pipeline: existing log-content heuristic (unchanged)
344188
# Walk recent events, classify each Bash command / Write target into a phase tag,
345189
# keep the LAST non-empty classification — that's the current phase.
346190
# Origin is captured from the same event so we can show e.g. "IMPL (sub)" when
@@ -456,7 +300,6 @@ parse_log() {
456300
# Current window advanced: write updated winner back to cache
457301
printf '%s\t%s\t%s\n' "$cur_rank" "$phase_label" "$phase_origin" > "$cache_file" 2>/dev/null || true
458302
fi
459-
fi # close: if [[ 3phase ]] ... else (legacy heuristic) ... fi
460303
else
461304
last_text=$(tail -200 "$log_file" 2>/dev/null \
462305
| grep -o '"type":"tool_use"[^}]*"name":"[^"]*"' \
@@ -539,59 +382,30 @@ parse_log() {
539382
fi
540383
}
541384

542-
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
543385
while true; do
544386
clear
545387
# In tmux: clear scrollback left by `clear` so prior refresh doesn't ghost below
546388
[[ -n "${TMUX:-}" ]] && tmux clear-history 2>/dev/null || true
547389
echo "═══ Active Deliveries (refreshes every 5s) ═══"
548390
echo ""
549391

550-
# Read active stories (3phase from locks + legacy from tmux)
551-
active_ids=()
552-
while IFS= read -r _id; do
553-
[[ -n "$_id" ]] && active_ids+=("$_id")
554-
done < <(detect_active_stories)
392+
# Find active tmux delivery sessions
393+
active_sessions=$(tmux list-sessions -F '#{session_name}' 2>/dev/null \
394+
| grep '^gaai-deliver-' \
395+
| sed 's/gaai-deliver-//' || true)
555396

556-
if [[ ${#active_ids[@]} -eq 0 ]]; then
397+
if [[ -z "$active_sessions" ]]; then
557398
echo -e " ${DIM}No active deliveries. Use /gaai-discover to create stories for the backlog.${NC}"
558399
sleep 5
559400
continue
560401
fi
561402

562-
for story_id in "${active_ids[@]}"; do
563-
# Determine pipeline
564-
pipeline=$(awk -v id="$story_id" '
565-
$0 == "- id: " id { found=1; next }
566-
found && /^- id:/ { exit }
567-
found && /^[[:space:]]+delivery_pipeline:/ {
568-
gsub(/^[[:space:]]+delivery_pipeline:[[:space:]]*/, "")
569-
gsub(/[[:space:]]*/, ""); print; exit
570-
}
571-
' "$BACKLOG" 2>/dev/null || true)
572-
573-
if [[ "$pipeline" == "3phase" ]]; then
574-
# AC1: marker-based phase detection
575-
phase_label=$(detect_phase_3phase "$story_id")
576-
# AC2: per-phase log path resolution
577-
log_path=$(resolve_3phase_log "$story_id")
578-
if [[ "$log_path" == "[no log yet]" || "$log_path" == "[?]" ]]; then
579-
echo "── $story_id ── [${phase_label}]"
580-
echo -e " ${DIM}${log_path}${NC}"
581-
echo ""
582-
continue
583-
fi
584-
echo "── $story_id ── [${phase_label}]"
585-
parse_log "$log_path" "$story_id" "3phase" "$phase_label"
586-
else
587-
# Legacy: unchanged path
588-
log_path="$LOG_DIR/${story_id}.log"
589-
echo "── $story_id ──"
590-
parse_log "$log_path" "$story_id" "legacy" ""
591-
fi
403+
for story_id in $active_sessions; do
404+
log_file="$LOG_DIR/${story_id}.log"
405+
echo "── $story_id ──"
406+
parse_log "$log_file" "$story_id"
592407
echo ""
593408
done
594409

595410
sleep 5
596411
done
597-
fi

0 commit comments

Comments
 (0)