@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
@@ -0,0 +1,303 @@
1
+ 'use strict';
2
+
3
+ const crypto = require('node:crypto');
4
+ const https = require('node:https');
5
+ const http = require('node:http');
6
+ const { URL } = require('node:url');
7
+
8
+ // ── S3-compatible provider (AWS S3, Cloudflare R2, MinIO, Backblaze B2) ──
9
+
10
+ function hmacSha256(key, data) {
11
+ return crypto.createHmac('sha256', key).update(data).digest();
12
+ }
13
+
14
+ function sha256Hex(data) {
15
+ return crypto.createHash('sha256').update(data).digest('hex');
16
+ }
17
+
18
+ function getSignatureKey(secretKey, dateStamp, region, service) {
19
+ let key = hmacSha256(`AWS4${secretKey}`, dateStamp);
20
+ key = hmacSha256(key, region);
21
+ key = hmacSha256(key, service);
22
+ key = hmacSha256(key, 'aws4_request');
23
+ return key;
24
+ }
25
+
26
+ function signV4(method, url, headers, body, config) {
27
+ const { accessKeyId, secretAccessKey, region } = config;
28
+ const now = new Date();
29
+ const dateStamp = now.toISOString().replace(/[-:]/g, '').slice(0, 8);
30
+ const amzDate = now.toISOString().replace(/[-:]/g, '').replace(/\.\d+/, '');
31
+ const service = 's3';
32
+ const scope = `${dateStamp}/${region}/${service}/aws4_request`;
33
+
34
+ const payloadHash = sha256Hex(body || '');
35
+ headers['x-amz-date'] = amzDate;
36
+ headers['x-amz-content-sha256'] = payloadHash;
37
+
38
+ const sortedHeaders = Object.keys(headers).sort();
39
+ const signedHeaders = sortedHeaders.map(k => k.toLowerCase()).join(';');
40
+ const canonicalHeaders = sortedHeaders
41
+ .map(k => `${k.toLowerCase()}:${headers[k].trim()}`)
42
+ .join('\n') + '\n';
43
+
44
+ const parsed = new URL(url);
45
+ const canonicalQuery = parsed.searchParams.toString();
46
+ const canonicalRequest = [
47
+ method,
48
+ parsed.pathname,
49
+ canonicalQuery,
50
+ canonicalHeaders,
51
+ signedHeaders,
52
+ payloadHash
53
+ ].join('\n');
54
+
55
+ const stringToSign = [
56
+ 'AWS4-HMAC-SHA256',
57
+ amzDate,
58
+ scope,
59
+ sha256Hex(canonicalRequest)
60
+ ].join('\n');
61
+
62
+ const signingKey = getSignatureKey(secretAccessKey, dateStamp, region, service);
63
+ const signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest('hex');
64
+
65
+ headers['authorization'] =
66
+ `AWS4-HMAC-SHA256 Credential=${accessKeyId}/${scope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
67
+
68
+ return headers;
69
+ }
70
+
71
+ function s3Request(method, url, body, config) {
72
+ return new Promise((resolve, reject) => {
73
+ const parsed = new URL(url);
74
+ const headers = {
75
+ 'host': parsed.host,
76
+ 'content-type': 'application/octet-stream'
77
+ };
78
+
79
+ if (body) {
80
+ headers['content-length'] = String(Buffer.byteLength(body));
81
+ }
82
+
83
+ signV4(method, url, headers, body || '', config);
84
+
85
+ const transport = parsed.protocol === 'https:' ? https : http;
86
+ const req = transport.request(
87
+ {
88
+ hostname: parsed.hostname,
89
+ port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80),
90
+ path: parsed.pathname + parsed.search,
91
+ method,
92
+ headers
93
+ },
94
+ (res) => {
95
+ const chunks = [];
96
+ res.on('data', c => chunks.push(c));
97
+ res.on('end', () => {
98
+ resolve({
99
+ statusCode: res.statusCode,
100
+ headers: res.headers,
101
+ body: Buffer.concat(chunks)
102
+ });
103
+ });
104
+ }
105
+ );
106
+ req.on('error', reject);
107
+ req.setTimeout(30000, () => {
108
+ req.destroy(new Error('S3 request timeout'));
109
+ });
110
+ if (body) req.write(body);
111
+ req.end();
112
+ });
113
+ }
114
+
115
+ function buildS3Url(config, key) {
116
+ const endpoint = config.endpoint || `https://s3.${config.region}.amazonaws.com`;
117
+ const base = endpoint.replace(/\/+$/, '');
118
+ const prefix = config.prefix ? config.prefix.replace(/\/+$/, '') + '/' : '';
119
+ return `${base}/${config.bucket}/${prefix}${key}`;
120
+ }
121
+
122
+ class S3Provider {
123
+ constructor(config) {
124
+ this.config = config;
125
+ if (!config.bucket) throw new Error('S3 provider requires "bucket"');
126
+ if (!config.accessKeyId) throw new Error('S3 provider requires "accessKeyId"');
127
+ if (!config.secretAccessKey) throw new Error('S3 provider requires "secretAccessKey"');
128
+ if (!config.region) this.config.region = 'us-east-1';
129
+ }
130
+
131
+ async upload(key, buffer, contentType = 'application/octet-stream') {
132
+ const url = buildS3Url(this.config, key);
133
+ const res = await s3Request('PUT', url, buffer, this.config);
134
+ if (res.statusCode < 200 || res.statusCode >= 300) {
135
+ throw new Error(`S3 PUT failed (${res.statusCode}): ${res.body.toString().slice(0, 200)}`);
136
+ }
137
+ return { ok: true, key, etag: res.headers.etag || null };
138
+ }
139
+
140
+ async download(key) {
141
+ const url = buildS3Url(this.config, key);
142
+ const res = await s3Request('GET', url, null, this.config);
143
+ if (res.statusCode === 404) return null;
144
+ if (res.statusCode < 200 || res.statusCode >= 300) {
145
+ throw new Error(`S3 GET failed (${res.statusCode}): ${res.body.toString().slice(0, 200)}`);
146
+ }
147
+ return res.body;
148
+ }
149
+
150
+ async exists(key) {
151
+ const url = buildS3Url(this.config, key);
152
+ const res = await s3Request('HEAD', url, null, this.config);
153
+ return res.statusCode === 200;
154
+ }
155
+
156
+ async list(prefix) {
157
+ const fullPrefix = this.config.prefix
158
+ ? `${this.config.prefix.replace(/\/+$/, '')}/${prefix}`
159
+ : prefix;
160
+
161
+ const endpoint = this.config.endpoint || `https://s3.${this.config.region}.amazonaws.com`;
162
+ const base = endpoint.replace(/\/+$/, '');
163
+ const url = `${base}/${this.config.bucket}?list-type=2&prefix=${encodeURIComponent(fullPrefix)}&max-keys=1000`;
164
+ const res = await s3Request('GET', url, null, this.config);
165
+
166
+ if (res.statusCode < 200 || res.statusCode >= 300) {
167
+ throw new Error(`S3 LIST failed (${res.statusCode})`);
168
+ }
169
+
170
+ // Simple XML parse for Key elements
171
+ const xml = res.body.toString();
172
+ const items = [];
173
+ const keyRegex = /<Key>([^<]+)<\/Key>/g;
174
+ let match;
175
+ while ((match = keyRegex.exec(xml)) !== null) {
176
+ const itemKey = match[1];
177
+ // Strip provider prefix to return relative keys
178
+ const relKey = this.config.prefix
179
+ ? itemKey.replace(new RegExp(`^${this.config.prefix.replace(/\/+$/, '')}/`), '')
180
+ : itemKey;
181
+ items.push({ key: relKey });
182
+ }
183
+ return items;
184
+ }
185
+ }
186
+
187
+ // ── Custom HTTP provider ──
188
+
189
+ function httpFetch(method, url, body, token) {
190
+ return new Promise((resolve, reject) => {
191
+ const parsed = new URL(url);
192
+ const headers = {
193
+ 'content-type': 'application/octet-stream'
194
+ };
195
+ if (token) {
196
+ headers['authorization'] = `Bearer ${token}`;
197
+ }
198
+ if (body) {
199
+ headers['content-length'] = String(Buffer.byteLength(body));
200
+ }
201
+
202
+ const transport = parsed.protocol === 'https:' ? https : http;
203
+ const req = transport.request(
204
+ {
205
+ hostname: parsed.hostname,
206
+ port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80),
207
+ path: parsed.pathname + parsed.search,
208
+ method,
209
+ headers
210
+ },
211
+ (res) => {
212
+ const chunks = [];
213
+ res.on('data', c => chunks.push(c));
214
+ res.on('end', () => {
215
+ resolve({
216
+ statusCode: res.statusCode,
217
+ headers: res.headers,
218
+ body: Buffer.concat(chunks)
219
+ });
220
+ });
221
+ }
222
+ );
223
+ req.on('error', reject);
224
+ req.setTimeout(30000, () => {
225
+ req.destroy(new Error('HTTP request timeout'));
226
+ });
227
+ if (body) req.write(body);
228
+ req.end();
229
+ });
230
+ }
231
+
232
+ class HttpProvider {
233
+ constructor(config) {
234
+ this.endpoint = (config.endpoint || '').replace(/\/+$/, '');
235
+ this.token = config.token || config.httpToken || null;
236
+ this.prefix = config.prefix ? config.prefix.replace(/\/+$/, '') + '/' : '';
237
+ if (!this.endpoint) throw new Error('HTTP provider requires "endpoint"');
238
+ }
239
+
240
+ _url(key) {
241
+ return `${this.endpoint}/${this.prefix}${key}`;
242
+ }
243
+
244
+ async upload(key, buffer, contentType = 'application/octet-stream') {
245
+ const res = await httpFetch('PUT', this._url(key), buffer, this.token);
246
+ if (res.statusCode < 200 || res.statusCode >= 300) {
247
+ throw new Error(`HTTP PUT failed (${res.statusCode}): ${res.body.toString().slice(0, 200)}`);
248
+ }
249
+ return { ok: true, key };
250
+ }
251
+
252
+ async download(key) {
253
+ const res = await httpFetch('GET', this._url(key), null, this.token);
254
+ if (res.statusCode === 404) return null;
255
+ if (res.statusCode < 200 || res.statusCode >= 300) {
256
+ throw new Error(`HTTP GET failed (${res.statusCode})`);
257
+ }
258
+ return res.body;
259
+ }
260
+
261
+ async exists(key) {
262
+ const res = await httpFetch('HEAD', this._url(key), null, this.token);
263
+ return res.statusCode === 200;
264
+ }
265
+
266
+ async list(prefix) {
267
+ const res = await httpFetch('GET', `${this._url(prefix)}?list=true`, null, this.token);
268
+ if (res.statusCode < 200 || res.statusCode >= 300) return [];
269
+ try {
270
+ return JSON.parse(res.body.toString());
271
+ } catch {
272
+ return [];
273
+ }
274
+ }
275
+ }
276
+
277
+ // ── Factory ──
278
+
279
+ function createProvider(config) {
280
+ if (!config || !config.provider) {
281
+ throw new Error('Backup config missing "provider" field. Expected "s3" or "http".');
282
+ }
283
+ switch (config.provider) {
284
+ case 's3':
285
+ return new S3Provider(config);
286
+ case 'http':
287
+ return new HttpProvider(config);
288
+ default:
289
+ throw new Error(`Unknown backup provider: "${config.provider}". Use "s3" or "http".`);
290
+ }
291
+ }
292
+
293
+ function contentHash(data) {
294
+ return sha256Hex(typeof data === 'string' ? data : JSON.stringify(data));
295
+ }
296
+
297
+ module.exports = {
298
+ createProvider,
299
+ S3Provider,
300
+ HttpProvider,
301
+ contentHash,
302
+ sha256Hex
303
+ };
package/src/cli.js CHANGED
@@ -11,6 +11,7 @@ const { runDoctorCommand } = require('./commands/doctor');
11
11
  const { runI18nAdd } = require('./commands/i18n-add');
