@jaimevalasek/aioson 1.3.0 → 1.4.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 (213) hide show
  1. package/README.md +19 -2
  2. package/docs/pt/README.md +62 -2
  3. package/docs/pt/advisor-spec.md +5 -5
  4. package/docs/pt/agentes-customizados.md +670 -0
  5. package/docs/pt/agentes.md +111 -13
  6. package/docs/pt/automacao-squads.md +407 -0
  7. package/docs/pt/cenarios.md +3 -3
  8. package/docs/pt/clientes-ai.md +62 -0
  9. package/docs/pt/comandos-cli.md +167 -17
  10. package/docs/pt/deyvin.md +115 -0
  11. package/docs/pt/genome-3.0-spec.md +11 -11
  12. package/docs/pt/inicio-rapido.md +45 -0
  13. package/docs/pt/memoria-contexto.md +255 -0
  14. package/docs/pt/output-strategy-delivery.md +655 -0
  15. package/docs/pt/profiler-system.md +17 -17
  16. package/docs/pt/runtime-observability.md +5 -1
  17. package/docs/pt/skills.md +175 -0
  18. package/docs/pt/{squad-genoma.md → squad-genome.md} +81 -75
  19. package/docs/testing/genome-2.0-rollout.md +1 -1
  20. package/package.json +3 -3
  21. package/src/agents.js +21 -5
  22. package/src/backup-provider.js +303 -0
  23. package/src/cli.js +178 -2
  24. package/src/commands/agents.js +22 -4
  25. package/src/commands/backup.js +533 -0
  26. package/src/commands/cloud.js +17 -17
  27. package/src/commands/context-pack.js +45 -0
  28. package/src/commands/implementation-plan.js +340 -0
  29. package/src/commands/learning.js +134 -0
  30. package/src/commands/live.js +1583 -0
  31. package/src/commands/runtime.js +833 -2
  32. package/src/commands/scan-project.js +288 -24
  33. package/src/commands/setup-context.js +23 -0
  34. package/src/commands/skill.js +558 -0
  35. package/src/commands/squad-agent-create.js +788 -0
  36. package/src/commands/squad-doctor.js +51 -1
  37. package/src/commands/squad-investigate.js +261 -0
  38. package/src/commands/squad-learning.js +209 -0
  39. package/src/commands/squad-pipeline.js +247 -1
  40. package/src/commands/squad-plan.js +329 -0
  41. package/src/commands/squad-status.js +1 -1
  42. package/src/commands/squad-validate.js +57 -1
  43. package/src/commands/test-agents.js +6 -1
  44. package/src/commands/workflow-next.js +8 -1
  45. package/src/commands/workflow-status.js +250 -0
  46. package/src/constants.js +80 -16
  47. package/src/context-memory.js +837 -0
  48. package/src/context-writer.js +2 -0
  49. package/src/delivery-runner.js +319 -0
  50. package/src/genome-files.js +1 -1
  51. package/src/genome-format.js +1 -1
  52. package/src/i18n/messages/en.js +206 -7
  53. package/src/i18n/messages/es.js +123 -6
  54. package/src/i18n/messages/fr.js +122 -5
  55. package/src/i18n/messages/pt-BR.js +205 -12
  56. package/src/installer.js +30 -2
  57. package/src/lib/genomes/compat.js +1 -1
  58. package/src/runtime-store.js +780 -42
  59. package/src/session-handoff.js +77 -0
  60. package/template/.aioson/agents/analyst.md +36 -9
  61. package/template/.aioson/agents/architect.md +20 -5
  62. package/template/.aioson/agents/dev.md +135 -15
  63. package/template/.aioson/agents/deyvin.md +166 -0
  64. package/template/.aioson/agents/discovery-design-doc.md +25 -1
  65. package/template/.aioson/agents/{genoma.md → genome.md} +20 -20
  66. package/template/.aioson/agents/orache.md +371 -0
  67. package/template/.aioson/agents/orchestrator.md +37 -2
  68. package/template/.aioson/agents/pair.md +5 -0
  69. package/template/.aioson/agents/pm.md +17 -5
  70. package/template/.aioson/agents/product.md +58 -22
  71. package/template/.aioson/agents/profiler-enricher.md +1 -1
  72. package/template/.aioson/agents/profiler-forge.md +9 -9
  73. package/template/.aioson/agents/profiler-researcher.md +1 -1
  74. package/template/.aioson/agents/qa.md +17 -5
  75. package/template/.aioson/agents/setup.md +81 -5
  76. package/template/.aioson/agents/squad.md +675 -28
  77. package/template/.aioson/agents/ux-ui.md +277 -34
  78. package/template/.aioson/config.md +175 -0
  79. package/template/.aioson/context/spec.md.template +17 -0
  80. package/template/.aioson/genomes/.gitkeep +0 -0
  81. package/template/.aioson/installed-skills/.gitkeep +0 -0
  82. package/template/.aioson/locales/en/agents/analyst.md +26 -4
  83. package/template/.aioson/locales/en/agents/architect.md +10 -0
  84. package/template/.aioson/locales/en/agents/dev.md +89 -4
  85. package/template/.aioson/locales/en/agents/deyvin.md +129 -0
  86. package/template/.aioson/locales/en/agents/{genoma.md → genome.md} +14 -14
  87. package/template/.aioson/locales/en/agents/orchestrator.md +36 -2
  88. package/template/.aioson/locales/en/agents/pair.md +5 -0
  89. package/template/.aioson/locales/en/agents/pm.md +7 -0
  90. package/template/.aioson/locales/en/agents/product.md +35 -17
  91. package/template/.aioson/locales/en/agents/qa.md +7 -0
  92. package/template/.aioson/locales/en/agents/setup.md +51 -5
  93. package/template/.aioson/locales/en/agents/squad.md +203 -15
  94. package/template/.aioson/locales/en/agents/ux-ui.md +375 -35
  95. package/template/.aioson/locales/es/agents/analyst.md +16 -4
  96. package/template/.aioson/locales/es/agents/architect.md +10 -0
  97. package/template/.aioson/locales/es/agents/dev.md +70 -2
  98. package/template/.aioson/locales/es/agents/deyvin.md +89 -0
  99. package/template/.aioson/locales/es/agents/{genoma.md → genome.md} +13 -13
  100. package/template/.aioson/locales/es/agents/orache.md +103 -0
  101. package/template/.aioson/locales/es/agents/orchestrator.md +36 -2
  102. package/template/.aioson/locales/es/agents/pair.md +5 -0
  103. package/template/.aioson/locales/es/agents/pm.md +7 -0
  104. package/template/.aioson/locales/es/agents/product.md +13 -3
  105. package/template/.aioson/locales/es/agents/qa.md +7 -0
  106. package/template/.aioson/locales/es/agents/setup.md +28 -5
  107. package/template/.aioson/locales/es/agents/squad.md +221 -15
  108. package/template/.aioson/locales/es/agents/ux-ui.md +26 -25
  109. package/template/.aioson/locales/fr/agents/analyst.md +16 -4
  110. package/template/.aioson/locales/fr/agents/architect.md +10 -0
  111. package/template/.aioson/locales/fr/agents/dev.md +70 -2
  112. package/template/.aioson/locales/fr/agents/deyvin.md +89 -0
  113. package/template/.aioson/locales/fr/agents/{genoma.md → genome.md} +7 -7
  114. package/template/.aioson/locales/fr/agents/orache.md +104 -0
  115. package/template/.aioson/locales/fr/agents/orchestrator.md +36 -2
  116. package/template/.aioson/locales/fr/agents/pair.md +5 -0
  117. package/template/.aioson/locales/fr/agents/pm.md +7 -0
  118. package/template/.aioson/locales/fr/agents/product.md +13 -3
  119. package/template/.aioson/locales/fr/agents/qa.md +7 -0
  120. package/template/.aioson/locales/fr/agents/setup.md +28 -5
  121. package/template/.aioson/locales/fr/agents/squad.md +216 -10
  122. package/template/.aioson/locales/fr/agents/ux-ui.md +26 -25
  123. package/template/.aioson/locales/pt-BR/agents/analyst.md +26 -4
  124. package/template/.aioson/locales/pt-BR/agents/architect.md +10 -0
  125. package/template/.aioson/locales/pt-BR/agents/dev.md +93 -4
  126. package/template/.aioson/locales/pt-BR/agents/deyvin.md +129 -0
  127. package/template/.aioson/locales/pt-BR/agents/{genoma.md → genome.md} +49 -49
  128. package/template/.aioson/locales/pt-BR/agents/orache.md +137 -0
  129. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +36 -2
  130. package/template/.aioson/locales/pt-BR/agents/pair.md +5 -0
  131. package/template/.aioson/locales/pt-BR/agents/pm.md +7 -0
  132. package/template/.aioson/locales/pt-BR/agents/product.md +35 -17
  133. package/template/.aioson/locales/pt-BR/agents/qa.md +7 -0
  134. package/template/.aioson/locales/pt-BR/agents/setup.md +51 -5
  135. package/template/.aioson/locales/pt-BR/agents/squad.md +486 -47
  136. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +361 -22
  137. package/template/.aioson/my-agents/.gitkeep +0 -0
  138. package/template/.aioson/rules/.gitkeep +0 -0
  139. package/template/.aioson/rules/squad/.gitkeep +0 -0
  140. package/template/.aioson/rules/squad/README.md +50 -0
  141. package/template/.aioson/schemas/genome-meta.schema.json +1 -1
  142. package/template/.aioson/schemas/genome.schema.json +1 -1
  143. package/template/.aioson/schemas/squad-blueprint.schema.json +11 -0
  144. package/template/.aioson/schemas/squad-manifest.schema.json +257 -1
  145. package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +157 -0
  146. package/template/.aioson/skills/design/cognitive-core-ui/references/components.md +407 -0
  147. package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +172 -0
  148. package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +490 -0
  149. package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +237 -0
  150. package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +289 -0
  151. package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +350 -0
  152. package/template/.aioson/skills/design/interface-design/SKILL.md +47 -0
  153. package/template/.aioson/skills/design/interface-design/references/components-and-states.md +105 -0
  154. package/template/.aioson/skills/design/interface-design/references/design-directions.md +101 -0
  155. package/template/.aioson/skills/design/interface-design/references/handoff-and-quality.md +71 -0
  156. package/template/.aioson/skills/design/interface-design/references/intent-and-domain.md +74 -0
  157. package/template/.aioson/skills/design/interface-design/references/tokens-and-depth.md +173 -0
  158. package/template/.aioson/skills/design/premium-command-center-ui/SKILL.md +62 -0
  159. package/template/.aioson/skills/design/premium-command-center-ui/references/operations.md +74 -0
  160. package/template/.aioson/skills/design/premium-command-center-ui/references/patterns.md +116 -0
  161. package/template/.aioson/skills/design/premium-command-center-ui/references/validation.md +47 -0
  162. package/template/.aioson/skills/design/premium-command-center-ui/references/visual-system.md +215 -0
  163. package/template/.aioson/skills/design-system/SKILL.md +92 -0
  164. package/template/.aioson/skills/design-system/cognitive-core-ui.skill +0 -0
  165. package/template/.aioson/skills/design-system/components/SKILL.md +274 -0
  166. package/template/.aioson/skills/design-system/components/SKILL.md:Zone.Identifier +0 -0
  167. package/template/.aioson/skills/design-system/dashboards/SKILL.md +184 -0
  168. package/template/.aioson/skills/design-system/dashboards/SKILL.md:Zone.Identifier +0 -0
  169. package/template/.aioson/skills/design-system/foundations/SKILL.md +250 -0
  170. package/template/.aioson/skills/design-system/foundations/SKILL.md:Zone.Identifier +0 -0
  171. package/template/.aioson/skills/design-system/motion/SKILL.md +197 -0
  172. package/template/.aioson/skills/design-system/motion/SKILL.md:Zone.Identifier +0 -0
  173. package/template/.aioson/skills/design-system/patterns/SKILL.md +231 -0
  174. package/template/.aioson/skills/design-system/patterns/SKILL.md:Zone.Identifier +0 -0
  175. package/template/.aioson/skills/squad/SKILL.md +58 -0
  176. package/template/.aioson/skills/squad/domains/.gitkeep +0 -0
  177. package/template/.aioson/skills/squad/formats/.gitkeep +0 -0
  178. package/template/.aioson/skills/squad/patterns/.gitkeep +0 -0
  179. package/template/.aioson/skills/squad/references/.gitkeep +0 -0
  180. package/template/.aioson/tasks/implementation-plan.md +288 -0
  181. package/template/.aioson/tasks/squad-create.md +1 -1
  182. package/template/.aioson/tasks/squad-execution-plan.md +279 -0
  183. package/template/.aioson/tasks/squad-export.md +1 -1
  184. package/template/.aioson/tasks/squad-investigate.md +44 -0
  185. package/template/.aioson/tasks/squad-learning-review.md +44 -0
  186. package/template/.aioson/tasks/squad-output-config.md +177 -0
  187. package/template/.aioson/tasks/squad-validate.md +1 -1
  188. package/template/.claude/commands/aioson/agent/deyvin.md +5 -0
  189. package/template/.claude/commands/aioson/agent/discovery-design-doc.md +5 -0
  190. package/template/.claude/commands/aioson/agent/genome.md +5 -0
  191. package/template/.claude/commands/aioson/agent/product.md +5 -0
  192. package/template/.claude/commands/aioson/agent/profiler-enricher.md +5 -0
  193. package/template/.claude/commands/aioson/agent/profiler-forge.md +5 -0
  194. package/template/.claude/commands/aioson/agent/profiler-researcher.md +5 -0
  195. package/template/.claude/commands/aioson/agent/squad.md +5 -0
  196. package/template/.gemini/GEMINI.md +2 -0
  197. package/template/.gemini/commands/aios-deyvin.toml +6 -0
  198. package/template/.gemini/commands/aios-pair.toml +6 -0
  199. package/template/AGENTS.md +34 -6
  200. package/template/CLAUDE.md +31 -4
  201. package/template/OPENCODE.md +6 -2
  202. package/template/squad-searches/.gitkeep +0 -0
  203. package/template/.aioson/skills/static/interface-design.md +0 -372
  204. package/template/.aioson/skills/static/premium-command-center-ui.md +0 -190
  205. /package/template/.aioson/{genomas → docs}/.gitkeep +0 -0
  206. /package/template/.claude/commands/aioson/{analyst.md → agent/analyst.md} +0 -0
  207. /package/template/.claude/commands/aioson/{architect.md → agent/architect.md} +0 -0
  208. /package/template/.claude/commands/aioson/{dev.md → agent/dev.md} +0 -0
  209. /package/template/.claude/commands/aioson/{orchestrator.md → agent/orchestrator.md} +0 -0
  210. /package/template/.claude/commands/aioson/{pm.md → agent/pm.md} +0 -0
  211. /package/template/.claude/commands/aioson/{qa.md → agent/qa.md} +0 -0
  212. /package/template/.claude/commands/aioson/{setup.md → agent/setup.md} +0 -0
  213. /package/template/.claude/commands/aioson/{ux-ui.md → agent/ux-ui.md} +0 -0
