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
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * YAML Command Generator
5
+ *
6
+ * Reads YAML source files from .aether/commands/ and generates
7
+ * both Claude Code and OpenCode command markdown files.
8
+ *
9
+ * Usage:
10
+ * node bin/generate-commands.js # Generate all command files
11
+ * node bin/generate-commands.js --check # Check if generated files are up-to-date
12
+ *
13
+ * @module bin/generate-commands
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const yaml = require('js-yaml');
19
+
20
+ const YAML_DIR = path.join(__dirname, '..', '.aether', 'commands');
21
+ const CLAUDE_DIR = path.join(__dirname, '..', '.claude', 'commands', 'ant');
22
+ const OPENCODE_DIR = path.join(__dirname, '..', '.opencode', 'commands', 'ant');
23
+
24
+ const NORMALIZE_PREAMBLE = `### Step -1: Normalize Arguments
25
+
26
+ Run: \`normalized_args=$(bash .aether/aether-utils.sh normalize-args "$@")\`
27
+
28
+ This ensures arguments work correctly in both Claude Code and OpenCode. Use \`$normalized_args\` throughout this command.
29
+
30
+ `;
31
+
32
+ /**
33
+ * Generate a command markdown file for a specific provider.
34
+ *
35
+ * @param {object} spec - Parsed YAML command spec
36
+ * @param {string} spec.name - Command name (e.g., "ant:focus")
37
+ * @param {string} spec.description - Shared description
38
+ * @param {string} [spec.description_claude] - Claude-specific description
39
+ * @param {string} [spec.description_opencode] - OpenCode-specific description
40
+ * @param {string} [spec.body] - Shared command body with template markers
41
+ * @param {string} [spec.body_claude] - Claude-specific body (skips template processing)
42
+ * @param {string} [spec.body_opencode] - OpenCode-specific body (skips template processing)
43
+ * @param {string} provider - Target provider: 'claude' or 'opencode'
44
+ * @returns {string} Generated markdown content
45
+ */
46
+ function generateForProvider(spec, provider) {
47
+ // 1. Description: use provider-specific if available
48
+ var desc = spec['description_' + provider] || spec.description;
49
+
50
+ // 2. Build frontmatter
51
+ var output = '---\nname: ' + spec.name + '\ndescription: "' + desc + '"\n---\n\n';
52
+
53
+ // 3. Header comment
54
+ var yamlFilename = spec.name.replace('ant:', '') + '.yaml';
55
+ output = '<!-- Generated from .aether/commands/' + yamlFilename + ' - DO NOT EDIT DIRECTLY -->\n' + output;
56
+
57
+ // 4. Determine body source
58
+ var providerBody = spec['body_' + provider];
59
+ var body;
60
+
61
+ if (providerBody) {
62
+ // Provider-specific body -- use directly, no template processing
63
+ body = providerBody;
64
+ } else if (spec.body) {
65
+ // Shared body -- apply template processing
66
+ body = spec.body;
67
+
68
+ // Replace {{ARGUMENTS}}
69
+ if (provider === 'claude') {
70
+ body = body.replace(/\{\{ARGUMENTS\}\}/g, '$ARGUMENTS');
71
+ } else {
72
+ body = body.replace(/\{\{ARGUMENTS\}\}/g, '$normalized_args');
73
+ }
74
+
75
+ // Replace {{TOOL_PREFIX "..."}}
76
+ if (provider === 'claude') {
77
+ body = body.replace(/\{\{TOOL_PREFIX "(.+?)"\}\}/g, 'Run using the Bash tool with description "$1":');
78
+ } else {
79
+ body = body.replace(/\{\{TOOL_PREFIX "(.+?)"\}\}/g, 'Run:');
80
+ }
81
+
82
+ // Strip opposite-provider blocks
83
+ var opposite = provider === 'claude' ? 'opencode' : 'claude';
84
+ var stripRegex = new RegExp('\\{\\{#' + opposite + '\\}\\}[\\s\\S]*?\\{\\{/' + opposite + '\\}\\}', 'g');
85
+ body = body.replace(stripRegex, '');
86
+
87
+ // Keep same-provider blocks (unwrap markers)
88
+ var keepRegex = new RegExp('\\{\\{#' + provider + '\\}\\}([\\s\\S]*?)\\{\\{/' + provider + '\\}\\}', 'g');
89
+ body = body.replace(keepRegex, '$1');
90
+ } else {
91
+ throw new Error('Command "' + spec.name + '" has no body field and no body_' + provider + ' field');
92
+ }
93
+
94
+ // 5. Inject normalize-args preamble for OpenCode
95
+ if (provider === 'opencode') {
96
+ output += NORMALIZE_PREAMBLE;
97
+ }
98
+
99
+ output += body;
100
+ return output;
101
+ }
102
+
103
+ /**
104
+ * Main function: read YAML sources, generate command files for both providers.
105
+ */
106
+ function main() {
107
+ var checkMode = process.argv.includes('--check');
108
+
109
+ // Ensure YAML source directory exists
110
+ if (!fs.existsSync(YAML_DIR)) {
111
+ console.log('No YAML source directory found at ' + YAML_DIR);
112
+ console.log('Run YAML conversion first to create .aether/commands/*.yaml files.');
113
+ process.exit(0);
114
+ }
115
+
116
+ // Read all YAML files
117
+ var yamlFiles = fs.readdirSync(YAML_DIR).filter(function (f) {
118
+ return f.endsWith('.yaml');
119
+ });
120
+
121
+ if (yamlFiles.length === 0) {
122
+ console.log('No .yaml files found in ' + YAML_DIR);
123
+ process.exit(0);
124
+ }
125
+
126
+ var mismatches = [];
127
+ var generated = 0;
128
+
129
+ yamlFiles.forEach(function (filename) {
130
+ var filePath = path.join(YAML_DIR, filename);
131
+ var content = fs.readFileSync(filePath, 'utf8');
132
+ var spec = yaml.load(content);
133
+ var outputName = filename.replace('.yaml', '.md');
134
+
135
+ var providers = [
136
+ { name: 'claude', dir: CLAUDE_DIR },
137
+ { name: 'opencode', dir: OPENCODE_DIR }
138
+ ];
139
+
140
+ providers.forEach(function (prov) {
141
+ var output = generateForProvider(spec, prov.name);
142
+ var outputPath = path.join(prov.dir, outputName);
143
+
144
+ if (checkMode) {
145
+ // Compare with existing file
146
+ if (fs.existsSync(outputPath)) {
147
+ var existing = fs.readFileSync(outputPath, 'utf8');
148
+ if (existing !== output) {
149
+ mismatches.push(outputPath);
150
+ }
151
+ } else {
152
+ mismatches.push(outputPath + ' (missing)');
153
+ }
154
+ } else {
155
+ // Ensure output directory exists
156
+ if (!fs.existsSync(prov.dir)) {
157
+ fs.mkdirSync(prov.dir, { recursive: true });
158
+ }
159
+ fs.writeFileSync(outputPath, output);
160
+ generated++;
161
+ }
162
+ });
163
+ });
164
+
165
+ if (checkMode) {
166
+ if (mismatches.length > 0) {
167
+ console.log('Generated files are out of date:');
168
+ mismatches.forEach(function (m) {
169
+ console.log(' ' + m);
170
+ });
171
+ console.log('\nRun "node bin/generate-commands.js" to regenerate.');
172
+ process.exit(1);
173
+ } else {
174
+ console.log('All generated files are up to date. (' + yamlFiles.length + ' YAML sources checked)');
175
+ process.exit(0);
176
+ }
177
+ } else {
178
+ console.log('Generated ' + generated + ' command files from ' + yamlFiles.length + ' YAML sources.');
179
+ }
180
+ }
181
+
182
+ module.exports = { generateForProvider };
183
+
184
+ if (require.main === module) {
185
+ main();
186
+ }
@@ -1,17 +1,16 @@
1
1
  #!/bin/bash
