aether-colony 3.1.17 → 5.0.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.
Files changed (183) hide show
  1. package/{runtime → .aether}/CONTEXT.md +1 -1
  2. package/{runtime → .aether}/aether-utils.sh +1772 -98
  3. package/.aether/docs/QUEEN-SYSTEM.md +211 -0
  4. package/.aether/docs/QUEEN.md +84 -0
  5. package/.aether/docs/README.md +68 -0
  6. package/.aether/docs/caste-system.md +48 -0
  7. package/{runtime → .aether/docs/disciplines}/DISCIPLINES.md +8 -8
  8. package/.aether/docs/error-codes.md +268 -0
  9. package/{runtime → .aether}/docs/known-issues.md +42 -26
  10. package/.aether/docs/queen-commands.md +97 -0
  11. package/.aether/exchange/colony-registry.xml +11 -0
  12. package/{runtime → .aether}/exchange/pheromone-xml.sh +2 -1
  13. package/.aether/exchange/pheromones.xml +87 -0
  14. package/.aether/exchange/queen-wisdom.xml +14 -0
  15. package/{runtime → .aether}/exchange/registry-xml.sh +7 -3
  16. package/{runtime → .aether}/exchange/wisdom-xml.sh +11 -4
  17. package/.aether/rules/aether-colony.md +134 -0
  18. package/.aether/schemas/example-prompt-builder.xml +234 -0
  19. package/.aether/templates/colony-state-reset.jq.template +22 -0
  20. package/.aether/templates/colony-state.template.json +35 -0
  21. package/.aether/templates/constraints.template.json +9 -0
  22. package/.aether/templates/crowned-anthill.template.md +36 -0
  23. package/.aether/templates/handoff-build-error.template.md +30 -0
  24. package/.aether/templates/handoff-build-success.template.md +39 -0
  25. package/.aether/templates/handoff.template.md +40 -0
  26. package/{runtime → .aether}/utils/atomic-write.sh +5 -5
  27. package/{runtime → .aether}/utils/chamber-compare.sh +23 -10
  28. package/{runtime → .aether}/utils/chamber-utils.sh +32 -20
  29. package/{runtime → .aether}/utils/error-handler.sh +13 -1
  30. package/{runtime → .aether}/utils/file-lock.sh +49 -13
  31. package/.aether/utils/semantic-cli.sh +413 -0
  32. package/{runtime → .aether}/utils/xml-compose.sh +7 -1
  33. package/.aether/utils/xml-convert.sh +273 -0
  34. package/.aether/utils/xml-query.sh +201 -0
  35. package/.aether/utils/xml-utils.sh +110 -0
  36. package/{runtime → .aether}/workers.md +14 -17
  37. package/.claude/agents/ant/aether-ambassador.md +264 -0
  38. package/.claude/agents/ant/aether-archaeologist.md +322 -0
  39. package/.claude/agents/ant/aether-auditor.md +266 -0
  40. package/.claude/agents/ant/aether-builder.md +187 -0
  41. package/.claude/agents/ant/aether-chaos.md +268 -0
  42. package/.claude/agents/ant/aether-chronicler.md +304 -0
  43. package/.claude/agents/ant/aether-gatekeeper.md +325 -0
  44. package/.claude/agents/ant/aether-includer.md +373 -0
  45. package/.claude/agents/ant/aether-keeper.md +271 -0
  46. package/.claude/agents/ant/aether-measurer.md +317 -0
  47. package/.claude/agents/ant/aether-probe.md +210 -0
  48. package/.claude/agents/ant/aether-queen.md +325 -0
  49. package/.claude/agents/ant/aether-route-setter.md +173 -0
  50. package/.claude/agents/ant/aether-sage.md +353 -0
  51. package/.claude/agents/ant/aether-scout.md +142 -0
  52. package/.claude/agents/ant/aether-surveyor-disciplines.md +416 -0
  53. package/.claude/agents/ant/aether-surveyor-nest.md +354 -0
  54. package/.claude/agents/ant/aether-surveyor-pathogens.md +288 -0
  55. package/.claude/agents/ant/aether-surveyor-provisions.md +359 -0
  56. package/.claude/agents/ant/aether-tracker.md +265 -0
  57. package/.claude/agents/ant/aether-watcher.md +244 -0
  58. package/.claude/agents/ant/aether-weaver.md +247 -0
  59. package/.claude/commands/ant/archaeology.md +16 -7
  60. package/.claude/commands/ant/build.md +415 -284
  61. package/.claude/commands/ant/chaos.md +19 -10
  62. package/.claude/commands/ant/colonize.md +58 -24
  63. package/.claude/commands/ant/continue.md +155 -145
  64. package/.claude/commands/ant/council.md +15 -5
  65. package/.claude/commands/ant/dream.md +16 -7
  66. package/.claude/commands/ant/entomb.md +274 -157
  67. package/.claude/commands/ant/feedback.md +33 -29
  68. package/.claude/commands/ant/flag.md +18 -10
  69. package/.claude/commands/ant/flags.md +14 -6
  70. package/.claude/commands/ant/focus.md +29 -21
  71. package/.claude/commands/ant/help.md +11 -1
  72. package/.claude/commands/ant/history.md +10 -0
  73. package/.claude/commands/ant/init.md +91 -65
  74. package/.claude/commands/ant/interpret.md +15 -4
  75. package/.claude/commands/ant/lay-eggs.md +55 -7
  76. package/.claude/commands/ant/maturity.md +11 -1
  77. package/.claude/commands/ant/migrate-state.md +14 -2
  78. package/.claude/commands/ant/oracle.md +23 -15
  79. package/.claude/commands/ant/organize.md +29 -20
  80. package/.claude/commands/ant/pause-colony.md +17 -7
  81. package/.claude/commands/ant/phase.md +17 -8
  82. package/.claude/commands/ant/plan.md +20 -9
  83. package/.claude/commands/ant/redirect.md +29 -32
  84. package/.claude/commands/ant/resume-colony.md +19 -9
  85. package/.claude/commands/ant/resume.md +272 -96
  86. package/.claude/commands/ant/seal.md +201 -191
  87. package/.claude/commands/ant/status.md +71 -32
  88. package/.claude/commands/ant/swarm.md +26 -44
  89. package/.claude/commands/ant/tunnels.md +279 -105
  90. package/.claude/commands/ant/update.md +81 -20
  91. package/.claude/commands/ant/verify-castes.md +14 -4
  92. package/.claude/commands/ant/watch.md +13 -12
  93. package/.opencode/agents/aether-ambassador.md +63 -20
  94. package/.opencode/agents/aether-archaeologist.md +29 -12
  95. package/.opencode/agents/aether-auditor.md +51 -18
  96. package/.opencode/agents/aether-builder.md +69 -19
  97. package/.opencode/agents/aether-chaos.md +29 -12
  98. package/.opencode/agents/aether-chronicler.md +60 -18
  99. package/.opencode/agents/aether-gatekeeper.md +27 -18
  100. package/.opencode/agents/aether-includer.md +27 -18
  101. package/.opencode/agents/aether-keeper.md +89 -18
  102. package/.opencode/agents/aether-measurer.md +27 -18
  103. package/.opencode/agents/aether-probe.md +60 -18
  104. package/.opencode/agents/aether-queen.md +172 -24
  105. package/.opencode/agents/aether-route-setter.md +57 -12
  106. package/.opencode/agents/aether-sage.md +26 -18
  107. package/.opencode/agents/aether-scout.md +27 -19
  108. package/.opencode/agents/aether-surveyor-disciplines.md +53 -1
  109. package/.opencode/agents/aether-surveyor-nest.md +53 -1
  110. package/.opencode/agents/aether-surveyor-pathogens.md +51 -1
  111. package/.opencode/agents/aether-surveyor-provisions.md +53 -1
  112. package/.opencode/agents/aether-tracker.md +64 -18
  113. package/.opencode/agents/aether-watcher.md +66 -19
  114. package/.opencode/agents/aether-weaver.md +61 -18
  115. package/.opencode/commands/ant/build.md +406 -192
  116. package/.opencode/commands/ant/continue.md +66 -76
  117. package/.opencode/commands/ant/entomb.md +106 -45
  118. package/.opencode/commands/ant/init.md +46 -48
  119. package/.opencode/commands/ant/organize.md +5 -5
  120. package/.opencode/commands/ant/resume.md +334 -0
  121. package/.opencode/commands/ant/seal.md +33 -24
  122. package/.opencode/commands/ant/status.md +11 -0
  123. package/.opencode/commands/ant/tunnels.md +149 -0
  124. package/.opencode/commands/ant/update.md +59 -16
  125. package/CHANGELOG.md +79 -0
  126. package/README.md +135 -353
  127. package/bin/cli.js +243 -122
  128. package/bin/generate-commands.sh +2 -2
  129. package/bin/lib/init.js +13 -3
  130. package/bin/lib/update-transaction.js +119 -117
  131. package/bin/sync-to-runtime.sh +5 -137
  132. package/bin/validate-package.sh +84 -0
  133. package/package.json +9 -6
  134. package/.opencode/agents/aether-architect.md +0 -66
  135. package/.opencode/agents/aether-guardian.md +0 -107
  136. package/.opencode/agents/workers.md +0 -1034
  137. package/runtime/QUEEN_ANT_ARCHITECTURE.md +0 -402
  138. package/runtime/data/signatures.json +0 -41
  139. package/runtime/docs/AETHER-2.0-IMPLEMENTATION-PLAN.md +0 -1343
  140. package/runtime/docs/AETHER-PHEROMONE-SYSTEM-MASTER-SPEC.md +0 -2642
  141. package/runtime/docs/PHEROMONE-INJECTION.md +0 -240
  142. package/runtime/docs/PHEROMONE-INTEGRATION.md +0 -192
  143. package/runtime/docs/PHEROMONE-SYSTEM-DESIGN.md +0 -426
  144. package/runtime/docs/README.md +0 -94
  145. package/runtime/docs/VISUAL-OUTPUT-SPEC.md +0 -219
  146. package/runtime/docs/biological-reference.md +0 -272
  147. package/runtime/docs/codebase-review.md +0 -399
  148. package/runtime/docs/command-sync.md +0 -164
  149. package/runtime/docs/constraints.md +0 -116
  150. package/runtime/docs/implementation-learnings.md +0 -89
  151. package/runtime/docs/namespace.md +0 -148
  152. package/runtime/docs/pathogen-schema-example.json +0 -36
  153. package/runtime/docs/pathogen-schema.md +0 -111
  154. package/runtime/docs/planning-discipline.md +0 -159
  155. package/runtime/docs/progressive-disclosure.md +0 -184
  156. package/runtime/lib/queen-utils.sh +0 -729
  157. package/runtime/planning.md +0 -159
  158. package/runtime/recover.sh +0 -136
  159. package/runtime/utils/xml-utils.sh +0 -2196
  160. package/runtime/workers-new-castes.md +0 -516
  161. /package/{runtime → .aether/docs/disciplines}/coding-standards.md +0 -0
  162. /package/{runtime → .aether/docs/disciplines}/debugging.md +0 -0
  163. /package/{runtime → .aether/docs/disciplines}/learning.md +0 -0
  164. /package/{runtime → .aether/docs/disciplines}/tdd.md +0 -0
  165. /package/{runtime → .aether/docs/disciplines}/verification-loop.md +0 -0
  166. /package/{runtime → .aether/docs/disciplines}/verification.md +0 -0
  167. /package/{runtime → .aether}/docs/pheromones.md +0 -0
  168. /package/{runtime → .aether}/model-profiles.yaml +0 -0
  169. /package/{runtime → .aether}/schemas/aether-types.xsd +0 -0
  170. /package/{runtime → .aether}/schemas/colony-registry.xsd +0 -0
  171. /package/{runtime → .aether}/schemas/pheromone.xsd +0 -0
  172. /package/{runtime → .aether}/schemas/prompt.xsd +0 -0
  173. /package/{runtime → .aether}/schemas/queen-wisdom.xsd +0 -0
  174. /package/{runtime → .aether}/schemas/worker-priming.xsd +0 -0
  175. /package/{runtime → .aether}/templates/QUEEN.md.template +0 -0
  176. /package/{runtime → .aether}/utils/colorize-log.sh +0 -0
  177. /package/{runtime → .aether}/utils/queen-to-md.xsl +0 -0
  178. /package/{runtime → .aether}/utils/spawn-tree.sh +0 -0
  179. /package/{runtime → .aether}/utils/spawn-with-model.sh +0 -0
  180. /package/{runtime → .aether}/utils/state-loader.sh +0 -0
  181. /package/{runtime → .aether}/utils/swarm-display.sh +0 -0
  182. /package/{runtime → .aether}/utils/watch-spawn-tree.sh +0 -0
  183. /package/{runtime → .aether}/utils/xml-core.sh +0 -0
