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.
Files changed (143) hide show
  1. package/.aether/aether-utils.sh +35 -0
  2. package/.aether/agents/aether-ambassador.md +140 -0
  3. package/.aether/agents/aether-archaeologist.md +108 -0
  4. package/.aether/agents/aether-architect.md +133 -0
  5. package/.aether/agents/aether-auditor.md +144 -0
  6. package/.aether/agents/aether-builder.md +184 -0
  7. package/.aether/agents/aether-chaos.md +115 -0
  8. package/.aether/agents/aether-chronicler.md +122 -0
  9. package/.aether/agents/aether-gatekeeper.md +116 -0
  10. package/.aether/agents/aether-includer.md +117 -0
  11. package/.aether/agents/aether-keeper.md +177 -0
  12. package/.aether/agents/aether-measurer.md +128 -0
  13. package/.aether/agents/aether-oracle.md +137 -0
  14. package/.aether/agents/aether-probe.md +133 -0
  15. package/.aether/agents/aether-queen.md +286 -0
  16. package/.aether/agents/aether-route-setter.md +130 -0
  17. package/.aether/agents/aether-sage.md +106 -0
  18. package/.aether/agents/aether-scout.md +101 -0
  19. package/.aether/agents/aether-surveyor-disciplines.md +391 -0
  20. package/.aether/agents/aether-surveyor-nest.md +329 -0
  21. package/.aether/agents/aether-surveyor-pathogens.md +264 -0
  22. package/.aether/agents/aether-surveyor-provisions.md +334 -0
  23. package/.aether/agents/aether-tracker.md +137 -0
  24. package/.aether/agents/aether-watcher.md +174 -0
  25. package/.aether/agents/aether-weaver.md +130 -0
  26. package/.aether/commands/claude/archaeology.md +334 -0
  27. package/.aether/commands/claude/build.md +65 -0
  28. package/.aether/commands/claude/chaos.md +336 -0
  29. package/.aether/commands/claude/colonize.md +259 -0
  30. package/.aether/commands/claude/continue.md +60 -0
  31. package/.aether/commands/claude/council.md +507 -0
  32. package/.aether/commands/claude/data-clean.md +81 -0
  33. package/.aether/commands/claude/dream.md +268 -0
  34. package/.aether/commands/claude/entomb.md +498 -0
  35. package/.aether/commands/claude/export-signals.md +57 -0
  36. package/.aether/commands/claude/feedback.md +96 -0
  37. package/.aether/commands/claude/flag.md +151 -0
  38. package/.aether/commands/claude/flags.md +169 -0
  39. package/.aether/commands/claude/focus.md +76 -0
  40. package/.aether/commands/claude/help.md +154 -0
  41. package/.aether/commands/claude/history.md +140 -0
  42. package/.aether/commands/claude/import-signals.md +71 -0
  43. package/.aether/commands/claude/init.md +505 -0
  44. package/.aether/commands/claude/insert-phase.md +105 -0
  45. package/.aether/commands/claude/interpret.md +278 -0
  46. package/.aether/commands/claude/lay-eggs.md +210 -0
  47. package/.aether/commands/claude/maturity.md +113 -0
  48. package/.aether/commands/claude/memory-details.md +77 -0
  49. package/.aether/commands/claude/migrate-state.md +171 -0
  50. package/.aether/commands/claude/oracle.md +642 -0
  51. package/.aether/commands/claude/organize.md +232 -0
  52. package/.aether/commands/claude/patrol.md +620 -0
  53. package/.aether/commands/claude/pause-colony.md +233 -0
  54. package/.aether/commands/claude/phase.md +115 -0
  55. package/.aether/commands/claude/pheromones.md +156 -0
  56. package/.aether/commands/claude/plan.md +693 -0
  57. package/.aether/commands/claude/preferences.md +65 -0
  58. package/.aether/commands/claude/quick.md +100 -0
  59. package/.aether/commands/claude/redirect.md +76 -0
  60. package/.aether/commands/claude/resume-colony.md +197 -0
  61. package/.aether/commands/claude/resume.md +388 -0
  62. package/.aether/commands/claude/run.md +231 -0
  63. package/.aether/commands/claude/seal.md +774 -0
  64. package/.aether/commands/claude/skill-create.md +286 -0
  65. package/.aether/commands/claude/status.md +410 -0
  66. package/.aether/commands/claude/swarm.md +349 -0
  67. package/.aether/commands/claude/tunnels.md +426 -0
  68. package/.aether/commands/claude/update.md +132 -0
  69. package/.aether/commands/claude/verify-castes.md +143 -0
  70. package/.aether/commands/claude/watch.md +239 -0
  71. package/.aether/commands/opencode/archaeology.md +331 -0
  72. package/.aether/commands/opencode/build.md +1168 -0
  73. package/.aether/commands/opencode/chaos.md +329 -0
  74. package/.aether/commands/opencode/colonize.md +195 -0
  75. package/.aether/commands/opencode/continue.md +1436 -0
  76. package/.aether/commands/opencode/council.md +437 -0
  77. package/.aether/commands/opencode/data-clean.md +77 -0
  78. package/.aether/commands/opencode/dream.md +260 -0
  79. package/.aether/commands/opencode/entomb.md +377 -0
  80. package/.aether/commands/opencode/export-signals.md +54 -0
  81. package/.aether/commands/opencode/feedback.md +99 -0
  82. package/.aether/commands/opencode/flag.md +149 -0
  83. package/.aether/commands/opencode/flags.md +167 -0
  84. package/.aether/commands/opencode/focus.md +73 -0
  85. package/.aether/commands/opencode/help.md +157 -0
  86. package/.aether/commands/opencode/history.md +136 -0
  87. package/.aether/commands/opencode/import-signals.md +68 -0
  88. package/.aether/commands/opencode/init.md +518 -0
  89. package/.aether/commands/opencode/insert-phase.md +111 -0
  90. package/.aether/commands/opencode/interpret.md +272 -0
  91. package/.aether/commands/opencode/lay-eggs.md +213 -0
  92. package/.aether/commands/opencode/maturity.md +108 -0
  93. package/.aether/commands/opencode/memory-details.md +83 -0
  94. package/.aether/commands/opencode/migrate-state.md +165 -0
  95. package/.aether/commands/opencode/oracle.md +593 -0
  96. package/.aether/commands/opencode/organize.md +226 -0
  97. package/.aether/commands/opencode/patrol.md +626 -0
  98. package/.aether/commands/opencode/pause-colony.md +203 -0
  99. package/.aether/commands/opencode/phase.md +113 -0
  100. package/.aether/commands/opencode/pheromones.md +162 -0
  101. package/.aether/commands/opencode/plan.md +684 -0
  102. package/.aether/commands/opencode/preferences.md +71 -0
  103. package/.aether/commands/opencode/quick.md +91 -0
  104. package/.aether/commands/opencode/redirect.md +84 -0
  105. package/.aether/commands/opencode/resume-colony.md +190 -0
  106. package/.aether/commands/opencode/resume.md +394 -0
  107. package/.aether/commands/opencode/run.md +237 -0
  108. package/.aether/commands/opencode/seal.md +452 -0
  109. package/.aether/commands/opencode/skill-create.md +63 -0
  110. package/.aether/commands/opencode/status.md +307 -0
  111. package/.aether/commands/opencode/swarm.md +15 -0
  112. package/.aether/commands/opencode/tunnels.md +400 -0
  113. package/.aether/commands/opencode/update.md +127 -0
  114. package/.aether/commands/opencode/verify-castes.md +139 -0
  115. package/.aether/commands/opencode/watch.md +227 -0
  116. package/.aether/docs/command-playbooks/build-full.md +1 -1
  117. package/.aether/docs/command-playbooks/build-prep.md +10 -3
  118. package/.aether/docs/command-playbooks/build-verify.md +51 -0
  119. package/.aether/docs/command-playbooks/continue-advance.md +115 -6
  120. package/.aether/docs/command-playbooks/continue-verify.md +32 -0
  121. package/.aether/utils/clash-detect.sh +239 -0
  122. package/.aether/utils/hooks/clash-pre-tool-use.js +99 -0
  123. package/.aether/utils/merge-driver-lockfile.sh +35 -0
  124. package/.aether/utils/midden.sh +534 -0
  125. package/.aether/utils/pheromone.sh +1376 -108
  126. package/.aether/utils/queen.sh +2 -4
  127. package/.aether/utils/state-api.sh +25 -4
  128. package/.aether/utils/swarm.sh +1 -1
  129. package/.aether/utils/worktree.sh +189 -0
  130. package/CHANGELOG.md +26 -0
  131. package/README.md +161 -161
  132. package/bin/cli.js +103 -61
  133. package/bin/lib/banner.js +14 -0
  134. package/bin/lib/init.js +8 -7
  135. package/bin/lib/interactive-setup.js +251 -0
  136. package/bin/npx-entry.js +21 -0
  137. package/bin/npx-install.js +9 -167
  138. package/bin/validate-package.sh +23 -0
  139. package/package.json +2 -2
  140. package/.aether/docs/plans/pheromone-display-plan.md +0 -257
  141. package/.aether/schemas/example-prompt-builder.xml +0 -234
  142. package/.aether/scripts/incident-test-add.sh +0 -47
  143. package/.aether/scripts/weekly-audit.sh +0 -79
@@ -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
- local tmp="${DATA_DIR}/COLONY_STATE.json.tmp.$$"
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
- local tmp_state="${DATA_DIR}/COLONY_STATE.json.tmp.$$"
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
- sm_expr="${1:-}"
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
  }
@@ -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.