aether-colony 5.0.0 → 5.2.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 (317) hide show
  1. package/.aether/aether-utils.sh +3226 -3345
  2. package/.aether/agents-claude/aether-ambassador.md +265 -0
  3. package/.aether/agents-claude/aether-archaeologist.md +327 -0
  4. package/.aether/agents-claude/aether-architect.md +236 -0
  5. package/.aether/agents-claude/aether-auditor.md +271 -0
  6. package/.aether/agents-claude/aether-builder.md +224 -0
  7. package/.aether/agents-claude/aether-chaos.md +269 -0
  8. package/.aether/agents-claude/aether-chronicler.md +305 -0
  9. package/.aether/agents-claude/aether-gatekeeper.md +330 -0
  10. package/.aether/agents-claude/aether-includer.md +374 -0
  11. package/.aether/agents-claude/aether-keeper.md +272 -0
  12. package/.aether/agents-claude/aether-measurer.md +322 -0
  13. package/.aether/agents-claude/aether-oracle.md +237 -0
  14. package/.aether/agents-claude/aether-probe.md +211 -0
  15. package/.aether/agents-claude/aether-queen.md +330 -0
  16. package/.aether/agents-claude/aether-route-setter.md +178 -0
  17. package/.aether/agents-claude/aether-sage.md +418 -0
  18. package/.aether/agents-claude/aether-scout.md +179 -0
  19. package/.aether/agents-claude/aether-surveyor-disciplines.md +417 -0
  20. package/.aether/agents-claude/aether-surveyor-nest.md +355 -0
  21. package/.aether/agents-claude/aether-surveyor-pathogens.md +289 -0
  22. package/.aether/agents-claude/aether-surveyor-provisions.md +360 -0
  23. package/.aether/agents-claude/aether-tracker.md +270 -0
  24. package/.aether/agents-claude/aether-watcher.md +280 -0
  25. package/.aether/agents-claude/aether-weaver.md +248 -0
  26. package/.aether/commands/archaeology.yaml +653 -0
  27. package/.aether/commands/build.yaml +1221 -0
  28. package/.aether/commands/chaos.yaml +653 -0
  29. package/.aether/commands/colonize.yaml +442 -0
  30. package/.aether/commands/continue.yaml +1484 -0
  31. package/.aether/commands/council.yaml +509 -0
  32. package/.aether/commands/data-clean.yaml +80 -0
  33. package/.aether/commands/dream.yaml +275 -0
  34. package/.aether/commands/entomb.yaml +863 -0
  35. package/.aether/commands/export-signals.yaml +64 -0
  36. package/.aether/commands/feedback.yaml +158 -0
  37. package/.aether/commands/flag.yaml +160 -0
  38. package/.aether/commands/flags.yaml +177 -0
  39. package/.aether/commands/focus.yaml +112 -0
  40. package/.aether/commands/help.yaml +167 -0
  41. package/.aether/commands/history.yaml +137 -0
  42. package/.aether/commands/import-signals.yaml +79 -0
  43. package/.aether/commands/init.yaml +502 -0
  44. package/.aether/commands/insert-phase.yaml +102 -0
  45. package/.aether/commands/interpret.yaml +285 -0
  46. package/.aether/commands/lay-eggs.yaml +224 -0
  47. package/.aether/commands/maturity.yaml +122 -0
  48. package/.aether/commands/memory-details.yaml +74 -0
  49. package/.aether/commands/migrate-state.yaml +174 -0
  50. package/.aether/commands/oracle.yaml +1224 -0
  51. package/.aether/commands/organize.yaml +446 -0
  52. package/.aether/commands/patrol.yaml +621 -0
  53. package/.aether/commands/pause-colony.yaml +424 -0
  54. package/.aether/commands/phase.yaml +124 -0
  55. package/.aether/commands/pheromones.yaml +153 -0
  56. package/.aether/commands/plan.yaml +1364 -0
  57. package/.aether/commands/preferences.yaml +63 -0
  58. package/.aether/commands/quick.yaml +104 -0
  59. package/.aether/commands/redirect.yaml +123 -0
  60. package/.aether/commands/resume-colony.yaml +375 -0
  61. package/.aether/commands/resume.yaml +407 -0
  62. package/.aether/commands/run.yaml +229 -0
  63. package/.aether/commands/seal.yaml +1214 -0
  64. package/.aether/commands/skill-create.yaml +337 -0
  65. package/.aether/commands/status.yaml +408 -0
  66. package/.aether/commands/swarm.yaml +352 -0
  67. package/.aether/commands/tunnels.yaml +814 -0
  68. package/.aether/commands/update.yaml +131 -0
  69. package/.aether/commands/verify-castes.yaml +159 -0
  70. package/.aether/commands/watch.yaml +454 -0
  71. package/.aether/docs/INCIDENT_TEMPLATE.md +32 -0
  72. package/.aether/docs/QUEEN-SYSTEM.md +11 -11
  73. package/.aether/docs/README.md +32 -2
  74. package/.aether/docs/command-playbooks/README.md +23 -0
  75. package/.aether/docs/command-playbooks/build-complete.md +349 -0
  76. package/.aether/docs/command-playbooks/build-context.md +282 -0
  77. package/.aether/docs/command-playbooks/build-full.md +1683 -0
  78. package/.aether/docs/command-playbooks/build-prep.md +284 -0
  79. package/.aether/docs/command-playbooks/build-verify.md +405 -0
  80. package/.aether/docs/command-playbooks/build-wave.md +749 -0
  81. package/.aether/docs/command-playbooks/continue-advance.md +524 -0
  82. package/.aether/docs/command-playbooks/continue-finalize.md +447 -0
  83. package/.aether/docs/command-playbooks/continue-full.md +1725 -0
  84. package/.aether/docs/command-playbooks/continue-gates.md +686 -0
  85. package/.aether/docs/command-playbooks/continue-verify.md +407 -0
  86. package/.aether/docs/context-continuity.md +84 -0
  87. package/.aether/docs/disciplines/DISCIPLINES.md +9 -7
  88. package/.aether/docs/error-codes.md +1 -1
  89. package/.aether/docs/known-issues.md +34 -173
  90. package/.aether/docs/pheromones.md +86 -6
  91. package/.aether/docs/plans/pheromone-display-plan.md +257 -0
  92. package/.aether/docs/queen-commands.md +10 -9
  93. package/.aether/docs/source-of-truth-map.md +132 -0
  94. package/.aether/docs/xml-utilities.md +47 -0
  95. package/.aether/rules/aether-colony.md +23 -13
  96. package/.aether/scripts/incident-test-add.sh +47 -0
  97. package/.aether/scripts/weekly-audit.sh +79 -0
  98. package/.aether/skills/.index.json +649 -0
  99. package/.aether/skills/colony/.manifest.json +16 -0
  100. package/.aether/skills/colony/build-discipline/SKILL.md +78 -0
  101. package/.aether/skills/colony/colony-interaction/SKILL.md +56 -0
  102. package/.aether/skills/colony/colony-lifecycle/SKILL.md +77 -0
  103. package/.aether/skills/colony/colony-visuals/SKILL.md +112 -0
  104. package/.aether/skills/colony/context-management/SKILL.md +80 -0
  105. package/.aether/skills/colony/error-presentation/SKILL.md +99 -0
  106. package/.aether/skills/colony/pheromone-protocol/SKILL.md +79 -0
  107. package/.aether/skills/colony/pheromone-visibility/SKILL.md +81 -0
  108. package/.aether/skills/colony/state-safety/SKILL.md +84 -0
  109. package/.aether/skills/colony/worker-priming/SKILL.md +82 -0
  110. package/.aether/skills/domain/.manifest.json +24 -0
  111. package/.aether/skills/domain/README.md +33 -0
  112. package/.aether/skills/domain/django/SKILL.md +49 -0
  113. package/.aether/skills/domain/docker/SKILL.md +52 -0
  114. package/.aether/skills/domain/golang/SKILL.md +52 -0
  115. package/.aether/skills/domain/graphql/SKILL.md +51 -0
  116. package/.aether/skills/domain/html-css/SKILL.md +48 -0
  117. package/.aether/skills/domain/nextjs/SKILL.md +45 -0
  118. package/.aether/skills/domain/nodejs/SKILL.md +53 -0
  119. package/.aether/skills/domain/postgresql/SKILL.md +53 -0
  120. package/.aether/skills/domain/prisma/SKILL.md +59 -0
  121. package/.aether/skills/domain/python/SKILL.md +50 -0
  122. package/.aether/skills/domain/rails/SKILL.md +52 -0
  123. package/.aether/skills/domain/react/SKILL.md +45 -0
  124. package/.aether/skills/domain/rest-api/SKILL.md +58 -0
  125. package/.aether/skills/domain/svelte/SKILL.md +47 -0
  126. package/.aether/skills/domain/tailwind/SKILL.md +45 -0
  127. package/.aether/skills/domain/testing/SKILL.md +53 -0
  128. package/.aether/skills/domain/typescript/SKILL.md +58 -0
  129. package/.aether/skills/domain/vue/SKILL.md +49 -0
  130. package/.aether/templates/QUEEN.md.template +23 -41
  131. package/.aether/templates/colony-state-reset.jq.template +1 -0
  132. package/.aether/templates/colony-state.template.json +4 -0
  133. package/.aether/templates/learning-observations.template.json +6 -0
  134. package/.aether/templates/midden.template.json +13 -0
  135. package/.aether/templates/pheromones.template.json +6 -0
  136. package/.aether/templates/session.template.json +9 -0
  137. package/.aether/utils/atomic-write.sh +63 -17
  138. package/.aether/utils/chamber-utils.sh +145 -2
  139. package/.aether/utils/council.sh +425 -0
  140. package/.aether/utils/emoji-audit.sh +166 -0
  141. package/.aether/utils/error-handler.sh +21 -7
  142. package/.aether/utils/file-lock.sh +182 -27
  143. package/.aether/utils/flag.sh +278 -0
  144. package/.aether/utils/hive.sh +572 -0
  145. package/.aether/utils/immune.sh +508 -0
  146. package/.aether/utils/learning.sh +1928 -0
  147. package/.aether/utils/midden.sh +520 -0
  148. package/.aether/utils/oracle/oracle.md +168 -0
  149. package/.aether/utils/oracle/oracle.sh +1023 -0
  150. package/.aether/utils/pheromone.sh +2029 -0
  151. package/.aether/utils/queen.sh +1710 -0
  152. package/.aether/utils/scan.sh +860 -0
  153. package/.aether/utils/semantic-cli.sh +10 -8
  154. package/.aether/utils/session.sh +816 -0
  155. package/.aether/utils/skills.sh +509 -0
  156. package/.aether/utils/spawn-tree.sh +103 -271
  157. package/.aether/utils/spawn.sh +260 -0
  158. package/.aether/utils/state-api.sh +389 -0
  159. package/.aether/utils/state-loader.sh +8 -6
  160. package/.aether/utils/suggest.sh +611 -0
  161. package/.aether/utils/swarm-display.sh +10 -1
  162. package/.aether/utils/swarm.sh +1004 -0
  163. package/.aether/utils/watch-spawn-tree.sh +11 -2
  164. package/.aether/utils/xml-compose.sh +2 -2
  165. package/.aether/utils/xml-convert.sh +9 -5
  166. package/.aether/utils/xml-core.sh +5 -9
  167. package/.aether/utils/xml-query.sh +4 -4
  168. package/.aether/workers.md +86 -67
  169. package/.claude/agents/ant/aether-ambassador.md +2 -1
  170. package/.claude/agents/ant/aether-archaeologist.md +6 -1
  171. package/.claude/agents/ant/aether-architect.md +236 -0
  172. package/.claude/agents/ant/aether-auditor.md +6 -1
  173. package/.claude/agents/ant/aether-builder.md +38 -1
  174. package/.claude/agents/ant/aether-chaos.md +2 -1
  175. package/.claude/agents/ant/aether-chronicler.md +1 -0
  176. package/.claude/agents/ant/aether-gatekeeper.md +6 -1
  177. package/.claude/agents/ant/aether-includer.md +1 -0
  178. package/.claude/agents/ant/aether-keeper.md +1 -0
  179. package/.claude/agents/ant/aether-measurer.md +6 -1
  180. package/.claude/agents/ant/aether-oracle.md +237 -0
  181. package/.claude/agents/ant/aether-probe.md +2 -1
  182. package/.claude/agents/ant/aether-queen.md +6 -1
  183. package/.claude/agents/ant/aether-route-setter.md +6 -1
  184. package/.claude/agents/ant/aether-sage.md +68 -3
  185. package/.claude/agents/ant/aether-scout.md +38 -1
  186. package/.claude/agents/ant/aether-surveyor-disciplines.md +2 -1
  187. package/.claude/agents/ant/aether-surveyor-nest.md +2 -1
  188. package/.claude/agents/ant/aether-surveyor-pathogens.md +2 -1
  189. package/.claude/agents/ant/aether-surveyor-provisions.md +2 -1
  190. package/.claude/agents/ant/aether-tracker.md +6 -1
  191. package/.claude/agents/ant/aether-watcher.md +37 -1
  192. package/.claude/agents/ant/aether-weaver.md +2 -1
  193. package/.claude/commands/ant/archaeology.md +1 -8
  194. package/.claude/commands/ant/build.md +43 -1159
  195. package/.claude/commands/ant/chaos.md +1 -14
  196. package/.claude/commands/ant/colonize.md +3 -14
  197. package/.claude/commands/ant/continue.md +40 -1026
  198. package/.claude/commands/ant/council.md +213 -15
  199. package/.claude/commands/ant/data-clean.md +81 -0
  200. package/.claude/commands/ant/dream.md +12 -9
  201. package/.claude/commands/ant/entomb.md +62 -87
  202. package/.claude/commands/ant/export-signals.md +57 -0
  203. package/.claude/commands/ant/feedback.md +18 -0
  204. package/.claude/commands/ant/flag.md +12 -0
  205. package/.claude/commands/ant/flags.md +22 -8
  206. package/.claude/commands/ant/focus.md +18 -0
  207. package/.claude/commands/ant/help.md +40 -8
  208. package/.claude/commands/ant/history.md +3 -0
  209. package/.claude/commands/ant/import-signals.md +71 -0
  210. package/.claude/commands/ant/init.md +349 -191
  211. package/.claude/commands/ant/insert-phase.md +105 -0
  212. package/.claude/commands/ant/interpret.md +11 -0
  213. package/.claude/commands/ant/lay-eggs.md +167 -158
  214. package/.claude/commands/ant/maturity.md +22 -11
  215. package/.claude/commands/ant/memory-details.md +77 -0
  216. package/.claude/commands/ant/migrate-state.md +6 -0
  217. package/.claude/commands/ant/oracle.md +317 -62
  218. package/.claude/commands/ant/organize.md +10 -5
  219. package/.claude/commands/ant/patrol.md +620 -0
  220. package/.claude/commands/ant/pause-colony.md +8 -22
  221. package/.claude/commands/ant/phase.md +26 -37
  222. package/.claude/commands/ant/pheromones.md +156 -0
  223. package/.claude/commands/ant/plan.md +199 -50
  224. package/.claude/commands/ant/preferences.md +65 -0
  225. package/.claude/commands/ant/quick.md +100 -0
  226. package/.claude/commands/ant/redirect.md +18 -0
  227. package/.claude/commands/ant/resume-colony.md +37 -22
  228. package/.claude/commands/ant/resume.md +60 -7
  229. package/.claude/commands/ant/run.md +231 -0
  230. package/.claude/commands/ant/seal.md +506 -78
  231. package/.claude/commands/ant/skill-create.md +286 -0
  232. package/.claude/commands/ant/status.md +171 -1
  233. package/.claude/commands/ant/swarm.md +11 -23
  234. package/.claude/commands/ant/tunnels.md +1 -0
  235. package/.claude/commands/ant/update.md +58 -135
  236. package/.claude/commands/ant/verify-castes.md +90 -42
  237. package/.claude/commands/ant/watch.md +1 -0
  238. package/.opencode/agents/aether-ambassador.md +1 -1
  239. package/.opencode/agents/aether-architect.md +133 -0
  240. package/.opencode/agents/aether-builder.md +3 -3
  241. package/.opencode/agents/aether-oracle.md +137 -0
  242. package/.opencode/agents/aether-queen.md +1 -1
  243. package/.opencode/agents/aether-route-setter.md +1 -1
  244. package/.opencode/agents/aether-scout.md +1 -1
  245. package/.opencode/agents/aether-surveyor-disciplines.md +6 -1
  246. package/.opencode/agents/aether-surveyor-nest.md +6 -1
  247. package/.opencode/agents/aether-surveyor-pathogens.md +6 -1
  248. package/.opencode/agents/aether-surveyor-provisions.md +6 -1
  249. package/.opencode/agents/aether-tracker.md +1 -1
  250. package/.opencode/agents/aether-watcher.md +1 -1
  251. package/.opencode/agents/aether-weaver.md +1 -1
  252. package/.opencode/commands/ant/archaeology.md +7 -14
  253. package/.opencode/commands/ant/build.md +54 -88
  254. package/.opencode/commands/ant/chaos.md +7 -24
  255. package/.opencode/commands/ant/colonize.md +10 -17
  256. package/.opencode/commands/ant/continue.md +595 -66
  257. package/.opencode/commands/ant/council.md +150 -18
  258. package/.opencode/commands/ant/data-clean.md +77 -0
  259. package/.opencode/commands/ant/dream.md +15 -17
  260. package/.opencode/commands/ant/entomb.md +28 -18
  261. package/.opencode/commands/ant/export-signals.md +54 -0
  262. package/.opencode/commands/ant/feedback.md +24 -5
  263. package/.opencode/commands/ant/flag.md +16 -4
  264. package/.opencode/commands/ant/flags.md +24 -10
  265. package/.opencode/commands/ant/focus.md +22 -5
  266. package/.opencode/commands/ant/help.md +41 -8
  267. package/.opencode/commands/ant/history.md +9 -0
  268. package/.opencode/commands/ant/import-signals.md +68 -0
  269. package/.opencode/commands/ant/init.md +396 -154
  270. package/.opencode/commands/ant/insert-phase.md +111 -0
  271. package/.opencode/commands/ant/interpret.md +16 -0
  272. package/.opencode/commands/ant/lay-eggs.md +184 -112
  273. package/.opencode/commands/ant/maturity.md +18 -2
  274. package/.opencode/commands/ant/memory-details.md +83 -0
  275. package/.opencode/commands/ant/migrate-state.md +12 -0
  276. package/.opencode/commands/ant/oracle.md +322 -67
  277. package/.opencode/commands/ant/organize.md +14 -12
  278. package/.opencode/commands/ant/patrol.md +626 -0
  279. package/.opencode/commands/ant/pause-colony.md +12 -29
  280. package/.opencode/commands/ant/phase.md +30 -40
  281. package/.opencode/commands/ant/pheromones.md +162 -0
  282. package/.opencode/commands/ant/plan.md +210 -57
  283. package/.opencode/commands/ant/preferences.md +71 -0
  284. package/.opencode/commands/ant/quick.md +91 -0
  285. package/.opencode/commands/ant/redirect.md +22 -5
  286. package/.opencode/commands/ant/resume-colony.md +41 -29
  287. package/.opencode/commands/ant/resume.md +80 -20
  288. package/.opencode/commands/ant/run.md +237 -0
  289. package/.opencode/commands/ant/seal.md +230 -25
  290. package/.opencode/commands/ant/skill-create.md +63 -0
  291. package/.opencode/commands/ant/status.md +125 -30
  292. package/.opencode/commands/ant/swarm.md +3 -345
  293. package/.opencode/commands/ant/tunnels.md +3 -9
  294. package/.opencode/commands/ant/update.md +63 -127
  295. package/.opencode/commands/ant/verify-castes.md +96 -42
  296. package/.opencode/commands/ant/watch.md +7 -0
  297. package/CHANGELOG.md +368 -1
  298. package/README.md +195 -324
  299. package/bin/cli.js +236 -429
  300. package/bin/generate-commands.js +186 -0
  301. package/bin/generate-commands.sh +128 -89
  302. package/bin/lib/spawn-logger.js +0 -15
  303. package/bin/lib/update-transaction.js +285 -35
  304. package/bin/npx-install.js +178 -0
  305. package/bin/validate-package.sh +85 -3
  306. package/package.json +16 -4
  307. package/.aether/CONTEXT.md +0 -160
  308. package/.aether/docs/QUEEN.md +0 -84
  309. package/.aether/exchange/colony-registry.xml +0 -11
  310. package/.aether/exchange/pheromones.xml +0 -87
  311. package/.aether/exchange/queen-wisdom.xml +0 -14
  312. package/.aether/model-profiles.yaml +0 -100
  313. package/.aether/utils/spawn-with-model.sh +0 -56
  314. package/bin/lib/model-profiles.js +0 -445
  315. package/bin/lib/model-verify.js +0 -288
  316. package/bin/lib/proxy-health.js +0 -253
  317. package/bin/lib/telemetry.js +0 -441
