@jaimevalasek/aioson 1.4.0 → 1.5.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 (199) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/LICENSE +661 -21
  3. package/README.md +3 -1
  4. package/docs/en/squad-dashboard.md +372 -0
  5. package/docs/openclaw-bridge.md +308 -0
  6. package/docs/pt/agentes.md +124 -10
  7. package/docs/pt/cenarios.md +46 -2
  8. package/docs/pt/comandos-cli.md +60 -1
  9. package/docs/pt/inicio-rapido.md +18 -2
  10. package/docs/pt/squad-dashboard.md +373 -0
  11. package/docs/testing/genome-2.0-matrix.md +5 -5
  12. package/docs/testing/genome-2.0-rollout.md +9 -9
  13. package/package.json +2 -2
  14. package/src/backup-local.js +74 -0
  15. package/src/cli.js +98 -0
  16. package/src/commands/backup-local-cmd.js +25 -0
  17. package/src/commands/runtime.js +242 -0
  18. package/src/commands/setup-context.js +7 -2
  19. package/src/commands/squad-daemon.js +209 -0
  20. package/src/commands/squad-dashboard.js +39 -0
  21. package/src/commands/squad-deploy.js +64 -0
  22. package/src/commands/squad-doctor.js +52 -0
  23. package/src/commands/squad-mcp.js +270 -0
  24. package/src/commands/squad-processes.js +56 -0
  25. package/src/commands/squad-recovery.js +42 -0
  26. package/src/commands/squad-roi.js +291 -0
  27. package/src/commands/squad-score.js +250 -0
  28. package/src/commands/squad-status.js +37 -1
  29. package/src/commands/squad-validate.js +62 -1
  30. package/src/commands/squad-webhook.js +160 -0
  31. package/src/commands/squad-worker.js +191 -0
  32. package/src/commands/squad-worktrees.js +75 -0
  33. package/src/commands/web-map.js +70 -0
  34. package/src/commands/web-scrape.js +71 -0
  35. package/src/constants.js +8 -0
  36. package/src/context-writer.js +45 -1
  37. package/src/i18n/messages/en.js +127 -1
  38. package/src/i18n/messages/es.js +117 -0
  39. package/src/i18n/messages/fr.js +117 -0
  40. package/src/i18n/messages/pt-BR.js +126 -1
  41. package/src/lib/webhook-server.js +328 -0
  42. package/src/mcp-connectors/registry.js +602 -0
  43. package/src/runtime-store.js +259 -2
  44. package/src/squad/external-session.js +180 -0
  45. package/src/squad/inter-squad.js +74 -0
  46. package/src/squad/recovery-context.js +201 -0
  47. package/src/squad/worktree-manager.js +114 -0
  48. package/src/squad-daemon.js +490 -0
  49. package/src/squad-dashboard/api.js +223 -0
  50. package/src/squad-dashboard/attachment-handler.js +93 -0
  51. package/src/squad-dashboard/context-monitor.js +157 -0
  52. package/src/squad-dashboard/execution-logs.js +115 -0
  53. package/src/squad-dashboard/hunk-review.js +209 -0
  54. package/src/squad-dashboard/metrics.js +133 -0
  55. package/src/squad-dashboard/process-monitor.js +125 -0
  56. package/src/squad-dashboard/renderer.js +858 -0
  57. package/src/squad-dashboard/server.js +232 -0
  58. package/src/squad-dashboard/styles.js +525 -0
  59. package/src/squad-dashboard/token-tracker.js +99 -0
  60. package/src/web.js +284 -0
  61. package/src/worker-runner.js +339 -0
  62. package/template/.aioson/agents/analyst.md +4 -0
  63. package/template/.aioson/agents/architect.md +4 -0
  64. package/template/.aioson/agents/dev.md +120 -11
  65. package/template/.aioson/agents/deyvin.md +8 -0
  66. package/template/.aioson/agents/neo.md +152 -0
  67. package/template/.aioson/agents/orache.md +17 -0
  68. package/template/.aioson/agents/orchestrator.md +26 -0
  69. package/template/.aioson/agents/product.md +60 -12
  70. package/template/.aioson/agents/qa.md +1 -0
  71. package/template/.aioson/agents/setup.md +63 -19
  72. package/template/.aioson/agents/sheldon.md +603 -0
  73. package/template/.aioson/agents/squad.md +191 -0
  74. package/template/.aioson/agents/tester.md +254 -0
  75. package/template/.aioson/agents/ux-ui.md +12 -0
  76. package/template/.aioson/config.md +6 -0
  77. package/template/.aioson/locales/en/agents/analyst.md +8 -0
  78. package/template/.aioson/locales/en/agents/architect.md +8 -0
  79. package/template/.aioson/locales/en/agents/dev.md +66 -7
  80. package/template/.aioson/locales/en/agents/deyvin.md +8 -0
  81. package/template/.aioson/locales/en/agents/neo.md +8 -0
  82. package/template/.aioson/locales/en/agents/orchestrator.md +26 -0
  83. package/template/.aioson/locales/en/agents/qa.md +49 -0
  84. package/template/.aioson/locales/en/agents/setup.md +2 -1
  85. package/template/.aioson/locales/en/agents/sheldon.md +340 -0
  86. package/template/.aioson/locales/en/agents/ux-ui.md +8 -0
  87. package/template/.aioson/locales/es/agents/analyst.md +8 -0
  88. package/template/.aioson/locales/es/agents/architect.md +8 -0
  89. package/template/.aioson/locales/es/agents/dev.md +66 -7
  90. package/template/.aioson/locales/es/agents/deyvin.md +8 -0
  91. package/template/.aioson/locales/es/agents/neo.md +48 -0
  92. package/template/.aioson/locales/es/agents/orchestrator.md +26 -0
  93. package/template/.aioson/locales/es/agents/qa.md +26 -0
  94. package/template/.aioson/locales/es/agents/setup.md +2 -1
  95. package/template/.aioson/locales/es/agents/sheldon.md +192 -0
  96. package/template/.aioson/locales/es/agents/squad.md +63 -0
  97. package/template/.aioson/locales/es/agents/ux-ui.md +8 -0
  98. package/template/.aioson/locales/fr/agents/analyst.md +8 -0
  99. package/template/.aioson/locales/fr/agents/architect.md +8 -0
  100. package/template/.aioson/locales/fr/agents/dev.md +66 -7
  101. package/template/.aioson/locales/fr/agents/deyvin.md +8 -0
  102. package/template/.aioson/locales/fr/agents/neo.md +48 -0
  103. package/template/.aioson/locales/fr/agents/orchestrator.md +26 -0
  104. package/template/.aioson/locales/fr/agents/qa.md +26 -0
  105. package/template/.aioson/locales/fr/agents/setup.md +2 -1
  106. package/template/.aioson/locales/fr/agents/sheldon.md +192 -0
  107. package/template/.aioson/locales/fr/agents/squad.md +63 -0
  108. package/template/.aioson/locales/fr/agents/ux-ui.md +8 -0
  109. package/template/.aioson/locales/pt-BR/agents/analyst.md +19 -0
  110. package/template/.aioson/locales/pt-BR/agents/architect.md +19 -0
  111. package/template/.aioson/locales/pt-BR/agents/dev.md +75 -12
  112. package/template/.aioson/locales/pt-BR/agents/deyvin.md +8 -0
  113. package/template/.aioson/locales/pt-BR/agents/neo.md +147 -0
  114. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +26 -0
  115. package/template/.aioson/locales/pt-BR/agents/product.md +8 -3
  116. package/template/.aioson/locales/pt-BR/agents/qa.md +60 -0
  117. package/template/.aioson/locales/pt-BR/agents/setup.md +2 -1
  118. package/template/.aioson/locales/pt-BR/agents/sheldon.md +192 -0
  119. package/template/.aioson/locales/pt-BR/agents/squad.md +105 -0
  120. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +8 -0
  121. package/template/.aioson/schemas/squad-blueprint.schema.json +21 -0
  122. package/template/.aioson/schemas/squad-manifest.schema.json +178 -1
  123. package/template/.aioson/skills/design/bold-editorial-ui/SKILL.md +205 -0
  124. package/template/.aioson/skills/design/bold-editorial-ui/references/art-direction.md +338 -0
  125. package/template/.aioson/skills/design/bold-editorial-ui/references/components.md +977 -0
  126. package/template/.aioson/skills/design/bold-editorial-ui/references/dashboards.md +218 -0
  127. package/template/.aioson/skills/design/bold-editorial-ui/references/design-tokens.md +326 -0
  128. package/template/.aioson/skills/design/bold-editorial-ui/references/motion.md +461 -0
  129. package/template/.aioson/skills/design/bold-editorial-ui/references/patterns.md +293 -0
  130. package/template/.aioson/skills/design/bold-editorial-ui/references/websites.md +352 -0
  131. package/template/.aioson/skills/design/clean-saas-ui/SKILL.md +210 -0
  132. package/template/.aioson/skills/design/clean-saas-ui/references/art-direction.md +319 -0
  133. package/template/.aioson/skills/design/clean-saas-ui/references/components.md +365 -0
  134. package/template/.aioson/skills/design/clean-saas-ui/references/dashboards.md +196 -0
  135. package/template/.aioson/skills/design/clean-saas-ui/references/design-tokens.md +244 -0
  136. package/template/.aioson/skills/design/clean-saas-ui/references/motion.md +235 -0
  137. package/template/.aioson/skills/design/clean-saas-ui/references/patterns.md +215 -0
  138. package/template/.aioson/skills/design/clean-saas-ui/references/websites.md +295 -0
  139. package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +55 -9
  140. package/template/.aioson/skills/design/cognitive-core-ui/references/art-direction.md +339 -0
  141. package/template/.aioson/skills/design/cognitive-core-ui/references/components.md +1 -1
  142. package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +100 -0
  143. package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +43 -9
  144. package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +40 -0
  145. package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +1 -1
  146. package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +99 -12
  147. package/template/.aioson/skills/design/warm-craft-ui/SKILL.md +209 -0
  148. package/template/.aioson/skills/design/warm-craft-ui/references/art-direction.md +324 -0
  149. package/template/.aioson/skills/design/warm-craft-ui/references/components.md +508 -0
  150. package/template/.aioson/skills/design/warm-craft-ui/references/dashboards.md +223 -0
  151. package/template/.aioson/skills/design/warm-craft-ui/references/design-tokens.md +374 -0
  152. package/template/.aioson/skills/design/warm-craft-ui/references/motion.md +356 -0
  153. package/template/.aioson/skills/design/warm-craft-ui/references/patterns.md +288 -0
  154. package/template/.aioson/skills/design/warm-craft-ui/references/websites.md +289 -0
  155. package/template/.aioson/skills/premium-visual-design/SKILL.md +83 -0
  156. package/template/.aioson/skills/premium-visual-design/components/agent-badge.md +92 -0
  157. package/template/.aioson/skills/premium-visual-design/components/dependency-node.md +102 -0
  158. package/template/.aioson/skills/premium-visual-design/components/mention-autocomplete.md +136 -0
  159. package/template/.aioson/skills/premium-visual-design/components/notification-center.md +136 -0
  160. package/template/.aioson/skills/premium-visual-design/components/review-action-bar.md +188 -0
  161. package/template/.aioson/skills/premium-visual-design/components/team-switcher.md +131 -0
  162. package/template/.aioson/skills/premium-visual-design/patterns/agent-message-thread.md +198 -0
  163. package/template/.aioson/skills/premium-visual-design/patterns/notification-panel.md +275 -0
  164. package/template/.aioson/skills/premium-visual-design/patterns/review-workflow-ui.md +234 -0
  165. package/template/.aioson/skills/premium-visual-design/patterns/task-dependency-graph.md +147 -0
  166. package/template/.aioson/skills/premium-visual-design/tokens/status-extended.md +142 -0
  167. package/template/.aioson/skills/squad/formats/catalog.json +15 -0
  168. package/template/.aioson/skills/squad/formats/content/blog-post.md +47 -0
  169. package/template/.aioson/skills/squad/formats/content/newsletter.md +47 -0
  170. package/template/.aioson/skills/squad/formats/creative/podcast-script.md +43 -0
  171. package/template/.aioson/skills/squad/formats/creative/video-script.md +41 -0
  172. package/template/.aioson/skills/squad/formats/social/instagram-feed.md +42 -0
  173. package/template/.aioson/skills/squad/formats/social/linkedin-post.md +42 -0
  174. package/template/.aioson/skills/squad/formats/social/tiktok.md +39 -0
  175. package/template/.aioson/skills/squad/formats/social/twitter-thread.md +39 -0
  176. package/template/.aioson/skills/squad/formats/social/youtube-long.md +47 -0
  177. package/template/.aioson/skills/squad/formats/social/youtube-shorts.md +39 -0
  178. package/template/.aioson/skills/squad/patterns/multi-platform-pattern.md +108 -0
  179. package/template/.aioson/skills/squad/patterns/persona-based-pattern.md +98 -0
  180. package/template/.aioson/skills/squad/patterns/pipeline-pattern.md +106 -0
  181. package/template/.aioson/skills/squad/patterns/review-loop-pattern.md +81 -0
  182. package/template/.aioson/skills/squad/references/checklist-templates.md +122 -0
  183. package/template/.aioson/skills/squad/references/executor-archetypes.md +123 -0
  184. package/template/.aioson/skills/squad/references/workflow-templates.md +169 -0
  185. package/template/.aioson/skills/static/debugging-protocol.md +42 -0
  186. package/template/.aioson/skills/static/git-worktrees.md +36 -0
  187. package/template/.aioson/tasks/implementation-plan.md +19 -0
  188. package/template/.aioson/tasks/squad-design.md +28 -0
  189. package/template/.aioson/tasks/squad-profile.md +48 -0
  190. package/template/.aioson/tasks/squad-review.md +61 -0
  191. package/template/.aioson/tasks/squad-task-decompose.md +66 -0
  192. package/template/.claude/commands/aioson/agent/neo.md +5 -0
  193. package/template/.claude/commands/aioson/agent/tester.md +5 -0
  194. package/template/.gemini/GEMINI.md +1 -0
  195. package/template/.gemini/commands/aios-neo.toml +4 -0
  196. package/template/.gemini/commands/aios-tester.toml +6 -0
  197. package/template/AGENTS.md +3 -0
  198. package/template/CLAUDE.md +5 -2
  199. package/template/OPENCODE.md +2 -0
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { scrapePage } = require('../web');
5
+
6
+ const SUPPORTED_FORMATS = new Set(['markdown', 'text', 'html', 'links']);
7
+
8
+ async function runWebScrape({ args, options = {}, logger, t }) {
9
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
10
+ const url = String(options.url || '').trim();
11
+ const format = String(options.format || 'markdown').trim().toLowerCase();
12
+
13
+ if (!url) {
14
+ logger.error(t('web_scrape.url_missing'));
15
+ process.exitCode = 1;
16
+ return { ok: false, error: 'url_missing' };
17
+ }
18
+ if (!SUPPORTED_FORMATS.has(format)) {
19
+ logger.error(t('web_scrape.invalid_format', { format }));
20
+ process.exitCode = 1;
21
+ return { ok: false, error: 'invalid_format' };
22
+ }
23
+
24
+ try {
25
+ logger.log(t('web_scrape.fetching', { url }));
26
+ const page = await scrapePage(url, { sameOriginOnly: false });
27
+ const selected = format === 'markdown'
28
+ ? page.markdown
29
+ : format === 'text'
30
+ ? page.text
31
+ : format === 'html'
32
+ ? page.html
33
+ : page.links;
34
+
35
+ const output = {
36
+ ok: true,
37
+ targetDir,
38
+ url: page.url,
39
+ statusCode: page.statusCode,
40
+ contentType: page.contentType,
41
+ title: page.title,
42
+ description: page.description,
43
+ canonical: page.canonical,
44
+ format,
45
+ content: selected,
46
+ links: page.links,
47
+ truncated: page.truncated
48
+ };
49
+
50
+ if (options.json) return output;
51
+
52
+ logger.log(t('web_scrape.title_line', { title: page.title || '-' }));
53
+ logger.log(t('web_scrape.status_line', { status: page.statusCode, type: page.contentType || '-' }));
54
+ logger.log(t('web_scrape.done', { format }));
55
+ if (Array.isArray(selected)) {
56
+ for (const link of selected) logger.log(link);
57
+ } else {
58
+ logger.log(String(selected || ''));
59
+ }
60
+ return output;
61
+ } catch (error) {
62
+ logger.error(t('web_scrape.failed', { error: error.message }));
63
+ process.exitCode = 1;
64
+ return { ok: false, error: 'scrape_failed', detail: error.message };
65
+ }
66
+ }
67
+
68
+ module.exports = {
69
+ runWebScrape,
70
+ SUPPORTED_FORMATS
71
+ };
package/src/constants.js CHANGED
@@ -304,6 +304,14 @@ const AGENT_DEFINITIONS = [
304
304
  dependsOn: ['.aioson/context/discovery.md'],
305
305
  output: 'QA report'
306
306
  },