@@ -63,6 +63,7 @@ function renderProjectContext(data) {
63
63
  const language = data.conversationLanguage || 'en';
64
64
  const codeCommentLanguage = data.codeCommentLanguage || language;
65
65
  const generatedAt = data.generatedAt || new Date().toISOString();
66
+ const designSkill = data.designSkill || '';
66
67
  const web3Enabled = Boolean(data.web3Enabled);
67
68
  const web3Networks = data.web3Networks || '';
68
69
  const contractFramework = data.contractFramework || '';
@@ -79,6 +80,7 @@ framework: "${data.framework}"
79
80
  framework_installed: ${data.frameworkInstalled ? 'true' : 'false'}
80
81
  classification: "${data.classification}"
81
82
  conversation_language: "${language}"
83
+ design_skill: "${designSkill}"
82
84
  web3_enabled: ${web3Enabled ? 'true' : 'false'}
83
85
  web3_networks: "${web3Networks}"
84
86
  contract_framework: "${contractFramework}"
@@ -0,0 +1,319 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const { spawn } = require('node:child_process');
6
+
7
+ const MAX_RETRIES = 3;
8
+ const RETRY_DELAYS = [1000, 3000, 8000]; // ms — exponential-ish backoff
9
+
10
+ function resolveEnvPlaceholders(value) {
11
+ return String(value || '').replace(/\{\{ENV:(\w+)\}\}/g, (_, varName) => {
12
+ return process.env[varName] || '';
13
+ });
14
+ }
15
+
16
+ function nowIso() {
17
+ return new Date().toISOString().replace('T', ' ').replace(/\.\d+Z$/, '');
18
+ }
19
+
20
+ function logDelivery(db, entry) {
21
+ db.prepare(`
22
+ INSERT INTO delivery_log (squad_slug, content_key, webhook_slug, trigger_type, url, status_code, response_body, error_message, attempt, created_at)
23
+ VALUES (@squad_slug, @content_key, @webhook_slug, @trigger_type, @url, @status_code, @response_body, @error_message, @attempt, @created_at)
24
+ `).run({
25
+ squad_slug: entry.squadSlug,
26
+ content_key: entry.contentKey || null,
27
+ webhook_slug: entry.webhookSlug || null,
28
+ trigger_type: entry.triggerType,
29
+ url: entry.url,
30
+ status_code: entry.statusCode ?? null,
31
+ response_body: entry.responseBody ? String(entry.responseBody).slice(0, 2000) : null,
32
+ error_message: entry.errorMessage || null,
33
+ attempt: entry.attempt || 1,
34
+ created_at: nowIso()
35
+ });
36
+ }
37
+
38
+ function sleep(ms) {
39
+ return new Promise((resolve) => setTimeout(resolve, ms));
40
+ }
41
+
42
+ async function executeWebhookHttp(url, headers, payload) {
43
+ const body = JSON.stringify(payload);
44
+ const controller = new AbortController();
45
+ const timeout = setTimeout(() => controller.abort(), 15000);
46
+
47
+ try {
48
+ const response = await fetch(url, {
49
+ method: 'POST',
50
+ headers: { 'Content-Type': 'application/json', ...headers },
51
+ body,
52
+ signal: controller.signal
53
+ });
54
+
55
+ const responseBody = await response.text().catch(() => '');
56
+ return {
57
+ statusCode: response.status,
58
+ responseBody,
59
+ ok: response.status >= 200 && response.status < 300
60
+ };
61
+ } catch (err) {
62
+ return {
63
+ statusCode: null,
64
+ responseBody: null,
65
+ ok: false,
66
+ errorMessage: err.name === 'AbortError' ? 'Request timeout (15s)' : err.message
67
+ };
68
+ } finally {
69
+ clearTimeout(timeout);
70
+ }
71
+ }
72
+
73
+ function executeWorkerScript(workerPath, payload) {
74
+ return new Promise((resolve) => {
75
+ const child = spawn('python3', [workerPath], {
76
+ stdio: ['pipe', 'pipe', 'pipe'],
77
+ timeout: 30000,
78
+ env: { ...process.env }
79
+ });
80
+
81
+ let stdout = '';
82
+ let stderr = '';
83
+ child.stdout.on('data', (data) => { stdout += data; });
84
+ child.stderr.on('data', (data) => { stderr += data; });
85
+
86
+ child.stdin.write(JSON.stringify(payload));
87
+ child.stdin.end();
88
+
89
+ child.on('close', (code) => {
90
+ resolve({
91
+ statusCode: code === 0 ? 200 : 500,
92
+ responseBody: stdout.slice(0, 2000),
93
+ ok: code === 0,
94
+ errorMessage: code !== 0 ? (stderr.slice(0, 500) || `Worker exited with code ${code}`) : null
95
+ });
96
+ });
97
+
98
+ child.on('error', (err) => {
99
+ resolve({
100
+ statusCode: null,
101
+ responseBody: null,
102
+ ok: false,
103
+ errorMessage: err.message
104
+ });
105
+ });
106
+ });
107
+ }
108
+
109
+ function isRetryable(result) {
110
+ if (result.errorMessage) return true; // network error, timeout
111
+ if (!result.statusCode) return true;
112
+ // Retry on 5xx and 429 (rate limit)
113
+ return result.statusCode >= 500 || result.statusCode === 429;
114
+ }
115
+
116
+ async function deliverWebhook(db, { squadSlug, contentKey, webhook, triggerType, payload, projectDir }) {
117
+ const resolvedUrl = resolveEnvPlaceholders(webhook.url);
118
+ if (!resolvedUrl) {
119
+ logDelivery(db, {
120
+ squadSlug,
121
+ contentKey,
122
+ webhookSlug: webhook.slug,
123
+ triggerType,
124
+ url: webhook.url || '(empty)',
125
+ errorMessage: 'URL resolved to empty — check ENV variable',
126
+ attempt: 1
127
+ });
128
+ return { ok: false, error: 'URL resolved to empty' };
129
+ }
130
+
131
+ const resolvedHeaders = {};
132
+ if (webhook.headers && typeof webhook.headers === 'object') {
133
+ for (const [key, value] of Object.entries(webhook.headers)) {
134
+ resolvedHeaders[key] = resolveEnvPlaceholders(value);
135
+ }
136
+ }
137
+
138
+ // Decide execution path: worker script or direct HTTP
139
+ const hasWorker = webhook.worker && typeof webhook.worker === 'string';
140
+ let workerAbsPath = null;
141
+ if (hasWorker) {
142
+ workerAbsPath = path.resolve(projectDir, webhook.worker);
143
+ try {
144
+ await fs.access(workerAbsPath);
145
+ } catch {
146
+ workerAbsPath = null; // Worker not found, fall back to HTTP
147
+ }
148
+ }
149
+
150
+ let lastResult = null;
151
+
152
+ for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
153
+ if (attempt > 1) {
154
+ await sleep(RETRY_DELAYS[attempt - 2] || 8000);
155
+ }
156
+
157
+ if (workerAbsPath) {
158
+ lastResult = await executeWorkerScript(workerAbsPath, payload);
159
+ } else {
160
+ lastResult = await executeWebhookHttp(resolvedUrl, resolvedHeaders, payload);
161
+ }
162
+
163
+ logDelivery(db, {
164
+ squadSlug,
165
+ contentKey,
166
+ webhookSlug: webhook.slug,
167
+ triggerType,
168
+ url: resolvedUrl,
169
+ statusCode: lastResult.statusCode,
170
+ responseBody: lastResult.responseBody,
171
+ errorMessage: lastResult.errorMessage || null,
172
+ attempt
173
+ });
174
+
175
+ if (lastResult.ok) {
176
+ return { ok: true, statusCode: lastResult.statusCode, attempts: attempt };
177
+ }
178
+
179
+ if (!isRetryable(lastResult)) {
180
+ return { ok: false, statusCode: lastResult.statusCode, error: lastResult.errorMessage, attempts: attempt };
181
+ }
182
+ }
183
+
184
+ return {
185
+ ok: false,
186
+ statusCode: lastResult?.statusCode ?? null,
187
+ error: lastResult?.errorMessage || `Failed after ${MAX_RETRIES} attempts`,
188
+ attempts: MAX_RETRIES
189
+ };
190
+ }
191
+
192
+ async function readSquadManifestJson(projectDir, squadSlug) {
193
+ const paths = [
194
+ path.join(projectDir, '.aioson', 'squads', squadSlug, 'squad.manifest.json'),
195
+ path.join(projectDir, 'agents', squadSlug, 'squad.manifest.json')
196
+ ];
197
+
198
+ for (const manifestPath of paths) {
199
+ try {
200
+ const raw = await fs.readFile(manifestPath, 'utf8');
201
+ return JSON.parse(raw);
202
+ } catch {
203
+ continue;
204
+ }
205
+ }
206
+
207
+ return null;
208
+ }
209
+
210
+ function getOutputStrategy(manifest) {
211
+ if (manifest.outputStrategy && typeof manifest.outputStrategy === 'object') {
212
+ return manifest.outputStrategy;
213
+ }
214
+ return null;
215
+ }
216
+
217
+ function getWebhooksForTrigger(outputStrategy, triggerType) {
218
+ if (!outputStrategy || !outputStrategy.delivery) return [];
219
+ const webhooks = Array.isArray(outputStrategy.delivery.webhooks) ? outputStrategy.delivery.webhooks : [];
220
+ return webhooks.filter((wh) => wh.trigger === triggerType || wh.trigger === 'on-create');
221
+ }
222
+
223
+ /**
224
+ * Main entry point — called after content item is upserted.
225
+ * Checks if auto-publish is enabled and fires matching webhooks.
226
+ */
227
+ async function runAutoDelivery(db, { projectDir, squadSlug, contentKey, contentPayload }) {
228
+ const manifest = await readSquadManifestJson(projectDir, squadSlug);
229
+ if (!manifest) return { delivered: false, reason: 'no_manifest' };
230
+
231
+ const strategy = getOutputStrategy(manifest);
232
+ if (!strategy) return { delivered: false, reason: 'no_output_strategy' };
233
+
234
+ const delivery = strategy.delivery && typeof strategy.delivery === 'object' ? strategy.delivery : {};
235
+ if (!delivery.autoPublish) return { delivered: false, reason: 'auto_publish_disabled' };
236
+
237
+ const webhooks = getWebhooksForTrigger(strategy, 'on-publish');
238
+ if (webhooks.length === 0) return { delivered: false, reason: 'no_matching_webhooks' };
239
+
240
+ const payload = {
241
+ squadSlug,
242
+ contentKey,
243
+ timestamp: new Date().toISOString(),
244
+ content: contentPayload || null
245
+ };
246
+
247
+ const results = [];
248
+ for (const webhook of webhooks) {
249
+ const result = await deliverWebhook(db, {
250
+ squadSlug,
251
+ contentKey,
252
+ webhook,
253
+ triggerType: 'auto',
254
+ payload,
255
+ projectDir
256
+ });
257
+ results.push({ webhookSlug: webhook.slug, ...result });
258
+ }
259
+
260
+ return {
261
+ delivered: true,
262
+ results,
263
+ allOk: results.every((r) => r.ok)
264
+ };
265
+ }
266
+
267
+ /**
268
+ * Manual delivery — triggered by CLI command or dashboard action.
269
+ * Fires all webhooks matching the given trigger type for a content item.
270
+ */
271
+ async function runManualDelivery(db, { projectDir, squadSlug, contentKey, triggerType = 'manual', contentPayload }) {
272
+ const manifest = await readSquadManifestJson(projectDir, squadSlug);
273
+ if (!manifest) return { delivered: false, reason: 'no_manifest' };
274
+
275
+ const strategy = getOutputStrategy(manifest);
276
+ if (!strategy) return { delivered: false, reason: 'no_output_strategy' };
277
+
278
+ const delivery = strategy.delivery && typeof strategy.delivery === 'object' ? strategy.delivery : {};
279
+ const webhooks = Array.isArray(delivery.webhooks) ? delivery.webhooks : [];
280
+
281
+ const matching = triggerType === 'manual'
282
+ ? webhooks
283
+ : webhooks.filter((wh) => wh.trigger === triggerType);
284
+
285
+ if (matching.length === 0) return { delivered: false, reason: 'no_matching_webhooks' };
286
+
287
+ const payload = {
288
+ squadSlug,
289
+ contentKey,
290
+ timestamp: new Date().toISOString(),
291
+ content: contentPayload || null
292
+ };
293
+
294
+ const results = [];
295
+ for (const webhook of matching) {
296
+ const result = await deliverWebhook(db, {
297
+ squadSlug,
298
+ contentKey,
299
+ webhook,
300
+ triggerType,
301
+ payload,
302
+ projectDir
303
+ });
304
+ results.push({ webhookSlug: webhook.slug, ...result });
305
+ }
306
+
307
+ return {
308
+ delivered: true,
309
+ results,
310
+ allOk: results.every((r) => r.ok)
311
+ };
312
+ }
313
+
314
+ module.exports = {
315
+ runAutoDelivery,
316
+ runManualDelivery,
317
+ deliverWebhook,
318
+ resolveEnvPlaceholders
319
+ };
@@ -12,7 +12,7 @@ const { assertValidGenome, assertValidGenomeMeta } = require('./genome-schema');
12
12
  const { ensureDir, exists } = require('./utils');
