Repository navigation
chore: rolling promotion dev -> main #644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5563199
040b667
ced87a7
c2c2246
df2870f
e8db57c
a76f265
4631b38
83cd1fb
9414139
f642101
29b892c
82e999a
ce60fa0
9d5dae3
d7ae157
56e2fac
136e08c
c5b6121
2405981
ba70b22
b6486ee
b80e277
2505055
c72a11a
90950d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -65,8 +65,22 @@ jobs: | |||||||||||||||||
| - name: Dead code check (knip) | ||||||||||||||||||
| run: bunx knip | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Test | ||||||||||||||||||
| run: bun test || bun test | ||||||||||||||||||
| - name: Test with coverage | ||||||||||||||||||
| run: | | ||||||||||||||||||
| COVERAGE_OUTPUT=$(bun test --coverage 2>&1) || true | ||||||||||||||||||
| echo "$COVERAGE_OUTPUT" | ||||||||||||||||||
| LINE_COV=$(echo "$COVERAGE_OUTPUT" | grep "All files" | awk -F'|' '{print $2}' | tr -d ' ') | ||||||||||||||||||
| echo "Line coverage: ${LINE_COV}%" | ||||||||||||||||||
| if [ -z "$LINE_COV" ]; then | ||||||||||||||||||
| echo "WARNING: Could not parse coverage — skipping threshold check" | ||||||||||||||||||
| exit 0 | ||||||||||||||||||
| fi | ||||||||||||||||||
|
Comment on lines
+74
to
+77
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Silent pass when coverage parsing fails may mask broken coverage reports. If coverage output format changes or Suggested alternative if [ -z "$LINE_COV" ]; then
- echo "WARNING: Could not parse coverage — skipping threshold check"
- exit 0
+ echo "ERROR: Could not parse coverage from output"
+ exit 1
fi📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| THRESHOLD=68 | ||||||||||||||||||
| if [ "$(echo "$LINE_COV < $THRESHOLD" | bc -l)" = "1" ]; then | ||||||||||||||||||
| echo "FAILED: Coverage ${LINE_COV}% is below ${THRESHOLD}% minimum" | ||||||||||||||||||
| exit 1 | ||||||||||||||||||
| fi | ||||||||||||||||||
| echo "PASSED: Coverage ${LINE_COV}% meets ${THRESHOLD}% minimum" | ||||||||||||||||||
|
|
||||||||||||||||||
| publish-next: | ||||||||||||||||||
| name: Publish @next | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,5 @@ | ||
| # Prevent GIT_DIR/GIT_WORK_TREE from leaking into child processes (see pre-push) | ||
| unset GIT_DIR | ||
| unset GIT_WORK_TREE | ||
|
|
||
| bunx commitlint --edit "$1" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| { | ||
| "name": "@automagik/genie", | ||
| "version": "3.260317.16", | ||
| "version": "3.260317.18", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new version |
||
| "description": "Collaborative terminal toolkit for human + AI workflows", | ||
| "type": "module", | ||
| "bin": { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,70 @@ | ||||||||||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard the Bash 4+ dependency.
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
| # Genie TUI — project session tabs for tmux top status bar | ||||||||||||||||||||||||||||||||
| # Reads workers.json for agent counts per session, merges with tmux sessions. | ||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||
| # Output format per session: | ||||||||||||||||||||||||||||||||
| # Active: #[bg=#7b2ff7,fg=#e0e0e0,bold] name (N) ● #[bg=#1a1a2e,fg=#7b2ff7] | ||||||||||||||||||||||||||||||||
| # Inactive: #[fg=#b8a9c9,bg=#1a1a2e] name (N) | ||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||
| # Env: GENIE_WORKERS — override path to workers.json (for testing) | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| workers_file="${GENIE_WORKERS:-${HOME}/.genie/workers.json}" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| # Get agent counts per session from workers.json (single jq pass) | ||||||||||||||||||||||||||||||||
| declare -A agent_counts=() | ||||||||||||||||||||||||||||||||
| if [[ -f "$workers_file" ]]; then | ||||||||||||||||||||||||||||||||
| worker_data=$(jq -r ' | ||||||||||||||||||||||||||||||||
| .workers // {} | to_entries | ||||||||||||||||||||||||||||||||
| | group_by(.value.session) | ||||||||||||||||||||||||||||||||
| | map({session: .[0].value.session, count: length}) | ||||||||||||||||||||||||||||||||
| | map(.session + "\t" + (.count | tostring)) | ||||||||||||||||||||||||||||||||
| | .[] | ||||||||||||||||||||||||||||||||
| ' "$workers_file" 2>/dev/null) || worker_data="" | ||||||||||||||||||||||||||||||||
|
Comment on lines
+18
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exclude team-lead rows from the session count.
Suggested fix- worker_data=$(jq -r '
- .workers // {} | to_entries
+ worker_data=$(jq -r '
+ .workers // {} | to_entries
+ | map(select(.value.role != "team-lead"))
| group_by(.value.session)
| map({session: .[0].value.session, count: length})📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if [[ -n "$worker_data" ]]; then | ||||||||||||||||||||||||||||||||
| while IFS=$'\t' read -r sess count; do | ||||||||||||||||||||||||||||||||
| [[ -z "$sess" ]] && continue | ||||||||||||||||||||||||||||||||
| agent_counts["$sess"]="$count" | ||||||||||||||||||||||||||||||||
| done <<< "$worker_data" | ||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| # Get the currently active session name | ||||||||||||||||||||||||||||||||
| has_tmux=true | ||||||||||||||||||||||||||||||||
| active_session="" | ||||||||||||||||||||||||||||||||
| if command -v tmux &>/dev/null; then | ||||||||||||||||||||||||||||||||
| active_session=$(tmux display-message -p '#{client_session}' 2>/dev/null) || active_session="" | ||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||
| has_tmux=false | ||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| output="" | ||||||||||||||||||||||||||||||||
| declare -A seen_sessions=() | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if [[ "$has_tmux" == "true" ]]; then | ||||||||||||||||||||||||||||||||
| # Merge tmux sessions with agent counts | ||||||||||||||||||||||||||||||||
| while IFS=$'\t' read -r session_name window_count; do | ||||||||||||||||||||||||||||||||
| [[ -z "$session_name" ]] && continue | ||||||||||||||||||||||||||||||||
| seen_sessions["$session_name"]=1 | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| # Use agent count from workers.json; fall back to window count | ||||||||||||||||||||||||||||||||
| task_count="${agent_counts[$session_name]:-$window_count}" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if [[ "$session_name" == "$active_session" ]]; then | ||||||||||||||||||||||||||||||||
| output+="#[bg=#7b2ff7,fg=#e0e0e0,bold] ${session_name} (${task_count}) ● #[bg=#1a1a2e,fg=#7b2ff7] " | ||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||
| output+="#[fg=#b8a9c9,bg=#1a1a2e] ${session_name} (${task_count}) " | ||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||
| done < <(tmux list-sessions -F "#{session_name} #{session_windows}" 2>/dev/null) | ||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| # Also include sessions from workers.json not yet seen (no tmux session or testing mode) | ||||||||||||||||||||||||||||||||
| for sess in "${!agent_counts[@]}"; do | ||||||||||||||||||||||||||||||||
| [[ -n "${seen_sessions[$sess]:-}" ]] && continue | ||||||||||||||||||||||||||||||||
| count="${agent_counts[$sess]}" | ||||||||||||||||||||||||||||||||
| output+="#[fg=#b8a9c9,bg=#1a1a2e] ${sess} (${count}) " | ||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| echo -n "$output" | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,138 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❓ Verification inconclusiveScript executed: # First, check if the file exists and get its line count
wc -l scripts/tmux/genie-tasks.shRepository: automagik-dev/genie Repository: automagik-dev/genie stdout: Script executed: # Read the entire file to verify the shebang, lines 86-87, and any version checks
cat -n scripts/tmux/genie-tasks.shRepository: automagik-dev/genie Repository: automagik-dev/genie stdout: Add Bash 4+ version check or declare the dependency explicitly. This script uses associative arrays ( 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Genie TUI — task window tabs for tmux bottom status bar | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Reads workers.json for agent counts + status emoji per window. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Usage: genie-tasks.sh <session_name> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Output format per window: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Active: #[bg=#7b2ff7,fg=#e0e0e0,bold] name ×count emoji #[bg=#16213e,fg=#7b2ff7] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Inactive: #[fg=#b8a9c9,bg=#16213e] name ×count emoji | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Env: GENIE_WORKERS — override path to workers.json (for testing) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| session_name="${1:-}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -z "$session_name" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo -n "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Verify session exists (skip check when running with mock data and no tmux) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| has_tmux=true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ! command -v tmux &>/dev/null; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| has_tmux=false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif ! tmux has-session -t "$session_name" 2>/dev/null; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Session doesn't exist in tmux — but if we have workers data, still render | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| has_tmux=false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workers_file="${GENIE_WORKERS:-${HOME}/.genie/workers.json}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # If workers file doesn't exist, fall back to plain tmux window list | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ ! -f "$workers_file" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$has_tmux" == "false" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo -n "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Fallback: plain window list without agent data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while IFS=$'\t' read -r window_index window_name window_active; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [[ -z "$window_index" ]] && continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$window_active" == "1" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output+="#[bg=#7b2ff7,fg=#e0e0e0,bold] ${window_index}:${window_name} #[bg=#16213e,fg=#7b2ff7] " | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output+="#[fg=#b8a9c9,bg=#16213e] ${window_index}:${window_name} " | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done < <(tmux list-windows -t "$session_name" -F "#{window_index} #{window_name} #{window_active}" 2>/dev/null) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo -n "$output" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # State priority for worst-state-wins aggregation (higher = worse) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # error > permission > working > spawning > idle > done > suspended | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Single jq pass: filter workers by session, group by windowName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # compute count + aggregate state per window. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Output: tab-separated lines: windowName\tcount\tworst_state | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| worker_data=$(jq -r --arg sess "$session_name" ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # State priority mapping | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def state_priority: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {"error": 7, "permission": 6, "working": 5, "spawning": 4, "idle": 3, "done": 2, "suspended": 1}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Emoji mapping | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def state_emoji: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {"spawning": "⏳", "working": "🔨", "idle": "⏸", "done": "✓", "error": "✗", "permission": "❓", "suspended": "💤"}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .workers // {} | to_entries | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | map(select(.value.session == $sess)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | group_by(.value.windowName // .value.team // "unknown") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | map({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| window: (.[0].value.windowName // .[0].value.team // "unknown"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| count: length, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| worst_state: ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| map(.value.state // "idle") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | map(. as $s | state_priority[$s] // 0) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | max | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | . as $max_pri | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | state_priority | to_entries | map(select(.value == $max_pri)) | .[0].key // "idle" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | map(.window + "\t" + (.count | tostring) + "\t" + (state_emoji[.worst_state] // "")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | .[] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ' "$workers_file" 2>/dev/null) || worker_data="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+58
to
+83
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle the full registry schema here.
Suggested fix- def state_priority:
- {"error": 7, "permission": 6, "working": 5, "spawning": 4, "idle": 3, "done": 2, "suspended": 1};
+ def state_priority:
+ {"error": 8, "permission": 7, "question": 6, "working": 5, "spawning": 4, "idle": 3, "done": 2, "suspended": 1};
- def state_emoji:
- {"spawning": "⏳", "working": "🔨", "idle": "⏸", "done": "✓", "error": "✗", "permission": "❓", "suspended": "💤"};
+ def state_emoji:
+ {"spawning": "⏳", "working": "🔨", "idle": "⏸", "done": "✓", "error": "✗", "permission": "❓", "question": "❔", "suspended": "💤"};
- | group_by(.value.windowName // .value.team // "unknown")
+ | group_by(.value.windowName // .value.window // .value.team // "unknown")
| map({
- window: (.[0].value.windowName // .[0].value.team // "unknown"),
+ window: (.[0].value.windowName // .[0].value.window // .[0].value.team // "unknown"),📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Build lookup table from worker data (avoid subshells in loop) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| declare -A window_counts=() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| declare -A window_emojis=() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n "$worker_data" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while IFS=$'\t' read -r wname wcount wemoji; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [[ -z "$wname" ]] && continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| window_counts["$wname"]="$wcount" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| window_emojis["$wname"]="$wemoji" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done <<< "$worker_data" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # If tmux is available, render with live window info | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$has_tmux" == "true" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while IFS=$'\t' read -r window_index window_name window_active; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [[ -z "$window_index" ]] && continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| count="${window_counts[$window_name]:-}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emoji="${window_emojis[$window_name]:-}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Build enriched label: name ×count emoji | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| label="${window_name}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n "$count" && "$count" -gt 0 ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| label+=" ×${count}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n "$emoji" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| label+=" ${emoji}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$window_active" == "1" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output+="#[bg=#7b2ff7,fg=#e0e0e0,bold] ${label} #[bg=#16213e,fg=#7b2ff7] " | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output+="#[fg=#b8a9c9,bg=#16213e] ${label} " | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done < <(tmux list-windows -t "$session_name" -F "#{window_index} #{window_name} #{window_active}" 2>/dev/null) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo -n "$output" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # No tmux available (testing mode): render from workers.json data only | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for wname in "${!window_counts[@]}"; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| count="${window_counts[$wname]}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emoji="${window_emojis[$wname]:-}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| label="${wname}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n "$count" && "$count" -gt 0 ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| label+=" ×${count}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n "$emoji" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| label+=" ${emoji}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output+="#[fg=#b8a9c9,bg=#16213e] ${label} " | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo -n "$output" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,24 +45,34 @@ setw -g mode-style "bg=#7b2ff7,fg=#e0e0e0" | |
| setw -g clock-mode-colour "#7b2ff7" | ||
|
|
||
| # ============================================================================ | ||
| # STATUS BAR | ||
| # STATUS BAR — Dual bar (tmux 3.2+) with fallback | ||
| # ============================================================================ | ||
| set -g status on | ||
| set -g status-interval 5 | ||
| set -g status-position top | ||
| set -g status-justify left | ||
| set -g status-style "bg=#1a1a2e,fg=#e0e0e0" | ||
|
|
||
| # --- Left: Genie branding + version --- | ||
| # --- Status bar height: 2 lines on tmux >= 3.2, 1 line otherwise --- | ||
| # The if-shell at the bottom of this file handles the fallback. | ||
| # Default to 2 (overridden by if-shell on old tmux). | ||
| set -g status 2 | ||
|
|
||
| # --- Top bar (status-format[0]): branding + project tabs + system info --- | ||
| set -g status-format[0] "#[align=left,bg=#1a1a2e]#[bg=#7b2ff7,fg=#e0e0e0,bold] #(genie --version 2>/dev/null | head -1 || echo 'Genie') #[bg=#1a1a2e,fg=#7b2ff7] #($HOME/.genie/scripts/genie-projects.sh)#[align=right]#[fg=#6c6c8a]#($HOME/.genie/scripts/genie-git.sh) #[fg=#0f3460]| #[fg=#00d2ff]CPU #($HOME/.genie/scripts/cpu-info.sh) #[fg=#0f3460]| #[fg=#00d2ff]RAM #($HOME/.genie/scripts/ram-info.sh) #[fg=#0f3460]| #[fg=#e0e0e0]%H:%M " | ||
|
|
||
| # --- Bottom bar (status-format[1]): task window tabs for active session --- | ||
| set -g status-format[1] "#[align=left,bg=#16213e] #($HOME/.genie/scripts/genie-tasks.sh #{session_name}) " | ||
|
|
||
| # --- Legacy single-line fallback values (used when dual status is unavailable) --- | ||
| set -g status-left-length 60 | ||
| set -g status-left "#[bg=#7b2ff7,fg=#e0e0e0,bold] #(genie --version 2>/dev/null | head -1 || echo 'Genie') #[bg=#1a1a2e,fg=#7b2ff7]" | ||
|
|
||
| # --- Right: git | CPU | RAM | clock --- | ||
| set -g status-right-length 120 | ||
| set -g status-right "#[fg=#6c6c8a]#($HOME/.genie/scripts/genie-git.sh) #[fg=#0f3460]| #[fg=#00d2ff]CPU #($HOME/.genie/scripts/cpu-info.sh) #[fg=#0f3460]| #[fg=#00d2ff]RAM #($HOME/.genie/scripts/ram-info.sh) #[fg=#0f3460]| #[fg=#e0e0e0]%H:%M " | ||
|
|
||
| # ============================================================================ | ||
| # WINDOW (TAB) STYLING — clickable tabs | ||
| # WINDOW (TAB) STYLING — clickable tabs (used by bottom bar in dual mode, | ||
| # or as main tabs in single-bar fallback) | ||
| # ============================================================================ | ||
|
|
||
| # Tab separator | ||
|
|
@@ -80,14 +90,16 @@ set -g visual-activity off | |
| set -g window-status-activity-style "fg=#f5a623,bg=#1a1a2e" | ||
|
|
||
| # ============================================================================ | ||
| # SECOND STATUS LINE — bottom tab bar (tmux 3.2+) | ||
| # VERSION GUARD — fallback for tmux < 3.2 (no dual status bar support) | ||
| # ============================================================================ | ||
| # Uncomment the following for a dual status bar (requires tmux 3.2+): | ||
| # set -g status 2 | ||
| # set -g status-format[1] "#[align=centre,fg=#6c6c8a,bg=#16213e] #($HOME/.genie/scripts/genie-update-check.sh) " | ||
| # tmux < 3.2 gets single bar. tmux >= 3.2 keeps dual bar (status-format[0..1]). | ||
| # Check major/minor explicitly; tmux 3.0/3.1 report status-format support as unavailable. | ||
| if-shell 'tmux -V | sed -nE "s/^tmux ([0-9]+)\\.([0-9]+).*/\\1 \\2/" | awk "{exit !($1 > 3 || ($1 == 3 && $2 >= 2))}"' \ | ||
| 'set -g status 2' \ | ||
| 'set -g status on' | ||
|
Comment on lines
+97
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, let me check the actual file content to understand the context better
cat -n scripts/tmux/genie.tmux.conf | sed -n '95,115p'Repository: automagik-dev/genie Length of output: 1095 🌐 Web query:
💡 Result: The tmux version output format on OpenBSD, obtained by running tmux -V, is a string in the form "openbsd-X.Y" where X.Y corresponds to the OpenBSD release version (e.g., "openbsd-6.8" on OpenBSD 6.8). This differs from portable tmux versions, which output "tmux 3.3a" style numbers. The OpenBSD man page confirms the -V flag "Report the tmux version." As of 2026-03-17, OpenBSD current likely uses a format like "openbsd-7.6" or newer, based on ongoing development. Citations:
🌐 Web query:
💡 Result: tmux status-format support was introduced in tmux 2.9. It is an array option that configures the format of each line in a multi-line status bar (when status is set to 2, 3, 4, or 5). The default status-format references existing status-* options like status-left, window-status-format, and status-right. Prior to 2.9, the status bar was configured using individual options such as status-left, status-right, window-status-format, and window-status-current-format, which supported format expansions (#[...] and #{...}). status-format enables per-line customization for multi-line status bars and full configuration using expanded formats and styles. Examples from documentation: - set -g status 2 - set -g status-format[0] '#[align=left] #{status-left}' - set -g status-format[1] '#[align=centre] #{window-list}' - set -g status-format[2] '#[align=right] #{status-right}' It has been available and unchanged in all subsequent versions up to the latest (3.4+ as of 2024), with ongoing format enhancements like mathematical operations in 3.2. Citations:
Fix the tmux version gate.
Parse both version formats or probe the 🤖 Prompt for AI Agents |
||
|
|
||
| # ============================================================================ | ||
| # KEYBINDINGS (standard — no changes from defaults beyond vi mode) | ||
| # KEYBINDINGS | ||
| # ============================================================================ | ||
|
|
||
| # Reload config | ||
|
|
@@ -96,3 +108,8 @@ bind r source-file ~/.tmux.conf \; display-message "Config reloaded" | |
| # Vi copy mode bindings | ||
| bind -T copy-mode-vi v send-keys -X begin-selection | ||
| bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel | ||
|
|
||
| # --- Session switching (project tabs) --- | ||
| # Ctrl+) / Ctrl+( — switch between project sessions | ||
| bind -n C-) switch-client -n | ||
| bind -n C-( switch-client -p | ||
|
Comment on lines
+112
to
+115
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, let's examine the file and understand the context
cat -n scripts/tmux/genie.tmux.conf | sed -n '100,125p'Repository: automagik-dev/genie Length of output: 726 🏁 Script executed: # Check if there are other key bindings in the file for reference
rg "bind -n" scripts/tmux/genie.tmux.conf -nRepository: automagik-dev/genie Length of output: 128 🌐 Web query:
💡 Result: Tmux key binding portability for C-), shifted keys, and extended-key support is limited by terminal capabilities and tmux configuration. C-) (Ctrl + )) is not portable without extended keys. The ) key is ASCII 0x29, Ctrl+) would ideally be 0x09 (Tab), but terminals typically send the same sequence for Ctrl+) as Tab, making distinct binding impossible without extended key support. No sources explicitly mention binding C-); similar keys like C-/, C-', C-! are unsupported traditionally as terminals do not send unique sequences ({1,15,16}). Shifted keys (e.g., S-a becomes A): Tmux uses uppercase or alternate names (e.g., no S-a, use A; S-Tab is BTab). For ASCII, Shift sends the shifted character; tmux treats it as such, ignoring layout. S- prefix used for function keys like S-Left. Binding shifted ASCII is not distinct from unshifted uppercase without extended keys ({1}). Extended-key support (tmux 2.4+, improved in 3.x): Enables binding Ctrl/Shift on more keys (e.g., C-1, C-., C-^) via modifyOtherKeys or CSI u sequences from terminals like xterm, mintty, iTerm2, foot. Configure with set -g extended-keys on|always or set -as terminal-features 'xterm*:extkeys' for auto-detection. Tmux recognizes extended sequences for bindings and forwards to inner apps if they request (or always mode). Portability issues: Terminal must support (check with cat outside/inside tmux); mismatches cause failures. Shifted uppercase may require binding as C-S-O not C-S-o ({1,3,5,7,17}). Test bindings with bind C-1 lsk and press key; use cat to verify sequences ({1}). For portability: Use extended-keys on, ensure TERM correct (e.g., xterm-256color), test per-terminal with cat(1). Not all terminals agree on sequences; xterm is reference ({1}). Citations:
🏁 Script executed: # Check if extended-keys is configured in the file
rg "extended-keys" scripts/tmux/genie.tmux.confRepository: automagik-dev/genie Length of output: 45 🏁 Script executed: # Check what other Alt/Meta bindings exist for reference
rg "bind -n M-" scripts/tmux/genie.tmux.confRepository: automagik-dev/genie Length of output: 45 Use a portable session-switch binding.
🤖 Prompt for AI Agents |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Coverage parsing is fragile — depends on exact
bun test --coverageoutput format.If Bun changes the coverage table format, this grep/awk chain will silently fail. Consider adding a fallback or documenting the expected format.
🤖 Prompt for AI Agents