aether-colony 1.1.5 → 1.1.9
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/aether-utils.sh +152 -53
- package/.aether/docs/command-playbooks/build-complete.md +0 -5
- package/.aether/docs/command-playbooks/build-context.md +5 -3
- package/.aether/docs/command-playbooks/build-full.md +14 -44
- package/.aether/docs/command-playbooks/build-prep.md +0 -6
- package/.aether/docs/command-playbooks/build-verify.md +13 -12
- package/.aether/docs/command-playbooks/build-wave.md +12 -31
- package/.aether/docs/command-playbooks/continue-finalize.md +28 -18
- package/.aether/docs/command-playbooks/continue-full.md +31 -44
- package/.aether/docs/command-playbooks/continue-gates.md +4 -16
- package/.aether/docs/command-playbooks/continue-verify.md +2 -16
- package/.aether/utils/atomic-write.sh +6 -6
- package/.aether/utils/file-lock.sh +52 -21
- package/.aether/workers.md +9 -1
- package/.claude/commands/ant/archaeology.md +0 -8
- package/.claude/commands/ant/chaos.md +0 -14
- package/.claude/commands/ant/colonize.md +0 -14
- package/.claude/commands/ant/council.md +0 -15
- package/.claude/commands/ant/dream.md +0 -17
- package/.claude/commands/ant/entomb.md +3 -15
- package/.claude/commands/ant/help.md +13 -0
- package/.claude/commands/ant/init.md +0 -22
- package/.claude/commands/ant/lay-eggs.md +0 -11
- package/.claude/commands/ant/maturity.md +11 -10
- package/.claude/commands/ant/oracle.md +0 -17
- package/.claude/commands/ant/organize.md +0 -22
- package/.claude/commands/ant/pause-colony.md +0 -15
- package/.claude/commands/ant/pheromones.md +0 -15
- package/.claude/commands/ant/plan.md +1 -37
- package/.claude/commands/ant/resume-colony.md +0 -15
- package/.claude/commands/ant/seal.md +26 -16
- package/.claude/commands/ant/swarm.md +10 -23
- package/.claude/commands/ant/update.md +56 -139
- package/.opencode/agents/aether-ambassador.md +1 -1
- package/.opencode/agents/aether-builder.md +2 -2
- package/.opencode/agents/aether-queen.md +1 -1
- package/.opencode/agents/aether-route-setter.md +1 -1
- package/.opencode/agents/aether-surveyor-disciplines.md +6 -1
- package/.opencode/agents/aether-surveyor-nest.md +6 -1
- package/.opencode/agents/aether-surveyor-pathogens.md +6 -1
- package/.opencode/agents/aether-surveyor-provisions.md +6 -1
- package/.opencode/agents/aether-tracker.md +1 -1
- package/.opencode/agents/aether-watcher.md +1 -1
- package/.opencode/agents/aether-weaver.md +1 -1
- package/.opencode/commands/ant/archaeology.md +0 -8
- package/.opencode/commands/ant/build.md +8 -62
- package/.opencode/commands/ant/chaos.md +0 -18
- package/.opencode/commands/ant/colonize.md +1 -18
- package/.opencode/commands/ant/continue.md +518 -62
- package/.opencode/commands/ant/council.md +0 -18
- package/.opencode/commands/ant/dream.md +0 -19
- package/.opencode/commands/ant/entomb.md +0 -18
- package/.opencode/commands/ant/init.md +0 -20
- package/.opencode/commands/ant/lay-eggs.md +0 -18
- package/.opencode/commands/ant/oracle.md +1 -24
- package/.opencode/commands/ant/pause-colony.md +0 -18
- package/.opencode/commands/ant/pheromones.md +8 -17
- package/.opencode/commands/ant/plan.md +2 -35
- package/.opencode/commands/ant/resume-colony.md +0 -18
- package/.opencode/commands/ant/seal.md +26 -18
- package/.opencode/commands/ant/swarm.md +0 -23
- package/.opencode/commands/ant/update.md +55 -131
- package/bin/cli.js +67 -2
- package/bin/lib/update-transaction.js +112 -3
- package/package.json +1 -1
package/.aether/aether-utils.sh
CHANGED
|
@@ -1078,7 +1078,14 @@ case "$cmd" in
|
|
|
1078
1078
|
HELP_EOF
|
|
1079
1079
|
;;
|
|
1080
1080
|
version)
|
|
1081
|
-
|
|
1081
|
+
# Read version from package.json if available, fallback to embedded
|
|
1082
|
+
_pkg_json="$SCRIPT_DIR/../package.json"
|
|
1083
|
+
if [[ -f "$_pkg_json" ]] && command -v jq >/dev/null 2>&1; then
|
|
1084
|
+
_ver=$(jq -r '.version // "unknown"' "$_pkg_json" 2>/dev/null)
|
|
1085
|
+
json_ok "\"$_ver\""
|
|
1086
|
+
else
|
|
1087
|
+
json_ok '"1.1.5"'
|
|
1088
|
+
fi
|
|
1082
1089
|
;;
|
|
1083
1090
|
validate-state)
|
|
1084
1091
|
# Schema migration helper: auto-upgrades pre-3.0 state files to v3.0
|
|
@@ -3428,6 +3435,22 @@ NODESCRIPT
|
|
|
3428
3435
|
|
|
3429
3436
|
[[ -z "$ant_name" || -z "$caste" || -z "$ant_status" ]] && json_err "$E_VALIDATION_FAILED" "Usage: swarm-display-update <ant_name> <caste> <ant_status> <task> [parent] [tools_json] [tokens] [chamber] [progress]"
|
|
3430
3437
|
|
|
3438
|
+
# Tolerate malformed argument ordering from LLM-generated commands.
|
|
3439
|
+
# Common failure mode: tools_json omitted, so tokens/chamber/progress shift left.
|
|
3440
|
+
tools_type=$(echo "$tools_json" | jq -r 'type' 2>/dev/null || echo "invalid")
|
|
3441
|
+
if [[ "$tools_type" != "object" ]]; then
|
|
3442
|
+
if [[ "$tools_json" =~ ^[0-9]+$ ]] && [[ ! "$tokens" =~ ^[0-9]+$ ]] && [[ "$chamber" =~ ^[0-9]+$ ]]; then
|
|
3443
|
+
progress="$chamber"
|
|
3444
|
+
chamber="$tokens"
|
|
3445
|
+
tokens="$tools_json"
|
|
3446
|
+
fi
|
|
3447
|
+
tools_json="{}"
|
|
3448
|
+
fi
|
|
3449
|
+
|
|
3450
|
+
# Ensure numeric fields are always valid for --argjson.
|
|
3451
|
+
[[ "$tokens" =~ ^-?[0-9]+$ ]] || tokens=0
|
|
3452
|
+
[[ "$progress" =~ ^-?[0-9]+$ ]] || progress=0
|
|
3453
|
+
|
|
3431
3454
|
display_file="$DATA_DIR/swarm-display.json"
|
|
3432
3455
|
|
|
3433
3456
|
# Initialize if doesn't exist
|
|
@@ -3489,7 +3512,7 @@ NODESCRIPT
|
|
|
3489
3512
|
# Update chamber activity counts
|
|
3490
3513
|
# Decrement old chamber if changed
|
|
3491
3514
|
(if $old_chamber != "" and $old_chamber != $new_chamber and has("chambers") and (.chambers | has($old_chamber)) then
|
|
3492
|
-
.chambers[$old_chamber].activity = [(.chambers[$old_chamber].activity // 1) - 1, 0] | max
|
|
3515
|
+
.chambers[$old_chamber].activity = ([(.chambers[$old_chamber].activity // 1) - 1, 0] | max)
|
|
3493
3516
|
else
|
|
3494
3517
|
.
|
|
3495
3518
|
end) |
|
|
@@ -6339,7 +6362,7 @@ $updated_meta
|
|
|
6339
6362
|
normalize-args)
|
|
6340
6363
|
# Normalize arguments from Claude Code ($ARGUMENTS) or OpenCode ($@)
|
|
6341
6364
|
# Usage: bash .aether/aether-utils.sh normalize-args [args...]
|
|
6342
|
-
#
|
|
6365
|
+
# Returns: a plain normalized argument string (safe for direct string parsing)
|
|
6343
6366
|
#
|
|
6344
6367
|
# Claude Code passes args in $ARGUMENTS variable
|
|
6345
6368
|
# OpenCode passes args in $@ (positional parameters)
|
|
@@ -6352,21 +6375,17 @@ $updated_meta
|
|
|
6352
6375
|
normalized="$ARGUMENTS"
|
|
6353
6376
|
# Fall back to OpenCode style ($@ positional params)
|
|
6354
6377
|
elif [ $# -gt 0 ]; then
|
|
6355
|
-
#
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
fi
|
|
6363
|
-
done
|
|
6364
|
-
# Trim leading space
|
|
6365
|
-
normalized="${normalized# }"
|
|
6378
|
+
# Join positional args into one parseable string without adding synthetic quotes
|
|
6379
|
+
normalized="$*"
|
|
6380
|
+
fi
|
|
6381
|
+
|
|
6382
|
+
# Collapse line breaks and repeated whitespace to avoid shell parse edge cases
|
|
6383
|
+
if [[ -n "$normalized" ]]; then
|
|
6384
|
+
normalized="$(printf '%s' "$normalized" | tr '\r\n' ' ' | sed 's/[[:space:]][[:space:]]*/ /g; s/^ //; s/ $//')"
|
|
6366
6385
|
fi
|
|
6367
6386
|
|
|
6368
6387
|
# Output normalized arguments
|
|
6369
|
-
|
|
6388
|
+
printf '%s\n' "$normalized"
|
|
6370
6389
|
exit 0
|
|
6371
6390
|
;;
|
|
6372
6391
|
|
|
@@ -6616,9 +6635,9 @@ $updated_meta
|
|
|
6616
6635
|
json_ok "{\"command\":\"$command_name\",\"cleared\":\"${cleared// /}\",\"errors\":\"${errors// /}\",\"dry_run\":$([[ "$dry_run" == "--dry-run" ]] && echo "true" || echo "false")}"
|
|
6617
6636
|
;;
|
|
6618
6637
|
|
|
6619
|
-
pheromone-export)
|
|
6620
|
-
# Export pheromones to eternal XML format
|
|
6621
|
-
# Usage: pheromone-export [input_json] [output_xml]
|
|
6638
|
+
pheromone-export-eternal)
|
|
6639
|
+
# Export pheromones to eternal XML format (distinct from xml-utils.sh pheromone-export function)
|
|
6640
|
+
# Usage: pheromone-export-eternal [input_json] [output_xml]
|
|
6622
6641
|
# input_json: Path to pheromones.json (default: .aether/data/pheromones.json)
|
|
6623
6642
|
# output_xml: Path to output XML (default: ~/.aether/eternal/pheromones.xml)
|
|
6624
6643
|
|
|
@@ -6719,9 +6738,9 @@ $updated_meta
|
|
|
6719
6738
|
|
|
6720
6739
|
# Generate ID and timestamps
|
|
6721
6740
|
pw_epoch=$(date +%s)
|
|
6722
|
-
|
|
6741
|
+
pw_rand=$(( RANDOM % 10000 ))
|
|
6723
6742
|
pw_type_lower=$(echo "$pw_type" | tr '[:upper:]' '[:lower:]')
|
|
6724
|
-
pw_id="sig_${pw_type_lower}_${
|
|
6743
|
+
pw_id="sig_${pw_type_lower}_${pw_epoch}_${pw_rand}"
|
|
6725
6744
|
pw_created=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
6726
6745
|
|
|
6727
6746
|
# Compute expires_at from TTL
|
|
@@ -7811,28 +7830,43 @@ $updated_meta
|
|
|
7811
7830
|
printf '%s\n' '{"version":"1.0.0","entries":[]}' > "$mw_midden_file"
|
|
7812
7831
|
fi
|
|
7813
7832
|
|
|
7814
|
-
# Create the new entry
|
|
7815
|
-
mw_new_entry=$(
|
|
7816
|
-
|
|
7817
|
-
"
|
|
7818
|
-
"
|
|
7819
|
-
"
|
|
7820
|
-
"
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
+
# Create the new entry using jq for safe JSON construction
|
|
7834
|
+
mw_new_entry=$(jq -n \
|
|
7835
|
+
--arg id "$mw_entry_id" \
|
|
7836
|
+
--arg ts "$mw_timestamp" \
|
|
7837
|
+
--arg cat "$mw_category" \
|
|
7838
|
+
--arg src "$mw_source" \
|
|
7839
|
+
--arg msg "$mw_message" \
|
|
7840
|
+
'{id: $id, timestamp: $ts, category: $cat, source: $src, message: $msg, reviewed: false}')
|
|
7841
|
+
|
|
7842
|
+
# Append to midden.json using jq with locking
|
|
7843
|
+
if acquire_lock "$mw_midden_file" 2>/dev/null; then
|
|
7844
|
+
mw_updated_midden=$(jq --argjson entry "$mw_new_entry" '
|
|
7845
|
+
.entries += [$entry] |
|
|
7846
|
+
.entry_count = (.entries | length)
|
|
7847
|
+
' "$mw_midden_file" 2>/dev/null)
|
|
7848
|
+
|
|
7849
|
+
if [[ -n "$mw_updated_midden" ]]; then
|
|
7850
|
+
printf '%s\n' "$mw_updated_midden" > "$mw_midden_file.tmp" && mv "$mw_midden_file.tmp" "$mw_midden_file"
|
|
7851
|
+
release_lock 2>/dev/null || true
|
|
7852
|
+
json_ok "{\"success\":true,\"entry_id\":\"$mw_entry_id\",\"category\":\"$mw_category\",\"midden_total\":$(jq '.entries | length' "$mw_midden_file" 2>/dev/null || echo 0)}"
|
|
7853
|
+
else
|
|
7854
|
+
release_lock 2>/dev/null || true
|
|
7855
|
+
json_ok "{\"success\":true,\"warning\":\"jq_processing_failed\",\"entry_id\":null}"
|
|
7856
|
+
fi
|
|
7833
7857
|
else
|
|
7834
|
-
#
|
|
7835
|
-
|
|
7858
|
+
# Lock failed — graceful degradation, try without lock
|
|
7859
|
+
mw_updated_midden=$(jq --argjson entry "$mw_new_entry" '
|
|
7860
|
+
.entries += [$entry] |
|
|
7861
|
+
.entry_count = (.entries | length)
|
|
7862
|
+
' "$mw_midden_file" 2>/dev/null)
|
|
7863
|
+
|
|
7864
|
+
if [[ -n "$mw_updated_midden" ]]; then
|
|
7865
|
+
printf '%s\n' "$mw_updated_midden" > "$mw_midden_file.tmp" && mv "$mw_midden_file.tmp" "$mw_midden_file"
|
|
7866
|
+
json_ok "{\"success\":true,\"entry_id\":\"$mw_entry_id\",\"category\":\"$mw_category\",\"warning\":\"lock_unavailable\"}"
|
|
7867
|
+
else
|
|
7868
|
+
json_ok "{\"success\":true,\"warning\":\"jq_processing_failed\",\"entry_id\":null}"
|
|
7869
|
+
fi
|
|
7836
7870
|
fi
|
|
7837
7871
|
;;
|
|
7838
7872
|
|
|
@@ -8543,7 +8577,7 @@ $updated_meta
|
|
|
8543
8577
|
session_file="$DATA_DIR/session.json"
|
|
8544
8578
|
baseline=$(git rev-parse HEAD 2>/dev/null || echo "")
|
|
8545
8579
|
|
|
8546
|
-
cat > "$session_file" << EOF
|
|
8580
|
+
cat > "$session_file.tmp" << EOF
|
|
8547
8581
|
{
|
|
8548
8582
|
"session_id": "$session_id",
|
|
8549
8583
|
"started_at": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
|
|
@@ -8560,15 +8594,16 @@ $updated_meta
|
|
|
8560
8594
|
"summary": "Session initialized"
|
|
8561
8595
|
}
|
|
8562
8596
|
EOF
|
|
8597
|
+
mv "$session_file.tmp" "$session_file"
|
|
8563
8598
|
json_ok "{\"session_id\":\"$session_id\",\"goal\":\"$goal\",\"file\":\"$session_file\"}"
|
|
8564
8599
|
;;
|
|
8565
8600
|
|
|
8566
8601
|
session-update)
|
|
8567
8602
|
# Update session with latest activity
|
|
8568
8603
|
# Usage: session-update <command> [suggested_next] [summary]
|
|
8569
|
-
cmd_run="${
|
|
8570
|
-
suggested="${
|
|
8571
|
-
summary="${
|
|
8604
|
+
cmd_run="${1:-}"
|
|
8605
|
+
suggested="${2:-}"
|
|
8606
|
+
summary="${3:-}"
|
|
8572
8607
|
|
|
8573
8608
|
session_file="$DATA_DIR/session.json"
|
|
8574
8609
|
|
|
@@ -8619,7 +8654,7 @@ EOF
|
|
|
8619
8654
|
.current_phase = $phase |
|
|
8620
8655
|
.current_milestone = $milestone |
|
|
8621
8656
|
.active_todos = $todos |
|
|
8622
|
-
.baseline_commit = $baseline' > "$session_file"
|
|
8657
|
+
.baseline_commit = $baseline' > "$session_file.tmp" && mv "$session_file.tmp" "$session_file"
|
|
8623
8658
|
|
|
8624
8659
|
json_ok "{\"updated\":true,\"command\":\"$cmd_run\"}"
|
|
8625
8660
|
;;
|
|
@@ -8640,7 +8675,9 @@ EOF
|
|
|
8640
8675
|
last_cmd_ts=$(echo "$session_data" | jq -r '.last_command_at // .started_at // empty')
|
|
8641
8676
|
if [[ -n "$last_cmd_ts" ]]; then
|
|
8642
8677
|
last_epoch=0 now_epoch=0
|
|
8643
|
-
last_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%SZ" "$last_cmd_ts" +%s 2>/dev/null
|
|
8678
|
+
last_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%SZ" "$last_cmd_ts" +%s 2>/dev/null \
|
|
8679
|
+
|| date -d "$last_cmd_ts" +%s 2>/dev/null \
|
|
8680
|
+
|| echo 0)
|
|
8644
8681
|
now_epoch=$(date +%s)
|
|
8645
8682
|
age_hours=$(( (now_epoch - last_epoch) / 3600 ))
|
|
8646
8683
|
[[ $age_hours -gt 24 ]] && is_stale=true || is_stale=false
|
|
@@ -8668,7 +8705,10 @@ EOF
|
|
|
8668
8705
|
exit 0
|
|
8669
8706
|
fi
|
|
8670
8707
|
|
|
8671
|
-
|
|
8708
|
+
# macOS uses -j -f, Linux uses -d
|
|
8709
|
+
last_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%SZ" "$last_cmd_ts" +%s 2>/dev/null \
|
|
8710
|
+
|| date -d "$last_cmd_ts" +%s 2>/dev/null \
|
|
8711
|
+
|| echo 0)
|
|
8672
8712
|
now_epoch=$(date +%s)
|
|
8673
8713
|
age_hours=$(( (now_epoch - last_epoch) / 3600 ))
|
|
8674
8714
|
|
|
@@ -8679,8 +8719,8 @@ EOF
|
|
|
8679
8719
|
fi
|
|
8680
8720
|
;;
|
|
8681
8721
|
|
|
8682
|
-
session-clear)
|
|
8683
|
-
# Mark session as cleared (preserves file but marks context_cleared)
|
|
8722
|
+
session-clear-context)
|
|
8723
|
+
# Mark session context as cleared (preserves file but marks context_cleared)
|
|
8684
8724
|
preserve="${2:-false}"
|
|
8685
8725
|
session_file="$DATA_DIR/session.json"
|
|
8686
8726
|
|
|
@@ -8799,18 +8839,77 @@ EOF
|
|
|
8799
8839
|
# ============================================
|
|
8800
8840
|
|
|
8801
8841
|
force-unlock)
|
|
8802
|
-
# Emergency lock cleanup —
|
|
8803
|
-
# Usage: force-unlock [--yes]
|
|
8842
|
+
# Emergency lock cleanup — remove all locks or stale-only locks
|
|
8843
|
+
# Usage: force-unlock [--yes] [--stale-only]
|
|
8804
8844
|
# Without --yes, lists locks and asks for confirmation in interactive mode
|
|
8805
8845
|
lock_dir="${AETHER_ROOT:-.}/.aether/locks"
|
|
8806
8846
|
auto_yes=false
|
|
8807
|
-
|
|
8847
|
+
stale_only=false
|
|
8848
|
+
|
|
8849
|
+
while [[ $# -gt 0 ]]; do
|
|
8850
|
+
case "$1" in
|
|
8851
|
+
--yes) auto_yes=true ;;
|
|
8852
|
+
--stale-only) stale_only=true ;;
|
|
8853
|
+
esac
|
|
8854
|
+
shift
|
|
8855
|
+
done
|
|
8808
8856
|
|
|
8809
8857
|
if [[ ! -d "$lock_dir" ]]; then
|
|
8810
8858
|
json_ok '{"removed":0,"message":"No locks directory found"}'
|
|
8811
8859
|
exit 0
|
|
8812
8860
|
fi
|
|
8813
8861
|
|
|
8862
|
+
if [[ "$stale_only" == "true" ]]; then
|
|
8863
|
+
lock_timeout="${LOCK_TIMEOUT:-300}"
|
|
8864
|
+
scanned=0
|
|
8865
|
+
removed=0
|
|
8866
|
+
skipped_live=0
|
|
8867
|
+
|
|
8868
|
+
is_lock_stale_for_cleanup() {
|
|
8869
|
+
local _lock_file="$1"
|
|
8870
|
+
local _pid_file="${_lock_file}.pid"
|
|
8871
|
+
local _pid
|
|
8872
|
+
_pid=$(cat "$_pid_file" 2>/dev/null || echo "")
|
|
8873
|
+
if [[ -z "$_pid" ]]; then
|
|
8874
|
+
_pid=$(cat "$_lock_file" 2>/dev/null || echo "")
|
|
8875
|
+
fi
|
|
8876
|
+
_pid=$(echo "$_pid" | tr -d '[:space:]')
|
|
8877
|
+
[[ "$_pid" =~ ^[0-9]+$ ]] || _pid=""
|
|
8878
|
+
|
|
8879
|
+
if [[ -n "$_pid" ]]; then
|
|
8880
|
+
kill -0 "$_pid" 2>/dev/null && return 1
|
|
8881
|
+
return 0
|
|
8882
|
+
fi
|
|
8883
|
+
|
|
8884
|
+
local _mtime=0
|
|
8885
|
+
if stat -f %m "$_lock_file" >/dev/null 2>&1; then
|
|
8886
|
+
_mtime=$(stat -f %m "$_lock_file" 2>/dev/null || echo 0)
|
|
8887
|
+
else
|
|
8888
|
+
_mtime=$(stat -c %Y "$_lock_file" 2>/dev/null || echo 0)
|
|
8889
|
+
fi
|
|
8890
|
+
local _age=$(( $(date +%s) - _mtime ))
|
|
8891
|
+
[[ "$_age" -gt "$lock_timeout" ]]
|
|
8892
|
+
}
|
|
8893
|
+
|
|
8894
|
+
for lock_file in "$lock_dir"/*.lock; do
|
|
8895
|
+
[[ -e "$lock_file" ]] || continue
|
|
8896
|
+
scanned=$((scanned + 1))
|
|
8897
|
+
if is_lock_stale_for_cleanup "$lock_file"; then
|
|
8898
|
+
rm -f "$lock_file" "${lock_file}.pid" 2>/dev/null || true
|
|
8899
|
+
removed=$((removed + 1))
|
|
8900
|
+
else
|
|
8901
|
+
skipped_live=$((skipped_live + 1))
|
|
8902
|
+
fi
|
|
8903
|
+
done
|
|
8904
|
+
|
|
8905
|
+
if [[ "$removed" -eq 0 && "$scanned" -eq 0 ]]; then
|
|
8906
|
+
json_ok '{"removed":0,"scanned":0,"skipped_live":0,"message":"No lock files found","mode":"stale-only"}'
|
|
8907
|
+
else
|
|
8908
|
+
json_ok "{\"removed\":$removed,\"scanned\":$scanned,\"skipped_live\":$skipped_live,\"message\":\"Stale locks cleared\",\"mode\":\"stale-only\"}"
|
|
8909
|
+
fi
|
|
8910
|
+
exit 0
|
|
8911
|
+
fi
|
|
8912
|
+
|
|
8814
8913
|
lock_files=$(find "$lock_dir" -name "*.lock" -o -name "*.lock.pid" 2>/dev/null)
|
|
8815
8914
|
|
|
8816
8915
|
if [[ -z "$lock_files" ]]; then
|
|
@@ -251,11 +251,6 @@ Note: This runs regardless of build success/failure. Failed builds may have reco
|
|
|
251
251
|
|
|
252
252
|
**This step runs ONLY after synthesis is complete. All values come from actual worker results.**
|
|
253
253
|
|
|
254
|
-
**Update swarm display state (always) and render (in-conversation):**
|
|
255
|
-
Run using the Bash tool with description "Recording build completion...": `bash .aether/aether-utils.sh swarm-display-update "Queen" "prime" "completed" "Phase {id} complete" "Colony" '{"read":10,"grep":5,"edit":5,"bash":2}' 100 "fungus_garden" 100`
|
|
256
|
-
|
|
257
|
-
If `visual_mode` is true, also run using the Bash tool with description "Rendering final swarm display...": `bash .aether/aether-utils.sh swarm-display-text "$build_id"`
|
|
258
|
-
|
|
259
254
|
**Display BUILD SUMMARY (always shown, replaces compact/verbose split):**
|
|
260
255
|
|
|
261
256
|
Calculate `total_tools` by summing `tool_count` from all worker return JSONs (builders + watcher + chaos).
|
|
@@ -127,7 +127,7 @@ log a warning and continue to Step 5.
|
|
|
127
127
|
|
|
128
128
|
Generate archaeologist name and dispatch:
|
|
129
129
|
Run using the Bash tool with description "Naming archaeologist...": `bash .aether/aether-utils.sh generate-ant-name "archaeologist"` (store as `{archaeologist_name}`)
|
|
130
|
-
Run using the Bash tool with description "Dispatching archaeologist...": `bash .aether/aether-utils.sh spawn-log "Queen" "scout" "{archaeologist_name}" "Pre-build archaeology scan"
|
|
130
|
+
Run using the Bash tool with description "Dispatching archaeologist...": `bash .aether/aether-utils.sh spawn-log "Queen" "scout" "{archaeologist_name}" "Pre-build archaeology scan"`
|
|
131
131
|
|
|
132
132
|
Display:
|
|
133
133
|
```
|
|
@@ -135,6 +135,8 @@ log a warning and continue to Step 5.
|
|
|
135
135
|
Scanning history of files to be modified...
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
+
> **Platform note**: In Claude Code, use `Task tool with subagent_type`. In OpenCode, use the equivalent agent spawning mechanism for your platform (e.g., invoke the agent definition from `.opencode/agents/`).
|
|
139
|
+
|
|
138
140
|
Spawn a Scout (using Task tool with `subagent_type="aether-archaeologist"`, include `description: "🏺 Archaeologist {archaeologist_name}: Pre-build history scan"`) with this prompt:
|
|
139
141
|
# FALLBACK: If "Agent type not found", use general-purpose and inject role: "You are an Archaeologist Ant - git historian that excavates why code exists."
|
|
140
142
|
|
|
@@ -164,8 +166,8 @@ log a warning and continue to Step 5.
|
|
|
164
166
|
|
|
165
167
|
**Wait for results** (blocking — use TaskOutput with `block: true`).
|
|
166
168
|
|
|
167
|
-
Log completion
|
|
168
|
-
Run using the Bash tool with description "Recording archaeologist findings...": `bash .aether/aether-utils.sh spawn-complete "{archaeologist_name}" "completed" "Pre-build archaeology scan"
|
|
169
|
+
Log completion:
|
|
170
|
+
Run using the Bash tool with description "Recording archaeologist findings...": `bash .aether/aether-utils.sh spawn-complete "{archaeologist_name}" "completed" "Pre-build archaeology scan"`
|
|
169
171
|
|
|
170
172
|
3. **Store and display findings:**
|
|
171
173
|
|
|
@@ -74,12 +74,6 @@ Do not touch during build:
|
|
|
74
74
|
- Other agents' config files (only modify files assigned to the current build task)
|
|
75
75
|
</read_only>
|
|
76
76
|
|
|
77
|
-
### Step 0: Version Check (Non-blocking)
|
|
78
|
-
|
|
79
|
-
Run using the Bash tool with description "Checking colony version...": `bash .aether/aether-utils.sh version-check-cached 2>/dev/null || true`
|
|
80
|
-
|
|
81
|
-
If the command succeeds and the JSON result contains a non-empty string, display it as a one-line notice. Proceed regardless of outcome.
|
|
82
|
-
|
|
83
77
|
### Step 0.6: Verify LiteLLM Proxy
|
|
84
78
|
|
|
85
79
|
Check that the LiteLLM proxy is running for model routing:
|
|
@@ -381,7 +375,7 @@ log a warning and continue to Step 5.
|
|
|
381
375
|
|
|
382
376
|
Generate archaeologist name and dispatch:
|
|
383
377
|
Run using the Bash tool with description "Naming archaeologist...": `bash .aether/aether-utils.sh generate-ant-name "archaeologist"` (store as `{archaeologist_name}`)
|
|
384
|
-
Run using the Bash tool with description "Dispatching archaeologist...": `bash .aether/aether-utils.sh spawn-log "Queen" "scout" "{archaeologist_name}" "Pre-build archaeology scan"
|
|
378
|
+
Run using the Bash tool with description "Dispatching archaeologist...": `bash .aether/aether-utils.sh spawn-log "Queen" "scout" "{archaeologist_name}" "Pre-build archaeology scan"`
|
|
385
379
|
|
|
386
380
|
Display:
|
|
387
381
|
```
|
|
@@ -419,7 +413,7 @@ log a warning and continue to Step 5.
|
|
|
419
413
|
**Wait for results** (blocking — use TaskOutput with `block: true`).
|
|
420
414
|
|
|
421
415
|
Log completion and update swarm display:
|
|
422
|
-
Run using the Bash tool with description "Recording archaeologist findings...": `bash .aether/aether-utils.sh spawn-complete "{archaeologist_name}" "completed" "Pre-build archaeology scan"
|
|
416
|
+
Run using the Bash tool with description "Recording archaeologist findings...": `bash .aether/aether-utils.sh spawn-complete "{archaeologist_name}" "completed" "Pre-build archaeology scan"`
|
|
423
417
|
|
|
424
418
|
3. **Store and display findings:**
|
|
425
419
|
|
|
@@ -441,20 +435,10 @@ log a warning and continue to Step 5.
|
|
|
441
435
|
|
|
442
436
|
**YOU (the Queen) will spawn workers directly. Do NOT delegate to a single Prime Worker.**
|
|
443
437
|
|
|
444
|
-
**
|
|
445
|
-
Run using the Bash tool with description "
|
|
438
|
+
**Log phase start:**
|
|
439
|
+
Run using the Bash tool with description "Logging phase start...":
|
|
446
440
|
```bash
|
|
447
|
-
# Generate unique build ID
|
|
448
|
-
build_id="build-$(date +%s)"
|
|
449
|
-
|
|
450
|
-
# Initialize swarm display for this build
|
|
451
|
-
bash .aether/aether-utils.sh swarm-display-init "$build_id"
|
|
452
|
-
|
|
453
|
-
# Log phase start
|
|
454
441
|
bash .aether/aether-utils.sh activity-log "EXECUTING" "Queen" "Phase {id}: {name} - Queen dispatching workers"
|
|
455
|
-
|
|
456
|
-
# Display animated header
|
|
457
|
-
bash .aether/aether-utils.sh swarm-display-update "Queen" "prime" "excavating" "Phase {id}: {name}" "Colony" '{"read":0,"grep":0,"edit":0,"bash":0}' 10 "fungus_garden" 0
|
|
458
442
|
```
|
|
459
443
|
|
|
460
444
|
**Show real-time display header:**
|
|
@@ -598,7 +582,7 @@ If `is_integration_phase` is `"true"`:
|
|
|
598
582
|
|
|
599
583
|
1. **Generate Ambassador name and dispatch:**
|
|
600
584
|
Run using the Bash tool with description "Naming ambassador...": `bash .aether/aether-utils.sh generate-ant-name "ambassador"` (store as `{ambassador_name}`)
|
|
601
|
-
Run using the Bash tool with description "Dispatching ambassador...": `bash .aether/aether-utils.sh spawn-log "Queen" "ambassador" "{ambassador_name}" "External integration design"
|
|
585
|
+
Run using the Bash tool with description "Dispatching ambassador...": `bash .aether/aether-utils.sh spawn-log "Queen" "ambassador" "{ambassador_name}" "External integration design"`
|
|
602
586
|
|
|
603
587
|
Display:
|
|
604
588
|
```
|
|
@@ -676,7 +660,7 @@ If `is_integration_phase` is `"true"`:
|
|
|
676
660
|
Extract from response: `integration_plan`, `env_vars_required`, `error_scenarios_covered`, `blockers`
|
|
677
661
|
|
|
678
662
|
Log completion and update swarm display:
|
|
679
|
-
Run using the Bash tool with description "Recording ambassador completion...": `bash .aether/aether-utils.sh spawn-complete "{ambassador_name}" "completed" "Integration design complete"
|
|
663
|
+
Run using the Bash tool with description "Recording ambassador completion...": `bash .aether/aether-utils.sh spawn-complete "{ambassador_name}" "completed" "Integration design complete"`
|
|
680
664
|
|
|
681
665
|
**Display Ambassador completion line:**
|
|
682
666
|
```
|
|
@@ -726,7 +710,7 @@ For each Wave 1 task, use Task tool with `subagent_type="aether-builder"`, inclu
|
|
|
726
710
|
- If `grave_context` is non-empty, display a visible line before spawning that worker:
|
|
727
711
|
`⚰️ Graveyard caution for {ant_name}: {file_1} ({level_1}), {file_2} ({level_2})`
|
|
728
712
|
|
|
729
|
-
**PER WORKER:** Run using the Bash tool with description "Preparing worker {name}...": `bash .aether/aether-utils.sh spawn-log "Queen" "builder" "{ant_name}" "{task_description}" && bash .aether/aether-utils.sh
|
|
713
|
+
**PER WORKER:** Run using the Bash tool with description "Preparing worker {name}...": `bash .aether/aether-utils.sh spawn-log "Queen" "builder" "{ant_name}" "{task_description}" && bash .aether/aether-utils.sh context-update worker-spawn "{ant_name}" "builder" "{task_description}"`
|
|
730
714
|
|
|
731
715
|
**Builder Worker Prompt (CLEAN OUTPUT):**
|
|
732
716
|
```
|
|
@@ -759,7 +743,6 @@ If integration_plan is provided above, you MUST:
|
|
|
759
743
|
|
|
760
744
|
**IMPORTANT:** When using the Bash tool for activity calls, always include a description parameter:
|
|
761
745
|
- activity-log calls → "Logging {action}..."
|
|
762
|
-
- swarm-display-update calls → "Updating build display..."
|
|
763
746
|
- pheromone-read calls → "Checking colony signals..."
|
|
764
747
|
- spawn-can-spawn calls → "Checking spawn budget..."
|
|
765
748
|
- generate-ant-name calls → "Naming sub-worker..."
|
|
@@ -854,7 +837,7 @@ bash .aether/aether-utils.sh memory-capture \
|
|
|
854
837
|
"worker:builder" 2>/dev/null || true
|
|
855
838
|
```
|
|
856
839
|
|
|
857
|
-
**PER WORKER:** Run using the Bash tool with description "Recording {name} completion...": `bash .aether/aether-utils.sh spawn-complete "{ant_name}" "completed" "{summary}" && bash .aether/aether-utils.sh
|
|
840
|
+
**PER WORKER:** Run using the Bash tool with description "Recording {name} completion...": `bash .aether/aether-utils.sh spawn-complete "{ant_name}" "completed" "{summary}" && bash .aether/aether-utils.sh context-update worker-complete "{ant_name}" "completed"`
|
|
858
841
|
|
|
859
842
|
**Check for total wave failure:**
|
|
860
843
|
|
|
@@ -915,10 +898,7 @@ If at least one worker succeeded, continue normally to the next wave.
|
|
|
915
898
|
|
|
916
899
|
**Parse each worker's validated JSON output to collect:** status, files_created, files_modified, blockers
|
|
917
900
|
|
|
918
|
-
|
|
919
|
-
If `visual_mode` is true AND the build is running inside a tmux session (`$TMUX` environment variable is set), run using the Bash tool with description "Rendering build progress...": `bash .aether/aether-utils.sh swarm-display-text "$build_id"`
|
|
920
|
-
|
|
921
|
-
If `$TMUX` is not set, skip this call entirely — do not attempt it. Chat users see the structured completion lines above instead.
|
|
901
|
+
Chat users see the structured completion lines above.
|
|
922
902
|
|
|
923
903
|
### Step 5.3: Spawn Wave 2+ Workers (Sequential Waves)
|
|
924
904
|
|
|
@@ -942,7 +922,7 @@ Repeat Step 5.1-5.2 for each subsequent wave, waiting for previous wave to compl
|
|
|
942
922
|
|
|
943
923
|
Spawn the Watcher using Task tool with `subagent_type="aether-watcher"`, include `description: "👁️ Watcher {Watcher-Name}: Independent verification"` (DO NOT use run_in_background - task blocks until complete):
|
|
944
924
|
|
|
945
|
-
Run using the Bash tool with description "Dispatching watcher...": `bash .aether/aether-utils.sh spawn-log "Queen" "watcher" "{watcher_name}" "Independent verification"
|
|
925
|
+
Run using the Bash tool with description "Dispatching watcher...": `bash .aether/aether-utils.sh spawn-log "Queen" "watcher" "{watcher_name}" "Independent verification"`
|
|
946
926
|
|
|
947
927
|
**Watcher Worker Prompt (CLEAN OUTPUT):**
|
|
948
928
|
```
|
|
@@ -958,7 +938,6 @@ Files to verify:
|
|
|
958
938
|
|
|
959
939
|
**IMPORTANT:** When using the Bash tool for activity calls, always include a description parameter:
|
|
960
940
|
- activity-log calls → "Logging {action}..."
|
|
961
|
-
- swarm-display-update calls → "Updating build display..."
|
|
962
941
|
- pheromone-read calls → "Checking colony signals..."
|
|
963
942
|
- spawn-log calls → "Dispatching sub-worker..."
|
|
964
943
|
|
|
@@ -1003,9 +982,6 @@ For failed verification:
|
|
|
1003
982
|
|
|
1004
983
|
**Store results for synthesis in Step 5.7**
|
|
1005
984
|
|
|
1006
|
-
**Update swarm display when Watcher completes:**
|
|
1007
|
-
Run using the Bash tool with description "Recording watcher completion...": `bash .aether/aether-utils.sh swarm-display-update "{watcher_name}" "watcher" "completed" "Verification complete" "Queen" '{"read":3,"grep":2,"edit":0,"bash":1}' 100 "nursery" 100`
|
|
1008
|
-
|
|
1009
985
|
### Step 5.5.1: Measurer Performance Agent (Conditional)
|
|
1010
986
|
|
|
1011
987
|
**Conditional step — only runs for performance-sensitive phases.**
|
|
@@ -1042,7 +1018,7 @@ Run using the Bash tool with description "Recording watcher completion...": `bas
|
|
|
1042
1018
|
3. **Generate Measurer name and dispatch:**
|
|
1043
1019
|
|
|
1044
1020
|
Run using the Bash tool with description "Naming measurer...": `bash .aether/aether-utils.sh generate-ant-name "measurer"` (store as `{measurer_name}`)
|
|
1045
|
-
Run using the Bash tool with description "Dispatching measurer...": `bash .aether/aether-utils.sh spawn-log "Queen" "measurer" "{measurer_name}" "Performance baseline measurement"
|
|
1021
|
+
Run using the Bash tool with description "Dispatching measurer...": `bash .aether/aether-utils.sh spawn-log "Queen" "measurer" "{measurer_name}" "Performance baseline measurement"`
|
|
1046
1022
|
|
|
1047
1023
|
Display:
|
|
1048
1024
|
```
|
|
@@ -1118,7 +1094,7 @@ Run using the Bash tool with description "Recording watcher completion...": `bas
|
|
|
1118
1094
|
Extract from response: `baselines_established`, `bottlenecks_identified`, `recommendations`, `tool_count`
|
|
1119
1095
|
|
|
1120
1096
|
Log completion and update swarm display:
|
|
1121
|
-
Run using the Bash tool with description "Recording measurer completion...": `bash .aether/aether-utils.sh spawn-complete "{measurer_name}" "completed" "Baselines established, bottlenecks identified"
|
|
1097
|
+
Run using the Bash tool with description "Recording measurer completion...": `bash .aether/aether-utils.sh spawn-complete "{measurer_name}" "completed" "Baselines established, bottlenecks identified"`
|
|
1122
1098
|
|
|
1123
1099
|
**Display Measurer completion line:**
|
|
1124
1100
|
```
|
|
@@ -1165,7 +1141,7 @@ Generate a chaos ant name and dispatch:
|
|
|
1165
1141
|
Run using the Bash tool with description "Naming chaos ant...": `bash .aether/aether-utils.sh generate-ant-name "chaos"` (store as `{chaos_name}`)
|
|
1166
1142
|
Run using the Bash tool with description "Loading existing flags...": `bash .aether/aether-utils.sh flag-list --phase {phase_number}`
|
|
1167
1143
|
Parse the result and extract unresolved flag titles into a list: `{existing_flag_titles}` (comma-separated titles from `.result.flags[].title`). If no flags exist, set `{existing_flag_titles}` to "None".
|
|
1168
|
-
Run using the Bash tool with description "Dispatching chaos ant...": `bash .aether/aether-utils.sh spawn-log "Queen" "chaos" "{chaos_name}" "Resilience testing of Phase {id} work"
|
|
1144
|
+
Run using the Bash tool with description "Dispatching chaos ant...": `bash .aether/aether-utils.sh spawn-log "Queen" "chaos" "{chaos_name}" "Resilience testing of Phase {id} work"`
|
|
1169
1145
|
|
|
1170
1146
|
**Announce the resilience testing wave:**
|
|
1171
1147
|
```
|
|
@@ -1188,7 +1164,6 @@ Skip these known issues: {existing_flag_titles}
|
|
|
1188
1164
|
|
|
1189
1165
|
**IMPORTANT:** When using the Bash tool for activity calls, always include a description parameter:
|
|
1190
1166
|
- activity-log calls → "Logging {action}..."
|
|
1191
|
-
- swarm-display-update calls → "Updating build display..."
|
|
1192
1167
|
- pheromone-read calls → "Checking colony signals..."
|
|
1193
1168
|
|
|
1194
1169
|
Use colony-flavored language, 4-8 words, trailing ellipsis.
|
|
@@ -1251,7 +1226,7 @@ bash .aether/aether-utils.sh memory-capture \
|
|
|
1251
1226
|
```
|
|
1252
1227
|
|
|
1253
1228
|
Log chaos ant completion and update swarm display:
|
|
1254
|
-
Run using the Bash tool with description "Recording chaos completion...": `bash .aether/aether-utils.sh spawn-complete "{chaos_name}" "completed" "{summary}"
|
|
1229
|
+
Run using the Bash tool with description "Recording chaos completion...": `bash .aether/aether-utils.sh spawn-complete "{chaos_name}" "completed" "{summary}"`
|
|
1255
1230
|
|
|
1256
1231
|
### Step 5.8: Create Flags for Verification Failures
|
|
1257
1232
|
|
|
@@ -1543,11 +1518,6 @@ Note: This runs regardless of build success/failure. Failed builds may have reco
|
|
|
1543
1518
|
|
|
1544
1519
|
**This step runs ONLY after synthesis is complete. All values come from actual worker results.**
|
|
1545
1520
|
|
|
1546
|
-
**Update swarm display state (always) and render (tmux only):**
|
|
1547
|
-
Run using the Bash tool with description "Recording build completion...": `bash .aether/aether-utils.sh swarm-display-update "Queen" "prime" "completed" "Phase {id} complete" "Colony" '{"read":10,"grep":5,"edit":5,"bash":2}' 100 "fungus_garden" 100`
|
|
1548
|
-
|
|
1549
|
-
If `$TMUX` is set, also run using the Bash tool with description "Rendering final swarm display...": `bash .aether/aether-utils.sh swarm-display-text "$build_id"`
|
|
1550
|
-
|
|
1551
1521
|
**Display BUILD SUMMARY (always shown, replaces compact/verbose split):**
|
|
1552
1522
|
|
|
1553
1523
|
Calculate `total_tools` by summing `tool_count` from all worker return JSONs (builders + watcher + chaos).
|
|
@@ -74,12 +74,6 @@ Do not touch during build:
|
|
|
74
74
|
- Other agents' config files (only modify files assigned to the current build task)
|
|
75
75
|
</read_only>
|
|
76
76
|
|
|
77
|
-
### Step 0: Version Check (Non-blocking)
|
|
78
|
-
|
|
79
|
-
Run using the Bash tool with description "Checking colony version...": `bash .aether/aether-utils.sh version-check-cached 2>/dev/null || true`
|
|
80
|
-
|
|
81
|
-
If the command succeeds and the JSON result contains a non-empty string, display it as a one-line notice. Proceed regardless of outcome.
|
|
82
|
-
|
|
83
77
|
### Step 0.6: Verify LiteLLM Proxy
|
|
84
78
|
|
|
85
79
|
Check that the LiteLLM proxy is running for model routing:
|