aether-colony 1.1.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/.aether/CONTEXT.md +160 -0
- package/.aether/QUEEN.md +84 -0
- package/.aether/aether-utils.sh +7749 -0
- package/.aether/docs/QUEEN-SYSTEM.md +211 -0
- package/.aether/docs/README.md +68 -0
- package/.aether/docs/caste-system.md +48 -0
- package/.aether/docs/disciplines/DISCIPLINES.md +93 -0
- package/.aether/docs/disciplines/coding-standards.md +197 -0
- package/.aether/docs/disciplines/debugging.md +207 -0
- package/.aether/docs/disciplines/learning.md +254 -0
- package/.aether/docs/disciplines/tdd.md +257 -0
- package/.aether/docs/disciplines/verification-loop.md +167 -0
- package/.aether/docs/disciplines/verification.md +116 -0
- package/.aether/docs/error-codes.md +268 -0
- package/.aether/docs/known-issues.md +233 -0
- package/.aether/docs/pheromones.md +205 -0
- package/.aether/docs/queen-commands.md +97 -0
- package/.aether/exchange/colony-registry.xml +11 -0
- package/.aether/exchange/pheromone-xml.sh +575 -0
- package/.aether/exchange/pheromones.xml +87 -0
- package/.aether/exchange/queen-wisdom.xml +14 -0
- package/.aether/exchange/registry-xml.sh +273 -0
- package/.aether/exchange/wisdom-xml.sh +319 -0
- package/.aether/midden/approach-changes.md +5 -0
- package/.aether/midden/build-failures.md +5 -0
- package/.aether/midden/test-failures.md +5 -0
- package/.aether/model-profiles.yaml +100 -0
- package/.aether/rules/aether-colony.md +134 -0
- package/.aether/schemas/aether-types.xsd +255 -0
- package/.aether/schemas/colony-registry.xsd +309 -0
- package/.aether/schemas/example-prompt-builder.xml +234 -0
- package/.aether/schemas/pheromone.xsd +163 -0
- package/.aether/schemas/prompt.xsd +416 -0
- package/.aether/schemas/queen-wisdom.xsd +325 -0
- package/.aether/schemas/worker-priming.xsd +276 -0
- package/.aether/templates/QUEEN.md.template +79 -0
- package/.aether/templates/colony-state-reset.jq.template +22 -0
- package/.aether/templates/colony-state.template.json +35 -0
- package/.aether/templates/constraints.template.json +9 -0
- package/.aether/templates/crowned-anthill.template.md +36 -0
- package/.aether/templates/handoff-build-error.template.md +30 -0
- package/.aether/templates/handoff-build-success.template.md +39 -0
- package/.aether/templates/handoff.template.md +40 -0
- package/.aether/templates/learning-observations.template.json +6 -0
- package/.aether/templates/midden.template.json +7 -0
- package/.aether/templates/pheromones.template.json +6 -0
- package/.aether/templates/session.template.json +9 -0
- package/.aether/utils/atomic-write.sh +219 -0
- package/.aether/utils/chamber-compare.sh +193 -0
- package/.aether/utils/chamber-utils.sh +297 -0
- package/.aether/utils/colorize-log.sh +132 -0
- package/.aether/utils/error-handler.sh +212 -0
- package/.aether/utils/file-lock.sh +158 -0
- package/.aether/utils/queen-to-md.xsl +395 -0
- package/.aether/utils/semantic-cli.sh +413 -0
- package/.aether/utils/spawn-tree.sh +428 -0
- package/.aether/utils/spawn-with-model.sh +56 -0
- package/.aether/utils/state-loader.sh +215 -0
- package/.aether/utils/swarm-display.sh +268 -0
- package/.aether/utils/watch-spawn-tree.sh +253 -0
- package/.aether/utils/xml-compose.sh +253 -0
- package/.aether/utils/xml-convert.sh +273 -0
- package/.aether/utils/xml-core.sh +186 -0
- package/.aether/utils/xml-query.sh +201 -0
- package/.aether/utils/xml-utils.sh +110 -0
- package/.aether/workers.md +765 -0
- package/.claude/agents/ant/aether-ambassador.md +264 -0
- package/.claude/agents/ant/aether-archaeologist.md +322 -0
- package/.claude/agents/ant/aether-auditor.md +266 -0
- package/.claude/agents/ant/aether-builder.md +187 -0
- package/.claude/agents/ant/aether-chaos.md +268 -0
- package/.claude/agents/ant/aether-chronicler.md +304 -0
- package/.claude/agents/ant/aether-gatekeeper.md +325 -0
- package/.claude/agents/ant/aether-includer.md +373 -0
- package/.claude/agents/ant/aether-keeper.md +271 -0
- package/.claude/agents/ant/aether-measurer.md +317 -0
- package/.claude/agents/ant/aether-probe.md +210 -0
- package/.claude/agents/ant/aether-queen.md +325 -0
- package/.claude/agents/ant/aether-route-setter.md +173 -0
- package/.claude/agents/ant/aether-sage.md +353 -0
- package/.claude/agents/ant/aether-scout.md +142 -0
- package/.claude/agents/ant/aether-surveyor-disciplines.md +416 -0
- package/.claude/agents/ant/aether-surveyor-nest.md +354 -0
- package/.claude/agents/ant/aether-surveyor-pathogens.md +288 -0
- package/.claude/agents/ant/aether-surveyor-provisions.md +359 -0
- package/.claude/agents/ant/aether-tracker.md +265 -0
- package/.claude/agents/ant/aether-watcher.md +244 -0
- package/.claude/agents/ant/aether-weaver.md +247 -0
- package/.claude/commands/ant/archaeology.md +341 -0
- package/.claude/commands/ant/build.md +1160 -0
- package/.claude/commands/ant/chaos.md +349 -0
- package/.claude/commands/ant/colonize.md +270 -0
- package/.claude/commands/ant/continue.md +1070 -0
- package/.claude/commands/ant/council.md +309 -0
- package/.claude/commands/ant/dream.md +265 -0
- package/.claude/commands/ant/entomb.md +487 -0
- package/.claude/commands/ant/feedback.md +78 -0
- package/.claude/commands/ant/flag.md +139 -0
- package/.claude/commands/ant/flags.md +155 -0
- package/.claude/commands/ant/focus.md +58 -0
- package/.claude/commands/ant/help.md +122 -0
- package/.claude/commands/ant/history.md +137 -0
- package/.claude/commands/ant/init.md +409 -0
- package/.claude/commands/ant/interpret.md +267 -0
- package/.claude/commands/ant/lay-eggs.md +201 -0
- package/.claude/commands/ant/maturity.md +102 -0
- package/.claude/commands/ant/memory-details.md +77 -0
- package/.claude/commands/ant/migrate-state.md +165 -0
- package/.claude/commands/ant/oracle.md +387 -0
- package/.claude/commands/ant/organize.md +227 -0
- package/.claude/commands/ant/pause-colony.md +247 -0
- package/.claude/commands/ant/phase.md +126 -0
- package/.claude/commands/ant/plan.md +544 -0
- package/.claude/commands/ant/redirect.md +58 -0
- package/.claude/commands/ant/resume-colony.md +182 -0
- package/.claude/commands/ant/resume.md +363 -0
- package/.claude/commands/ant/seal.md +306 -0
- package/.claude/commands/ant/status.md +272 -0
- package/.claude/commands/ant/swarm.md +361 -0
- package/.claude/commands/ant/tunnels.md +425 -0
- package/.claude/commands/ant/update.md +209 -0
- package/.claude/commands/ant/verify-castes.md +95 -0
- package/.claude/commands/ant/watch.md +238 -0
- package/.opencode/agents/aether-ambassador.md +140 -0
- package/.opencode/agents/aether-archaeologist.md +108 -0
- package/.opencode/agents/aether-auditor.md +144 -0
- package/.opencode/agents/aether-builder.md +184 -0
- package/.opencode/agents/aether-chaos.md +115 -0
- package/.opencode/agents/aether-chronicler.md +122 -0
- package/.opencode/agents/aether-gatekeeper.md +116 -0
- package/.opencode/agents/aether-includer.md +117 -0
- package/.opencode/agents/aether-keeper.md +177 -0
- package/.opencode/agents/aether-measurer.md +128 -0
- package/.opencode/agents/aether-probe.md +133 -0
- package/.opencode/agents/aether-queen.md +286 -0
- package/.opencode/agents/aether-route-setter.md +130 -0
- package/.opencode/agents/aether-sage.md +106 -0
- package/.opencode/agents/aether-scout.md +101 -0
- package/.opencode/agents/aether-surveyor-disciplines.md +386 -0
- package/.opencode/agents/aether-surveyor-nest.md +324 -0
- package/.opencode/agents/aether-surveyor-pathogens.md +259 -0
- package/.opencode/agents/aether-surveyor-provisions.md +329 -0
- package/.opencode/agents/aether-tracker.md +137 -0
- package/.opencode/agents/aether-watcher.md +174 -0
- package/.opencode/agents/aether-weaver.md +130 -0
- package/.opencode/commands/ant/archaeology.md +338 -0
- package/.opencode/commands/ant/build.md +1200 -0
- package/.opencode/commands/ant/chaos.md +346 -0
- package/.opencode/commands/ant/colonize.md +202 -0
- package/.opencode/commands/ant/continue.md +938 -0
- package/.opencode/commands/ant/council.md +305 -0
- package/.opencode/commands/ant/dream.md +262 -0
- package/.opencode/commands/ant/entomb.md +367 -0
- package/.opencode/commands/ant/feedback.md +80 -0
- package/.opencode/commands/ant/flag.md +137 -0
- package/.opencode/commands/ant/flags.md +153 -0
- package/.opencode/commands/ant/focus.md +56 -0
- package/.opencode/commands/ant/help.md +124 -0
- package/.opencode/commands/ant/history.md +127 -0
- package/.opencode/commands/ant/init.md +337 -0
- package/.opencode/commands/ant/interpret.md +256 -0
- package/.opencode/commands/ant/lay-eggs.md +141 -0
- package/.opencode/commands/ant/maturity.md +92 -0
- package/.opencode/commands/ant/memory-details.md +77 -0
- package/.opencode/commands/ant/migrate-state.md +153 -0
- package/.opencode/commands/ant/oracle.md +338 -0
- package/.opencode/commands/ant/organize.md +224 -0
- package/.opencode/commands/ant/pause-colony.md +220 -0
- package/.opencode/commands/ant/phase.md +123 -0
- package/.opencode/commands/ant/plan.md +531 -0
- package/.opencode/commands/ant/redirect.md +67 -0
- package/.opencode/commands/ant/resume-colony.md +178 -0
- package/.opencode/commands/ant/resume.md +363 -0
- package/.opencode/commands/ant/seal.md +247 -0
- package/.opencode/commands/ant/status.md +272 -0
- package/.opencode/commands/ant/swarm.md +357 -0
- package/.opencode/commands/ant/tunnels.md +406 -0
- package/.opencode/commands/ant/update.md +191 -0
- package/.opencode/commands/ant/verify-castes.md +85 -0
- package/.opencode/commands/ant/watch.md +220 -0
- package/.opencode/opencode.json +3 -0
- package/CHANGELOG.md +325 -0
- package/DISCLAIMER.md +74 -0
- package/LICENSE +21 -0
- package/README.md +258 -0
- package/bin/cli.js +2436 -0
- package/bin/generate-commands.sh +291 -0
- package/bin/lib/caste-colors.js +57 -0
- package/bin/lib/colors.js +76 -0
- package/bin/lib/errors.js +255 -0
- package/bin/lib/event-types.js +190 -0
- package/bin/lib/file-lock.js +695 -0
- package/bin/lib/init.js +454 -0
- package/bin/lib/logger.js +242 -0
- package/bin/lib/model-profiles.js +445 -0
- package/bin/lib/model-verify.js +288 -0
- package/bin/lib/nestmate-loader.js +130 -0
- package/bin/lib/proxy-health.js +253 -0
- package/bin/lib/spawn-logger.js +266 -0
- package/bin/lib/state-guard.js +602 -0
- package/bin/lib/state-sync.js +516 -0
- package/bin/lib/telemetry.js +441 -0
- package/bin/lib/update-transaction.js +1454 -0
- package/bin/npx-install.js +178 -0
- package/bin/sync-to-runtime.sh +6 -0
- package/bin/validate-package.sh +88 -0
- package/package.json +70 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Real-time swarm activity display
|
|
3
|
+
# Usage: bash swarm-display.sh [swarm_id]
|
|
4
|
+
|
|
5
|
+
SWARM_ID="${1:-current}"
|
|
6
|
+
DATA_DIR="${DATA_DIR:-.aether/data}"
|
|
7
|
+
DISPLAY_FILE="$DATA_DIR/swarm-display.json"
|
|
8
|
+
|
|
9
|
+
# ANSI colors (matching caste-colors.js)
|
|
10
|
+
BLUE='\033[34m'
|
|
11
|
+
GREEN='\033[32m'
|
|
12
|
+
YELLOW='\033[33m'
|
|
13
|
+
RED='\033[31m'
|
|
14
|
+
MAGENTA='\033[35m'
|
|
15
|
+
BOLD='\033[1m'
|
|
16
|
+
UNDERLINE='\033[4m'
|
|
17
|
+
DIM='\033[2m'
|
|
18
|
+
RESET='\033[0m'
|
|
19
|
+
|
|
20
|
+
# Caste colors (must match caste-colors.js)
|
|
21
|
+
get_caste_color() {
|
|
22
|
+
case "$1" in
|
|
23
|
+
builder) echo "$BLUE" ;;
|
|
24
|
+
watcher) echo "$GREEN" ;;
|
|
25
|
+
scout) echo "$YELLOW" ;;
|
|
26
|
+
chaos) echo "$RED" ;;
|
|
27
|
+
prime) echo "$MAGENTA" ;;
|
|
28
|
+
*) echo "$RESET" ;;
|
|
29
|
+
esac
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Caste emojis (must match aether-utils.sh)
|
|
33
|
+
get_caste_emoji() {
|
|
34
|
+
case "$1" in
|
|
35
|
+
builder) echo "🔨🐜" ;;
|
|
36
|
+
watcher) echo "👁️🐜" ;;
|
|
37
|
+
scout) echo "🔍🐜" ;;
|
|
38
|
+
chaos) echo "🎲🐜" ;;
|
|
39
|
+
prime) echo "👑🐜" ;;
|
|
40
|
+
*) echo "🐜" ;;
|
|
41
|
+
esac
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Animated status phrases
|
|
45
|
+
get_status_phrase() {
|
|
46
|
+
local caste="$1"
|
|
47
|
+
local idx=$(($(date +%s) % 4))
|
|
48
|
+
case "$caste" in
|
|
49
|
+
builder)
|
|
50
|
+
phrases=("excavating..." "building..." "forging..." "constructing...")
|
|
51
|
+
;;
|
|
52
|
+
watcher)
|
|
53
|
+
phrases=("observing..." "monitoring..." "watching..." "tracking...")
|
|
54
|
+
;;
|
|
55
|
+
scout)
|
|
56
|
+
phrases=("exploring..." "searching..." "investigating..." "probing...")
|
|
57
|
+
;;
|
|
58
|
+
chaos)
|
|
59
|
+
phrases=("disrupting..." "testing..." "probing..." "stressing...")
|
|
60
|
+
;;
|
|
61
|
+
*)
|
|
62
|
+
phrases=("working..." "foraging..." "excavating..." "tunneling...")
|
|
63
|
+
;;
|
|
64
|
+
esac
|
|
65
|
+
echo "${phrases[$idx]}"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
# Format tool usage: "📖5 🔍3 ✏️2 ⚡1"
|
|
69
|
+
format_tools() {
|
|
70
|
+
local read="${1:-0}"
|
|
71
|
+
local grep="${2:-0}"
|
|
72
|
+
local edit="${3:-0}"
|
|
73
|
+
local bash="${4:-0}"
|
|
74
|
+
local result=""
|
|
75
|
+
[[ "$read" -gt 0 ]] && result="${result}📖${read} "
|
|
76
|
+
[[ "$grep" -gt 0 ]] && result="${result}🔍${grep} "
|
|
77
|
+
[[ "$edit" -gt 0 ]] && result="${result}✏️${edit} "
|
|
78
|
+
[[ "$bash" -gt 0 ]] && result="${result}⚡${bash}"
|
|
79
|
+
echo "$result"
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# Format duration from seconds
|
|
83
|
+
format_duration() {
|
|
84
|
+
local seconds="${1:-0}"
|
|
85
|
+
if [[ "$seconds" -lt 60 ]]; then
|
|
86
|
+
echo "${seconds}s"
|
|
87
|
+
else
|
|
88
|
+
local mins=$((seconds / 60))
|
|
89
|
+
local secs=$((seconds % 60))
|
|
90
|
+
echo "${mins}m${secs}s"
|
|
91
|
+
fi
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Render progress bar
|
|
95
|
+
render_progress_bar() {
|
|
96
|
+
local percent="${1:-0}"
|
|
97
|
+
local width="${2:-20}"
|
|
98
|
+
|
|
99
|
+
# Clamp percent to 0-100
|
|
100
|
+
[[ "$percent" -lt 0 ]] && percent=0
|
|
101
|
+
[[ "$percent" -gt 100 ]] && percent=100
|
|
102
|
+
|
|
103
|
+
local filled=$((percent * width / 100))
|
|
104
|
+
local empty=$((width - filled))
|
|
105
|
+
|
|
106
|
+
local bar=""
|
|
107
|
+
for ((i=0; i<filled; i++)); do bar+="█"; done
|
|
108
|
+
for ((i=0; i<empty; i++)); do bar+="░"; done
|
|
109
|
+
|
|
110
|
+
echo "[$bar] $percent%"
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
# Get animated spinner
|
|
114
|
+
get_spinner() {
|
|
115
|
+
local spinners=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
|
|
116
|
+
local idx=$(($(date +%s) % 10))
|
|
117
|
+
echo "${spinners[$idx]}"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# Get excavation phrase based on progress
|
|
121
|
+
get_excavation_phrase() {
|
|
122
|
+
local caste="$1"
|
|
123
|
+
local progress="${2:-0}"
|
|
124
|
+
|
|
125
|
+
if [[ "$progress" -lt 25 ]]; then
|
|
126
|
+
echo "🚧 Starting excavation..."
|
|
127
|
+
elif [[ "$progress" -lt 50 ]]; then
|
|
128
|
+
echo "⛏️ Digging deeper..."
|
|
129
|
+
elif [[ "$progress" -lt 75 ]]; then
|
|
130
|
+
echo "🪨 Moving earth..."
|
|
131
|
+
elif [[ "$progress" -lt 100 ]]; then
|
|
132
|
+
echo "🏗️ Almost there..."
|
|
133
|
+
else
|
|
134
|
+
echo "✅ Excavation complete!"
|
|
135
|
+
fi
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# Render the swarm display
|
|
139
|
+
render_swarm() {
|
|
140
|
+
clear
|
|
141
|
+
|
|
142
|
+
# Header
|
|
143
|
+
echo -e "${BOLD}${MAGENTA}"
|
|
144
|
+
cat << 'EOF'
|
|
145
|
+
.-.
|
|
146
|
+
(o o) AETHER COLONY
|
|
147
|
+
| O | Swarm Activity
|
|
148
|
+
`-`
|
|
149
|
+
EOF
|
|
150
|
+
echo -e "${RESET}"
|
|
151
|
+
echo -e "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
|
|
152
|
+
echo ""
|
|
153
|
+
|
|
154
|
+
if [[ ! -f "$DISPLAY_FILE" ]]; then
|
|
155
|
+
echo -e "${DIM}Waiting for swarm activity...${RESET}"
|
|
156
|
+
echo ""
|
|
157
|
+
echo -e "${DIM}0 foragers excavating...${RESET}"
|
|
158
|
+
return
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
# Read swarm data
|
|
162
|
+
local swarm_data=$(cat "$DISPLAY_FILE" 2>/dev/null)
|
|
163
|
+
if [[ -z "$swarm_data" ]]; then
|
|
164
|
+
echo -e "${DIM}No active swarm data${RESET}"
|
|
165
|
+
return
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
# Check if we have active ants
|
|
169
|
+
local total_active=$(echo "$swarm_data" | jq -r '.summary.total_active // 0')
|
|
170
|
+
|
|
171
|
+
if [[ "$total_active" -eq 0 ]]; then
|
|
172
|
+
echo -e "${DIM}No active foragers${RESET}"
|
|
173
|
+
echo ""
|
|
174
|
+
echo -e "${DIM}0 foragers excavating...${RESET}"
|
|
175
|
+
return
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
# Render each active ant
|
|
179
|
+
echo "$swarm_data" | jq -r '.active_ants[] |
|
|
180
|
+
"\(.name)|\(.caste)|\(.status)|\(.task // "")|\(.tools.read // 0)|\(.tools.grep // 0)|\(.tools.edit // 0)|\(.tools.bash // 0)|\(.tokens // 0)|\(.started_at // "")|\(.parent // "Queen")|\(.progress // 0)"' 2>/dev/null | \
|
|
181
|
+
while IFS='|' read -r name caste status task read_count grep_count edit_count bash_count tokens started_at parent progress; do
|
|
182
|
+
color=$(get_caste_color "$caste")
|
|
183
|
+
emoji=$(get_caste_emoji "$caste")
|
|
184
|
+
phrase=$(get_status_phrase "$caste")
|
|
185
|
+
|
|
186
|
+
# Parent ants: bold + underline
|
|
187
|
+
if [[ "$parent" == "Queen" ]] || [[ "$parent" == "Prime"* ]]; then
|
|
188
|
+
style="${BOLD}${UNDERLINE}"
|
|
189
|
+
else
|
|
190
|
+
style="${BOLD}"
|
|
191
|
+
fi
|
|
192
|
+
|
|
193
|
+
# Format tools
|
|
194
|
+
tools_str=$(format_tools "$read_count" "$grep_count" "$edit_count" "$bash_count")
|
|
195
|
+
|
|
196
|
+
# Calculate elapsed time
|
|
197
|
+
elapsed_str=""
|
|
198
|
+
if [[ -n "$started_at" ]]; then
|
|
199
|
+
started_ts=$(date -j -f "%Y-%m-%dT%H:%M:%SZ" "$started_at" +%s 2>/dev/null || date -d "$started_at" +%s 2>/dev/null || echo "0")
|
|
200
|
+
now_ts=$(date +%s)
|
|
201
|
+
elapsed=$((now_ts - started_ts))
|
|
202
|
+
if [[ $elapsed -gt 0 ]]; then
|
|
203
|
+
elapsed_str="${DIM}($(format_duration $elapsed))${RESET}"
|
|
204
|
+
fi
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
# Trophallaxis (token) indicator
|
|
208
|
+
token_str=""
|
|
209
|
+
if [[ "$tokens" -gt 0 ]]; then
|
|
210
|
+
token_str="${DIM}🍯${tokens}${RESET}"
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
# Truncate task if too long
|
|
214
|
+
display_task="$task"
|
|
215
|
+
[[ ${#display_task} -gt 35 ]] && display_task="${display_task:0:32}..."
|
|
216
|
+
|
|
217
|
+
# Output line: "🔨 Builder: excavating... Implement auth 📖5 🔍3 (2m3s) 🍯1250"
|
|
218
|
+
echo -e "${color}${emoji} ${style}${name}${RESET}${color}: ${phrase}${RESET} ${display_task}"
|
|
219
|
+
echo -e " ${tools_str} ${elapsed_str} ${token_str}"
|
|
220
|
+
|
|
221
|
+
# Show progress bar if progress > 0
|
|
222
|
+
if [[ "$progress" -gt 0 ]]; then
|
|
223
|
+
progress_bar=$(render_progress_bar "$progress" 15)
|
|
224
|
+
excavation_phrase=$(get_excavation_phrase "$caste" "$progress")
|
|
225
|
+
echo -e " ${DIM}${progress_bar}${RESET}"
|
|
226
|
+
echo -e " ${DIM}$(get_spinner) ${excavation_phrase}${RESET}"
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
echo ""
|
|
230
|
+
done
|
|
231
|
+
|
|
232
|
+
# Chamber activity map (VIZ-07)
|
|
233
|
+
echo -e "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
|
|
234
|
+
echo ""
|
|
235
|
+
echo -e "${BOLD}Chamber Activity:${RESET}"
|
|
236
|
+
|
|
237
|
+
# Show active chambers with fire intensity
|
|
238
|
+
echo "$swarm_data" | jq -r '.chambers | to_entries[] | "\(.key)|\(.value.activity)|\(.value.icon)"' 2>/dev/null | \
|
|
239
|
+
while IFS='|' read -r chamber activity icon; do
|
|
240
|
+
if [[ "$activity" -gt 0 ]]; then
|
|
241
|
+
# Fire intensity based on activity count
|
|
242
|
+
if [[ "$activity" -ge 5 ]]; then
|
|
243
|
+
fires="🔥🔥🔥"
|
|
244
|
+
elif [[ "$activity" -ge 3 ]]; then
|
|
245
|
+
fires="🔥🔥"
|
|
246
|
+
else
|
|
247
|
+
fires="🔥"
|
|
248
|
+
fi
|
|
249
|
+
echo -e " ${icon} ${chamber//_/ } ${fires} (${activity} ants)"
|
|
250
|
+
fi
|
|
251
|
+
done
|
|
252
|
+
|
|
253
|
+
# Summary line (VIZ-06: ant-themed presentation)
|
|
254
|
+
echo ""
|
|
255
|
+
echo -e "${DIM}${total_active} forager$([[ "$total_active" -eq 1 ]] || echo "s") excavating...${RESET}"
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
# Main loop with file watching
|
|
259
|
+
render_swarm
|
|
260
|
+
|
|
261
|
+
if command -v fswatch &>/dev/null; then
|
|
262
|
+
fswatch -o "$DISPLAY_FILE" 2>/dev/null | while read; do render_swarm; done
|
|
263
|
+
elif command -v inotifywait &>/dev/null; then
|
|
264
|
+
while inotifywait -q -e modify "$DISPLAY_FILE" 2>/dev/null; do render_swarm; done
|
|
265
|
+
else
|
|
266
|
+
# Fallback: poll every 2 seconds
|
|
267
|
+
while true; do sleep 2; render_swarm; done
|
|
268
|
+
fi
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Live spawn tree visualization for tmux watch pane
|
|
3
|
+
# Usage: bash watch-spawn-tree.sh [data_dir]
|
|
4
|
+
|
|
5
|
+
DATA_DIR="${1:-.aether/data}"
|
|
6
|
+
SPAWN_FILE="$DATA_DIR/spawn-tree.txt"
|
|
7
|
+
VIEW_STATE_FILE="$DATA_DIR/view-state.json"
|
|
8
|
+
|
|
9
|
+
# ANSI colors
|
|
10
|
+
YELLOW='\033[33m'
|
|
11
|
+
GREEN='\033[32m'
|
|
12
|
+
RED='\033[31m'
|
|
13
|
+
CYAN='\033[36m'
|
|
14
|
+
MAGENTA='\033[35m'
|
|
15
|
+
BOLD='\033[1m'
|
|
16
|
+
DIM='\033[2m'
|
|
17
|
+
RESET='\033[0m'
|
|
18
|
+
|
|
19
|
+
# Caste emojis
|
|
20
|
+
get_emoji() {
|
|
21
|
+
case "$1" in
|
|
22
|
+
builder) echo "🔨" ;;
|
|
23
|
+
watcher) echo "👁️ " ;;
|
|
24
|
+
scout) echo "🔍" ;;
|
|
25
|
+
colonizer) echo "🗺️ " ;;
|
|
26
|
+
architect) echo "🏛️ " ;;
|
|
27
|
+
prime) echo "👑" ;;
|
|
28
|
+
*) echo "🐜" ;;
|
|
29
|
+
esac
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Load view state
|
|
33
|
+
load_view_state() {
|
|
34
|
+
if [[ -f "$VIEW_STATE_FILE" ]]; then
|
|
35
|
+
cat "$VIEW_STATE_FILE" 2>/dev/null || echo '{}'
|
|
36
|
+
else
|
|
37
|
+
echo '{"tunnel_view":{"expanded":[],"collapsed":["__depth_3_plus__"],"default_expand_depth":2,"show_completed":true}}'
|
|
38
|
+
fi
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# Check if item is expanded
|
|
42
|
+
is_expanded() {
|
|
43
|
+
local item="$1"
|
|
44
|
+
local depth="${2:-1}"
|
|
45
|
+
local view_state=$(load_view_state)
|
|
46
|
+
|
|
47
|
+
# Check if explicitly expanded
|
|
48
|
+
if echo "$view_state" | jq -e ".tunnel_view.expanded | contains([\"$item\"])" >/dev/null 2>&1; then
|
|
49
|
+
return 0
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Check if depth-based auto-collapse applies
|
|
53
|
+
local default_depth=$(echo "$view_state" | jq -r '.tunnel_view.default_expand_depth // 2')
|
|
54
|
+
if [[ "$depth" -gt "$default_depth" ]]; then
|
|
55
|
+
# Check if __depth_3_plus__ is in collapsed (indicating auto-collapse enabled)
|
|
56
|
+
if echo "$view_state" | jq -e '.tunnel_view.collapsed | contains(["__depth_3_plus__"])' >/dev/null 2>&1; then
|
|
57
|
+
return 1 # Collapsed by depth
|
|
58
|
+
fi
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Check if explicitly collapsed
|
|
62
|
+
if echo "$view_state" | jq -e ".tunnel_view.collapsed | contains([\"$item\"])" >/dev/null 2>&1; then
|
|
63
|
+
return 1
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
return 0 # Default to expanded
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Status colors
|
|
70
|
+
get_status_color() {
|
|
71
|
+
case "$1" in
|
|
72
|
+
completed) echo "$GREEN" ;;
|
|
73
|
+
failed) echo "$RED" ;;
|
|
74
|
+
spawned) echo "$YELLOW" ;;
|
|
75
|
+
*) echo "$CYAN" ;;
|
|
76
|
+
esac
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
render_tree() {
|
|
80
|
+
clear
|
|
81
|
+
|
|
82
|
+
# Header
|
|
83
|
+
echo -e "${BOLD}${CYAN}"
|
|
84
|
+
cat << 'EOF'
|
|
85
|
+
.-.
|
|
86
|
+
(o o) AETHER COLONY
|
|
87
|
+
| O | Spawn Tree (Collapsible)
|
|
88
|
+
`-`
|
|
89
|
+
EOF
|
|
90
|
+
echo -e "${RESET}"
|
|
91
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
92
|
+
echo ""
|
|
93
|
+
|
|
94
|
+
# Always show Queen at depth 0
|
|
95
|
+
echo -e " ${BOLD}👑 Queen${RESET} ${DIM}(depth 0)${RESET}"
|
|
96
|
+
echo -e " ${DIM}│${RESET}"
|
|
97
|
+
|
|
98
|
+
if [[ ! -f "$SPAWN_FILE" ]]; then
|
|
99
|
+
echo -e " ${DIM}└── (no workers spawned yet)${RESET}"
|
|
100
|
+
return
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# Parse spawn tree file
|
|
104
|
+
# Format: timestamp|parent_id|child_caste|child_name|task_summary|status
|
|
105
|
+
declare -A workers
|
|
106
|
+
declare -A worker_status
|
|
107
|
+
declare -A worker_task
|
|
108
|
+
declare -A worker_caste
|
|
109
|
+
declare -a roots
|
|
110
|
+
|
|
111
|
+
while IFS='|' read -r ts parent caste name task status rest; do
|
|
112
|
+
[[ -z "$name" ]] && continue
|
|
113
|
+
|
|
114
|
+
# Check if this is a status update (only 4 fields)
|
|
115
|
+
if [[ -z "$task" && -n "$caste" ]]; then
|
|
116
|
+
# This is a status update: ts|name|status|summary
|
|
117
|
+
worker_status["$parent"]="$caste"
|
|
118
|
+
continue
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
workers["$name"]="$parent"
|
|
122
|
+
worker_caste["$name"]="$caste"
|
|
123
|
+
worker_task["$name"]="$task"
|
|
124
|
+
worker_status["$name"]="${status:-spawned}"
|
|
125
|
+
|
|
126
|
+
# Track root workers (spawned by Prime or Queen)
|
|
127
|
+
if [[ "$parent" == "Prime"* || "$parent" == "prime"* || "$parent" == "Queen" ]]; then
|
|
128
|
+
roots+=("$name")
|
|
129
|
+
fi
|
|
130
|
+
done < "$SPAWN_FILE"
|
|
131
|
+
|
|
132
|
+
# Render workers in tree structure
|
|
133
|
+
# Group by parent to show hierarchy
|
|
134
|
+
printed=()
|
|
135
|
+
|
|
136
|
+
# Function to render a worker and its children
|
|
137
|
+
render_worker() {
|
|
138
|
+
local name="$1"
|
|
139
|
+
local indent="$2"
|
|
140
|
+
local depth="$3"
|
|
141
|
+
local is_last="$4"
|
|
142
|
+
|
|
143
|
+
[[ " ${printed[*]} " =~ " $name " ]] && return
|
|
144
|
+
printed+=("$name")
|
|
145
|
+
|
|
146
|
+
emoji=$(get_emoji "${worker_caste[$name]}")
|
|
147
|
+
status="${worker_status[$name]}"
|
|
148
|
+
color=$(get_status_color "$status")
|
|
149
|
+
task="${worker_task[$name]}"
|
|
150
|
+
|
|
151
|
+
# Check if collapsed
|
|
152
|
+
local collapsed=false
|
|
153
|
+
local child_count=0
|
|
154
|
+
|
|
155
|
+
# Count children
|
|
156
|
+
for child in "${!workers[@]}"; do
|
|
157
|
+
if [[ "${workers[$child]}" == "$name" ]]; then
|
|
158
|
+
child_count=$((child_count + 1))
|
|
159
|
+
fi
|
|
160
|
+
done
|
|
161
|
+
|
|
162
|
+
# Check collapse state (only if has children)
|
|
163
|
+
if [[ $child_count -gt 0 ]] && ! is_expanded "$name" "$depth"; then
|
|
164
|
+
collapsed=true
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
# Truncate task for display
|
|
168
|
+
[[ ${#task} -gt 30 ]] && task="${task:0:27}..."
|
|
169
|
+
|
|
170
|
+
# Tree connectors
|
|
171
|
+
if [[ "$is_last" == "true" ]]; then
|
|
172
|
+
connector="└──"
|
|
173
|
+
else
|
|
174
|
+
connector="├──"
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
# Show expand/collapse indicator
|
|
178
|
+
local expand_indicator=""
|
|
179
|
+
if [[ $child_count -gt 0 ]]; then
|
|
180
|
+
if [[ "$collapsed" == "true" ]]; then
|
|
181
|
+
expand_indicator="▶ [$child_count hidden] "
|
|
182
|
+
else
|
|
183
|
+
expand_indicator="▼ "
|
|
184
|
+
fi
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
echo -e "${indent}${DIM}${connector}${RESET} ${emoji} ${color}${name}${RESET}: ${expand_indicator}${task} ${DIM}[depth $depth]${RESET}"
|
|
188
|
+
|
|
189
|
+
# Render children if not collapsed
|
|
190
|
+
if [[ "$collapsed" != "true" ]]; then
|
|
191
|
+
local children=()
|
|
192
|
+
for child in "${!workers[@]}"; do
|
|
193
|
+
if [[ "${workers[$child]}" == "$name" ]]; then
|
|
194
|
+
children+=("$child")
|
|
195
|
+
fi
|
|
196
|
+
done
|
|
197
|
+
|
|
198
|
+
local child_count=${#children[@]}
|
|
199
|
+
local child_idx=0
|
|
200
|
+
for child in "${children[@]}"; do
|
|
201
|
+
child_idx=$((child_idx + 1))
|
|
202
|
+
local child_is_last="false"
|
|
203
|
+
[[ $child_idx -eq $child_count ]] && child_is_last="true"
|
|
204
|
+
|
|
205
|
+
local child_indent="${indent} "
|
|
206
|
+
if [[ "$is_last" != "true" ]]; then
|
|
207
|
+
child_indent="${indent}${DIM}│${RESET} "
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
render_worker "$child" "$child_indent" $((depth + 1)) "$child_is_last"
|
|
211
|
+
done
|
|
212
|
+
fi
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
# Render root workers (spawned by Queen) at depth 1
|
|
216
|
+
local root_count=${#roots[@]}
|
|
217
|
+
local root_idx=0
|
|
218
|
+
for name in "${roots[@]}"; do
|
|
219
|
+
root_idx=$((root_idx + 1))
|
|
220
|
+
local is_last="false"
|
|
221
|
+
[[ $root_idx -eq $root_count ]] && is_last="true"
|
|
222
|
+
render_worker "$name" " " 1 "$is_last"
|
|
223
|
+
done
|
|
224
|
+
|
|
225
|
+
# Summary
|
|
226
|
+
echo ""
|
|
227
|
+
echo -e "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
|
|
228
|
+
completed=$(grep -c "completed" "$SPAWN_FILE" 2>/dev/null || echo "0")
|
|
229
|
+
active=$(grep -c "spawned" "$SPAWN_FILE" 2>/dev/null || echo "0")
|
|
230
|
+
echo -e "Workers: ${GREEN}$completed completed${RESET} | ${YELLOW}$active active${RESET}"
|
|
231
|
+
echo ""
|
|
232
|
+
echo -e "${DIM}Controls: e+<name> to expand, c+<name> to collapse${RESET}"
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
# Initial render
|
|
236
|
+
render_tree
|
|
237
|
+
|
|
238
|
+
# Watch for changes and re-render
|
|
239
|
+
if command -v fswatch &>/dev/null; then
|
|
240
|
+
fswatch -o "$SPAWN_FILE" 2>/dev/null | while read; do
|
|
241
|
+
render_tree
|
|
242
|
+
done
|
|
243
|
+
elif command -v inotifywait &>/dev/null; then
|
|
244
|
+
while inotifywait -q -e modify "$SPAWN_FILE" 2>/dev/null; do
|
|
245
|
+
render_tree
|
|
246
|
+
done
|
|
247
|
+
else
|
|
248
|
+
# Fallback: poll every 2 seconds
|
|
249
|
+
while true; do
|
|
250
|
+
sleep 2
|
|
251
|
+
render_tree
|
|
252
|
+
done
|
|
253
|
+
fi
|