@@ -15,206 +15,65 @@ SPAWN_TREE_FILE="${SPAWN_TREE_FILE:-$SPAWN_TREE_DATA_DIR/spawn-tree.txt}"
15
15
  parse_spawn_tree() {
16
16
  local file_path="${1:-$SPAWN_TREE_FILE}"
17
17
 
18
- # Check if file exists
19
- if [[ ! -f "$file_path" ]]; then
18
+ if [[ ! -f "$file_path" ]] || [[ ! -s "$file_path" ]]; then
20
19
  echo '{"spawns":[],"metadata":{"total_count":0,"active_count":0,"completed_count":0,"file_exists":false}}'
21
20
  return 0
22
21
  fi
23
22
 
24
- # Temporary files for data storage (Bash 3.2 compatible)
25
- local tmpdir
26
- tmpdir=$(mktemp -d)
27
- local names_file="$tmpdir/names"
28
- local parents_file="$tmpdir/parents"
29
- local castes_file="$tmpdir/castes"
30
- local tasks_file="$tmpdir/tasks"
31
- local statuses_file="$tmpdir/statuses"
32
- local timestamps_file="$tmpdir/timestamps"
33
- local completed_file="$tmpdir/completed"
34
- local children_file="$tmpdir/children"
35
-
36
- touch "$names_file" "$parents_file" "$castes_file" "$tasks_file" "$statuses_file" "$timestamps_file" "$completed_file" "$children_file"
37
-
38
- # Read file line by line
39
- while IFS= read -r line || [[ -n "$line" ]]; do
40
- # Skip empty lines
41
- [[ -z "$line" ]] && continue
42
-
43
- # Count pipe separators to determine line type
44
- local pipe_count
45
- pipe_count=$(echo "$line" | tr -cd '|' | wc -c | tr -d ' ')
46
-
47
- if [[ $pipe_count -eq 6 ]]; then
48
- # Spawn event: timestamp|parent|caste|child_name|task|model|status
49
- local timestamp parent caste child_name task model spawn_status
50
- timestamp=$(echo "$line" | cut -d'|' -f1)
51
- parent=$(echo "$line" | cut -d'|' -f2)
52
- caste=$(echo "$line" | cut -d'|' -f3)
53
- child_name=$(echo "$line" | cut -d'|' -f4)
54
- task=$(echo "$line" | cut -d'|' -f5)
55
- model=$(echo "$line" | cut -d'|' -f6)
56
- spawn_status=$(echo "$line" | cut -d'|' -f7)
57
-
58
- # Add to files
59
- echo "$child_name" >> "$names_file"
60
- echo "$parent" >> "$parents_file"
61
- echo "$caste" >> "$castes_file"
62
- echo "$task" >> "$tasks_file"
63
- echo "$spawn_status" >> "$statuses_file"
64
- echo "$timestamp" >> "$timestamps_file"
65
- echo "" >> "$completed_file"
66
- echo "" >> "$children_file"
67
-
68
- elif [[ $pipe_count -eq 3 ]]; then
69
- # Completion event: timestamp|ant_name|status|summary
70
- local timestamp ant_name complete_status summary
71
- timestamp=$(echo "$line" | cut -d'|' -f1)
72
- ant_name=$(echo "$line" | cut -d'|' -f2)
73
- complete_status=$(echo "$line" | cut -d'|' -f3)
74
-
75
- # Find the ant and update its status
76
- local idx=0
77
- local found=0
78
- while IFS= read -r name; do
79
- if [[ "$name" == "$ant_name" ]]; then
80
- found=1
81
- break
82
- fi
83
- ((idx++))
84
- done < "$names_file"
85
-
86
- if [[ $found -eq 1 ]]; then
87
- # Update status at line idx+1 (sed is 1-indexed)
88
- sed -i.bak "${idx}d" "$statuses_file" 2>/dev/null || sed -i "${idx}d" "$statuses_file"
89
- sed -i.bak "${idx}i\\
90
- $complete_status" "$statuses_file" 2>/dev/null || sed -i "${idx}i\\
91
- $complete_status" "$statuses_file"
92
- sed -i.bak "${idx}d" "$completed_file" 2>/dev/null || sed -i "${idx}d" "$completed_file"
93
- sed -i.bak "${idx}i\\
94
- $timestamp" "$completed_file" 2>/dev/null || sed -i "${idx}i\\
95
- $timestamp" "$completed_file"
96
- rm -f "$statuses_file.bak" "$completed_file.bak" 2>/dev/null
97
- fi
98
- fi
99
- done < "$file_path"
100
-
101
- # Build parent-child relationships
102
- local total_count
103
- total_count=$(wc -l < "$names_file" | tr -d ' ')
104
-
105
- if [[ $total_count -gt 0 ]]; then
106
- local i
107
- for ((i = 1; i <= total_count; i++)); do
108
- local parent
109
- parent=$(sed -n "${i}p" "$parents_file")
110
-
111
- # Find parent index
112
- local parent_idx=0
113
- local found=0
114
- while IFS= read -r name; do
115
- if [[ "$name" == "$parent" ]]; then
116
- found=1
117
- break
118
- fi
119
- ((parent_idx++))
120
- done < "$names_file"
121
-
122
- if [[ $found -eq 1 ]]; then
123
- # Add child i-1 to parent's children (0-indexed)
124
- local child_idx=$((i - 1))
125
- local current_children
126
- current_children=$(sed -n "$((parent_idx + 1))p" "$children_file")
127
- if [[ -z "$current_children" ]]; then
128
- sed -i.bak "$((parent_idx + 1))d" "$children_file" 2>/dev/null || sed -i "$((parent_idx + 1))d" "$children_file"
129
- sed -i.bak "$((parent_idx + 1))i\\
130
- $child_idx" "$children_file" 2>/dev/null || sed -i "$((parent_idx + 1))i\\
131
- $child_idx" "$children_file"
132
- else
133
- sed -i.bak "$((parent_idx + 1))d" "$children_file" 2>/dev/null || sed -i "$((parent_idx + 1))d" "$children_file"
134
- sed -i.bak "$((parent_idx + 1))i\\
135
- $current_children $child_idx" "$children_file" 2>/dev/null || sed -i "$((parent_idx + 1))i\\
136
- $current_children $child_idx" "$children_file"
137
- fi
138
- rm -f "$children_file.bak" 2>/dev/null
139
- fi
140
- done
141
- fi
142
-
143
- # Count statuses
144
- local active_count=0
145
- local completed_count=0
146
- while IFS= read -r status; do
147
- if [[ "$status" == "active" || "$status" == "spawned" ]]; then
148
- ((active_count++))
149
- elif [[ "$status" == "completed" || "$status" == "failed" || "$status" == "blocked" ]]; then
150
- ((completed_count++))
151
- fi
152
- done < "$statuses_file"
153
-
154
- # Build spawns array
155
- local spawns_json="["
156
- local i
157
- for ((i = 1; i <= total_count; i++)); do
158
- if [[ $i -gt 1 ]]; then
159
- spawns_json+=","
160
- fi
161
-
162
- local name parent caste task status timestamp completed children
163
- name=$(sed -n "${i}p" "$names_file")
164
- parent=$(sed -n "${i}p" "$parents_file")
165
- caste=$(sed -n "${i}p" "$castes_file")
166
- task=$(sed -n "${i}p" "$tasks_file")
167
- status=$(sed -n "${i}p" "$statuses_file")
168
- timestamp=$(sed -n "${i}p" "$timestamps_file")
169
- completed=$(sed -n "${i}p" "$completed_file")
170
- children=$(sed -n "${i}p" "$children_file")
171
-
172
- # Build children array
173
- local children_json="["
174
- if [[ -n "$children" ]]; then
175
- local first_child=true
176
- for child_idx in $children; do
177
- if [[ "$first_child" == "true" ]]; then
178
- first_child=false
179
- else
180
- children_json+=","
181
- fi
182
- local child_name
183
- child_name=$(sed -n "$((child_idx + 1))p" "$names_file")
184
- children_json+="\"$child_name\""
185
- done
186
- fi
187
- children_json+="]"
188
-
189
- # Escape task for JSON
190
- task=$(echo "$task" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g')
191
-
192
- spawns_json+="{"
193
- spawns_json+="\"name\":\"$name\","
194
- spawns_json+="\"parent\":\"$parent\","
195
- spawns_json+="\"caste\":\"$caste\","
196
- spawns_json+="\"task\":\"$task\","
197
- spawns_json+="\"status\":\"$status\","
198
- spawns_json+="\"spawned_at\":\"$timestamp\","
199
- spawns_json+="\"completed_at\":\"$completed\","
200
- spawns_json+="\"children\":$children_json"
201
- spawns_json+="}"
202
- done
203
- spawns_json+="]"
204
-
205
- # Output JSON
206
- echo "{"
207
- echo " \"spawns\": $spawns_json,"
208
- echo " \"metadata\": {"
209
- echo " \"total_count\": $total_count,"
210
- echo " \"active_count\": $active_count,"
211
- echo " \"completed_count\": $completed_count,"
212
- echo " \"file_exists\": true"
213
- echo " }"
214
- echo "}"
215
-
216
- # Cleanup
217
- rm -rf "$tmpdir"
23
+ awk -F'|' '
24
+ BEGIN { n=0; active=0; completed_n=0 }
25
+ NF == 7 && $7 == "spawned" {
26
+ names[n] = $4; parents[n] = $2; castes[n] = $3
27
+ tasks[n] = $5; statuses[n] = "spawned"; timestamps[n] = $1
28
+ completed_at[n] = ""; children_str[n] = ""
29
+ name_to_idx[$4] = n; n++
30
+ }
31
+ $3 ~ /^(completed|failed|blocked)$/ && NF >= 4 {
32
+ ant = $2
33
+ if (ant in name_to_idx) {
34
+ idx = name_to_idx[ant]; statuses[idx] = $3; completed_at[idx] = $1
35
+ }
36
+ }
37
+ END {
38
+ for (i = 0; i < n; i++) {
39
+ p = parents[i]
40
+ if (p in name_to_idx) {
41
+ pidx = name_to_idx[p]
42
+ if (children_str[pidx] == "") children_str[pidx] = i
43
+ else children_str[pidx] = children_str[pidx] " " i
44
+ }
45
+ }
46
+ for (i = 0; i < n; i++) {
47
+ if (statuses[i] == "spawned" || statuses[i] == "active") active++
48
+ else if (statuses[i] ~ /^(completed|failed|blocked)$/) completed_n++
49
+ }
50
+ printf "{"
51
+ printf "\"spawns\":["
52
+ for (i = 0; i < n; i++) {
53
+ if (i > 0) printf ","
54
+ nm = names[i]; gsub(/\\/, "\\\\", nm); gsub(/"/, "\\\"", nm); gsub(/\t/, "\\t", nm); gsub(/\n/, "\\n", nm); gsub(/\r/, "\\r", nm)
55
+ pr = parents[i]; gsub(/\\/, "\\\\", pr); gsub(/"/, "\\\"", pr); gsub(/\t/, "\\t", pr); gsub(/\n/, "\\n", pr); gsub(/\r/, "\\r", pr)
56
+ tk = tasks[i]; gsub(/\\/, "\\\\", tk); gsub(/"/, "\\\"", tk); gsub(/\t/, "\\t", tk); gsub(/\n/, "\\n", tk); gsub(/\r/, "\\r", tk)
57
+ printf "{\"name\":\"%s\",\"parent\":\"%s\",\"caste\":\"%s\",", nm, pr, castes[i]
58
+ printf "\"task\":\"%s\",\"status\":\"%s\",", tk, statuses[i]
59
+ printf "\"spawned_at\":\"%s\",\"completed_at\":\"%s\",", timestamps[i], completed_at[i]
60
+ printf "\"children\":["
61
+ if (children_str[i] != "") {
62
+ split(children_str[i], cidxs, " ")
63
+ for (j = 1; j <= length(cidxs); j++) {
64
+ if (j > 1) printf ","
65
+ cn = names[cidxs[j]+0]
66
+ gsub(/\\/, "\\\\", cn); gsub(/"/, "\\\"", cn); gsub(/\t/, "\\t", cn); gsub(/\n/, "\\n", cn); gsub(/\r/, "\\r", cn)
67
+ printf "\"%s\"", cn
68
+ }
69
+ }
70
+ printf "]}"
71
+ }
72
+ printf "],"
73
+ printf "\"metadata\":{\"total_count\":%d,\"active_count\":%d,\"completed_count\":%d,\"file_exists\":true}", n, active, completed_n
74
+ printf "}"
75
+ }
76
+ ' "$file_path"
218
77
  }
219
78
 
220
79
  # Get spawn depth for a given ant name
@@ -224,20 +83,21 @@ get_spawn_depth() {
224
83
  local ant_name="${1:-}"
225
84
 
226
85
  if [[ -z "$ant_name" || "$ant_name" == "Queen" ]]; then
227
- echo "{\"ant\":\"${ant_name:-Queen}\",\"depth\":0}"
86
+ jq -n --arg ant "${ant_name:-Queen}" '{ant: $ant, depth: 0}'
228
87
  return 0
229
88
  fi
230
89
 
231
90
  local file_path="${SPAWN_TREE_FILE}"
232
91
 
233
92
  if [[ ! -f "$file_path" ]]; then
234
- echo "{\"ant\":\"$ant_name\",\"depth\":1,\"found\":false}"
93
+ jq -n --arg ant "$ant_name" '{ant: $ant, depth: 1, found: false}'
235
94
  return 0
236
95
  fi
237
96
 
238
97
  # Check if ant exists
239
- if ! grep -q "|$ant_name|" "$file_path" 2>/dev/null; then
240
- echo "{\"ant\":\"$ant_name\",\"depth\":1,\"found\":false}"
98
+ # -F: ant_name may contain regex metacharacters (dots, plus, brackets, etc.)
99
+ if ! grep -qF "|$ant_name|" "$file_path" 2>/dev/null; then
100
+ jq -n --arg ant "$ant_name" '{ant: $ant, depth: 1, found: false}'
241
101
  return 0
242
102
  fi
243
103
 
@@ -249,7 +109,7 @@ get_spawn_depth() {
249
109
  while [[ $safety -lt 5 ]]; do
250
110
  # Find who spawned this ant
251
111
  local parent
252
- parent=$(grep "|$current|" "$file_path" 2>/dev/null | grep "|spawned$" | head -1 | cut -d'|' -f2 || echo "")
112
+ parent=$(grep -F "|$current|" "$file_path" 2>/dev/null | grep "|spawned$" | head -1 | cut -d'|' -f2 || echo "")
253
113
 
254
114
  if [[ -z "$parent" || "$parent" == "Queen" ]]; then
255
115
  break
@@ -260,7 +120,7 @@ get_spawn_depth() {
260
120
  ((safety++))
261
121
  done
262
122
 
263
- echo "{\"ant\":\"$ant_name\",\"depth\":$depth,\"found\":true}"
123
+ jq -n --arg ant "$ant_name" --argjson depth "$depth" '{ant: $ant, depth: $depth, found: true}'
264
124
  }
265
125
 
266
126
  # Get list of active spawns
@@ -269,60 +129,35 @@ get_spawn_depth() {
269
129
  get_active_spawns() {
270
130
  local file_path="${1:-$SPAWN_TREE_FILE}"
271
131
 
272
- if [[ ! -f "$file_path" ]]; then
132
+ if [[ ! -f "$file_path" ]] || [[ ! -s "$file_path" ]]; then
273
133
  echo "[]"
274
134
  return 0
275
135
  fi
276
136
 
277
- local active_json="["
278
- local first=true
279
-
280
- # Read spawn events and check if completed
281
- while IFS= read -r line || [[ -n "$line" ]]; do
282
- [[ -z "$line" ]] && continue
283
-
284
- local pipe_count
285
- pipe_count=$(echo "$line" | tr -cd '|' | wc -c | tr -d ' ')
286
-
287
- if [[ $pipe_count -eq 6 ]]; then
288
- # Spawn event: timestamp|parent|caste|child_name|task|model|status
289
- local timestamp parent caste child_name task model spawn_status
290
- timestamp=$(echo "$line" | cut -d'|' -f1)
291
- parent=$(echo "$line" | cut -d'|' -f2)
292
- caste=$(echo "$line" | cut -d'|' -f3)
293
- child_name=$(echo "$line" | cut -d'|' -f4)
294
- task=$(echo "$line" | cut -d'|' -f5)
295
- model=$(echo "$line" | cut -d'|' -f6)
296
-
297
- # Check if this ant has a completion event
298
- local is_completed=false
299
- if grep -q "^[^|]*|$child_name|completed\|^[^|]*|$child_name|failed\|^[^|]*|$child_name|blocked" "$file_path" 2>/dev/null; then
300
- is_completed=true
301
- fi
302
-
303
- if [[ "$is_completed" == "false" ]]; then
304
- if [[ "$first" == "true" ]]; then
305
- first=false
306
- else
307
- active_json+=","
308
- fi
309
-
310
- # Escape task for JSON
311
- task=$(echo "$task" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g')
312
-
313
- active_json+="{"
314
- active_json+="\"name\":\"$child_name\","
315
- active_json+="\"caste\":\"$caste\","
316
- active_json+="\"parent\":\"$parent\","
317
- active_json+="\"task\":\"$task\","
318
- active_json+="\"spawned_at\":\"$timestamp\""
319
- active_json+="}"
320
- fi
321
- fi
322
- done < "$file_path"
323
-
324
- active_json+="]"
325
- echo "$active_json"
137
+ awk -F'|' '
138
+ BEGIN { spawn_n=0 }
139
+ $3 ~ /^(completed|failed|blocked)$/ && NF >= 4 { done_set[$2] = 1 }
140
+ NF == 7 && $7 == "spawned" {
141
+ spawn_names[spawn_n] = $4; spawn_parents[spawn_n] = $2
142
+ spawn_castes[spawn_n] = $3; spawn_tasks[spawn_n] = $5
143
+ spawn_ts[spawn_n] = $1; spawn_n++
144
+ }
145
+ END {
146
+ printf "["
147
+ first = 1
148
+ for (i = 0; i < spawn_n; i++) {
149
+ if (!(spawn_names[i] in done_set)) {
150
+ if (!first) printf ","
151
+ first = 0
152
+ nm = spawn_names[i]; gsub(/\\/, "\\\\", nm); gsub(/"/, "\\\"", nm); gsub(/\t/, "\\t", nm); gsub(/\n/, "\\n", nm); gsub(/\r/, "\\r", nm)
153
+ pr = spawn_parents[i]; gsub(/\\/, "\\\\", pr); gsub(/"/, "\\\"", pr); gsub(/\t/, "\\t", pr); gsub(/\n/, "\\n", pr); gsub(/\r/, "\\r", pr)
154
+ tk = spawn_tasks[i]; gsub(/\\/, "\\\\", tk); gsub(/"/, "\\\"", tk); gsub(/\t/, "\\t", tk); gsub(/\n/, "\\n", tk); gsub(/\r/, "\\r", tk)
155
+ printf "{\"name\":\"%s\",\"caste\":\"%s\",\"parent\":\"%s\",\"task\":\"%s\",\"spawned_at\":\"%s\"}", nm, spawn_castes[i], pr, tk, spawn_ts[i]
156
+ }
157
+ }
158
+ printf "]"
159
+ }
160
+ ' "$file_path"
326
161
  }
327
162
 
328
163
  # Get direct children of a spawn
@@ -337,8 +172,8 @@ get_spawn_children() {
337
172
  return 0
338
173
  fi
339
174
 
340
- local children_json="["
341
- local first=true
175
+ # Collect children names safely, then build JSON array via jq
176
+ local -a children_arr=()
342
177
 
343
178
  # Find all spawns where parent matches
344
179
  while IFS= read -r line || [[ -n "$line" ]]; do
@@ -353,18 +188,16 @@ get_spawn_children() {
353
188
  child_name=$(echo "$line" | cut -d'|' -f4)
354
189
 
355
190
  if [[ "$parent" == "$ant_name" ]]; then
356
- if [[ "$first" == "true" ]]; then
357
- first=false
358
- else
359
- children_json+=","
360
- fi
361
- children_json+="\"$child_name\""
191
+ children_arr+=("$child_name")
362
192
  fi
363
193
  fi
364
194
  done < "$file_path"
365
195
 
366
- children_json+="]"
367
- echo "$children_json"
196
+ if [[ ${#children_arr[@]} -eq 0 ]]; then
197
+ echo "[]"
198
+ else
199
+ printf '%s\n' "${children_arr[@]}" | jq -R . | jq -s .
200
+ fi
368
201
  }
369
202
 
370
203
  # Get full lineage from ant up to Queen
@@ -380,33 +213,32 @@ get_spawn_lineage() {
380
213
  fi
381
214
 
382
215
  if [[ ! -f "$file_path" ]]; then
383
- echo "[\"$ant_name\",\"Queen\"]"
216
+ jq -n --arg ant "$ant_name" '[$ant, "Queen"]'
384
217
  return 0
385
218
  fi
386
219
 
387
- # Build lineage array (ant first, then ancestors)
388
- local lineage=""
220
+ # Build lineage array (ant first, then ancestors) using jq for safe JSON escaping
221
+ local -a lineage_arr=("$ant_name")
389
222
  local current="$ant_name"
390
223
  local safety=0
391
224
 
392
- lineage="\"$current\""
393
-
394
225
  while [[ $safety -lt 5 ]]; do
395
226
  # Find who spawned this ant
396
227
  local parent
397
- parent=$(grep "|$current|" "$file_path" 2>/dev/null | grep "|spawned$" | head -1 | cut -d'|' -f2 || echo "")
228
+ parent=$(grep -F "|$current|" "$file_path" 2>/dev/null | grep "|spawned$" | head -1 | cut -d'|' -f2 || echo "")
398
229
 
399
230
  if [[ -z "$parent" || "$parent" == "Queen" ]]; then
400
- lineage+=",\"Queen\""
231
+ lineage_arr+=("Queen")
401
232
  break
402
233
  fi
403
234
 
404
- lineage+=",\"$parent\""
235
+ lineage_arr+=("$parent")
405
236
  current="$parent"
406
237
  ((safety++))
407
238
  done
408
239
 
409
- echo "[$lineage]"
240
+ # Build JSON array safely via jq
241
+ printf '%s\n' "${lineage_arr[@]}" | jq -R . | jq -s .
410
242
  }
411
243
 
412
244
  # Reconstruct full tree as JSON