307
+ {
308
+ id: 'tester',
309
+ displayName: 'Tester',
310
+ command: '@tester',
311
+ path: '.aioson/agents/tester.md',
312
+ dependsOn: ['.aioson/context/project.context.md'],
313
+ output: '.aioson/context/test-inventory.md + .aioson/context/test-plan.md'
314
+ },
307
315
  {
308
316
  id: 'orchestrator',
309
317
  displayName: 'Orchestrator',
@@ -64,6 +64,7 @@ function renderProjectContext(data) {
64
64
  const codeCommentLanguage = data.codeCommentLanguage || language;
65
65
  const generatedAt = data.generatedAt || new Date().toISOString();
66
66
  const designSkill = data.designSkill || '';
67
+ const testRunner = data.testRunner || '';
67
68
  const web3Enabled = Boolean(data.web3Enabled);
68
69
  const web3Networks = data.web3Networks || '';
69
70
  const contractFramework = data.contractFramework || '';
@@ -81,6 +82,7 @@ framework_installed: ${data.frameworkInstalled ? 'true' : 'false'}
81
82
  classification: "${data.classification}"
82
83
  conversation_language: "${language}"
83
84
  design_skill: "${designSkill}"
85
+ test_runner: "${testRunner}"
84
86
  web3_enabled: ${web3Enabled ? 'true' : 'false'}
85
87
  web3_networks: "${web3Networks}"
86
88
  contract_framework: "${contractFramework}"
@@ -139,6 +141,47 @@ async function writeProjectContext(targetDir, content) {
139
141
  return filePath;
140
142
  }
141
143
 
144
+ async function renderSquadApiSection(projectDir) {
145
+ const squadsDir = path.join(projectDir, '.aioson', 'squads');
146
+ let slugs = [];
147
+ try {
148
+ const entries = await fs.readdir(squadsDir, { withFileTypes: true });
149
+ slugs = entries.filter(e => e.isDirectory()).map(e => e.name);
150
+ } catch {
151
+ return '';
152
+ }
153
+
154
+ const endpointRows = [];
155
+ for (const slug of slugs) {
156
+ let squadJson = null;
157
+ try {
158
+ const raw = await fs.readFile(path.join(squadsDir, slug, 'squad.json'), 'utf8');
159
+ squadJson = JSON.parse(raw);
160
+ } catch { continue; }
161
+
162
+ if (!Array.isArray(squadJson?.api_endpoints) || squadJson.api_endpoints.length === 0) continue;
163
+ for (const ep of squadJson.api_endpoints) {
164
+ endpointRows.push(
165
+ `| ${slug} | \`${ep.method || 'POST'} http://localhost:${squadJson.port || '?'}/api${ep.path}\` | ${ep.description || ''} |`
166
+ );
167
+ }
168
+ }
169
+
170
+ if (endpointRows.length === 0) return '';
171
+
172
+ return [
173
+ '## Squad API Endpoints',
174
+ '',
175
+ 'Endpoints HTTP expostos pelos squad-daemons para chamadas do frontend.',
176
+ '',
177
+ '| Squad | Endpoint | Descrição |',
178
+ '|-------|----------|-----------|',
179
+ ...endpointRows,
180
+ '',
181
+ 'Use estes endpoints ao implementar componentes frontend que precisam consultar dados dos squads.',
182
+ ].join('\n');
183
+ }
184
+
142
185
  module.exports = {
143
186
  toPositiveInt,
144
187
  scoreUserTypes,
@@ -148,5 +191,6 @@ module.exports = {
148
191
  classificationFromScore,
149
192
  normalizeBoolean,
150
193
  renderProjectContext,
151
- writeProjectContext
194
+ writeProjectContext,
195
+ renderSquadApiSection
152
196
  };
@@ -57,6 +57,10 @@ module.exports = {
57
57
  'aioson qa:scan [path] [--url=<app-url>] [--depth=3] [--max-pages=50] [--headed] [--html] [--json] [--locale=en]',
58
58
  help_qa_report:
59
59
  'aioson qa:report [path] [--html] [--json] [--locale=en]',
60
+ help_web_map:
61
+ 'aioson web:map [path] --url=<url> [--depth=<N>] [--max-pages=<N>] [--include-external] [--json] [--locale=en]',
62
+ help_web_scrape:
63
+ 'aioson web:scrape [path] --url=<url> [--format=markdown|text|html|links] [--json] [--locale=en]',
60
64
  help_scan_project:
61
65
  '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]',
62
66
  help_config:
@@ -87,6 +91,18 @@ module.exports = {
87
91
  'aioson squad:plan [path] [--sub=show|status|checkpoint|stale|register] [--squad=<slug>] [--round=<N>] [--locale=en]',
88
92
  help_squad_learning:
89
93
  'aioson squad:learning [path] [--sub=list|stats|archive|promote|export] [--squad=<slug>] [--status=<status>] [--locale=en]',
94
+ help_squad_dashboard:
95
+ 'aioson squad:dashboard [path] [--port=4180] [--squad=<slug>] [--locale=en]',
96
+ help_squad_worker:
97
+ 'aioson squad:worker [path] [--sub=list|run|test|logs|scaffold] [--squad=<slug>] [--worker=<slug>] [--input=<json>] [--locale=en]',
98
+ help_squad_daemon:
99
+ 'aioson squad:daemon [path] [--sub=start|status|stop|logs] [--squad=<slug>] [--port=<N>] [--locale=en]',
100
+ help_squad_mcp:
101
+ 'aioson squad:mcp [path] [--sub=status|connectors|configure|test] [--squad=<slug>] [--mcp=<slug>] [--connector=<id>]',
102
+ help_squad_roi:
103
+ 'aioson squad:roi [path] [--sub=config|metric|report|export] [--squad=<slug>] [--key=<metric>] [--value=<N>]',
104
+ help_squad_score:
105
+ 'aioson squad:score [path] --squad=<slug> [--locale=en]',
90
106
  help_learning:
91
107
  'aioson learning [path] [--sub=list|stats|promote] [--status=<status>] [--id=<learning-id>] [--locale=en]',
92
108
  help_runtime_init:
@@ -729,6 +745,23 @@ module.exports = {
729
745
  not_found: 'No QA report found. Run: aioson qa:run or aioson qa:scan',
730
746
  html_report_written: 'HTML report written: {path}'
731
747
  },
748
+ web_map: {
749
+ url_missing: 'Missing required option: --url=<url>.',
750
+ starting: 'Mapping site: {url}',
751
+ pages_found: 'Pages discovered: {count}',
752
+ page_line: '- {url} | depth={depth} | status={status} | links={links}',
753
+ done: 'Web map complete.',
754
+ failed: 'Web map failed: {error}'
755
+ },
756
+ web_scrape: {
757
+ url_missing: 'Missing required option: --url=<url>.',
758
+ invalid_format: 'Invalid --format value: {format}. Use markdown, text, html, or links.',
759
+ fetching: 'Fetching page: {url}',
760
+ title_line: 'Title: {title}',
761
+ status_line: 'Status: {status} | Content-Type: {type}',
762
+ done: 'Web scrape complete ({format}).',
763
+ failed: 'Web scrape failed: {error}'
764
+ },
732
765
  config: {
733
766
  usage_error:
734
767
  'Usage: aioson config <set KEY=value|show|get KEY> [--json] [--locale=en]',
@@ -811,7 +844,9 @@ module.exports = {
811
844
  sessions: ' Sessions : {count} ({path})',
812
845
  latest_html: ' Latest HTML : {value}',
813
846
  logs: ' Logs : {count} ({path})',
814
- genomes: ' Genomes : {count} squad-level / {agent_count} agent bindings'
847
+ genomes: ' Genomes : {count} squad-level / {agent_count} agent bindings',
848
+ model_tiers: ' Model Tiers : {value}',
849
+ estimated_cost: ' Est. Cost : ~${value}/run'
815
850
  },
816
851
  squad_agent_create: {
817
852
  no_name: 'Usage: aioson squad:agent-create [path] --name=<agent-name> [--type=agent|assistant|clone|worker] [--scope=my-agents|squad] [--squad=<slug>]',
@@ -936,6 +971,97 @@ module.exports = {
936
971
  unknown_sub: 'Unknown subcommand: {sub}. Use: list, show, score, link, register.'
937
972
  },
938
973
 
974
+ squad_daemon: {
975
+ squad_required: 'Squad slug is required. Use --squad=<slug>.',
976
+ started: 'Daemon started for squad "{squad}" on port {port} ({workers} workers, {cron} cron jobs)',
977
+ webhook_hint: 'Webhook endpoint: POST http://127.0.0.1:{port}/webhook/<worker-slug>',
978
+ stop_hint: 'Press Ctrl+C to stop.',
979
+ stopping: 'Stopping daemon...',
980
+ start_failed: 'Failed to start daemon: {error}',
981
+ no_runtime: 'Runtime store not found. Run aioson runtime:init first.',
982
+ no_daemons: 'No daemon records found.',
983
+ not_found: 'No daemon record for squad: {squad}',
984
+ not_running: 'Daemon for squad "{squad}" is not running.',
985
+ signal_sent: 'SIGTERM sent to daemon for "{squad}" (pid {pid}).',
986
+ process_gone: 'Daemon process for "{squad}" is no longer running.',
987
+ no_logs: 'No daemon activity logs found.',
988
+ unknown_sub: 'Unknown subcommand: {sub}. Use: start, status, stop, logs.'
989
+ },
990
+
991
+ squad_mcp: {
992
+ squad_required: 'Squad slug is required. Use --squad=<slug>.',
993
+ connectors_title: 'Built-in MCP Connectors:',
994
+ actions: 'Actions',
995
+ required_config: 'Required',
996
+ no_integrations: 'No integrations configured for squad "{squad}".',
997
+ missing_config: 'Missing config',
998
+ calls: 'Calls',
999
+ mcp_required: 'MCP slug is required. Use --mcp=<slug>.',
1000
+ connector_required: 'Connector ID is required. Use --connector=<id>.',
1001
+ unknown_connector: 'Unknown connector: {connector}. Use --sub=connectors to list available.',
1002
+ configured: 'Integration "{mcp}" configured with connector "{connector}" (status: {status}).',
1003
+ still_missing: 'Still missing env/config: {keys}',
1004
+ not_configured: 'Integration "{mcp}" is not configured.',
1005
+ test_missing: 'Integration "{mcp}" has missing config: {keys}',
1006
+ test_ok: 'Integration "{mcp}" ({connector}) — config OK.',
1007
+ health_url: 'Health check URL: {url}',
1008
+ testing_connection: 'Testing connection...',
1009
+ health_ok: 'Connection OK (HTTP {statusCode})',
1010
+ health_error: 'Connection error: {error}',
1011
+ health_skipped: 'Health check not available for this connector',
1012
+ action_required: 'Action slug is required. Use --action=<slug>.',
1013
+ invalid_input: 'Invalid JSON. Provide valid JSON with --input.',
1014
+ unknown_sub: 'Unknown subcommand: {sub}. Use: status, connectors, configure, test, call.'
1015
+ },
1016
+
1017
+ squad_roi: {
1018
+ squad_required: 'Squad slug is required. Use --squad=<slug>.',
1019
+ config_saved: 'ROI config saved for squad "{squad}".',
1020
+ pricing_model: 'Pricing model',
1021
+ setup_fee: 'Setup fee',
1022
+ monthly_fee: 'Monthly fee',
1023
+ percentage: 'Percentage',
1024
+ contract: 'Contract',
1025
+ metric_required: 'Metric key and value are required. Use --key=<name> --value=<N>.',
1026
+ metric_saved: 'Metric "{key}" = {value} saved for squad "{squad}".',
1027
+ no_metrics: 'No metrics found for squad "{squad}".',
1028
+ report_title: 'ROI Report — {squad}',
1029
+ baseline: 'Baseline',
1030
+ actual: 'Current',
1031
+ target: 'Target',
1032
+ period: 'Period',
1033
+ cost_section: 'Cost Summary:',
1034
+ monthly_cost: 'Monthly effective cost',
1035
+ exported: 'Report exported to {file} ({format}).',
1036
+ unknown_sub: 'Unknown subcommand: {sub}. Use: config, metric, report, export.'
1037
+ },
1038
+
1039
+ squad_worker: {
1040
+ squad_required: 'Squad slug is required. Use --squad=<slug>.',
1041
+ no_workers: 'No workers found for this squad.',
1042
+ run_usage: 'Usage: aioson squad:worker --sub=run --squad=<slug> --worker=<slug> [--input=<json>]',
1043
+ test_usage: 'Usage: aioson squad:worker --sub=test --squad=<slug> --worker=<slug>',
1044
+ scaffold_usage: 'Usage: aioson squad:worker --sub=scaffold --squad=<slug> --worker=<slug> [--trigger=manual|event|scheduled]',
1045
+ not_found: 'Worker not found: {worker}',
1046
+ invalid_input: 'Invalid JSON input. Provide valid JSON with --input.',
1047
+ run_success: 'Worker "{worker}" completed successfully.',
1048
+ run_failed: 'Worker "{worker}" failed: {error}',
1049
+ test_passed: 'Worker "{worker}" test passed.',
1050
+ test_failed: 'Worker "{worker}" test failed: {error}',
1051
+ scaffold_created: 'Worker "{worker}" scaffolded at {path}',
1052
+ no_runtime: 'Runtime store not found. Run aioson runtime:init first.',
1053
+ no_logs: 'No worker runs found.',
1054
+ unknown_sub: 'Unknown subcommand: {sub}. Use: list, run, test, logs, scaffold.'
1055
+ },
1056
+
1057
+ squad_dashboard: {
1058
+ started: 'Squad Dashboard running at {url} (port {port})',
1059
+ filtered: 'Filtering to squad: {squad}',
1060
+ stop_hint: 'Press Ctrl+C to stop.',
1061
+ stopping: 'Stopping Squad Dashboard...',
1062
+ port_in_use: 'Port {port} is already in use. Try --port=<another>'
1063
+ },
1064
+
939
1065
  implementation_plan: {
940
1066
  not_found: 'Implementation plan not found: {file}',
941
1067
  no_runtime: 'Runtime store not found. Run aioson runtime:init first.',
@@ -54,6 +54,10 @@ module.exports = {
54
54
  'aioson qa:scan [path] [--url=<app-url>] [--depth=3] [--max-pages=50] [--headed] [--html] [--json] [--locale=es]',
55
55
  help_qa_report:
56
56
  'aioson qa:report [path] [--html] [--json] [--locale=es]',
57
+ help_web_map:
58
+ 'aioson web:map [path] --url=<url> [--depth=<N>] [--max-pages=<N>] [--include-external] [--json] [--locale=es]',
59
+ help_web_scrape:
60
+ 'aioson web:scrape [path] --url=<url> [--format=markdown|text|html|links] [--json] [--locale=es]',
57
61
  help_scan_project:
58
62
  'aioson scan:project [path] --folder=<ruta[,ruta2]> [--summary-mode=titles|summaries|raw] [--context-mode=merge|rewrite] [--with-llm] [--provider=<name>] [--llm-model=<name>] [--dry-run] [--json] [--locale=es]',
59
63
  help_config:
@@ -76,6 +80,18 @@ module.exports = {
76
80
  'aioson squad:investigate [path] [--sub=list|show|score|link|register] [--investigation=<slug>] [--squad=<slug>] [--locale=es]',
77
81
  help_squad_learning:
78
82
  'aioson squad:learning [path] [--sub=list|stats|archive|promote|export] [--squad=<slug>] [--status=<status>] [--locale=es]',
83
+ help_squad_dashboard:
84
+ 'aioson squad:dashboard [path] [--port=4180] [--squad=<slug>] [--locale=es]',
85
+ help_squad_worker:
86
+ 'aioson squad:worker [path] [--sub=list|run|test|logs|scaffold] [--squad=<slug>] [--worker=<slug>] [--input=<json>] [--locale=es]',
87
+ help_squad_daemon:
88
+ 'aioson squad:daemon [path] [--sub=start|status|stop|logs] [--squad=<slug>] [--port=<N>] [--locale=es]',
89
+ help_squad_mcp:
90
+ 'aioson squad:mcp [path] [--sub=status|connectors|configure|test] [--squad=<slug>] [--mcp=<slug>] [--connector=<id>]',
91
+ help_squad_roi:
92
+ 'aioson squad:roi [path] [--sub=config|metric|report|export] [--squad=<slug>] [--key=<metrica>] [--value=<N>]',
93
+ help_squad_score:
94
+ 'aioson squad:score [path] --squad=<slug> [--locale=es]',
79
95
  help_learning:
80
96
  'aioson learning [path] [--sub=list|stats|promote] [--status=<status>] [--id=<learning-id>] [--locale=es]',
81
97
  dashboard_moved:
@@ -672,6 +688,23 @@ module.exports = {
672
688
  not_found: 'No se encontro reporte QA. Ejecuta: aioson qa:run o aioson qa:scan',
673
689
  html_report_written: 'Reporte HTML escrito: {path}'
674
690
  },
691
+ web_map: {
692
+ url_missing: 'Falta la opcion obligatoria: --url=<url>.',
693
+ starting: 'Mapeando sitio: {url}',
694
+ pages_found: 'Paginas descubiertas: {count}',
695
+ page_line: '- {url} | profundidad={depth} | estado={status} | links={links}',
696
+ done: 'Mapa web completado.',
697
+ failed: 'Fallo en mapa web: {error}'
698
+ },
699
+ web_scrape: {
700
+ url_missing: 'Falta la opcion obligatoria: --url=<url>.',
701
+ invalid_format: 'Valor invalido para --format: {format}. Usa markdown, text, html o links.',
702
+ fetching: 'Obteniendo pagina: {url}',
703
+ title_line: 'Titulo: {title}',
704
+ status_line: 'Estado: {status} | Content-Type: {type}',
705
+ done: 'Web scrape completado ({format}).',
706
+ failed: 'Fallo en web scrape: {error}'
707
+ },
675
708
  config: {
676
709
  usage_error:
677
710
  'Uso: aioson config <set KEY=value|show|get KEY> [--json] [--locale=es]',
@@ -789,6 +822,90 @@ module.exports = {
789
822
  registered: 'Investigacion registrada: {slug} ({path})',
790
823
  unknown_sub: 'Subcomando desconocido: {sub}. Usa: list, show, score, link, register.'
791
824
  },
825
+ squad_daemon: {
826
+ squad_required: 'El slug del squad es obligatorio. Use --squad=<slug>.',
827
+ started: 'Daemon iniciado para squad "{squad}" en puerto {port} ({workers} workers, {cron} cron jobs)',
828
+ webhook_hint: 'Endpoint webhook: POST http://127.0.0.1:{port}/webhook/<worker-slug>',
829
+ stop_hint: 'Presione Ctrl+C para detener.',
830
+ stopping: 'Deteniendo daemon...',
831
+ start_failed: 'Error al iniciar daemon: {error}',
832
+ no_runtime: 'Runtime store no encontrado. Ejecute aioson runtime:init primero.',
833
+ no_daemons: 'No se encontraron registros de daemon.',
834
+ not_found: 'No hay registro de daemon para el squad: {squad}',
835
+ not_running: 'El daemon del squad "{squad}" no esta en ejecucion.',
836
+ signal_sent: 'SIGTERM enviado al daemon de "{squad}" (pid {pid}).',
837
+ process_gone: 'El proceso del daemon de "{squad}" ya no esta en ejecucion.',
838
+ no_logs: 'No se encontraron registros de actividad del daemon.',
839
+ unknown_sub: 'Subcomando desconocido: {sub}. Use: start, status, stop, logs.'
840
+ },
841
+
842
+ squad_mcp: {
843
+ squad_required: 'El slug del squad es obligatorio. Use --squad=<slug>.',
844
+ connectors_title: 'Conectores MCP Integrados:',
845
+ actions: 'Acciones',
846
+ required_config: 'Requerido',
847
+ no_integrations: 'No hay integraciones configuradas para el squad "{squad}".',
848
+ missing_config: 'Config faltante',
849
+ calls: 'Llamadas',
850
+ mcp_required: 'El slug del MCP es obligatorio. Use --mcp=<slug>.',
851
+ connector_required: 'El ID del conector es obligatorio. Use --connector=<id>.',
852
+ unknown_connector: 'Conector desconocido: {connector}. Use --sub=connectors para listar.',
853
+ configured: 'Integracion "{mcp}" configurada con conector "{connector}" (estado: {status}).',
854
+ still_missing: 'Aun faltan env/config: {keys}',
855
+ not_configured: 'La integracion "{mcp}" no esta configurada.',
856
+ test_missing: 'La integracion "{mcp}" tiene config faltante: {keys}',
857
+ test_ok: 'Integracion "{mcp}" ({connector}) — config OK.',
858
+ health_url: 'URL de health check: {url}',
859
+ unknown_sub: 'Subcomando desconocido: {sub}. Use: status, connectors, configure, test.'
860
+ },
861
+
862
+ squad_roi: {
863
+ squad_required: 'El slug del squad es obligatorio. Use --squad=<slug>.',
864
+ config_saved: 'Config de ROI guardada para el squad "{squad}".',
865
+ pricing_model: 'Modelo de precios',
866
+ setup_fee: 'Tarifa de instalacion',
867
+ monthly_fee: 'Mensualidad',
868
+ percentage: 'Porcentaje',
869
+ contract: 'Contrato',
870
+ metric_required: 'La clave y el valor de la metrica son obligatorios. Use --key=<nombre> --value=<N>.',
871
+ metric_saved: 'Metrica "{key}" = {value} guardada para el squad "{squad}".',
872
+ no_metrics: 'No se encontraron metricas para el squad "{squad}".',
873
+ report_title: 'Reporte de ROI — {squad}',
874
+ baseline: 'Baseline',
875
+ actual: 'Actual',
876
+ target: 'Meta',
877
+ period: 'Periodo',
878
+ cost_section: 'Resumen de Costos:',
879
+ monthly_cost: 'Costo mensual efectivo',
880
+ exported: 'Reporte exportado a {file} ({format}).',
881
+ unknown_sub: 'Subcomando desconocido: {sub}. Use: config, metric, report, export.'
882
+ },
883
+
884
+ squad_worker: {
885
+ squad_required: 'El slug del squad es obligatorio. Use --squad=<slug>.',
886
+ no_workers: 'No se encontraron workers para este squad.',
887
+ run_usage: 'Uso: aioson squad:worker --sub=run --squad=<slug> --worker=<slug> [--input=<json>]',
888
+ test_usage: 'Uso: aioson squad:worker --sub=test --squad=<slug> --worker=<slug>',
889
+ scaffold_usage: 'Uso: aioson squad:worker --sub=scaffold --squad=<slug> --worker=<slug> [--trigger=manual|event|scheduled]',
890
+ not_found: 'Worker no encontrado: {worker}',
891
+ invalid_input: 'JSON invalido. Proporcione JSON valido con --input.',
892
+ run_success: 'Worker "{worker}" completado exitosamente.',
893
+ run_failed: 'Worker "{worker}" fallo: {error}',
894
+ test_passed: 'Worker "{worker}" prueba aprobada.',
895
+ test_failed: 'Worker "{worker}" prueba fallo: {error}',
896
+ scaffold_created: 'Worker "{worker}" creado en {path}',
897
+ no_runtime: 'Runtime store no encontrado. Ejecute aioson runtime:init primero.',
898
+ no_logs: 'No se encontraron ejecuciones de worker.',
899
+ unknown_sub: 'Subcomando desconocido: {sub}. Use: list, run, test, logs, scaffold.'
900
+ },
901
+
902
+ squad_dashboard: {
903
+ started: 'Squad Dashboard ejecutandose en {url} (puerto {port})',
904
+ filtered: 'Filtrando al squad: {squad}',
905
+ stop_hint: 'Presione Ctrl+C para detener.',
906
+ stopping: 'Deteniendo Squad Dashboard...',
907
+ port_in_use: 'El puerto {port} ya esta en uso. Intente --port=<otro>'
908
+ },
792
909
  implementation_plan: {
793
910
  not_found: 'Plan de implementacion no encontrado: {file}',
794
911
  no_runtime: 'Runtime store no encontrado. Ejecuta aioson runtime:init primero.',
@@ -54,6 +54,10 @@ module.exports = {
54
54
  'aioson qa:scan [path] [--url=<app-url>] [--depth=3] [--max-pages=50] [--headed] [--html] [--json] [--locale=fr]',
55
55
  help_qa_report:
56
56
  'aioson qa:report [path] [--html] [--json] [--locale=fr]',
57
+ help_web_map:
58
+ 'aioson web:map [path] --url=<url> [--depth=<N>] [--max-pages=<N>] [--include-external] [--json] [--locale=fr]',
59
+ help_web_scrape:
60
+ 'aioson web:scrape [path] --url=<url> [--format=markdown|text|html|links] [--json] [--locale=fr]',
57
61
  help_scan_project:
58
62
  'aioson scan:project [path] --folder=<chemin[,chemin2]> [--summary-mode=titles|summaries|raw] [--context-mode=merge|rewrite] [--with-llm] [--provider=<name>] [--llm-model=<name>] [--dry-run] [--json] [--locale=fr]',
59
63
  help_config:
@@ -76,6 +80,18 @@ module.exports = {
76
80
  'aioson squad:investigate [path] [--sub=list|show|score|link|register] [--investigation=<slug>] [--squad=<slug>] [--locale=fr]',
77
81
  help_squad_learning:
78
82
  'aioson squad:learning [path] [--sub=list|stats|archive|promote|export] [--squad=<slug>] [--status=<status>] [--locale=fr]',
83
+ help_squad_dashboard:
84
+ 'aioson squad:dashboard [path] [--port=4180] [--squad=<slug>] [--locale=fr]',
85
+ help_squad_worker:
86
+ 'aioson squad:worker [path] [--sub=list|run|test|logs|scaffold] [--squad=<slug>] [--worker=<slug>] [--input=<json>] [--locale=fr]',
87
+ help_squad_daemon:
88
+ 'aioson squad:daemon [path] [--sub=start|status|stop|logs] [--squad=<slug>] [--port=<N>] [--locale=fr]',
89
+ help_squad_mcp:
90
+ 'aioson squad:mcp [path] [--sub=status|connectors|configure|test] [--squad=<slug>] [--mcp=<slug>] [--connector=<id>]',
91
+ help_squad_roi:
92
+ 'aioson squad:roi [path] [--sub=config|metric|report|export] [--squad=<slug>] [--key=<metrique>] [--value=<N>]',
93
+ help_squad_score:
94
+ 'aioson squad:score [path] --squad=<slug> [--locale=fr]',
79
95
  help_learning:
80
96
  'aioson learning [path] [--sub=list|stats|promote] [--status=<status>] [--id=<learning-id>] [--locale=fr]',
81
97
  dashboard_moved:
@@ -679,6 +695,23 @@ module.exports = {
679
695
  not_found: 'Aucun rapport QA trouve. Executez : aioson qa:run ou aioson qa:scan',
680
696
  html_report_written: 'Rapport HTML ecrit : {path}'
681
697
  },
698
+ web_map: {
699
+ url_missing: 'Option obligatoire manquante : --url=<url>.',
700
+ starting: 'Cartographie du site : {url}',
701
+ pages_found: 'Pages decouvertes : {count}',
702
+ page_line: '- {url} | profondeur={depth} | statut={status} | liens={links}',
703
+ done: 'Cartographie web terminee.',
704
+ failed: 'Echec de la cartographie web : {error}'
705
+ },
706
+ web_scrape: {
707
+ url_missing: 'Option obligatoire manquante : --url=<url>.',
708
+ invalid_format: 'Valeur invalide pour --format : {format}. Utilisez markdown, text, html ou links.',
709
+ fetching: 'Recuperation de la page : {url}',
710
+ title_line: 'Titre : {title}',
711
+ status_line: 'Statut : {status} | Content-Type : {type}',
712
+ done: 'Web scrape termine ({format}).',
713
+ failed: 'Echec du web scrape : {error}'
714
+ },
682
715
  config: {
683
716
  usage_error:
684
717
  'Utilisation : aioson config <set KEY=value|show|get KEY> [--json] [--locale=fr]',
@@ -796,6 +829,90 @@ module.exports = {
796
829
  registered: 'Investigation enregistree : {slug} ({path})',
797
830
  unknown_sub: 'Sous-commande inconnue : {sub}. Utilisez : list, show, score, link, register.'
798
831
  },
832
+ squad_daemon: {
833
+ squad_required: 'Le slug du squad est obligatoire. Utilisez --squad=<slug>.',
834
+ started: 'Daemon demarre pour le squad "{squad}" sur le port {port} ({workers} workers, {cron} cron jobs)',
835
+ webhook_hint: 'Endpoint webhook : POST http://127.0.0.1:{port}/webhook/<worker-slug>',
836
+ stop_hint: 'Appuyez sur Ctrl+C pour arreter.',
837
+ stopping: 'Arret du daemon...',
838
+ start_failed: 'Echec du demarrage du daemon : {error}',
839
+ no_runtime: 'Runtime store non trouve. Executez aioson runtime:init d\'abord.',
840
+ no_daemons: 'Aucun enregistrement de daemon trouve.',
841
+ not_found: 'Aucun enregistrement de daemon pour le squad : {squad}',
842
+ not_running: 'Le daemon du squad "{squad}" n\'est pas en cours d\'execution.',
843
+ signal_sent: 'SIGTERM envoye au daemon de "{squad}" (pid {pid}).',
844
+ process_gone: 'Le processus du daemon de "{squad}" n\'est plus en cours d\'execution.',
845
+ no_logs: 'Aucun journal d\'activite du daemon trouve.',
846
+ unknown_sub: 'Sous-commande inconnue : {sub}. Utilisez : start, status, stop, logs.'
847
+ },
848
+
849
+ squad_mcp: {
850
+ squad_required: 'Le slug du squad est obligatoire. Utilisez --squad=<slug>.',
851
+ connectors_title: 'Connecteurs MCP Integres :',
852
+ actions: 'Actions',
853
+ required_config: 'Requis',
854
+ no_integrations: 'Aucune integration configuree pour le squad "{squad}".',
855
+ missing_config: 'Config manquante',
856
+ calls: 'Appels',
857
+ mcp_required: 'Le slug du MCP est obligatoire. Utilisez --mcp=<slug>.',
858
+ connector_required: 'L\'ID du connecteur est obligatoire. Utilisez --connector=<id>.',
859
+ unknown_connector: 'Connecteur inconnu : {connector}. Utilisez --sub=connectors pour lister.',
860
+ configured: 'Integration "{mcp}" configuree avec le connecteur "{connector}" (statut : {status}).',
861
+ still_missing: 'Config env encore manquante : {keys}',
862
+ not_configured: 'L\'integration "{mcp}" n\'est pas configuree.',
863
+ test_missing: 'L\'integration "{mcp}" a une config manquante : {keys}',
864
+ test_ok: 'Integration "{mcp}" ({connector}) — config OK.',
865
+ health_url: 'URL de verification : {url}',
866
+ unknown_sub: 'Sous-commande inconnue : {sub}. Utilisez : status, connectors, configure, test.'
867
+ },
868
+
869
+ squad_roi: {
870
+ squad_required: 'Le slug du squad est obligatoire. Utilisez --squad=<slug>.',
871
+ config_saved: 'Config ROI enregistree pour le squad "{squad}".',
872
+ pricing_model: 'Modele tarifaire',
873
+ setup_fee: 'Frais d\'installation',
874
+ monthly_fee: 'Mensualite',
875
+ percentage: 'Pourcentage',
876
+ contract: 'Contrat',
877
+ metric_required: 'La cle et la valeur de la metrique sont obligatoires. Utilisez --key=<nom> --value=<N>.',
878
+ metric_saved: 'Metrique "{key}" = {value} enregistree pour le squad "{squad}".',
879
+ no_metrics: 'Aucune metrique trouvee pour le squad "{squad}".',
880
+ report_title: 'Rapport ROI — {squad}',
881
+ baseline: 'Baseline',
882
+ actual: 'Actuel',
883
+ target: 'Objectif',
884
+ period: 'Periode',
885
+ cost_section: 'Resume des Couts :',
886
+ monthly_cost: 'Cout mensuel effectif',
887
+ exported: 'Rapport exporte vers {file} ({format}).',
888
+ unknown_sub: 'Sous-commande inconnue : {sub}. Utilisez : config, metric, report, export.'
889
+ },
890
+
891
+ squad_worker: {
892
+ squad_required: 'Le slug du squad est obligatoire. Utilisez --squad=<slug>.',
893
+ no_workers: 'Aucun worker trouve pour ce squad.',
894
+ run_usage: 'Usage : aioson squad:worker --sub=run --squad=<slug> --worker=<slug> [--input=<json>]',
895
+ test_usage: 'Usage : aioson squad:worker --sub=test --squad=<slug> --worker=<slug>',
896
+ scaffold_usage: 'Usage : aioson squad:worker --sub=scaffold --squad=<slug> --worker=<slug> [--trigger=manual|event|scheduled]',
897
+ not_found: 'Worker non trouve : {worker}',
898
+ invalid_input: 'JSON invalide. Fournissez un JSON valide avec --input.',
899
+ run_success: 'Worker "{worker}" termine avec succes.',
900
+ run_failed: 'Worker "{worker}" echoue : {error}',
901
+ test_passed: 'Worker "{worker}" test reussi.',
902
+ test_failed: 'Worker "{worker}" test echoue : {error}',
903
+ scaffold_created: 'Worker "{worker}" cree dans {path}',
904
+ no_runtime: 'Runtime store non trouve. Executez aioson runtime:init d\'abord.',
905
+ no_logs: 'Aucune execution de worker trouvee.',
906
+ unknown_sub: 'Sous-commande inconnue : {sub}. Utilisez : list, run, test, logs, scaffold.'
907
+ },
908
+
909
+ squad_dashboard: {
910
+ started: 'Squad Dashboard en cours sur {url} (port {port})',
911
+ filtered: 'Filtrage sur le squad : {squad}',
912
+ stop_hint: 'Appuyez sur Ctrl+C pour arreter.',
913
+ stopping: 'Arret du Squad Dashboard...',
914
+ port_in_use: 'Le port {port} est deja utilise. Essayez --port=<autre>'
915
+ },
799
916
  implementation_plan: {
800
917
  not_found: 'Plan d\'implementation introuvable : {file}',
801
918
  no_runtime: 'Runtime store introuvable. Lancez aioson runtime:init d\'abord.',