@@ -0,0 +1,413 @@
1
+ #!/bin/bash
2
+ # Semantic CLI - Shell interface to Python semantic layer
3
+ #
4
+ # Provides semantic search and indexing capabilities for Aether colony.
5
+ # Uses Python semantic_layer.py for embeddings and similarity search.
6
+ #
7
+ # Usage:
8
+ # source .aether/utils/semantic-cli.sh
9
+ # semantic-init # Initialize semantic store
10
+ # semantic-index "text" # Add text to index
11
+ # semantic-search "query" # Find similar entries
12
+ # semantic-rebuild # Rebuild from all sources
13
+
14
+ # Only set strict mode when executed directly, not when sourced
15
+ if [[ "${BASH_SOURCE[0]:-$0}" == "${0}" ]]; then
16
+ set -euo pipefail
17
+ fi
18
+
19
+ # Get script directory for relative paths
20
+ # Fallback for when BASH_SOURCE isn't set (non-interactive sourcing)
21
+ if [[ -n "${BASH_SOURCE[0]:-}" ]]; then
22
+ SEMANTIC_CLI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
23
+ else
24
+ # Try to find .aether directory from current location
25
+ if [[ -d ".aether" ]]; then
26
+ SEMANTIC_CLI_DIR="$(pwd)/.aether/utils"
27
+ elif [[ -d "../.aether" ]]; then
28
+ SEMANTIC_CLI_DIR="$(cd .. && pwd)/.aether/utils"
29
+ else
30
+ # Last resort - use aether-utils.sh's detected AETHER_DIR if available
31
+ SEMANTIC_CLI_DIR="${AETHER_DIR:-$HOME/.aether/system}/utils"
32
+ fi
33
+ fi
34
+ AETHER_DIR="$(dirname "$SEMANTIC_CLI_DIR")"
35
+ PROJECT_ROOT="$(dirname "$AETHER_DIR")"
36
+
37
+ # Data directory for semantic store
38
+ SEMANTIC_DATA_DIR="${AETHER_DIR}/data/semantic"
39
+ SEMANTIC_EMBEDDINGS_FILE="${SEMANTIC_DATA_DIR}/embeddings.json"
40
+
41
+ # Check if Python dependencies are available
42
+ semantic-check-deps() {
43
+ python3 -c "import sys; sys.path.insert(0, '$AETHER_DIR'); from semantic_layer import EmbeddingModel; print('ok')" 2>/dev/null
44
+ }
45
+
46
+ # Initialize semantic store directory
47
+ semantic-init() {
48
+ mkdir -p "$SEMANTIC_DATA_DIR"
49
+
50
+ if [[ ! -f "$SEMANTIC_DATA_DIR/index.json" ]]; then
51
+ cat > "$SEMANTIC_DATA_DIR/index.json" << 'EOF'
52
+ {
53
+ "version": "1.0",
54
+ "entries": [],
55
+ "last_updated": null,
56
+ "stats": {
57
+ "total_entries": 0,
58
+ "by_source": {}
59
+ }
60
+ }
61
+ EOF
62
+ fi
63
+
64
+ if [[ ! -f "$SEMANTIC_EMBEDDINGS_FILE" ]]; then
65
+ echo '{"embeddings":{}}' > "$SEMANTIC_EMBEDDINGS_FILE"
66
+ fi
67
+ }
68
+
69
+ # Index a single text entry
70
+ # Usage: semantic-index <text> <source> [entry_id]
71
+ semantic-index() {
72
+ local text="${1:-}"
73
+ local source="${2:-unknown}"
74
+ local entry_id="${3:-}"
75
+
76
+ if [[ -z "$text" ]]; then
77
+ json_err 1 "semantic-index requires text argument"
78
+ return 1
79
+ fi
80
+
81
+ semantic-init
82
+
83
+ # Generate entry ID if not provided
84
+ if [[ -z "$entry_id" ]]; then
85
+ entry_id="${source}_$(date +%s)_$((RANDOM % 10000))"
86
+ fi
87
+
88
+ local timestamp
89
+ timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
90
+
91
+ # Call Python to compute embedding and save everything
92
+ python3 << PYTHON_SCRIPT 2>/dev/null
93
+ import sys
94
+ import json
95
+ sys.path.insert(0, '$AETHER_DIR')
96
+ from semantic_layer import EmbeddingModel
97
+
98
+ # Compute embedding
99
+ model = EmbeddingModel()
100
+ embedding = model.encode('''$text''')
101
+
102
+ # Load existing embeddings
103
+ try:
104
+ with open('$SEMANTIC_EMBEDDINGS_FILE', 'r') as f:
105
+ emb_store = json.load(f)
106
+ except:
107
+ emb_store = {'embeddings': {}}
108
+
109
+ # Store embedding
110
+ emb_store['embeddings']['$entry_id'] = {
111
+ 'embedding': embedding,
112
+ 'text': '''$text''',
113
+ 'source': '$source',
114
+ 'indexed_at': '$timestamp'
115
+ }
116
+
117
+ # Save embeddings
118
+ with open('$SEMANTIC_EMBEDDINGS_FILE', 'w') as f:
119
+ json.dump(emb_store, f)
120
+
121
+ # Update index
122
+ try:
123
+ with open('$SEMANTIC_DATA_DIR/index.json', 'r') as f:
124
+ index = json.load(f)
125
+ except:
126
+ index = {'version': '1.0', 'entries': [], 'stats': {}}
127
+
128
+ index['entries'].append({
129
+ 'id': '$entry_id',
130
+ 'source': '$source',
131
+ 'text_preview': '''${text:0:200}''',
132
+ 'indexed_at': '$timestamp'
133
+ })
134
+ index['last_updated'] = '$timestamp'
135
+ index['stats']['total_entries'] = len(index['entries'])
136
+
137
+ by_source = {}
138
+ for e in index['entries']:
139
+ src = e.get('source', 'unknown')
140
+ by_source[src] = by_source.get(src, 0) + 1
141
+ index['stats']['by_source'] = by_source
142
+
143
+ with open('$SEMANTIC_DATA_DIR/index.json', 'w') as f:
144
+ json.dump(index, f, indent=2)
145
+
146
+ print(json.dumps({
147
+ 'ok': True,
148
+ 'entry_id': '$entry_id',
149
+ 'embedding_dim': len(embedding),
150
+ 'source': '$source'
151
+ }))
152
+ PYTHON_SCRIPT
153
+ }
154
+
155
+ # Search for similar entries
156
+ # Usage: semantic-search <query> [top_k] [threshold] [source_filter]
157
+ semantic-search() {
158
+ local query="${1:-}"
159
+ local top_k="${2:-5}"
160
+ local threshold="${3:-0.5}"
161
+ local source_filter="${4:-}"
162
+
163
+ if [[ -z "$query" ]]; then
164
+ json_err 1 "semantic-search requires query argument"
165
+ return 1
166
+ fi
167
+
168
+ if [[ ! -f "$SEMANTIC_EMBEDDINGS_FILE" ]]; then
169
+ json_ok '{"results":[]}' "No semantic index found. Run semantic-init first."
170
+ return 0
171
+ fi
172
+
173
+ # Call Python to search
174
+ python3 << PYTHON_SCRIPT 2>/dev/null
175
+ import sys
176
+ import json
177
+ import math
178
+ sys.path.insert(0, '$AETHER_DIR')
179
+ from semantic_layer import EmbeddingModel
180
+
181
+ def cosine_similarity(v1, v2):
182
+ dot = sum(a*b for a,b in zip(v1, v2))
183
+ norm1 = math.sqrt(sum(a*a for a in v1))
184
+ norm2 = math.sqrt(sum(b*b for b in v2))
185
+ if norm1 == 0 or norm2 == 0:
186
+ return 0.0
187
+ return dot / (norm1 * norm2)
188
+
189
+ # Compute query embedding
190
+ model = EmbeddingModel()
191
+ query_emb = model.encode('''$query''')
192
+
193
+ # Load stored embeddings
194
+ with open('$SEMANTIC_EMBEDDINGS_FILE', 'r') as f:
195
+ emb_store = json.load(f)
196
+
197
+ # Search
198
+ results = []
199
+ for entry_id, data in emb_store.get('embeddings', {}).items():
200
+ # Source filter
201
+ source = data.get('source', '')
202
+ if '$source_filter' and source != '$source_filter':
203
+ continue
204
+
205
+ stored_emb = data.get('embedding', [])
206
+ if not stored_emb:
207
+ continue
208
+
209
+ similarity = cosine_similarity(query_emb, stored_emb)
210
+
211
+ if similarity >= $threshold:
212
+ results.append({
213
+ 'id': entry_id,
214
+ 'text': data.get('text', ''),
215
+ 'source': source,
216
+ 'similarity': round(similarity, 3),
217
+ 'indexed_at': data.get('indexed_at', '')
218
+ })
219
+
220
+ # Sort by similarity
221
+ results.sort(key=lambda x: x['similarity'], reverse=True)
222
+ results = results[:$top_k]
223
+
224
+ print(json.dumps({
225
+ 'ok': True,
226
+ 'query': '''$query''',
227
+ 'count': len(results),
228
+ 'results': results
229
+ }))
230
+ PYTHON_SCRIPT
231
+ }
232
+
233
+ # Find similar entries to check for duplicates
234
+ semantic-find-duplicate() {
235
+ local text="${1:-}"
236
+ local threshold="${2:-0.85}"
237
+
238
+ if [[ -z "$text" ]]; then
239
+ json_err 1 "semantic-find-duplicate requires text argument"
240
+ return 1
241
+ fi
242
+
243
+ local result
244
+ result=$(semantic-search "$text" 3 "$threshold")
245
+
246
+ local count
247
+ count=$(echo "$result" | jq -r '.count // 0')
248
+
249
+ if [[ "$count" -gt 0 ]]; then
250
+ echo "$result" | jq '. + {"is_duplicate": true}'
251
+ else
252
+ json_ok "[]" "No duplicates found"
253
+ fi
254
+ }
255
+
256
+ # Rebuild entire index from all Aether data sources
257
+ semantic-rebuild() {
258
+ echo "Rebuilding semantic index from all sources..."
259
+
260
+ # Reset
261
+ rm -rf "$SEMANTIC_DATA_DIR"/*
262
+ semantic-init
263
+
264
+ local count=0
265
+
266
+ # Index flags
267
+ if [[ -f "$AETHER_DIR/data/flags.json" ]]; then
268
+ echo " Indexing flags..."
269
+ local flags_json
270
+ flags_json=$(jq -c '.flags[]' "$AETHER_DIR/data/flags.json" 2>/dev/null || echo "")
271
+
272
+ while IFS= read -r flag; do
273
+ [[ -z "$flag" ]] && continue
274
+ local flag_id flag_title flag_desc
275
+ flag_id=$(echo "$flag" | jq -r '.id // empty')
276
+ flag_title=$(echo "$flag" | jq -r '.title // empty')
277
+ flag_desc=$(echo "$flag" | jq -r '.description // empty')
278
+
279
+ if [[ -n "$flag_title" ]]; then
280
+ semantic-index "$flag_title: $flag_desc" "flags" "$flag_id" >/dev/null 2>&1 || true
281
+ ((count++)) || true
282
+ fi
283
+ done <<< "$flags_json"
284
+ fi
285
+
286
+ # Index dreams
287
+ if [[ -d "$AETHER_DIR/dreams" ]]; then
288
+ echo " Indexing dreams..."
289
+ for dream in "$AETHER_DIR/dreams"/*.md; do
290
+ [[ -f "$dream" ]] || continue
291
+ local dream_id dream_content
292
+ dream_id=$(basename "$dream" .md)
293
+ dream_content=$(head -100 "$dream" | tr '\n' ' ')
294
+
295
+ if [[ -n "$dream_content" ]]; then
296
+ semantic-index "$dream_content" "dreams" "$dream_id" >/dev/null 2>&1 || true
297
+ ((count++)) || true
298
+ fi
299
+ done
300
+ fi
301
+
302
+ # Index pheromones
303
+ if [[ -f "$AETHER_DIR/data/pheromones.json" ]]; then
304
+ echo " Indexing pheromones..."
305
+ local signals_json
306
+ signals_json=$(jq -c '.signals[]' "$AETHER_DIR/data/pheromones.json" 2>/dev/null || echo "")
307
+
308
+ while IFS= read -r signal; do
309
+ [[ -z "$signal" ]] && continue
310
+ local sig_id sig_type sig_content
311
+ sig_id=$(echo "$signal" | jq -r '.id // empty')
312
+ sig_type=$(echo "$signal" | jq -r '.type // empty')
313
+ sig_content=$(echo "$signal" | jq -r '.content.text // .content // empty')
314
+
315
+ if [[ -n "$sig_content" ]]; then
316
+ semantic-index "[$sig_type] $sig_content" "pheromones" "$sig_id" >/dev/null 2>&1 || true
317
+ ((count++)) || true
318
+ fi
319
+ done <<< "$signals_json"
320
+ fi
321
+
322
+ # Index QUEEN.md if exists
323
+ if [[ -f "$AETHER_DIR/data/QUEEN.md" ]]; then
324
+ echo " Indexing QUEEN.md..."
325
+ local queen_content
326
+ queen_content=$(cat "$AETHER_DIR/data/QUEEN.md" | tr '\n' ' ')
327
+ semantic-index "$queen_content" "queen" "queen-wisdom" >/dev/null 2>&1 || true
328
+ ((count++)) || true
329
+ fi
330
+
331
+ echo "✅ Indexed $count entries"
332
+ jq -c '.stats' "$SEMANTIC_DATA_DIR/index.json"
333
+ }
334
+
335
+ # Get context relevant to a task (for worker injection)
336
+ semantic-get-context() {
337
+ local task="${1:-}"
338
+ local max_results="${2:-3}"
339
+
340
+ if [[ -z "$task" ]]; then
341
+ echo ""
342
+ return 0
343
+ fi
344
+
345
+ if ! semantic-check-deps >/dev/null 2>&1; then
346
+ echo ""
347
+ return 0
348
+ fi
349
+
350
+ local result
351
+ result=$(semantic-search "$task" "$max_results" 0.5 2>/dev/null || echo '{"results":[]}')
352
+
353
+ local count
354
+ count=$(echo "$result" | jq -r '.count // 0')
355
+
356
+ if [[ "$count" -eq 0 ]]; then
357
+ echo ""
358
+ return 0
359
+ fi
360
+
361
+ echo "---"
362
+ echo "## Relevant Context (semantic search)"
363
+ echo ""
364
+ echo "$result" | jq -r '.results[] | "### \(.source // "unknown") (similarity: \(.similarity))\n\(.text[:200] // .text)\n"'
365
+ echo "---"
366
+ }
367
+
368
+ # Check semantic layer status
369
+ semantic-status() {
370
+ if [[ ! -f "$SEMANTIC_DATA_DIR/index.json" ]]; then
371
+ json_ok '{"initialized": false, "message": "Run semantic-init to initialize"}'
372
+ return 0
373
+ fi
374
+
375
+ local deps_ok
376
+ if semantic-check-deps >/dev/null 2>&1; then
377
+ deps_ok="true"
378
+ else
379
+ deps_ok="false"
380
+ fi
381
+
382
+ local entry_count
383
+ entry_count=$(jq '.entries | length' "$SEMANTIC_DATA_DIR/index.json" 2>/dev/null || echo "0")
384
+
385
+ jq -n --arg deps_ok "$deps_ok" --arg entries "$entry_count" \
386
+ '{"initialized": true, "dependencies_ok": ($deps_ok == "true"), "total_entries": ($entries | tonumber)}'
387
+ }
388
+
389
+ # Helper: Output JSON OK response
390
+ json_ok() {
391
+ local result="${1:-}"
392
+ local message="${2:-}"
393
+ jq -n --argjson result "$result" --arg message "$message" \
394
+ '{"ok": true, "result": $result, "message": $message}'
395
+ }
396
+
397
+ # Helper: Output JSON error response
398
+ json_err() {
399
+ local code="${1:-1}"
400
+ local message="${2:-Unknown error}"
401
+ jq -n --arg code "$code" --arg message "$message" \
402
+ '{"ok": false, "error": {"code": $code, "message": $message}}'
403
+ }
404
+
405
+ # Export functions
406
+ export -f semantic-init
407
+ export -f semantic-index
408
+ export -f semantic-search
409
+ export -f semantic-find-duplicate
410
+ export -f semantic-rebuild
411
+ export -f semantic-get-context
412
+ export -f semantic-status
413
+ export -f semantic-check-deps
@@ -5,14 +5,20 @@
5
5
  # Usage: source .aether/utils/xml-compose.sh
6
6
  # xml-compose <input_xml> [output_xml]
7
7
  # xml-compose-worker-priming <priming_xml> [output_xml]
8
+ # xml-list-includes <xml_file>
8
9
  #
9
10
  # These functions enable declarative composition of worker configurations
10
11
  # using XInclude directives to merge queen-wisdom, active-trails, and stack-profiles.
11
12
 
12
13
  set -euo pipefail
13
14
 
14
- # Note: This file should be sourced AFTER xml-utils.sh
15
+ # Note: This file should be sourced AFTER xml-utils.sh or xml-core.sh
15
16
  # It relies on xml_json_ok, xml_json_err, and XMLLINT_AVAILABLE variables
17
+ # Source xml-core.sh for JSON helpers and tool detection if not already loaded
18
+ if ! type xml_json_ok &>/dev/null; then
19
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
+ source "$SCRIPT_DIR/xml-core.sh"
21
+ fi
16
22
 
17
23
  # ============================================================================
18
24
  # Path Validation (Security)