aether-colony 5.2.1 → 5.3.1
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 +35 -0
- package/.aether/agents/aether-ambassador.md +140 -0
- package/.aether/agents/aether-archaeologist.md +108 -0
- package/.aether/agents/aether-architect.md +133 -0
- package/.aether/agents/aether-auditor.md +144 -0
- package/.aether/agents/aether-builder.md +184 -0
- package/.aether/agents/aether-chaos.md +115 -0
- package/.aether/agents/aether-chronicler.md +122 -0
- package/.aether/agents/aether-gatekeeper.md +116 -0
- package/.aether/agents/aether-includer.md +117 -0
- package/.aether/agents/aether-keeper.md +177 -0
- package/.aether/agents/aether-measurer.md +128 -0
- package/.aether/agents/aether-oracle.md +137 -0
- package/.aether/agents/aether-probe.md +133 -0
- package/.aether/agents/aether-queen.md +286 -0
- package/.aether/agents/aether-route-setter.md +130 -0
- package/.aether/agents/aether-sage.md +106 -0
- package/.aether/agents/aether-scout.md +101 -0
- package/.aether/agents/aether-surveyor-disciplines.md +391 -0
- package/.aether/agents/aether-surveyor-nest.md +329 -0
- package/.aether/agents/aether-surveyor-pathogens.md +264 -0
- package/.aether/agents/aether-surveyor-provisions.md +334 -0
- package/.aether/agents/aether-tracker.md +137 -0
- package/.aether/agents/aether-watcher.md +174 -0
- package/.aether/agents/aether-weaver.md +130 -0
- package/.aether/commands/claude/archaeology.md +334 -0
- package/.aether/commands/claude/build.md +65 -0
- package/.aether/commands/claude/chaos.md +336 -0
- package/.aether/commands/claude/colonize.md +259 -0
- package/.aether/commands/claude/continue.md +60 -0
- package/.aether/commands/claude/council.md +507 -0
- package/.aether/commands/claude/data-clean.md +81 -0
- package/.aether/commands/claude/dream.md +268 -0
- package/.aether/commands/claude/entomb.md +498 -0
- package/.aether/commands/claude/export-signals.md +57 -0
- package/.aether/commands/claude/feedback.md +96 -0
- package/.aether/commands/claude/flag.md +151 -0
- package/.aether/commands/claude/flags.md +169 -0
- package/.aether/commands/claude/focus.md +76 -0
- package/.aether/commands/claude/help.md +154 -0
- package/.aether/commands/claude/history.md +140 -0
- package/.aether/commands/claude/import-signals.md +71 -0
- package/.aether/commands/claude/init.md +505 -0
- package/.aether/commands/claude/insert-phase.md +105 -0
- package/.aether/commands/claude/interpret.md +278 -0
- package/.aether/commands/claude/lay-eggs.md +210 -0
- package/.aether/commands/claude/maturity.md +113 -0
- package/.aether/commands/claude/memory-details.md +77 -0
- package/.aether/commands/claude/migrate-state.md +171 -0
- package/.aether/commands/claude/oracle.md +642 -0
- package/.aether/commands/claude/organize.md +232 -0
- package/.aether/commands/claude/patrol.md +620 -0
- package/.aether/commands/claude/pause-colony.md +233 -0
- package/.aether/commands/claude/phase.md +115 -0
- package/.aether/commands/claude/pheromones.md +156 -0
- package/.aether/commands/claude/plan.md +693 -0
- package/.aether/commands/claude/preferences.md +65 -0
- package/.aether/commands/claude/quick.md +100 -0
- package/.aether/commands/claude/redirect.md +76 -0
- package/.aether/commands/claude/resume-colony.md +197 -0
- package/.aether/commands/claude/resume.md +388 -0
- package/.aether/commands/claude/run.md +231 -0
- package/.aether/commands/claude/seal.md +774 -0
- package/.aether/commands/claude/skill-create.md +286 -0
- package/.aether/commands/claude/status.md +410 -0
- package/.aether/commands/claude/swarm.md +349 -0
- package/.aether/commands/claude/tunnels.md +426 -0
- package/.aether/commands/claude/update.md +132 -0
- package/.aether/commands/claude/verify-castes.md +143 -0
- package/.aether/commands/claude/watch.md +239 -0
- package/.aether/commands/opencode/archaeology.md +331 -0
- package/.aether/commands/opencode/build.md +1168 -0
- package/.aether/commands/opencode/chaos.md +329 -0
- package/.aether/commands/opencode/colonize.md +195 -0
- package/.aether/commands/opencode/continue.md +1436 -0
- package/.aether/commands/opencode/council.md +437 -0
- package/.aether/commands/opencode/data-clean.md +77 -0
- package/.aether/commands/opencode/dream.md +260 -0
- package/.aether/commands/opencode/entomb.md +377 -0
- package/.aether/commands/opencode/export-signals.md +54 -0
- package/.aether/commands/opencode/feedback.md +99 -0
- package/.aether/commands/opencode/flag.md +149 -0
- package/.aether/commands/opencode/flags.md +167 -0
- package/.aether/commands/opencode/focus.md +73 -0
- package/.aether/commands/opencode/help.md +157 -0
- package/.aether/commands/opencode/history.md +136 -0
- package/.aether/commands/opencode/import-signals.md +68 -0
- package/.aether/commands/opencode/init.md +518 -0
- package/.aether/commands/opencode/insert-phase.md +111 -0
- package/.aether/commands/opencode/interpret.md +272 -0
- package/.aether/commands/opencode/lay-eggs.md +213 -0
- package/.aether/commands/opencode/maturity.md +108 -0
- package/.aether/commands/opencode/memory-details.md +83 -0
- package/.aether/commands/opencode/migrate-state.md +165 -0
- package/.aether/commands/opencode/oracle.md +593 -0
- package/.aether/commands/opencode/organize.md +226 -0
- package/.aether/commands/opencode/patrol.md +626 -0
- package/.aether/commands/opencode/pause-colony.md +203 -0
- package/.aether/commands/opencode/phase.md +113 -0
- package/.aether/commands/opencode/pheromones.md +162 -0
- package/.aether/commands/opencode/plan.md +684 -0
- package/.aether/commands/opencode/preferences.md +71 -0
- package/.aether/commands/opencode/quick.md +91 -0
- package/.aether/commands/opencode/redirect.md +84 -0
- package/.aether/commands/opencode/resume-colony.md +190 -0
- package/.aether/commands/opencode/resume.md +394 -0
- package/.aether/commands/opencode/run.md +237 -0
- package/.aether/commands/opencode/seal.md +452 -0
- package/.aether/commands/opencode/skill-create.md +63 -0
- package/.aether/commands/opencode/status.md +307 -0
- package/.aether/commands/opencode/swarm.md +15 -0
- package/.aether/commands/opencode/tunnels.md +400 -0
- package/.aether/commands/opencode/update.md +127 -0
- package/.aether/commands/opencode/verify-castes.md +139 -0
- package/.aether/commands/opencode/watch.md +227 -0
- package/.aether/docs/command-playbooks/build-full.md +1 -1
- package/.aether/docs/command-playbooks/build-prep.md +10 -3
- package/.aether/docs/command-playbooks/build-verify.md +51 -0
- package/.aether/docs/command-playbooks/continue-advance.md +115 -6
- package/.aether/docs/command-playbooks/continue-verify.md +32 -0
- package/.aether/utils/clash-detect.sh +239 -0
- package/.aether/utils/hooks/clash-pre-tool-use.js +99 -0
- package/.aether/utils/merge-driver-lockfile.sh +35 -0
- package/.aether/utils/midden.sh +534 -0
- package/.aether/utils/pheromone.sh +1376 -108
- package/.aether/utils/queen.sh +2 -4
- package/.aether/utils/state-api.sh +25 -4
- package/.aether/utils/swarm.sh +1 -1
- package/.aether/utils/worktree.sh +189 -0
- package/CHANGELOG.md +26 -0
- package/README.md +161 -161
- package/bin/cli.js +103 -61
- package/bin/lib/banner.js +14 -0
- package/bin/lib/init.js +8 -7
- package/bin/lib/interactive-setup.js +251 -0
- package/bin/npx-entry.js +21 -0
- package/bin/npx-install.js +9 -167
- package/bin/validate-package.sh +23 -0
- package/package.json +2 -2
- package/.aether/docs/plans/pheromone-display-plan.md +0 -257
- package/.aether/schemas/example-prompt-builder.xml +0 -234
- package/.aether/scripts/incident-test-add.sh +0 -47
- package/.aether/scripts/weekly-audit.sh +0 -79
package/.aether/utils/queen.sh
CHANGED
|
@@ -1391,8 +1391,7 @@ _colony_depth() {
|
|
|
1391
1391
|
local new_depth="${2:-}"
|
|
1392
1392
|
case "$new_depth" in
|
|
1393
1393
|
light|standard|deep|full)
|
|
1394
|
-
|
|
1395
|
-
jq --arg d "$new_depth" '.colony_depth = $d' "$DATA_DIR/COLONY_STATE.json" > "$tmp" && mv "$tmp" "$DATA_DIR/COLONY_STATE.json"
|
|
1394
|
+
NEW_DEPTH="$new_depth" _state_mutate '.colony_depth = env.NEW_DEPTH'
|
|
1396
1395
|
json_ok "$(jq -n --arg depth "$new_depth" '{depth: $depth, updated: true}')"
|
|
1397
1396
|
;;
|
|
1398
1397
|
*)
|
|
@@ -1476,8 +1475,7 @@ _queen_write_charter() {
|
|
|
1476
1475
|
local current_name
|
|
1477
1476
|
current_name=$(jq -r '.colony_name // empty' "$DATA_DIR/COLONY_STATE.json" 2>/dev/null) || true
|
|
1478
1477
|
if [[ -z "$current_name" && -n "$cw_colony_name" ]]; then
|
|
1479
|
-
|
|
1480
|
-
jq --arg cn "$cw_colony_name" '.colony_name = $cn' "$DATA_DIR/COLONY_STATE.json" > "$tmp_state" && mv "$tmp_state" "$DATA_DIR/COLONY_STATE.json"
|
|
1478
|
+
CW_COLONY_NAME="$cw_colony_name" _state_mutate '.colony_name = env.CW_COLONY_NAME'
|
|
1481
1479
|
fi
|
|
1482
1480
|
fi
|
|
1483
1481
|
|
|
@@ -96,11 +96,32 @@ _state_write() {
|
|
|
96
96
|
|
|
97
97
|
_state_mutate() {
|
|
98
98
|
# Read-modify-write COLONY_STATE.json with a jq expression
|
|
99
|
-
# Usage: state-mutate '<jq_expression>'
|
|
99
|
+
# Usage: state-mutate [--arg NAME VALUE] [--argjson NAME VALUE] '<jq_expression>'
|
|
100
|
+
# Supports jq --arg, --argjson, --slurpfile, --rawfile flags (forwarded to jq)
|
|
100
101
|
# Acquires lock, creates backup, applies jq, validates, writes atomically
|
|
101
102
|
# Returns: json_ok with mutated:true, or json_err on failure
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
# Parse jq flags (--arg, --argjson, --slurpfile, --rawfile) from arguments
|
|
105
|
+
# The jq expression is always the last argument (after all flags)
|
|
106
|
+
local sm_jq_flags=()
|
|
107
|
+
local sm_expr=""
|
|
108
|
+
local i=0
|
|
109
|
+
local args=("$@")
|
|
110
|
+
|
|
111
|
+
while [[ $i -lt ${#args[@]} ]]; do
|
|
112
|
+
case "${args[$i]}" in
|
|
113
|
+
--arg|--argjson|--slurpfile|--rawfile)
|
|
114
|
+
# Flag requires a name and value — consume next two args
|
|
115
|
+
sm_jq_flags+=("${args[$i]}" "${args[$((i+1))]}" "${args[$((i+2))]}")
|
|
116
|
+
i=$((i + 3))
|
|
117
|
+
;;
|
|
118
|
+
*)
|
|
119
|
+
# Last argument is the jq expression
|
|
120
|
+
sm_expr="${args[$i]}"
|
|
121
|
+
i=$((i + 1))
|
|
122
|
+
;;
|
|
123
|
+
esac
|
|
124
|
+
done
|
|
104
125
|
|
|
105
126
|
if [[ -z "$sm_expr" ]]; then
|
|
106
127
|
json_err "$E_VALIDATION_FAILED" "state-mutate requires a jq expression argument"
|
|
@@ -122,8 +143,8 @@ _state_mutate() {
|
|
|
122
143
|
fi
|
|
123
144
|
fi
|
|
124
145
|
|
|
125
|
-
# Apply jq expression to current state
|
|
126
|
-
sm_updated=$(jq "$sm_expr" "$sm_state_file" 2>/dev/null) || {
|
|
146
|
+
# Apply jq expression to current state (with forwarded flags)
|
|
147
|
+
sm_updated=$(jq ${sm_jq_flags[@]+"${sm_jq_flags[@]}"} "$sm_expr" "$sm_state_file" 2>/dev/null) || {
|
|
127
148
|
release_lock 2>/dev/null || true # SUPPRESS:OK -- cleanup: lock may not be held
|
|
128
149
|
json_err "$E_JSON_INVALID" "jq expression failed: $sm_expr"
|
|
129
150
|
}
|
package/.aether/utils/swarm.sh
CHANGED
|
@@ -32,7 +32,7 @@ _autofix_checkpoint() {
|
|
|
32
32
|
label="${1:-autofix-$(date +%s)}"
|
|
33
33
|
stash_name="aether-checkpoint: $label"
|
|
34
34
|
# Only stash Aether-managed directories, never touch user files
|
|
35
|
-
if git stash push -m "$stash_name" -- $target_dirs >/dev/null 2>&1; then # SUPPRESS:OK -- existence-test: stash operation may fail
|
|
35
|
+
if git stash push -m "$stash_name" -- $target_dirs ":(exclude).aether/data/" >/dev/null 2>&1; then # SUPPRESS:OK -- existence-test: stash operation may fail
|
|
36
36
|
json_ok "$(jq -n --arg ref "$stash_name" '{type: "stash", ref: $ref}')"
|
|
37
37
|
else
|
|
38
38
|
# Stash failed (possibly due to conflicts), record commit hash
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Worktree utility functions -- extracted from aether-utils.sh
|
|
3
|
+
# Provides: _worktree_create, _worktree_cleanup
|
|
4
|
+
#
|
|
5
|
+
# These functions are sourced by aether-utils.sh at startup.
|
|
6
|
+
# All shared infrastructure (json_ok, json_err, atomic_write, acquire_lock,
|
|
7
|
+
# release_lock, DATA_DIR, COLONY_DATA_DIR, SCRIPT_DIR, AETHER_ROOT, error
|
|
8
|
+
# constants) is available.
|
|
9
|
+
|
|
10
|
+
# Default worktree location relative to AETHER_ROOT
|
|
11
|
+
WORKTREE_BASE_DIR="${AETHER_ROOT}/.aether/worktrees"
|
|
12
|
+
|
|
13
|
+
# _worktree_create
|
|
14
|
+
# Creates a git worktree for an agent working on a specific task.
|
|
15
|
+
#
|
|
16
|
+
# Usage: _worktree_create --branch <branch-name> [--base <base-branch>] [--task-id <task-id>]
|
|
17
|
+
# Returns JSON: {ok:true, result:{path, branch, base, worktree_dir, task_id}}
|
|
18
|
+
_worktree_create() {
|
|
19
|
+
local branch=""
|
|
20
|
+
local base=""
|
|
21
|
+
local task_id=""
|
|
22
|
+
|
|
23
|
+
# Parse arguments
|
|
24
|
+
while [[ $# -gt 0 ]]; do
|
|
25
|
+
case "$1" in
|
|
26
|
+
--branch) branch="${2:-}"; shift 2 ;;
|
|
27
|
+
--base) base="${2:-}"; shift 2 ;;
|
|
28
|
+
--task-id) task_id="${2:-}"; shift 2 ;;
|
|
29
|
+
*) shift ;;
|
|
30
|
+
esac
|
|
31
|
+
done
|
|
32
|
+
|
|
33
|
+
# Validate required arguments
|
|
34
|
+
if [[ -z "$branch" ]]; then
|
|
35
|
+
json_err "$E_VALIDATION_FAILED" "Usage: worktree-create --branch <branch-name> [--base <base-branch>] [--task-id <task-id>]"
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Sanitize branch name: reject obviously dangerous patterns
|
|
39
|
+
if [[ "$branch" == *..* ]] || [[ "$branch" == */* ]] || [[ "$branch" == *\\* ]]; then
|
|
40
|
+
json_err "$E_VALIDATION_FAILED" "Branch name must not contain '..', '/', or backslashes"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Default base to current branch
|
|
44
|
+
if [[ -z "$base" ]]; then
|
|
45
|
+
base=$(git -C "$AETHER_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
local worktree_dir="$WORKTREE_BASE_DIR/$branch"
|
|
49
|
+
|
|
50
|
+
# Check if worktree already exists
|
|
51
|
+
if [[ -d "$worktree_dir" ]]; then
|
|
52
|
+
json_err "$E_VALIDATION_FAILED" "Worktree already exists for branch '$branch' at $worktree_dir"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Check if branch already exists as a git branch (would indicate duplicate)
|
|
56
|
+
if git -C "$AETHER_ROOT" show-ref --verify --quiet "refs/heads/$branch" 2>/dev/null; then
|
|
57
|
+
json_err "$E_VALIDATION_FAILED" "Branch '$branch' already exists"
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Ensure base branch exists
|
|
61
|
+
if ! git -C "$AETHER_ROOT" show-ref --verify --quiet "refs/heads/$base" 2>/dev/null; then
|
|
62
|
+
json_err "$E_GIT_ERROR" "Base branch '$base' does not exist"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Ensure parent directory exists
|
|
66
|
+
mkdir -p "$WORKTREE_BASE_DIR"
|
|
67
|
+
|
|
68
|
+
# Create the worktree (git worktree add creates the branch automatically)
|
|
69
|
+
if ! git -C "$AETHER_ROOT" worktree add "$worktree_dir" -b "$branch" "$base" >/dev/null 2>&1; then
|
|
70
|
+
json_err "$E_GIT_ERROR" "Failed to create worktree for branch '$branch'"
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Copy .aether/data/ structure to the new worktree so the agent has colony context
|
|
74
|
+
# Per state-contract-design.md, branch-local state lives in .aether/data/ (gitignored)
|
|
75
|
+
# and each worktree gets its own independent copy for colony context isolation.
|
|
76
|
+
if [[ -d "$AETHER_ROOT/.aether/data" ]]; then
|
|
77
|
+
mkdir -p "$worktree_dir/.aether/data"
|
|
78
|
+
cp -r "$AETHER_ROOT/.aether/data/." "$worktree_dir/.aether/data/" 2>/dev/null || true # SUPPRESS:OK -- copy: data dir may be empty
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Copy exchange scripts so xml-utils.sh can source pheromone-xml.sh etc.
|
|
82
|
+
if [[ -d "$AETHER_ROOT/.aether/exchange" ]]; then
|
|
83
|
+
mkdir -p "$worktree_dir/.aether/exchange"
|
|
84
|
+
cp -r "$AETHER_ROOT/.aether/exchange/." "$worktree_dir/.aether/exchange/" 2>/dev/null || true
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Inject main's pheromone signals into the worktree (per D-01)
|
|
88
|
+
# Non-blocking: if injection fails, worktree still works without injected signals
|
|
89
|
+
if [[ -f "$worktree_dir/.aether/data/pheromones.json" ]]; then
|
|
90
|
+
local main_head
|
|
91
|
+
main_head=$(git -C "$AETHER_ROOT" rev-parse HEAD 2>/dev/null || echo "unknown")
|
|
92
|
+
(
|
|
93
|
+
cd "$worktree_dir" 2>/dev/null && \
|
|
94
|
+
DATA_DIR="$worktree_dir/.aether/data" \
|
|
95
|
+
COLONY_DATA_DIR="$worktree_dir/.aether/data" \
|
|
96
|
+
bash "$AETHER_ROOT/.aether/aether-utils.sh" \
|
|
97
|
+
pheromone-snapshot-inject --from-branch "$base" --from-commit "$main_head" \
|
|
98
|
+
>/dev/null 2>&1 || true
|
|
99
|
+
)
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# Build result JSON
|
|
103
|
+
local result
|
|
104
|
+
result=$(jq -n \
|
|
105
|
+
--arg path "$worktree_dir" \
|
|
106
|
+
--arg branch "$branch" \
|
|
107
|
+
--arg base "$base" \
|
|
108
|
+
--arg worktree_dir "$worktree_dir" \
|
|
109
|
+
--arg task_id "${task_id:-null}" \
|
|
110
|
+
'{
|
|
111
|
+
path: $path,
|
|
112
|
+
branch: $branch,
|
|
113
|
+
base: $base,
|
|
114
|
+
worktree_dir: $worktree_dir,
|
|
115
|
+
task_id: (if $task_id == "null" then null else $task_id end)
|
|
116
|
+
}')
|
|
117
|
+
|
|
118
|
+
json_ok "$result"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# _worktree_cleanup
|
|
122
|
+
# Removes a git worktree and cleans up tracking.
|
|
123
|
+
#
|
|
124
|
+
# Usage: _worktree_cleanup --branch <branch-name> [--force]
|
|
125
|
+
# Returns JSON: {ok:true, result:{removed, branch, path}}
|
|
126
|
+
_worktree_cleanup() {
|
|
127
|
+
local branch=""
|
|
128
|
+
local force=false
|
|
129
|
+
|
|
130
|
+
# Parse arguments
|
|
131
|
+
while [[ $# -gt 0 ]]; do
|
|
132
|
+
case "$1" in
|
|
133
|
+
--branch) branch="${2:-}"; shift 2 ;;
|
|
134
|
+
--force) force=true; shift ;;
|
|
135
|
+
*) shift ;;
|
|
136
|
+
esac
|
|
137
|
+
done
|
|
138
|
+
|
|
139
|
+
# Validate required arguments
|
|
140
|
+
if [[ -z "$branch" ]]; then
|
|
141
|
+
json_err "$E_VALIDATION_FAILED" "Usage: worktree-cleanup --branch <branch-name> [--force]"
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
# Sanitize branch name
|
|
145
|
+
if [[ "$branch" == *..* ]] || [[ "$branch" == */* ]] || [[ "$branch" == *\\* ]]; then
|
|
146
|
+
json_err "$E_VALIDATION_FAILED" "Branch name must not contain '..', '/', or backslashes"
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
local worktree_dir="$WORKTREE_BASE_DIR/$branch"
|
|
150
|
+
|
|
151
|
+
# Check if worktree exists
|
|
152
|
+
if [[ ! -d "$worktree_dir" ]]; then
|
|
153
|
+
json_err "$E_RESOURCE_NOT_FOUND" "No worktree found for branch '$branch'"
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# Check for uncommitted changes (unless --force)
|
|
157
|
+
# Exclude .aether/ files since they are branch-local state copies, not user changes
|
|
158
|
+
if [[ "$force" == "false" ]]; then
|
|
159
|
+
local dirty_count
|
|
160
|
+
dirty_count=$(git -C "$worktree_dir" status --porcelain 2>/dev/null \
|
|
161
|
+
| grep -v '\.aether/' \
|
|
162
|
+
| wc -l \
|
|
163
|
+
| tr -d ' ') || dirty_count=0
|
|
164
|
+
|
|
165
|
+
if [[ "$dirty_count" -gt 0 ]]; then
|
|
166
|
+
json_err "$E_VALIDATION_FAILED" "Worktree '$branch' has $dirty_count uncommitted changes. Use --force to remove anyway."
|
|
167
|
+
fi
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
# Remove the worktree using git worktree remove
|
|
171
|
+
if ! git -C "$AETHER_ROOT" worktree remove "$worktree_dir" --force 2>/dev/null; then
|
|
172
|
+
# Fallback: manual cleanup if git worktree remove fails
|
|
173
|
+
rm -rf "$worktree_dir" 2>/dev/null || true
|
|
174
|
+
# Also prune stale worktree entries
|
|
175
|
+
git -C "$AETHER_ROOT" worktree prune 2>/dev/null || true
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
# Attempt to delete the branch (best-effort -- may fail if branch is checked out elsewhere)
|
|
179
|
+
git -C "$AETHER_ROOT" branch -D "$branch" >/dev/null 2>&1 || true
|
|
180
|
+
|
|
181
|
+
# Build result JSON
|
|
182
|
+
local result
|
|
183
|
+
result=$(jq -n \
|
|
184
|
+
--arg branch "$branch" \
|
|
185
|
+
--arg path "$worktree_dir" \
|
|
186
|
+
'{removed: true, branch: $branch, path: $path}')
|
|
187
|
+
|
|
188
|
+
json_ok "$result"
|
|
189
|
+
}
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [5.3.0] - 2026-03-31
|
|
11
|
+
|
|
12
|
+
Aether v2.7 — PR Workflow + Stability. Six phases (39-44) adding multi-branch safety, clash detection, and release hardening.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- **Pheromone propagation** — Signals flow across git branches via `pheromone-snapshot-inject` and `pheromone-merge-back`; worktree creation auto-copies active pheromones
|
|
16
|
+
- **Midden collection** — Failure records from merged branches collected into main via `midden-collect` with idempotent dedup; cross-PR pattern detection via `midden-cross-pr-analysis`; revert-aware tagging via `midden-handle-revert`
|
|
17
|
+
- **Clash detection** — PreToolUse hook (`clash-pre-tool-use.js`) blocks edits to files modified in other active worktrees; `.aether/data/` files allowlisted (branch-local state)
|
|
18
|
+
- **Worktree utilities** — `_worktree_create` auto-copies colony context (COLONY_STATE.json, pheromones.json) and runs pheromone-snapshot-inject
|
|
19
|
+
- **Merge driver** — `.gitattributes` merge driver resolves package-lock.json conflicts by keeping "ours" via `merge-driver-lockfile.sh`
|
|
20
|
+
- **Midden wiring** — `midden-collect` and `midden-cross-pr-analysis` wired into `/ant:continue` playbooks (non-blocking, follows pheromone merge-back pattern)
|
|
21
|
+
- **Interactive installer** — `npx aether-colony` now shows a 3-option menu (Full setup / Global only / Repo only) with environment detection and context-sensitive defaults; supports `--global`, `--repo`, `--yes` flags for scripting
|
|
22
|
+
- **`aether setup` command** — CLI equivalent of `/ant:lay-eggs` for setting up Aether in a repo without Claude Code open
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- **Package validation** — `validate-package.sh` expanded from 15 to 38+ required file entries (100% coverage of packaged utils)
|
|
26
|
+
- **NPX installer** — Replaced `npx-install.js` with interactive `npx-entry.js`; old installer kept as deprecation redirect
|
|
27
|
+
- **Package cleanliness** — 8 dev-only files excluded from npm tarball (scripts/, design docs, example schemas)
|
|
28
|
+
- **CLAUDE.md** — Full accuracy audit: version bumped to v2.7.0, all counts verified (5,500 lines, 35 utils, 45 commands, 509 tests)
|
|
29
|
+
- **README.md** — Architecture counts updated (35 utils, 45 commands, ~5,500 lines)
|
|
30
|
+
- **YAML commands** — 6 stale command files regenerated from YAML sources (init, plan, seal for Claude and OpenCode)
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- **Clash detection dispatcher** — `clash-detect.sh` and `worktree.sh` wired into `aether-utils.sh` dispatcher (source lines, dispatch cases, help JSON)
|
|
34
|
+
- **Init command** — Clash detection hook verification and read-only worktree list integrated into `/ant:init` Step 7.6
|
|
35
|
+
|
|
10
36
|
## [2.1.0] - 2026-03-24
|
|
11
37
|
|
|
12
38
|
Six phases of production hardening (Phases 9-14) targeting reliability, maintainability, and developer experience.
|