2
- # generate-commands.sh - Sync commands between Claude Code and OpenCode
2
+ # generate-commands.sh - Validate YAML source -> generated command file sync
3
3
  #
4
- # This script helps keep commands in sync between the two platforms.
5
- # Currently it provides a simple diff-based sync, with plans for full
6
- # YAML-based generation in the future.
4
+ # This script validates that generated .md files (.claude/commands/ant/*.md and
5
+ # .opencode/commands/ant/*.md) match the output from YAML sources (.aether/commands/*.yaml).
7
6
  #
8
7
  # Usage:
9
- # ./bin/generate-commands.sh [check|sync|diff]
8
+ # ./bin/generate-commands.sh [check|diff|help]
10
9
  #
11
10
  # Commands:
12
- # check - Check if commands are in sync (exit 1 if not)
13
- # sync - Copy Claude Code commands to OpenCode (with tool name translation)
11
+ # check - Validate generated files match YAML sources
14
12
  # diff - Show differences between command sets
13
+ # help - Show this help message
15
14
 
16
15
  set -e
17
16
 
@@ -20,6 +19,9 @@ PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
20
19
 
21
20
  CLAUDE_DIR="$PROJECT_DIR/.claude/commands/ant"
22
21
  OPENCODE_DIR="$PROJECT_DIR/.opencode/commands/ant"