13
13
 
14
14
  function getGenomeDir(projectRoot) {
15
- return path.join(projectRoot, '.aioson', 'genomas');
15
+ return path.join(projectRoot, '.aioson', 'genomes');
16
16
  }
17
17
 
18
18
  function getGenomeMarkdownPath(projectRoot, slug) {
@@ -271,7 +271,7 @@ function extractTitle(markdown) {
271
271
  const match = line.match(/^#\s+(.+?)\s*$/);
272
272
  if (!match) continue;
273
273
  return match[1]
274
- .replace(/^(Genome|Genoma)\s*:\s*/i, '')
274
+ .replace(/^(Genome|Genome)\s*:\s*/i, '')
275
275
  .trim();
276
276
  }
277
277
  return '';
@@ -18,6 +18,8 @@ module.exports = {
18
18
  help_agent_prompt:
19
19
  'aioson agent:prompt <agent> [path] [--tool=codex|claude|gemini|opencode] [--lang=en|pt-BR|es|fr] [--locale=en]',
20
20
  help_context_validate: 'aioson context:validate [path] [--json] [--locale=en]',
21
+ help_context_pack:
22
+ 'aioson context:pack [path] [--agent=<agent>] [--goal=<text>] [--module=<module-or-folder>] [--max-files=8] [--json] [--locale=en]',
21
23
  help_setup_context:
22
24
  'aioson setup:context [path] [--defaults] [--project-type=web_app|api|site|script|dapp] [--framework=<name>] [--backend=<name>] [--frontend=<name>] [--database=<name>] [--auth=<name>] [--uiux=<name>] [--language=en] [--web3-enabled=true|false] [--locale=en]',
23
25
  help_locale_apply: 'aioson locale:apply [path] [--lang=en|pt-BR|es|fr] [--dry-run] [--locale=en]',
@@ -30,7 +32,9 @@ module.exports = {
30
32
  help_workflow_plan:
31
33
  'aioson workflow:plan [path] [--classification=MICRO|SMALL|MEDIUM] [--json] [--locale=en]',
32
34
  help_workflow_next:
33
- 'aioson workflow:next [path] [--complete[=<agent>]] [--agent=<agent>] [--skip=<agent>] [--tool=codex|claude|gemini|opencode] [--json] [--locale=en]',
35
+ 'aioson workflow:next [path] [--complete[=<agent>]] [--agent=<agent>] [--skip=<agent>] [--status] [--tool=codex|claude|gemini|opencode] [--json] [--locale=en]',
36
+ help_workflow_status:
37
+ 'aioson workflow:status [path] [--json] [--locale=en]',
34
38
  help_parallel_init:
35
39
  'aioson parallel:init [path] [--workers=2..6] [--force] [--dry-run] [--json] [--locale=en]',
36
40
  help_parallel_doctor:
@@ -54,7 +58,7 @@ module.exports = {
54
58
  help_qa_report:
55
59
  'aioson qa:report [path] [--html] [--json] [--locale=en]',
56
60
  help_scan_project:
57
- 'aioson scan:project [path] --folder=<path[,path2]> [--summary-mode=titles|summaries|raw] [--with-llm] [--provider=<name>] [--llm-model=<name>] [--dry-run] [--json] [--locale=en]',
61
+ 'aioson scan:project [path] --folder=<path[,path2]> [--summary-mode=titles|summaries|raw] [--context-mode=merge|rewrite] [--with-llm] [--provider=<name>] [--llm-model=<name>] [--dry-run] [--json] [--locale=en]',
58
62
  help_config:
59
63
  'aioson config <set KEY=value|show|get KEY> [--json] [--locale=en]',
60
64
  help_genome_doctor:
@@ -73,6 +77,18 @@ module.exports = {
73
77
  'aioson squad:export [path] --squad=<slug> [--locale=en]',
74
78
  help_squad_pipeline:
75
79
  'aioson squad:pipeline [path] [--sub=list|show|status] [--pipeline=<slug>] [--locale=en]',
80
+ help_squad_agent_create:
81
+ 'aioson squad:agent-create [path] --name=<name> [--scope=my-agents|squad] [--squad=<slug>] [--type=agent|assistant|clone|worker] [--tier=0|1|2|3] [--disc=<profile>] [--mission=<text>] [--domain=<text>] [--specialist=<name>] [--with-infra] [--locale=en]',
82
+ help_squad_investigate:
83
+ 'aioson squad:investigate [path] [--sub=list|show|score|link|register] [--investigation=<slug>] [--squad=<slug>] [--locale=en]',
84
+ help_plan:
85
+ 'aioson plan [path] [--sub=show|status|checkpoint|stale|register] [--feature=<slug>] [--phase=<N>] [--locale=en]',
86
+ help_squad_plan:
87
+ 'aioson squad:plan [path] [--sub=show|status|checkpoint|stale|register] [--squad=<slug>] [--round=<N>] [--locale=en]',
88
+ help_squad_learning:
89
+ 'aioson squad:learning [path] [--sub=list|stats|archive|promote|export] [--squad=<slug>] [--status=<status>] [--locale=en]',
90
+ help_learning:
91
+ 'aioson learning [path] [--sub=list|stats|promote] [--status=<status>] [--id=<learning-id>] [--locale=en]',
76
92
  help_runtime_init:
77
93
  'aioson runtime:init [path] [--json] [--locale=en]',
78
94
  help_runtime_ingest:
@@ -95,6 +111,36 @@ module.exports = {
95
111
  'aioson runtime:status [path] [--json] [--locale=en]',
96
112
  help_runtime_log:
97
113
  'aioson runtime:log [path] --agent=<name> --message=<text> [--type=<event>] [--finish] [--status=completed|failed] [--summary=<text>] [--title=<task-title>] [--json] [--locale=en]',
114
+ help_runtime_session_start:
115
+ 'aioson runtime:session:start [path] --agent=<name> [--title=<text>] [--message=<text>] [--session=<key>] [--json] [--locale=en]',
116
+ help_runtime_session_log:
117
+ 'aioson runtime:session:log [path] --agent=<name> --message=<text> [--type=<event>] [--title=<text>] [--json] [--locale=en]',
118
+ help_runtime_session_finish:
119
+ 'aioson runtime:session:finish [path] --agent=<name> [--message=<text>] [--summary=<text>] [--status=completed|failed] [--json] [--locale=en]',
120
+ help_runtime_session_status:
121
+ 'aioson runtime:session:status [path] --agent=<name> [--limit=8] [--watch=2] [--json] [--locale=en]',
122
+ help_runtime_emit:
123
+ 'aioson runtime:emit [path] --agent=<name> [--type=<event>] [--summary=<text>] [--title=<text>] [--refs=<file[,file2]>] [--plan-step=<id>] [--meta=<json>] [--json] [--locale=en]',
124
+ help_live_start:
125
+ 'aioson live:start [path] --tool=codex|claude|gemini|opencode --agent=<name> [--tool-bin=<binary>] [--tool-args=<args>] [--title=<text>] [--goal=<text>] [--plan=<file>] [--session=<key>] [--message=<text>] [--attach] [--no-launch] [--json] [--locale=en]',
126
+ help_live_status:
127
+ 'aioson live:status [path] [--agent=<name>] [--limit=8] [--watch=2] [--json] [--locale=en]',
128
+ help_live_handoff:
129
+ 'aioson live:handoff [path] --agent=<name> --to=<name> [--reason=<text>] [--summary=<text>] [--message=<text>] [--json] [--locale=en]',
130
+ help_live_close:
131
+ 'aioson live:close [path] [--agent=<name>] [--summary=<text>] [--message=<text>] [--status=completed|failed] [--json] [--locale=en]',
132
+ help_live_list:
133
+ 'aioson live:list [path] [--json] [--locale=en]',
134
+ help_runtime_backup:
135
+ 'aioson runtime:backup [path] [--tables=tasks,runs,...] [--force] [--dry-run] [--json] [--locale=en]',
136
+ help_runtime_restore:
137
+ 'aioson runtime:restore [path] [--tables=tasks,runs,...] [--dry-run] [--json] [--locale=en]',
138
+ help_skill_install:
139
+ 'aioson skill:install [path] --slug=<name> [--from=npm|cloud|./path] [--force] [--json] [--locale=en]',
140
+ help_skill_list:
141
+ 'aioson skill:list [path] [--json] [--locale=en]',
142
+ help_skill_remove:
143
+ 'aioson skill:remove [path] --slug=<name> [--json] [--locale=en]',
98
144
  help_cloud_import_squad:
99
145
  'aioson cloud:import:squad [path] --url=<snapshot-url> [--force] [--snapshots-only] [--dry-run] [--json] [--locale=en]',
100
146
  help_cloud_import_genome:
@@ -147,7 +193,7 @@ module.exports = {
147
193
  step_agent_prompt: '3. Generate setup prompt for your tool: aioson agent:prompt setup --tool={tool}',
148
194
  existing_project_detected: '⚠ Existing project detected ({count} files). Run the scanner before starting:',
149
195
  existing_project_scan_hint:
150
- ' aioson scan:project --folder=src (builds scan-index.md locally; add --with-llm to generate discovery.md)'
196
+ ' aioson scan:project . --folder=src --with-llm --provider=<provider> (generates discovery.md + skeleton-system.md; omit --with-llm for local maps only)'
151
197
  },
152
198
  update: {
153
199
  not_installed: 'No AIOSON installation found in {targetDir}.',
@@ -243,7 +289,7 @@ module.exports = {
243
289
  active_path: 'Active path',
244
290
  depends: 'Depends on',
245
291
  output: 'Output',
246
- agent_line: '- Agent: {command} ({id})',
292
+ agent_line: '- Agent: {label} - {command} ({id})',
247
293
  path_line: ' Path: {path}',
248
294
  active_path_line: ' Active path: {path}',
249
295
  depends_line: ' Depends on: {value}',
@@ -269,6 +315,13 @@ module.exports = {
269
315
  issue_line: '- {issue}',
270
316
  valid: 'Context file is valid.'
271
317
  },
318
+ context_pack: {
319
+ generated: 'Context pack written to: {path}',
320
+ no_matches: 'No relevant context files were selected yet. Run setup/context/scan before packing.',
321
+ selected_title: 'Files included in the pack:',
322
+ selected_line: ' {index}. {path} — {reason}',
323
+ hint_use: 'Use {path} as the minimum starting context in your AI session.'
324
+ },
272
325
  setup_context: {
273
326
  detected: 'Detected framework: {framework} (installed={installed})',
274
327
  q_project_name: 'Project name',
@@ -712,7 +765,38 @@ module.exports = {
712
765
  status_active_task_line: '- {task} | squad: {squad} | status: {status} | work: {title}',
713
766
  status_no_active: 'No active agent runs.',
714
767
  status_active_title: 'Active runs:',
715
- status_active_line: '- {agent} | squad: {squad} | status: {status} | work: {title}'
768
+ status_active_line: '- {agent} | squad: {squad} | status: {status} | work: {title}',
769
+ status_live_sessions_title: 'Active live sessions:',
770
+ status_live_session_line: '- {task} | agent: {agent} | status: {status} | plan: {plan} | micro: {micro} | handoffs: {handoffs} | work: {title}',
771
+ status_micro_tasks_title: 'Active micro-tasks:',
772
+ status_micro_task_line: '- {task} | parent: {parent} | status: {status} | work: {title}',
773
+ status_handoffs_title: 'Recent handoffs:',
774
+ status_handoff_line: '- {created} | {from} -> {to} | session: {session} | {message}'
775
+ },
776
+ live: {
777
+ unsupported_tool: 'Unsupported live tool: {tool}. Supported tools: {supported}',
778
+ plan_not_found: 'Plan file not found: {plan}',
779
+ no_active_session: 'No active live session found for {agent}.',
780
+ session_not_active: 'Live session for {agent} is not active.',
781
+ json_requires_no_launch: '--json requires --no-launch for live:start because foreground launch is interactive.',
782
+ tool_binary_not_found: 'Tool binary not found in PATH: {binary}',
783
+ tool_mismatch: 'Active session uses tool "{existing}" but --tool={requested} was given. Close the session first or use the same tool.',
784
+ micro_task_already_open: 'A live micro-task is already open for {agent}. Emit task_completed before task_started again.',
785
+ handoff_same_agent: 'live:handoff requires different --agent and --to values.',
786
+ handoff_agent_mismatch: 'No active live session found for {agent}.',
787
+ watch_json_conflict: '--watch cannot be combined with --json.',
788
+ no_session_found: 'No live session found.',
789
+ no_session_for_agent: 'No live session found for {agent}.',
790
+ session_already_closed: 'Live session {session} is already closed.',
791
+ session_already_active: 'Live session already active: {agent} | session: {session} | run: {runKey} ({dbPath})',
792
+ session_started: 'Live session started: {agent} | tool: {tool} | session: {session} ({dbPath})',
793
+ event_recorded: 'Live event recorded: {agent} | {eventType} | {session} ({dbPath})',
794
+ handoff_recorded: 'Live handoff recorded: {from} -> {to} | {session} ({dbPath})',
795
+ session_closed: 'Live session closed: {agent} | {session} ({dbPath})',
796
+ process_dead_warning: 'Process is dead while the live session is still open. Close it manually with `aioson live:close . --status=failed`.',
797
+ list_title: 'Live sessions ({count}):',
798
+ list_empty: 'No live sessions found.',
799
+ list_line: '- {session} | {agent} | {tool} | {phase} | {updatedAt}'
716
800
  },
717
801
  squad_status: {
718
802
  no_squad: 'No squads found.',
@@ -729,6 +813,17 @@ module.exports = {
729
813
  logs: ' Logs : {count} ({path})',
730
814
  genomes: ' Genomes : {count} squad-level / {agent_count} agent bindings'
731
815
  },
816
+ squad_agent_create: {
817
+ no_name: 'Usage: aioson squad:agent-create [path] --name=<agent-name> [--type=agent|assistant|clone|worker] [--scope=my-agents|squad] [--squad=<slug>]',
818
+ invalid_scope: 'Invalid scope: "{scope}". Use "my-agents" or "squad".',
819
+ invalid_type: 'Invalid type: "{type}". Use: agent, assistant, clone, worker.',
820
+ invalid_tier: 'Invalid tier: "{tier}". Use: 0 (foundation), 1 (master), 2 (systematizer), 3 (specialist).',
821
+ invalid_disc: 'Invalid DISC profile: "{disc}".',
822
+ no_squads: 'No squads found. Create a squad first with @squad or provide --squad=<slug>.',
823
+ squad_required: '--squad=<slug> required when scope is "squad".',
824
+ squad_not_found: 'Squad "{squad}" not found.',
825
+ already_exists: 'Agent already exists: {path}'
826
+ },
732
827
  squad_doctor: {
733
828
  prefix_ok: 'OK',
734
829
  prefix_warn: 'WARN',
@@ -752,6 +847,19 @@ module.exports = {
752
847
  scanning: 'aioson scan:project — scanning {dir}',
753
848
  folder_required:
754
849
  'Pass --folder=<path[,path2]> to generate full scans for specific folders. Example: --folder=src or --folder=app.',
850
+ folder_required_examples_title: '\x1b[33mQuick start:\x1b[0m',
851
+ folder_required_example_local:
852
+ ' Local maps only : aioson scan:project . --folder=src',
853
+ folder_required_example_multi:
854
+ ' Multiple folders: aioson scan:project . --folder=src,app',
855
+ folder_required_example_llm:
856
+ ' API automation : aioson scan:project . --folder=src --with-llm --provider=openai',
857
+ folder_required_example_cli:
858
+ ' No API in aioson: aioson scan:project . --folder=src -> then run @analyst in Codex/Claude/Gemini',
859
+ folder_required_example_prompt:
860
+ ' Ready prompt : aioson agent:prompt analyst --tool=codex',
861
+ folder_required_example_next:
862
+ ' Workflow after full scan: @analyst -> @architect -> @dev',
755
863
  folder_not_found: 'Folder "{folder}" was not found in this project. Top-level directories detected: {available}',
756
864
  config_missing: '{file} not found. To use LLM mode, copy aioson-models.json and fill in your API keys.',
757
865
  config_invalid: 'Invalid JSON in aioson-models.json: {error}',
@@ -761,6 +869,10 @@ module.exports = {
761
869
  context_found: ' Context : project.context.md found',
762
870
  context_missing: ' Context : project.context.md not found (run aioson setup:context first)',
763
871
  spec_found: ' Spec : spec.md found — development memory included',
872
+ existing_discovery_found: ' Context : existing discovery.md found at {path}',
873
+ existing_skeleton_found: ' Context : existing skeleton-system.md found at {path}',
874
+ context_update_mode: ' Mode : update/merge of existing discovery.md + skeleton-system.md enabled',
875
+ context_mode: ' Context : context-mode={mode} (recommended default for brownfield: merge)',
764
876
  local_only: ' LLM : disabled by default — local scan only (use --with-llm to generate discovery.md + skeleton-system.md)',
765
877
  walking: ' Scanning project structure...',
766
878
  walk_done: ' Files : {files} entries mapped | Key files: {keys} read',
@@ -768,17 +880,104 @@ module.exports = {
768
880
  folders_written: ' Folders : folder map written to {path}',
769
881
  folder_written: ' Folder : full map for {folder} written to {path}',
770
882
  forge_written: ' AIOS : useful .aioson map written to {path}',
883
+ memory_index_written: ' Memory : memory-index.md written to {path}',
884
+ spec_current_written: ' Memory : spec-current.md written to {path}',
885
+ spec_history_written: ' Memory : spec-history.md written to {path}',
886
+ module_memory_written: ' Module : focused memory for {folder} written to {path}',
771
887
  dry_run_done: '[dry-run] Would scan {treeCount} entries and {keyCount} key files — no LLM call made.',
772
888
  local_done: ' Result : local scan completed — index, folder map, requested folder scans and .aioson map are ready.',
889
+ local_missing: ' Missing : discovery.md + skeleton-system.md were not generated in this local-only scan.',
890
+ architecture_note: ' Note : architecture.md is not generated by scan:project; it comes later from @architect.',
891
+ local_paths_title: '\n\x1b[33m How to generate discovery now:\x1b[0m',
892
+ local_path_api: ' \x1b[32mPath A — API automation\x1b[0m',
773
893
  calling_llm: ' Calling {provider} ({model})...',
774
894
  llm_missing_api_key:
775
895
  'The API key for provider "{provider}" is still missing in {file}. Fill providers.{provider}.api_key or choose another provider with --provider=...',
776
896
  llm_error: 'LLM call failed: {error}',
897
+ gitignore_policy_written:
898
+ ' Gitignore: AIOSON policy updated in {path} to ignore framework-managed files',
899
+ gitignore_tracked_note:
900
+ ' Gitignore: if those files were already tracked by Git before, you still need one git rm --cached pass for them to stop appearing in status',
901
+ invalid_llm_output_discovery_empty:
902
+ 'The LLM returned an empty discovery.md. No existing files were overwritten. Keep the current backup and retry with a stronger model or fewer folders.',
903
+ invalid_llm_output_skeleton_empty:
904
+ 'The LLM returned an empty skeleton-system.md after the delimiter. No existing files were overwritten. Retry with a stronger model or a smaller scope.',
905
+ gitignore_backups_written: ' Gitignore: local backup rule ensured in {path}',
906
+ backups_written: ' Backup : saved {count} file(s) into {path}',
777
907
  discovery_written: 'discovery.md written: {path} ({chars} chars)',
778
908
  skeleton_written: 'skeleton-system.md written: {path} ({chars} chars)',
779
909
  skeleton_missing: 'Skeleton delimiter not found in LLM response — skeleton-system.md not written.',
910
+ local_next_steps: ' 1. Run: aioson scan:project {target} --folder={folders} --with-llm --provider=<provider>',
911
+ local_path_cli: ' \x1b[36mPath B — Your AI CLI (no API inside aioson)\x1b[0m',
912
+ local_cli_step_analyst: ' 2. In Codex, Claude Code, or another client, run @analyst — it can use scan-index.md + scan-folders.md + scan-<folder>.md to write discovery.md',
913
+ local_cli_step_prompt_codex: ' 3. If the client does not understand @analyst, generate a ready prompt: aioson agent:prompt analyst --tool=codex',
914
+ local_cli_step_prompt_claude: ' 4. Swap --tool=codex for --tool=claude or --tool=gemini when needed',
915
+ local_cli_step_model_hint: ' 5. If your client supports model selection, prefer a fast/cheap model for this discovery step',
916
+ local_workflow_title: '\n\x1b[33m After discovery:\x1b[0m',
917
+ local_step_architect: ' 3. Run @architect — generates architecture.md from the consolidated discovery',
918
+ local_step_dev: ' 4. Run @dev — only start coding after discovery.md + architecture.md are ready',
780
919
  next_steps: '\n Next steps:',
781
- step_analyst: ' 1. Open your AI coding session and run @analyst — reads discovery.md + skeleton-system.md automatically',
782
- step_dev: ' 2. Run @devreads skeleton-system.md first, then discovery.md + spec.md'
920
+ step_analyst: ' 1. Open your AI coding session and run @analyst — review discovery.md + skeleton-system.md and consolidate the current scope',
921
+ step_architect: ' 2. Run @architectgenerates architecture.md from the consolidated discovery',
922
+ step_dev: ' 3. Run @dev — reads skeleton-system.md first, then discovery.md + architecture.md + spec.md'
923
+ },
924
+ squad_investigate: {
925
+ no_runtime: 'Runtime store not found. Run aioson runtime:init first.',
926
+ no_investigations: 'No investigations found.',
927
+ not_found: 'Investigation not found: {slug}',
928
+ no_report: 'Investigation "{slug}" has no report file.',
929
+ report_missing: 'Report file not found: {path}',
930
+ show_usage: 'Usage: aioson squad:investigate [path] --sub=show --investigation=<slug>',
931
+ score_usage: 'Usage: aioson squad:investigate [path] --sub=score --investigation=<slug>',
932
+ link_usage: 'Usage: aioson squad:investigate [path] --sub=link --investigation=<slug> --squad=<slug>',
933
+ register_usage: 'Usage: aioson squad:investigate [path] --sub=register --report=<path> [--domain=<name>] [--squad=<slug>]',
934
+ linked: 'Investigation "{investigation}" linked to squad "{squad}".',
935
+ registered: 'Investigation registered: {slug} ({path})',
936
+ unknown_sub: 'Unknown subcommand: {sub}. Use: list, show, score, link, register.'
937
+ },
938
+
939
+ implementation_plan: {
940
+ not_found: 'Implementation plan not found: {file}',
941
+ no_runtime: 'Runtime store not found. Run aioson runtime:init first.',
942
+ no_plans: 'No implementation plans registered.',
943
+ no_created_date: 'Plan has no created date in frontmatter — cannot check staleness.',
944
+ is_stale: 'Plan is STALE — source artifacts changed after plan was created.',
945
+ is_fresh: 'Plan is up to date.',
946
+ checkpoint_usage: 'Usage: aioson plan [path] --sub=checkpoint --feature=<slug> --phase=<N>',
947
+ phase_completed: 'Phase {phase} marked as completed.',
948
+ phase_not_found: 'Phase {phase} not found in plan.',
949
+ registered: 'Implementation plan registered: {planId} ({phases} phases)'
950
+ },
951
+
952
+ squad_plan: {
953
+ slug_required: 'Squad slug is required.',
954
+ not_found: 'Execution plan not found for squad: {slug}',
955
+ no_runtime: 'Runtime store not found. Run aioson runtime:init first.',
956
+ no_plan: 'No execution plan registered for squad: {slug}',
957
+ no_created_date: 'Plan has no created date in frontmatter — cannot check staleness.',
958
+ is_stale: 'Execution plan is STALE — squad artifacts changed after plan was created.',
959
+ is_fresh: 'Execution plan is up to date.',
960
+ checkpoint_usage: 'Usage: aioson squad:plan [path] --sub=checkpoint --squad=<slug> --round=<N>',
961
+ round_completed: 'Round {round} marked as completed.',
962
+ round_not_found: 'Round {round} not found in plan.',
963
+ registered: 'Execution plan registered: {planSlug} ({rounds} rounds)'
964
+ },
965
+
966
+ squad_learning: {
967
+ slug_required: 'Squad slug is required.',
968
+ no_runtime: 'Runtime store not found. Run aioson runtime:init first.',
969
+ no_learnings: 'No learnings found for squad: {slug}',
970
+ not_found: 'Learning not found: {id}',
971
+ archived_count: '{count} learning(s) marked as stale for squad: {slug}',
972
+ promote_usage: 'Usage: aioson squad:learning [path] --sub=promote --squad=<slug> --id=<learning-id> [--to=<rule-path>]',
973
+ promoted: 'Learning {id} promoted to rule at {path}'
974
+ },
975
+
976
+ learning: {
977
+ no_runtime: 'Runtime store not found. Run aioson runtime:init first.',
978
+ no_learnings: 'No project learnings found.',
979
+ not_found: 'Learning not found: {id}',
980
+ promote_usage: 'Usage: aioson learning [path] --sub=promote --id=<learning-id> [--to=<rule-path>]',
981
+ promoted: 'Learning {id} promoted to rule at {path}'
783
982
  }
784
983
  };