12
12
  const { runAgentsList, runAgentPrompt } = require('./commands/agents');
13
13
  const { runContextValidate } = require('./commands/context-validate');
14
+ const { runContextPack } = require('./commands/context-pack');
14
15
  const { runSetupContext } = require('./commands/setup-context');
15
16
  const { runLocaleApply } = require('./commands/locale-apply');
16
17
  const { runSmokeTest } = require('./commands/smoke');
@@ -19,6 +20,7 @@ const { runMcpDoctor } = require('./commands/mcp-doctor');
19
20
  const { runPackageTest } = require('./commands/package-e2e');
20
21
  const { runWorkflowPlan } = require('./commands/workflow-plan');
21
22
  const { runWorkflowNext } = require('./commands/workflow-next');
23
+ const { runWorkflowStatus } = require('./commands/workflow-status');
22
24
  const { runParallelInit } = require('./commands/parallel-init');
23
25
  const { runParallelDoctor } = require('./commands/parallel-doctor');
24
26
  const { runParallelAssign } = require('./commands/parallel-assign');
@@ -40,6 +42,12 @@ const { runSquadRepairGenomes } = require('./commands/squad-repair-genomes');
40
42
  const { runSquadValidate } = require('./commands/squad-validate');
41
43
  const { runSquadExport } = require('./commands/squad-export');