22
+ CLAUDE_AGENT_DIR="$PROJECT_DIR/.claude/agents/ant"
23
+ OPENCODE_AGENT_DIR="$PROJECT_DIR/.opencode/agents"
24
+ AETHER_AGENT_MIRROR_DIR="$PROJECT_DIR/.aether/agents-claude"
23
25
 
24
26
  # Colors for output
25
27
  RED='\033[0;31m'
@@ -86,6 +88,14 @@ list_commands() {
86
88
  fi
87
89
  }
88
90
 
91
+ # List agent definition files (*.md) by basename
92
+ list_agents() {
93
+ local dir="$1"
94
+ if [[ -d "$dir" ]]; then
95
+ find "$dir" -name "*.md" -type f -exec basename {} \; | sort
96
+ fi
97
+ }
98
+
89
99
  # Check if directories are in sync (by file count and names)
90
100
  check_sync() {
91
101
  log_info "Checking command sync status..."
@@ -133,95 +143,110 @@ check_sync() {
133
143
  return 0
134
144
  }
135
145
 
136
- # Check content-level sync using checksums (Pass 2)
137
- # Compares each matching file pair by SHA-1 hash and reports diffs
138
- check_content() {
139
- log_info "Checking content-level sync (checksums)..."
146
+ # Check YAML generation sync (Pass 2)
147
+ # Validates that generated .md files match YAML sources
148
+ check_yaml_generation() {
149
+ log_info "Checking YAML generation sync..."
140
150
 
141
- local drift_count=0
142
- local error_count=0
143
- local match_count=0
144
- local drift_files=""
145
- local error_files=""
151
+ # Verify YAML source directory exists
152
+ local yaml_dir="$PROJECT_DIR/.aether/commands"
153
+ if [[ ! -d "$yaml_dir" ]]; then
154
+ log_error "YAML source directory not found: $yaml_dir"
155
+ return 1
156
+ fi
146
157
 
147
- # Use null delimiter for safe iteration (handles filenames with spaces)
148
- while IFS= read -r -d '' claude_file; do
149
- local file
150
- file=$(basename "$claude_file")
151
- local opencode_file="$OPENCODE_DIR/$file"
158
+ local yaml_count
159
+ yaml_count=$(find "$yaml_dir" -name "*.yaml" | wc -l | tr -d ' ')
160
+ if [[ "$yaml_count" -eq 0 ]]; then
161
+ log_error "No YAML source files found in $yaml_dir"
162
+ return 1
163
+ fi
152
164
 
153
- # Skip if OpenCode file doesn't exist (already caught by Pass 1)
154
- if [[ ! -f "$opencode_file" ]]; then
155
- continue
156
- fi
165
+ log_info "Found $yaml_count YAML source files"
157
166
 
158
- # Compute hashes with error handling
159
- local claude_hash opencode_hash
160
- claude_hash=$(compute_hash "$claude_file")
161
- if [[ $? -ne 0 ]]; then
162
- log_error "Cannot hash $claude_file ($claude_hash)"
163
- error_files="${error_files} ${file} (${claude_hash})\n"
164
- error_count=$((error_count + 1))
165
- continue
166
- fi
167
+ # Run generator in check mode
168
+ if node "$PROJECT_DIR/bin/generate-commands.js" --check; then
169
+ log_info "Generated files match YAML sources ($yaml_count commands)"
170
+ return 0
171
+ else
172
+ log_error "Generated files are out of date. Run 'npm run generate' to update."
173
+ return 1
174
+ fi
175
+ }
167
176
 
168
- opencode_hash=$(compute_hash "$opencode_file")
169
- if [[ $? -ne 0 ]]; then
170
- log_error "Cannot hash $opencode_file ($opencode_hash)"
171
- error_files="${error_files} ${file} (${opencode_hash})\n"
172
- error_count=$((error_count + 1))
173
- continue
174
- fi
177
+ # Check agent sync strategy:
178
+ # 1) Claude <-> OpenCode: structural parity (count + file names)
179
+ # 2) Claude <-> .aether mirror: exact parity (count + names + content hash)
180
+ check_agent_sync() {
181
+ log_info "Checking agent sync status..."
175
182
 
176
- if [[ "$claude_hash" != "$opencode_hash" ]]; then
177
- drift_count=$((drift_count + 1))
178
- drift_files="${drift_files} ${file}\n"
179
-
180
- log_warn "Content drift: $file"
181
- echo " Claude: $claude_hash"
182
- echo " OpenCode: $opencode_hash"
183
-
184
- # PLAN-006 fix #12 - improved diff error handling
185
- echo " ---"
186
- local diff_output
187
- if diff_output=$(diff -u "$claude_file" "$opencode_file" 2>&1); then
188
- # Files are same (shouldn't happen if hashes differ, but handle it)
189
- echo "$diff_output" | head -20
190
- else
191
- local diff_exit=$?
192
- if [[ "$diff_output" == *"diff:"* && "$diff_output" == *"No such file"* ]]; then
193
- log_error "diff failed: $diff_output"
194
- else
195
- # Normal diff output (exit 1 means files differ)
196
- echo "$diff_output" | head -20
197
- fi
198
- fi
199
- echo " ---"
200
- echo ""
201
- else
202
- match_count=$((match_count + 1))
203
- fi
204
- done < <(find "$CLAUDE_DIR" -name "*.md" -type f -print0 2>/dev/null | sort -z)
183
+ local claude_count
184
+ local opencode_count
185
+ local mirror_count
186
+ claude_count=$(count_commands "$CLAUDE_AGENT_DIR")
187
+ opencode_count=$(count_commands "$OPENCODE_AGENT_DIR")
188
+ mirror_count=$(count_commands "$AETHER_AGENT_MIRROR_DIR")
205
189
 
206
- # Report results
207
- if [[ "$error_count" -gt 0 ]]; then
208
- echo ""
209
- log_error "Hash errors in $error_count file(s):"
210
- echo -e "$error_files"
190
+ echo "Claude agents: $claude_count"
191
+ echo "OpenCode agents: $opencode_count"
192
+ echo "Aether mirror agents: $mirror_count"
193
+
194
+ if [[ "$claude_count" != "$opencode_count" ]]; then
195
+ log_error "Claude/OpenCode agent counts don't match!"
196
+ return 1
197
+ fi
198
+
199
+ if [[ "$claude_count" != "$mirror_count" ]]; then
200
+ log_error "Claude/.aether mirror agent counts don't match!"
201
+ return 1
211
202
  fi
212
203
 
213
- if [[ "$drift_count" -gt 0 ]]; then
204
+ local claude_files
205
+ local opencode_files
206
+ local mirror_files
207
+ claude_files=$(list_agents "$CLAUDE_AGENT_DIR")
208
+ opencode_files=$(list_agents "$OPENCODE_AGENT_DIR")
209
+ mirror_files=$(list_agents "$AETHER_AGENT_MIRROR_DIR")
210
+
211
+ if [[ "$claude_files" != "$opencode_files" ]]; then
212
+ log_error "Claude/OpenCode agent file names don't match!"
214
213
  echo ""
215
- log_warn "Content drift detected in $drift_count file(s) (non-blocking):"
216
- echo -e "$drift_files"
217
- # Content drift is advisory — structural sync is what matters
214
+ echo "Only in Claude:"
215
+ comm -23 <(echo "$claude_files") <(echo "$opencode_files") | sed 's/^/ /'
216
+ echo ""
217
+ echo "Only in OpenCode:"
218
+ comm -13 <(echo "$claude_files") <(echo "$opencode_files") | sed 's/^/ /'
219
+ return 1
218
220
  fi
219
221
 
220
- if [[ "$error_count" -gt 0 ]]; then
222
+ if [[ "$claude_files" != "$mirror_files" ]]; then
223
+ log_error "Claude/.aether mirror agent file names don't match!"
224
+ echo ""
225
+ echo "Only in Claude:"
226
+ comm -23 <(echo "$claude_files") <(echo "$mirror_files") | sed 's/^/ /'
227
+ echo ""
228
+ echo "Only in .aether mirror:"
229
+ comm -13 <(echo "$claude_files") <(echo "$mirror_files") | sed 's/^/ /'
221
230
  return 1
222
231
  fi
223
232
 
224
- log_info "All file contents match (checksums verified: $match_count files)"
233
+ # Claude and mirror should be byte-identical.
234
+ local file
235
+ while IFS= read -r file; do
236
+ [[ -z "$file" ]] && continue
237
+ local claude_file="$CLAUDE_AGENT_DIR/$file"
238
+ local mirror_file="$AETHER_AGENT_MIRROR_DIR/$file"
239
+ local claude_hash
240
+ local mirror_hash
241
+ claude_hash=$(compute_hash "$claude_file")
242
+ mirror_hash=$(compute_hash "$mirror_file")
243
+ if [[ "$claude_hash" != "$mirror_hash" ]]; then
244
+ log_error "Claude/.aether mirror content drift: $file"
245
+ return 1
246
+ fi
247
+ done <<< "$claude_files"
248
+
249
+ log_info "Agents are in sync (Claude/OpenCode structural parity, Claude/.aether mirror exact parity)"
225
250
  return 0
226
251
  }
227
252
 
@@ -229,6 +254,13 @@ check_content() {
229
254
  show_diff() {
230
255
  log_info "Comparing command sets..."
231
256
 
257
+ local yaml_dir="$PROJECT_DIR/.aether/commands"
258
+ local yaml_count=0
259
+ if [[ -d "$yaml_dir" ]]; then
260
+ yaml_count=$(find "$yaml_dir" -name "*.yaml" | wc -l | tr -d ' ')
261
+ fi
262
+ echo "YAML source files: $yaml_count"
263
+
232
264
  # Use null delimiter for safe iteration (handles filenames with spaces)
233
265
  while IFS= read -r -d '' claude_file; do
234
266
  local file
@@ -252,21 +284,26 @@ show_diff() {
252
284
 
253
285
  # Display help
254
286
  show_help() {
255
- echo "Aether Command Sync Tool"
287
+ echo "Aether YAML Generation Validation Tool"
256
288
  echo ""
257
289
  echo "Usage: $0 [command]"
258
290
  echo ""
259
291
  echo "Commands:"
260
- echo " check Check if commands are in sync"
292
+ echo " check Validate generated .md files match YAML sources"
261
293
  echo " diff Show differences between command sets"
262
294
  echo " help Show this help message"
263
295
  echo ""
264
296
  echo "Directories:"
265
- echo " Claude Code: $CLAUDE_DIR"
266
- echo " OpenCode: $OPENCODE_DIR"
297
+ echo " YAML sources: $PROJECT_DIR/.aether/commands"
298
+ echo " Claude output: $CLAUDE_DIR"
299
+ echo " OpenCode output: $OPENCODE_DIR"
300
+ echo " Claude agents: $CLAUDE_AGENT_DIR"
301
+ echo " OpenCode agents: $OPENCODE_AGENT_DIR"
302
+ echo " Aether mirror: $AETHER_AGENT_MIRROR_DIR"
267
303
  echo ""
268
- echo "Note: Commands are maintained manually in both directories."
269
- echo "Use this tool to verify they stay in sync."
304
+ echo "Note: Command specs are maintained in .aether/commands/*.yaml."
305
+ echo "Run 'npm run generate' to regenerate .md files from YAML sources."
306
+ echo "Use this tool to verify generated files are up to date."
270
307
  }
271
308
 
272
309
  # Main
@@ -274,8 +311,10 @@ case "${1:-check}" in
274
311
  check)
275
312
  # Pass 1: file count + name check
276
313
  check_sync
277
- # Pass 2: content-level checksum comparison
278
- check_content
314
+ # Pass 2: YAML generation check
315
+ check_yaml_generation
316
+ # Pass 3: agent sync policy checks
317
+ check_agent_sync
279
318
  ;;
280
319
  diff)
281
320
  show_diff
@@ -10,7 +10,6 @@
10
10
  const fs = require('fs');
11
11
  const path = require('path');
12
12
  const { logActivity } = require('./logger');
13
- const { recordSpawnTelemetry } = require('./telemetry');
14
13
 
15
14
  /**
16
15
  * Caste emoji mapping for display
@@ -72,20 +71,6 @@ async function logSpawn(repoPath, { parent, caste, child, task, model, status =
72
71
  const description = `${child} (${caste}): ${task} [model: ${model || 'default'}]`;
73
72
  logActivity('SPAWN', casteForLog, description);
74
73
 
75
- // Record telemetry for performance tracking
76
- // Handle errors gracefully - don't fail spawn logging if telemetry fails
77
- try {
78
- recordSpawnTelemetry(repoPath, {
79
- task: task || 'unknown',
80
- caste: caste || 'unknown',
81
- model: model || 'default',
82
- source: source || 'caste-default',
83
- timestamp
84
- });
85
- } catch (telemetryError) {
86
- // Silent fail for telemetry errors
87
- }
88
-
89
74
  return true;
90
75
  } catch (error) {
91
76
  // Silent fail - don't cascade errors from logging