42
44
  const { runSquadPipeline } = require('./commands/squad-pipeline');
45
+ const { runSquadAgentCreate } = require('./commands/squad-agent-create');
46
+ const { runSquadInvestigate } = require('./commands/squad-investigate');
47
+ const { runImplementationPlan } = require('./commands/implementation-plan');
48
+ const { runSquadPlan } = require('./commands/squad-plan');
49
+ const { runSquadLearning } = require('./commands/squad-learning');
50
+ const { runLearning } = require('./commands/learning');
43
51
  const {
44
52
  runRuntimeInit,
45
53
  runRuntimeIngest,
@@ -51,14 +59,40 @@ const {
51
59
  runRuntimeTaskFail,
52
60
  runRuntimeFail,
53
61
  runRuntimeStatus,
54
- runRuntimeLog
62
+ runRuntimeLog,
63
+ runRuntimeSessionStart,
64
+ runRuntimeSessionLog,
65
+ runRuntimeSessionFinish,
66
+ runRuntimeSessionStatus,
67
+ runDeliver,
68
+ runOutputStrategyExport,
69
+ runOutputStrategyImport,
70
+ runDevlogSync,
71
+ runRuntimePrune
55
72
  } = require('./commands/runtime');
73
+ const {
74
+ runLiveStart,
75
+ runRuntimeEmit,
76
+ runLiveHandoff,
77
+ runLiveStatus,
78
+ runLiveClose,
79
+ runLiveList
80
+ } = require('./commands/live');
56
81
  const {
57
82
  runCloudImportSquad,
58
83
  runCloudImportGenome,
59
84
  runCloudPublishGenome,
60
85
  runCloudPublishSquad
61
86
  } = require('./commands/cloud');
87
+ const {
88
+ runRuntimeBackup,
89
+ runRuntimeRestore
90
+ } = require('./commands/backup');
91
+ const {
92
+ runSkillInstall,
93
+ runSkillList,
94
+ runSkillRemove
95
+ } = require('./commands/skill');
62
96
 
63
97
  const JSON_SUPPORTED_COMMANDS = new Set([
64
98
  'init',
@@ -77,6 +111,8 @@ const JSON_SUPPORTED_COMMANDS = new Set([
77
111
  'doctor',
78
112
  'context:validate',
79
113
  'context-validate',
114
+ 'context:pack',
115
+ 'context-pack',
80
116
  'test:smoke',
81
117
  'test-smoke',
82
118
  'test:agents',
@@ -89,6 +125,8 @@ const JSON_SUPPORTED_COMMANDS = new Set([
89
125
  'workflow-plan',
90
126
  'workflow:next',
91
127
  'workflow-next',
128
+ 'workflow:status',
129
+ 'workflow-status',
92
130
  'agent:next',
93
131
  'agent-next',
94
132
  'parallel:init',
@@ -140,6 +178,24 @@ const JSON_SUPPORTED_COMMANDS = new Set([
140
178
  'squad-export',
141
179
  'squad:pipeline',
142
180
  'squad-pipeline',
181
+ 'squad:agent-create',
182
+ 'squad-agent-create',
183
+ 'squad:investigate',
184
+ 'squad-investigate',
185
+ 'plan:show',
186
+ 'plan:status',
187
+ 'plan:checkpoint',
188
+ 'plan:stale',
189
+ 'plan:register',
190
+ 'plan',
191
+ 'squad:plan',
192
+ 'squad-plan',
193
+ 'squad:learning',
194
+ 'squad-learning',
195
+ 'learning',
196
+ 'learning:list',
197
+ 'learning:stats',
198
+ 'learning:promote',
143
199
  'runtime:init',
144
200
  'runtime-init',
145
201
  'runtime:ingest',
@@ -162,6 +218,29 @@ const JSON_SUPPORTED_COMMANDS = new Set([
162
218
  'runtime-status',
163
219
  'runtime:log',
164
220
  'runtime-log',
221
+ 'runtime:session:start',
222
+ 'runtime-session-start',
223
+ 'runtime:session:log',
224
+ 'runtime-session-log',
225
+ 'runtime:session:finish',
226
+ 'runtime-session-finish',
227
+ 'runtime:session:status',
228
+ 'runtime-session-status',
229
+ 'runtime:emit',
230
+ 'runtime-emit',
231
+ 'live:start',
232
+ 'live-start',
233
+ 'live:status',
234
+ 'live-status',
235
+ 'live:handoff',
236
+ 'live-handoff',
237
+ 'live:close',
238
+ 'live-close',
239
+ 'live:list',
240
+ 'live-list',
241
+ 'deliver',
242
+ 'output-strategy:export',
243
+ 'output-strategy:import',
165
244
  'cloud:import:squad',
166
245
  'cloud-import-squad',
167
246
  'cloud:import:genome',
@@ -170,6 +249,16 @@ const JSON_SUPPORTED_COMMANDS = new Set([
170
249
  'cloud-publish-squad',
171
250
  'cloud:publish:genome',
172
251
  'cloud-publish-genome',
252
+ 'runtime:backup',
253
+ 'runtime-backup',
254
+ 'runtime:restore',
255
+ 'runtime-restore',
256
+ 'skill:install',
257
+ 'skill-install',
258
+ 'skill:list',
259
+ 'skill-list',
260
+ 'skill:remove',
261
+ 'skill-remove',
173
262
  'version',
174
263
  '--version',
175
264
  '-v'
@@ -223,6 +312,7 @@ function printHelp(t, logger) {
223
312
  logHelpLine(t, logger, 'cli.help_agents');
224
313
  logHelpLine(t, logger, 'cli.help_agent_prompt');
225
314
  logHelpLine(t, logger, 'cli.help_context_validate');
315
+ logHelpLine(t, logger, 'cli.help_context_pack');
226
316
  logHelpLine(t, logger, 'cli.help_setup_context');
227
317
  logHelpLine(t, logger, 'cli.help_locale_apply');
228
318
  logHelpLine(t, logger, 'cli.help_locale_diff');
@@ -231,6 +321,7 @@ function printHelp(t, logger) {
231
321
  logHelpLine(t, logger, 'cli.help_test_package');
232
322
  logHelpLine(t, logger, 'cli.help_workflow_plan');
233
323
  logHelpLine(t, logger, 'cli.help_workflow_next');
324
+ logHelpLine(t, logger, 'cli.help_workflow_status');
234
325
  logHelpLine(t, logger, 'cli.help_parallel_init');
235
326
  logHelpLine(t, logger, 'cli.help_parallel_doctor');
236
327
  logHelpLine(t, logger, 'cli.help_parallel_assign');
@@ -252,6 +343,10 @@ function printHelp(t, logger) {
252
343
  logHelpLine(t, logger, 'cli.help_squad_validate');
253
344
  logHelpLine(t, logger, 'cli.help_squad_export');
254
345
  logHelpLine(t, logger, 'cli.help_squad_pipeline');
346
+ logHelpLine(t, logger, 'cli.help_squad_agent_create');
347
+ logHelpLine(t, logger, 'cli.help_squad_investigate');
348
+ logHelpLine(t, logger, 'cli.help_squad_learning');
349
+ logHelpLine(t, logger, 'cli.help_learning');
255
350
  logHelpLine(t, logger, 'cli.help_runtime_init');
256
351
  logHelpLine(t, logger, 'cli.help_runtime_ingest');
257
352
  logHelpLine(t, logger, 'cli.help_runtime_task_start');
@@ -262,6 +357,20 @@ function printHelp(t, logger) {
262
357
  logHelpLine(t, logger, 'cli.help_runtime_task_fail');
263
358
  logHelpLine(t, logger, 'cli.help_runtime_fail');
264
359
  logHelpLine(t, logger, 'cli.help_runtime_status');
360
+ logHelpLine(t, logger, 'cli.help_runtime_session_start');
361
+ logHelpLine(t, logger, 'cli.help_runtime_session_log');
362
+ logHelpLine(t, logger, 'cli.help_runtime_session_finish');
363
+ logHelpLine(t, logger, 'cli.help_runtime_session_status');
364
+ logHelpLine(t, logger, 'cli.help_runtime_emit');
365
+ logHelpLine(t, logger, 'cli.help_live_start');
366
+ logHelpLine(t, logger, 'cli.help_live_status');
367
+ logHelpLine(t, logger, 'cli.help_live_handoff');
368
+ logHelpLine(t, logger, 'cli.help_live_close');
369
+ logHelpLine(t, logger, 'cli.help_runtime_backup');
370
+ logHelpLine(t, logger, 'cli.help_runtime_restore');
371
+ logHelpLine(t, logger, 'cli.help_skill_install');
372
+ logHelpLine(t, logger, 'cli.help_skill_list');
373
+ logHelpLine(t, logger, 'cli.help_skill_remove');
265
374
  logHelpLine(t, logger, 'cli.help_cloud_import_squad');
266
375
  logHelpLine(t, logger, 'cli.help_cloud_import_genome');
267
376
  logHelpLine(t, logger, 'cli.help_cloud_publish_squad');
@@ -339,6 +448,8 @@ async function main() {
339
448
  result = await runAgentPrompt({ args, options, logger: commandLogger, t });
340
449
  } else if (command === 'context:validate' || command === 'context-validate') {
341
450
  result = await runContextValidate({ args, options, logger: commandLogger, t });
451
+ } else if (command === 'context:pack' || command === 'context-pack') {
452
+ result = await runContextPack({ args, options, logger: commandLogger, t });
342
453
  } else if (command === 'setup:context' || command === 'setup-context') {
343
454
  result = await runSetupContext({ args, options, logger: commandLogger, t });
344
455
  } else if (command === 'locale:apply' || command === 'locale-apply') {
@@ -359,7 +470,17 @@ async function main() {
359
470
  command === 'agent:next' ||
360
471
  command === 'agent-next'
361
472
  ) {
362
- result = await runWorkflowNext({ args, options, logger: commandLogger, t });
473
+ // --status flag routes to workflow:status
474
+ if (options.status) {
475
+ result = await runWorkflowStatus({ args, options, logger: commandLogger, t });
476
+ } else {
477
+ result = await runWorkflowNext({ args, options, logger: commandLogger, t });
478
+ }
479
+ } else if (
480
+ command === 'workflow:status' ||
481
+ command === 'workflow-status'
482
+ ) {
483
+ result = await runWorkflowStatus({ args, options, logger: commandLogger, t });
363
484
  } else if (
364
485
  command === 'parallel:init' ||
365
486
  command === 'parallel-init' ||
@@ -422,6 +543,21 @@ async function main() {
422
543
  result = await runSquadExport({ args, options, logger: commandLogger, t });
423
544
  } else if (command === 'squad:pipeline' || command === 'squad-pipeline') {
424
545
  result = await runSquadPipeline({ args, options, logger: commandLogger, t });
546
+ } else if (command === 'squad:agent-create' || command === 'squad-agent-create') {
547
+ result = await runSquadAgentCreate({ args, options, logger: commandLogger, t });
548
+ } else if (command === 'squad:investigate' || command === 'squad-investigate') {
549
+ result = await runSquadInvestigate({ args, options, logger: commandLogger, t });
550
+ } else if (command === 'squad:plan' || command === 'squad-plan') {
551
+ result = await runSquadPlan({ args, options, logger: commandLogger, t });
552
+ } else if (command === 'squad:learning' || command === 'squad-learning') {
553
+ const sub = args[1] || 'list';
554
+ result = await runSquadLearning({ args, options: { ...options, sub }, logger: commandLogger, t });
555
+ } else if (command.startsWith('learning:') || command === 'learning') {
556
+ const sub = command === 'learning' ? (args[1] || 'list') : command.split(':')[1];
557
+ result = await runLearning({ args, options: { ...options, sub }, logger: commandLogger, t });
558
+ } else if (command.startsWith('plan:') || command === 'plan') {
559
+ const sub = command === 'plan' ? (args[1] || 'show') : command.split(':')[1];
560
+ result = await runImplementationPlan({ args, options: { ...options, sub }, logger: commandLogger, t });
425
561
  } else if (command === 'runtime:init' || command === 'runtime-init') {
426
562
  result = await runRuntimeInit({ args, options, logger: commandLogger, t });
427
563
  } else if (command === 'runtime:ingest' || command === 'runtime-ingest') {
@@ -444,6 +580,46 @@ async function main() {
444
580
  result = await runRuntimeStatus({ args, options, logger: commandLogger, t });
445
581
  } else if (command === 'runtime:log' || command === 'runtime-log') {
446
582
  result = await runRuntimeLog({ args, options, logger: commandLogger, t });
583
+ } else if (command === 'runtime:session:start' || command === 'runtime-session-start') {
584
+ result = await runRuntimeSessionStart({ args, options, logger: commandLogger, t });
585
+ } else if (command === 'runtime:session:log' || command === 'runtime-session-log') {
586
+ result = await runRuntimeSessionLog({ args, options, logger: commandLogger, t });
587
+ } else if (command === 'runtime:session:finish' || command === 'runtime-session-finish') {
588
+ result = await runRuntimeSessionFinish({ args, options, logger: commandLogger, t });
589
+ } else if (command === 'runtime:session:status' || command === 'runtime-session-status') {
590
+ result = await runRuntimeSessionStatus({ args, options, logger: commandLogger, t });
591
+ } else if (command === 'runtime:emit' || command === 'runtime-emit') {
592
+ result = await runRuntimeEmit({ args, options, logger: commandLogger, t });
593
+ } else if (command === 'live:start' || command === 'live-start') {
594
+ result = await runLiveStart({ args, options, logger: commandLogger, t });
595
+ } else if (command === 'live:status' || command === 'live-status') {
596
+ result = await runLiveStatus({ args, options, logger: commandLogger, t });
597
+ } else if (command === 'live:handoff' || command === 'live-handoff') {
598
+ result = await runLiveHandoff({ args, options, logger: commandLogger, t });
599
+ } else if (command === 'live:close' || command === 'live-close') {
600
+ result = await runLiveClose({ args, options, logger: commandLogger, t });
601
+ } else if (command === 'live:list' || command === 'live-list') {
602
+ result = await runLiveList({ args, options, logger: commandLogger, t });
603
+ } else if (command === 'deliver') {
604
+ result = await runDeliver({ args, options, logger: commandLogger, t });
605
+ } else if (command === 'output-strategy:export') {
606
+ result = await runOutputStrategyExport({ args, options, logger: commandLogger, t });
607
+ } else if (command === 'output-strategy:import') {
608
+ result = await runOutputStrategyImport({ args, options, logger: commandLogger, t });
609
+ } else if (command === 'devlog:sync' || command === 'devlog-sync') {
610
+ result = await runDevlogSync({ args, options, logger: commandLogger, t });
611
+ } else if (command === 'runtime:prune' || command === 'runtime-prune') {
612
+ result = await runRuntimePrune({ args, options, logger: commandLogger, t });
613
+ } else if (command === 'runtime:backup' || command === 'runtime-backup') {
614
+ result = await runRuntimeBackup({ args, options, logger: commandLogger, t });
615
+ } else if (command === 'runtime:restore' || command === 'runtime-restore') {
616
+ result = await runRuntimeRestore({ args, options, logger: commandLogger, t });
617
+ } else if (command === 'skill:install' || command === 'skill-install') {
618
+ result = await runSkillInstall({ args, options, logger: commandLogger, t });
619
+ } else if (command === 'skill:list' || command === 'skill-list') {
620
+ result = await runSkillList({ args, options, logger: commandLogger, t });
621
+ } else if (command === 'skill:remove' || command === 'skill-remove') {
622
+ result = await runSkillRemove({ args, options, logger: commandLogger, t });
447
623
  } else if (command === 'cloud:import:squad' || command === 'cloud-import-squad') {
448
624
  result = await runCloudImportSquad({ args, options, logger: commandLogger, t });
449
625
  } else if (command === 'cloud:import:genome' || command === 'cloud-import-genome') {
@@ -17,6 +17,18 @@ const {
17
17
  classifyDirectAgentRuntime
18
18
  } = require('../execution-gateway');
19
19
 
20
+ const WORKFLOW_AGENT_IDS = new Set([
21
+ 'setup',
22
+ 'product',
23
+ 'analyst',
24
+ 'architect',
25
+ 'ux-ui',
26
+ 'pm',
27
+ 'orchestrator',
28
+ 'dev',
29
+ 'qa'
30
+ ]);
31
+
20
32
  async function resolveLocaleForTarget(targetDir, options) {
21
33
  const fromOption = options.language || options.lang;
22
34
  if (fromOption) return resolveAgentLocale(fromOption);
@@ -44,7 +56,13 @@ async function runAgentsList({ args, options, logger, t }) {
44
56
  for (const agent of agents) {
45
57
  const deps = agent.dependsOn.length > 0 ? agent.dependsOn.join(', ') : t('agents.none');
46
58
  const instructionPath = await resolveExistingInstructionPath(targetDir, agent, locale);
47
- logger.log(t('agents.agent_line', { command: agent.command, id: agent.id }));
59
+ logger.log(
60
+ t('agents.agent_line', {
61
+ label: agent.displayName || agent.id,
62
+ command: agent.command,
63
+ id: agent.id
64
+ })
65
+ );
48
66
  logger.log(t('agents.path_line', { path: instructionPath }));
49
67
  logger.log(t('agents.active_path_line', { path: agent.path }));
50
68
  logger.log(t('agents.depends_line', { value: deps }));
@@ -76,10 +94,10 @@ async function runAgentPrompt({ args, options, logger, t }) {
76
94
  let instructionPath = null;
77
95
  let prompt = null;
78
96
 
79
- const context = await validateProjectContextFile(targetDir);
80
- if (context.valid) {
97
+ if (WORKFLOW_AGENT_IDS.has(requestedAgent)) {
81
98
  const loaded = await loadOrCreateState(targetDir, options);
82
- if (loaded.state.sequence.includes(requestedAgent)) {
99
+ const hasWorkflowStage = Boolean(loaded.state.current || loaded.state.next || loaded.state.sequence.length > 0);
100
+ if (hasWorkflowStage) {
83
101
  const workflowResult = await runWorkflowNext({
84
102
  args: [targetDir],
85
103
  options: {