jarvis-ai-framework 2.1.0 → 3.0.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 (303) hide show
  1. package/AGENTS.md +22 -122
  2. package/agents/AGENTS.md +20 -24
  3. package/agents/README.md +25 -129
  4. package/agents/engineering/data/eng.data-engineer.agent.md +12 -35
  5. package/agents/engineering/eng.agent.md +18 -30
  6. package/agents/engineering/eng.bug-hunter.md +9 -12
  7. package/agents/engineering/eng.dev-code-reviewer.md +5 -1
  8. package/agents/engineering/eng.docs-writer.md +3 -3
  9. package/agents/engineering/eng.frontend.agent.md +13 -8
  10. package/agents/engineering/eng.rpa.agent.md +5 -13
  11. package/agents/engineering/eng.ux-designer.agent.md +4 -0
  12. package/agents/engineering/qa/eng.qa.quality-champion-task-agent.md +4 -0
  13. package/agents/engineering/qa/eng.qa.quality-strategist.md +13 -8
  14. package/agents/engineering/qa/eng.qa.test-architect.md +16 -15
  15. package/agents/engineering/qa/eng.qa.test-planner.md +22 -17
  16. package/agents/engineering/qa/eng.qa.testing-engineer.md +99 -15
  17. package/agents/product/prod.discovery-interviewer.md +22 -3
  18. package/agents/product/prod.pm-checker.md +4 -0
  19. package/bin/README.md +142 -0
  20. package/bin/commands/docs-publish.js +105 -141
  21. package/bin/commands/docs-sync.js +66 -104
  22. package/bin/commands/info.js +7 -27
  23. package/bin/commands/init.js +23 -51
  24. package/bin/commands/install-rtk.js +9 -3
  25. package/bin/commands/list.js +5 -18
  26. package/bin/commands/map.js +58 -0
  27. package/bin/commands/qa-signoff.js +58 -55
  28. package/bin/commands/tokens.js +90 -0
  29. package/bin/commands/whoami.js +30 -26
  30. package/bin/jarvis.js +9 -153
  31. package/bin/lib/auth/session.js +20 -20
  32. package/bin/lib/cli/program.js +219 -0
  33. package/bin/lib/cli/shared-options.js +29 -0
  34. package/bin/lib/config/constants.js +70 -2
  35. package/bin/lib/config/ide-config.js +4 -8
  36. package/bin/lib/core/profile-filter.js +116 -0
  37. package/bin/lib/core/scanner.js +5 -31
  38. package/bin/lib/core/sync-engine.js +21 -14
  39. package/bin/lib/core/token-report.js +100 -0
  40. package/bin/lib/docs/fetch-file.js +39 -0
  41. package/bin/lib/docs/publish-file.js +194 -0
  42. package/bin/lib/docs/redis-cache.js +49 -0
  43. package/bin/lib/docs/validate-frontmatter.js +9 -39
  44. package/bin/lib/env-loader.js +11 -34
  45. package/bin/lib/flow-map/index.js +65 -0
  46. package/bin/lib/flow-map/parse.js +223 -0
  47. package/bin/lib/flow-map/render.js +89 -0
  48. package/bin/lib/flow-map/tree.js +248 -0
  49. package/bin/lib/tasks/comment.js +40 -35
  50. package/bin/lib/utils/frontmatter.js +57 -0
  51. package/bin/lib/utils/git-parser.js +4 -6
  52. package/bin/lib/utils/npmrc-parser.js +6 -13
  53. package/bin/lib/utils/paths.js +2 -4
  54. package/bin/lib/utils/ui.js +3 -9
  55. package/bin/lib/vcs/api.js +25 -41
  56. package/bin/lib/vcs/create-issue.js +49 -33
  57. package/bin/lib/vcs/create-merge.js +47 -31
  58. package/bin/lib/vcs/fetch-raw.js +35 -23
  59. package/members.md +1 -1
  60. package/package.json +15 -4
  61. package/rules/AGENTS.md +18 -7
  62. package/rules/engineering/eng-rules.md +3 -13
  63. package/rules/engineering/eng-security-rules.md +19 -18
  64. package/rules/engineering/eng.bump-rules.md +3 -2
  65. package/rules/engineering/eng.docs-scraping-rules.md +4 -4
  66. package/rules/engineering/eng.integrations-rules.md +3 -7
  67. package/rules/engineering/eng.skills-rules.md +1 -5
  68. package/rules/engineering/eng.specializations-rules.md +18 -8
  69. package/rules/engineering/frontend/eng.frontend-rules.md +1 -4
  70. package/rules/engineering/qa/eng.qa.cypress-standards-rules.md +1 -1
  71. package/rules/engineering/rpa/eng.rpa-rules.md +4 -9
  72. package/rules/product/README.md +1 -0
  73. package/rules/product/prod-rules.md +1 -4
  74. package/rules/product/prod.spec-rules.md +0 -4
  75. package/rules/rtk-rules.md +0 -1
  76. package/{rules → rules-on-demand}/engineering/eng.breakdown-subtasks-rules.md +0 -4
  77. package/{rules → rules-on-demand}/engineering/eng.plan-rules.md +0 -4
  78. package/{rules → rules-on-demand}/engineering/eng.pr-rules.md +0 -4
  79. package/{rules → rules-on-demand}/engineering/eng.pre-pr-rules.md +0 -4
  80. package/{rules → rules-on-demand}/engineering/eng.start-rules.md +0 -4
  81. package/{rules → rules-on-demand}/engineering/eng.tech-spec-rules.md +1 -2
  82. package/{rules → rules-on-demand}/engineering/eng.work-rules.md +0 -4
  83. package/skills/AGENTS.md +69 -106
  84. package/skills/SKILLS-ROADMAP.md +47 -132
  85. package/skills/eng-ai/SKILL.md +270 -0
  86. package/skills/eng-ai/references/1-fundamentos-ml.md +24 -0
  87. package/skills/eng-ai/references/10-arquitetura-solucoes-ia.md +24 -0
  88. package/skills/eng-ai/references/11-governanca-ia.md +24 -0
  89. package/skills/eng-ai/references/12-seguranca-ia-responsavel.md +25 -0
  90. package/skills/eng-ai/references/2-matematica-estatistica.md +24 -0
  91. package/skills/eng-ai/references/3-dados-para-ia.md +24 -0
  92. package/skills/eng-ai/references/4-deep-learning-fundacionais.md +24 -0
  93. package/skills/eng-ai/references/5-llms-chatbots-agentes-rag.md +25 -0
  94. package/skills/eng-ai/references/6-avaliacao-experimentacao.md +24 -0
  95. package/skills/eng-ai/references/7-engenharia-sistemas-ia.md +24 -0
  96. package/skills/eng-ai/references/8-mlops-plataforma.md +24 -0
  97. package/skills/eng-ai/references/9-produto-ia.md +24 -0
  98. package/skills/eng-ai/references/especializacoes.md +17 -0
  99. package/skills/eng-automation/SKILL.md +290 -0
  100. package/skills/eng-automation/references/1-fundamentos-automacao.md +25 -0
  101. package/skills/eng-automation/references/10-ingestao-dados.md +25 -0
  102. package/skills/eng-automation/references/11-captcha-antibot.md +25 -0
  103. package/skills/eng-automation/references/12-limites-taxa-sessoes.md +25 -0
  104. package/skills/eng-automation/references/13-agendamento-orquestracao.md +24 -0
  105. package/skills/eng-automation/references/14-retentativa-erros.md +25 -0
  106. package/skills/eng-automation/references/15-autenticacao-credenciais.md +24 -0
  107. package/skills/eng-automation/references/16-observabilidade-confiabilidade.md +24 -0
  108. package/skills/eng-automation/references/2-aquisicao-dados.md +25 -0
  109. package/skills/eng-automation/references/3-automacao-navegador.md +24 -0
  110. package/skills/eng-automation/references/4-scraping-crawling.md +25 -0
  111. package/skills/eng-automation/references/5-apis-rest-graphql-soap.md +26 -0
  112. package/skills/eng-automation/references/6-webhooks-integracao.md +25 -0
  113. package/skills/eng-automation/references/7-rpa.md +25 -0
  114. package/skills/eng-automation/references/8-extracao-estruturada.md +25 -0
  115. package/skills/eng-automation/references/9-extracao-documentos.md +25 -0
  116. package/skills/eng-automation/references/especializacoes.md +18 -0
  117. package/skills/eng-backend/SKILL.md +6 -0
  118. package/skills/eng-backend-arch-c4/SKILL.md +10 -4
  119. package/skills/eng-backend-microservices-trace/SKILL.md +6 -0
  120. package/skills/eng-backend-nestjs/SKILL.md +17 -462
  121. package/skills/eng-backend-nestjs/references/1-arquitetura-modulos.md +54 -0
  122. package/skills/eng-backend-nestjs/references/2-guards-autenticacao.md +118 -0
  123. package/skills/eng-backend-nestjs/references/3-interceptors-pipes-filters.md +113 -0
  124. package/skills/eng-backend-nestjs/references/4-config-logging.md +61 -0
  125. package/skills/eng-backend-nestjs/references/5-testes.md +83 -0
  126. package/skills/eng-backend-nestjs/references/6-problemas-comuns.md +53 -0
  127. package/skills/eng-backend-rabbitmq/SKILL.md +15 -298
  128. package/skills/eng-backend-rabbitmq/references/1-referencia-endpoints.md +28 -0
  129. package/skills/eng-backend-rabbitmq/references/2-codigo-consumer-producer.md +90 -0
  130. package/skills/eng-backend-rabbitmq/references/3-arquiteturas-comuns.md +101 -0
  131. package/skills/eng-backend-rabbitmq/references/4-troubleshooting.md +93 -0
  132. package/skills/eng-data/SKILL.md +271 -0
  133. package/skills/eng-data/references/1-fundamentos-dados.md +24 -0
  134. package/skills/eng-data/references/10-ciencia-dados.md +24 -0
  135. package/skills/eng-data/references/11-dataops-plataforma.md +24 -0
  136. package/skills/eng-data/references/12-seguranca-privacidade.md +24 -0
  137. package/skills/eng-data/references/2-modelagem-dados.md +24 -0
  138. package/skills/eng-data/references/3-bancos-dados.md +24 -0
  139. package/skills/eng-data/references/4-arquitetura-dados.md +24 -0
  140. package/skills/eng-data/references/5-pipelines-integracao.md +24 -0
  141. package/skills/eng-data/references/6-qualidade-dados.md +24 -0
  142. package/skills/eng-data/references/7-governanca-metadados.md +24 -0
  143. package/skills/eng-data/references/8-estatistica-analise.md +24 -0
  144. package/skills/eng-data/references/9-analytics-bi.md +24 -0
  145. package/skills/eng-data/references/especializacoes.md +20 -0
  146. package/skills/eng-frontend/SKILL.md +18 -5
  147. package/skills/eng-frontend/references/13-design-system.md +48 -0
  148. package/skills/eng-frontend/references/14-microfrontend.md +46 -0
  149. package/skills/eng-global-docs-write/SKILL.md +10 -5
  150. package/skills/eng-global-pr/SKILL.md +7 -1
  151. package/skills/eng-global-task-comment/SKILL.md +8 -2
  152. package/skills/eng-platform/SKILL.md +331 -0
  153. package/skills/eng-platform/references/1-fundamentos-sistemas.md +23 -0
  154. package/skills/eng-platform/references/10-resiliencia-arquitetura.md +24 -0
  155. package/skills/eng-platform/references/11-plataforma-devex.md +24 -0
  156. package/skills/eng-platform/references/12-finops-custos.md +24 -0
  157. package/skills/eng-platform/references/13-seguranca-fundamentos.md +26 -0
  158. package/skills/eng-platform/references/14-profiling-performance.md +23 -0
  159. package/skills/eng-platform/references/15-testes-carga-chaos.md +23 -0
  160. package/skills/eng-platform/references/16-cache-multicamada.md +22 -0
  161. package/skills/eng-platform/references/2-redes.md +23 -0
  162. package/skills/eng-platform/references/3-cloud.md +24 -0
  163. package/skills/eng-platform/references/4-iac-automacao.md +24 -0
  164. package/skills/eng-platform/references/5-containers-orquestracao.md +25 -0
  165. package/skills/eng-platform/references/6-cicd-entrega.md +24 -0
  166. package/skills/eng-platform/references/7-observabilidade.md +24 -0
  167. package/skills/eng-platform/references/8-confiabilidade-sre.md +24 -0
  168. package/skills/eng-platform/references/9-seguranca-infra.md +26 -0
  169. package/skills/eng-platform/references/especializacoes.md +34 -0
  170. package/skills/eng-qa/SKILL.md +283 -0
  171. package/skills/eng-qa/references/1-fundamentos-qualidade.md +25 -0
  172. package/skills/eng-qa/references/10-confiabilidade.md +25 -0
  173. package/skills/eng-qa/references/11-seguranca.md +24 -0
  174. package/skills/eng-qa/references/12-acessibilidade.md +24 -0
  175. package/skills/eng-qa/references/13-dados-testes.md +24 -0
  176. package/skills/eng-qa/references/14-gestao-testes-defeitos.md +25 -0
  177. package/skills/eng-qa/references/15-arquitetura-qa.md +25 -0
  178. package/skills/eng-qa/references/2-estrategia-planejamento.md +25 -0
  179. package/skills/eng-qa/references/3-design-testes.md +25 -0
  180. package/skills/eng-qa/references/4-manual-exploratorio.md +24 -0
  181. package/skills/eng-qa/references/5-automacao-testes.md +25 -0
  182. package/skills/eng-qa/references/6-api-integracao.md +25 -0
  183. package/skills/eng-qa/references/7-contrato.md +24 -0
  184. package/skills/eng-qa/references/8-interface-compat-mobile.md +24 -0
  185. package/skills/eng-qa/references/9-performance.md +24 -0
  186. package/skills/eng-qa/references/especializacoes.md +29 -0
  187. package/skills/eng-qa-planner/SKILL.md +264 -0
  188. package/skills/jarvis-context-detect/SKILL.md +7 -1
  189. package/skills/jarvis-context-detect/assets/context-profile-template.md +1 -1
  190. package/skills/jarvis-create-specialization/SKILL.md +14 -0
  191. package/skills/jarvis-docs-central/README.md +31 -28
  192. package/skills/jarvis-docs-central/SKILL.md +11 -5
  193. package/skills/jarvis-docs-index/SKILL.md +10 -2
  194. package/skills/jarvis-evolution-architect/SKILL.md +6 -0
  195. package/skills/jarvis-init/SKILL.md +22 -15
  196. package/skills/jarvis-init/assets/passo-adicionar-stacks.md +47 -18
  197. package/skills/jarvis-list-specializations/SKILL.md +36 -17
  198. package/skills/jarvis-report-issue/SKILL.md +7 -1
  199. package/skills/product-roadmap-report/SKILL.md +8 -0
  200. package/skills/product-specs/SKILL.md +9 -0
  201. package/skills/product-specs-update/SKILL.md +6 -0
  202. package/taxonomy.md +16 -28
  203. package/templates/AGENTS.md +2 -0
  204. package/templates/ENV-template.md +10 -2
  205. package/templates/engineering/qa/qa.sprint-plan-template.md +1 -1
  206. package/templates/engineering/tech-spec-delivery-template.md +179 -0
  207. package/workflows/AGENTS.md +14 -2
  208. package/workflows/README.md +8 -16
  209. package/workflows/all-tools.md +7 -1
  210. package/workflows/engineering/data/data.contract.md +8 -0
  211. package/workflows/engineering/data/data.new-pipeline.md +15 -4
  212. package/workflows/engineering/eng.breakdown-subtasks.md +9 -0
  213. package/workflows/engineering/eng.bug-audit.md +10 -13
  214. package/workflows/engineering/eng.build-tech-spec.md +17 -146
  215. package/workflows/engineering/eng.create-ard-from-code.md +8 -0
  216. package/workflows/engineering/eng.create-ard.md +8 -0
  217. package/workflows/engineering/eng.create-rfc.md +7 -0
  218. package/workflows/engineering/eng.debug.md +5 -21
  219. package/workflows/engineering/eng.docs.md +9 -0
  220. package/workflows/engineering/eng.light-arch.md +7 -0
  221. package/workflows/engineering/eng.plan.md +15 -2
  222. package/workflows/engineering/eng.pr.md +24 -30
  223. package/workflows/engineering/eng.pre-pr.md +33 -15
  224. package/workflows/engineering/eng.review.md +18 -11
  225. package/workflows/engineering/eng.rpa.robot.md +17 -7
  226. package/workflows/engineering/eng.start.md +33 -12
  227. package/workflows/engineering/eng.work.md +25 -17
  228. package/workflows/engineering/frontend/eng.frontend-component.md +7 -0
  229. package/workflows/engineering/frontend/eng.frontend-perf-audit.md +8 -0
  230. package/workflows/engineering/frontend/eng.frontend-review.md +8 -0
  231. package/workflows/engineering/qa/eng.qa-refinement-entry.md +7 -0
  232. package/workflows/engineering/qa/eng.qa-release-signoff.md +6 -0
  233. package/workflows/engineering/qa/eng.qa-sprint-planning.md +7 -1
  234. package/workflows/product/prod.roadmap.preview.md +9 -0
  235. package/workflows/product/prod.spec.ard.md +97 -0
  236. package/workflows/product/prod.spec.breakdown.md +10 -0
  237. package/workflows/product/prod.spec.clarify.md +8 -2
  238. package/workflows/product/prod.spec.discovery.md +11 -1
  239. package/workflows/product/prod.spec.epic.md +8 -0
  240. package/workflows/product/prod.spec.frd.md +7 -0
  241. package/workflows/product/prod.spec.issue.md +6 -0
  242. package/workflows/product/prod.spec.md +15 -1
  243. package/workflows/product/prod.spec.prd.md +7 -0
  244. package/workflows/taxonomy.md +58 -6
  245. package/workflows/warm-up.md +47 -60
  246. package/agents/engineering/eng.cybersecurity.agent.md +0 -488
  247. package/agents/engineering/qa/eng.qa.cypress-specialist.md +0 -109
  248. package/bin/lib/docs/fetch-file.sh +0 -41
  249. package/bin/lib/docs/publish-file.sh +0 -284
  250. package/rules/engineering/eng.downstream-flow-rules.md +0 -297
  251. package/rules/engineering/qa/eng.qa.exploratory-session-rules.md +0 -137
  252. package/rules/engineering/qa/eng.qa.quality-gate-scoring-rules.md +0 -181
  253. package/rules/engineering/qa/eng.qa.tech-spec-validation-criteria-rules.md +0 -120
  254. package/skills/eng-ai-engineer/SKILL.md +0 -297
  255. package/skills/eng-data-bi/SKILL.md +0 -200
  256. package/skills/eng-data-debug/SKILL.md +0 -308
  257. package/skills/eng-data-engineer/SKILL.md +0 -257
  258. package/skills/eng-data-onboard/SKILL.md +0 -311
  259. package/skills/eng-data-orchestrator/SKILL.md +0 -427
  260. package/skills/eng-devops-performance-engineer/SKILL.md +0 -313
  261. package/skills/eng-frontend-design-system/SKILL.md +0 -621
  262. package/skills/eng-frontend-microfrontend/SKILL.md +0 -604
  263. package/skills/eng-global-browser-extension-builder/SKILL.md +0 -386
  264. package/skills/eng-global-jira-comment/SKILL.md +0 -21
  265. package/skills/eng-qa-a11y-audit/SKILL.md +0 -270
  266. package/skills/eng-qa-bug-report/SKILL.md +0 -1089
  267. package/skills/eng-qa-bug-report/TASK_MANAGERS.md +0 -138
  268. package/skills/eng-qa-cypress-e2e/SKILL.md +0 -178
  269. package/skills/eng-qa-dev-guide/SKILL.md +0 -165
  270. package/skills/eng-qa-e2e/SKILL.md +0 -401
  271. package/skills/eng-qa-e2e-spec-writer/SKILL.md +0 -323
  272. package/skills/eng-qa-exploratory/SKILL.md +0 -189
  273. package/skills/eng-qa-gate/SKILL.md +0 -371
  274. package/skills/eng-qa-gate/assets/checklist-validacao.md +0 -291
  275. package/skills/eng-qa-graphql-contract/SKILL.md +0 -257
  276. package/skills/eng-qa-quality-report/SKILL.md +0 -413
  277. package/skills/eng-qa-test-plan/SKILL.md +0 -467
  278. package/skills/eng-qa-testsprite/SKILL.md +0 -326
  279. package/skills/eng-qa-testsprite/references/testsprite-mcp.md +0 -224
  280. package/skills/eng-qa-unit-test/SKILL.md +0 -472
  281. package/skills/eng-scraper/SKILL.md +0 -684
  282. package/skills/eng-scraper-robot-builder/SKILL.md +0 -371
  283. package/skills/eng-security-cybersecurity/SKILL.md +0 -646
  284. package/skills/eng-security-patch/SKILL.md +0 -382
  285. package/skills/eng-security-threat-model/SKILL.md +0 -165
  286. package/skills/eng-security-triage/SKILL.md +0 -270
  287. package/templates/engineering/qa/eng.qa.quality-gate-examples-template.md +0 -311
  288. package/templates/engineering/qa/eng.qa.quality-gate-report-template.md +0 -249
  289. package/templates/engineering/qa/qa.cypress-test-template.md +0 -172
  290. package/templates/engineering/qa/qa.exploratory-session-template.md +0 -148
  291. package/templates/engineering/qa/qa.quality-report-template.md +0 -130
  292. package/workflows/engineering/eng.security-audit.md +0 -312
  293. package/workflows/engineering/eng.security-incident.md +0 -275
  294. package/workflows/engineering/eng.security-pipeline.md +0 -210
  295. package/workflows/engineering/eng.security-review.md +0 -235
  296. package/workflows/engineering/qa/eng.qa-dev-quality-guide.md +0 -51
  297. package/workflows/engineering/qa/eng.qa-e2e-test-generation.md +0 -51
  298. package/workflows/engineering/qa/eng.qa-exploratory-session.md +0 -60
  299. package/workflows/engineering/qa/eng.qa-quality-gate-validation.md +0 -202
  300. package/workflows/engineering/qa/eng.qa-quality-report.md +0 -78
  301. /package/skills/{eng-qa-test-plan → eng-qa-planner}/assets/test-coverage-template.md +0 -0
  302. /package/skills/{eng-qa-test-plan → eng-qa-planner}/assets/test-patterns.md +0 -0
  303. /package/templates/{CDD aplicado a Prompts.md → cdd-aplicado-a-prompts.md} +0 -0
@@ -1,139 +1,101 @@
1
- import { loadEnv, resolveEnvPath } from '../lib/env-loader.js'
2
- import { exec } from 'node:child_process'
3
- import { promisify } from 'node:util'
4
- import { existsSync } from 'node:fs'
5
- import { join, dirname } from 'node:path'
6
- import { fileURLToPath } from 'node:url'
7
-
8
- const execAsync = promisify(exec)
9
- const __filename = fileURLToPath(import.meta.url)
10
- const __dirname = dirname(__filename)
1
+ import { loadEnv, resolveEnvPath } from "../lib/env-loader.js";
2
+ import { fetchFile } from "../lib/docs/fetch-file.js";
3
+ import { logger, configureFromFlags } from "../lib/utils/logger.js";
11
4
 
12
5
  /**
13
6
  * Sincroniza documentação do central-docs
14
7
  * Executado automaticamente em /warm-up
15
- *
8
+ *
16
9
  * @param {Object} flags - Flags do comando
17
- * @param {boolean} flags.silent - Modo silencioso (sem output)
18
- * @param {boolean} flags.verbose - Modo verbose (mostra conteúdo)
10
+ * @param {boolean} flags.silent - Modo silencioso (nem erros aparecem)
11
+ * @param {boolean} flags.quiet - Só erros aparecem
12
+ * @param {boolean} flags.verbose - Mostra o conteúdo completo retornado
19
13
  * @param {string} flags.envFile - Path customizado do ENV.md
20
14
  */
21
15
  export async function docsSync(flags = {}) {
22
- const cwd = process.cwd()
23
-
16
+ configureFromFlags(flags);
17
+
18
+ const cwd = process.cwd();
19
+
24
20
  // Resolver path do ENV.md (suporta --ide e --env-file)
25
- let envPath
21
+ let envPath;
26
22
  try {
27
- const resolved = resolveEnvPath(cwd, flags)
28
- envPath = resolved.path
23
+ const resolved = resolveEnvPath(cwd, flags);
24
+ envPath = resolved.path;
29
25
  } catch (error) {
30
- if (!flags.silent) {
31
- console.error('❌ Erro ao resolver ENV.md:', error.message)
32
- }
33
- process.exit(1)
26
+ logger.error("❌ Erro ao resolver ENV.md:", error.message);
27
+ process.exit(1);
34
28
  }
35
-
29
+
36
30
  // Carregar ENV.md
37
- let env
31
+ let env;
38
32
  try {
39
- env = loadEnv(cwd, envPath)
33
+ env = loadEnv(cwd, envPath);
40
34
  } catch (error) {
41
- if (!flags.silent) {
42
- console.error('❌ Erro ao carregar ENV.md:', error.message)
43
- }
44
- process.exit(1)
35
+ logger.error("❌ Erro ao carregar ENV.md:", error.message);
36
+ process.exit(1);
45
37
  }
46
-
38
+
47
39
  // Verificar se central-docs está configurado
48
40
  if (!env.CENTRAL_DOCS_REPO) {
49
- if (!flags.silent) {
50
- console.log('ℹ️ Central docs não configurado (CENTRAL_DOCS_REPO vazio)')
51
- }
52
- return
41
+ logger.info("ℹ️ Central docs não configurado (CENTRAL_DOCS_REPO vazio)");
42
+ return;
53
43
  }
54
-
55
- const { SQUAD, WORKSPACE, CENTRAL_DOCS_REF = 'main' } = env
56
-
44
+
45
+ const { SQUAD, WORKSPACE, CENTRAL_DOCS_REF = "main" } = env;
46
+
57
47
  if (!SQUAD || !WORKSPACE) {
58
- if (!flags.silent) {
59
- console.error('❌ SQUAD ou WORKSPACE não definidos no ENV.md')
60
- }
61
- process.exit(1)
62
- }
63
-
64
- if (!flags.silent) {
65
- console.log(`🔄 Sincronizando docs do squad ${SQUAD}...`)
48
+ logger.error("❌ SQUAD ou WORKSPACE não definidos no ENV.md");
49
+ process.exit(1);
66
50
  }
67
51
 
68
- // Verificar se script fetch-file.sh existe
69
- // Usar path relativo ao módulo, não ao cwd do usuário
70
- const fetchScript = join(__dirname, '../lib/docs/fetch-file.sh')
71
- if (!existsSync(fetchScript)) {
72
- console.error('❌ Script não encontrado:', fetchScript)
73
- process.exit(1)
74
- }
52
+ logger.info(`🔄 Sincronizando docs do squad ${SQUAD}...`);
75
53
 
76
54
  // Buscar index.md do squad
77
- const indexPath = `${SQUAD}/index.md`
78
-
55
+ const indexPath = `${SQUAD}/index.md`;
56
+
79
57
  try {
80
- // Exportar variáveis de ambiente para o script bash
81
- const envVars = {
82
- ...process.env,
83
- CENTRAL_DOCS_REPO: env.CENTRAL_DOCS_REPO,
84
- CENTRAL_DOCS_CACHE_TTL: env.CENTRAL_DOCS_CACHE_TTL || '3600'
85
- }
86
-
87
- const { stdout, stderr } = await execAsync(
88
- `bash "${fetchScript}" "${indexPath}" "${CENTRAL_DOCS_REF}"`,
89
- { env: envVars }
90
- )
91
-
92
- if (!flags.silent) {
93
- console.log('✅ Docs sincronizados')
94
- }
95
-
96
- if (flags.verbose && stdout) {
97
- console.log('\n📄 Conteúdo do index.md:\n')
98
- console.log(stdout)
58
+ const content = await fetchFile(indexPath, CENTRAL_DOCS_REF, {
59
+ repo: env.CENTRAL_DOCS_REPO,
60
+ cacheTtl: env.CENTRAL_DOCS_CACHE_TTL || "3600",
61
+ });
62
+
63
+ logger.info("✅ Docs sincronizados");
64
+
65
+ if (content) {
66
+ logger.debug("\n📄 Conteúdo do index.md:\n");
67
+ logger.debug(content);
99
68
  }
100
-
69
+
101
70
  // Parsear index.md para contar documentos
102
- if (!flags.silent && stdout) {
103
- const prdCount = (stdout.match(/\[prd-.*\.md\]/g) || []).length
104
- const frdCount = (stdout.match(/\[frd-.*\.md\]/g) || []).length
105
- const ardCount = (stdout.match(/\[ard-.*\.md\]/g) || []).length
106
- const rfcCount = (stdout.match(/\[rfc-.*\.md\]/g) || []).length
107
-
108
- const total = prdCount + frdCount + ardCount + rfcCount
109
-
71
+ if (content) {
72
+ const prdCount = (content.match(/\[prd-.*\.md\]/g) || []).length;
73
+ const frdCount = (content.match(/\[frd-.*\.md\]/g) || []).length;
74
+ const ardCount = (content.match(/\[ard-.*\.md\]/g) || []).length;
75
+ const rfcCount = (content.match(/\[rfc-.*\.md\]/g) || []).length;
76
+
77
+ const total = prdCount + frdCount + ardCount + rfcCount;
78
+
110
79
  if (total > 0) {
111
- console.log(`📊 ${total} documentos disponíveis:`)
112
- if (prdCount > 0) console.log(` - ${prdCount} PRD(s)`)
113
- if (frdCount > 0) console.log(` - ${frdCount} FRD(s)`)
114
- if (ardCount > 0) console.log(` - ${ardCount} ARD(s)`)
115
- if (rfcCount > 0) console.log(` - ${rfcCount} RFC(s)`)
80
+ logger.info(`📊 ${total} documentos disponíveis:`);
81
+ if (prdCount > 0) logger.info(` - ${prdCount} PRD(s)`);
82
+ if (frdCount > 0) logger.info(` - ${frdCount} FRD(s)`);
83
+ if (ardCount > 0) logger.info(` - ${ardCount} ARD(s)`);
84
+ if (rfcCount > 0) logger.info(` - ${rfcCount} RFC(s)`);
116
85
  }
117
86
  }
118
-
119
- if (stderr && !flags.silent) {
120
- console.warn('⚠️ Avisos:', stderr)
121
- }
122
-
123
87
  } catch (error) {
124
- if (!flags.silent) {
125
- console.error('❌ Erro ao sincronizar docs:', error.message)
126
-
127
- // Dicas de troubleshooting
128
- if (error.message.includes('Token GitLab')) {
129
- console.error('\n💡 Configure o token GitLab no .npmrc:')
130
- console.error(' //gitlab.com/api/v4/packages/npm/:_authToken=seu-token')
131
- } else if (error.message.includes('não encontrado')) {
132
- console.error('\n💡 Verifique se o squad existe no central-docs:')
133
- console.error(` ${SQUAD}/index.md`)
134
- }
88
+ logger.error("❌ Erro ao sincronizar docs:", error.message);
89
+
90
+ // Dicas de troubleshooting
91
+ if (error.message.includes("Token GitLab")) {
92
+ logger.error("\n💡 Configure o token GitLab no .npmrc:");
93
+ logger.error(" //gitlab.com/api/v4/packages/npm/:_authToken=seu-token");
94
+ } else if (error.message.includes("não encontrado")) {
95
+ logger.error("\n💡 Verifique se o squad existe no central-docs:");
96
+ logger.error(` ${SQUAD}/index.md`);
135
97
  }
136
98
 
137
- process.exit(1)
99
+ process.exit(1);
138
100
  }
139
101
  }
@@ -1,14 +1,5 @@
1
1
  import { findPrompt, discoverAll } from "../lib/core/scanner.js";
2
- import {
3
- showBanner,
4
- RED,
5
- GREEN,
6
- BLUE,
7
- YELLOW,
8
- CYAN,
9
- DIM,
10
- NC,
11
- } from "../lib/utils/ui.js";
2
+ import { showBanner, RED, GREEN, BLUE, YELLOW, CYAN, DIM, NC } from "../lib/utils/ui.js";
12
3
  import { logger } from "../lib/utils/logger.js";
13
4
 
14
5
  export async function info(target) {
@@ -40,15 +31,12 @@ export async function info(target) {
40
31
 
41
32
  if (!prompt) {
42
33
  logger.error(`${RED}❌ Não encontrado: ${YELLOW}${target}${NC}`);
43
- logger.info(
44
- `${DIM}Execute: ${YELLOW}jarvis list${DIM} para ver prompts disponíveis${NC}\n`,
45
- );
34
+ logger.info(`${DIM}Execute: ${YELLOW}jarvis list${DIM} para ver prompts disponíveis${NC}\n`);
46
35
  process.exit(1);
47
36
  }
48
37
 
49
38
  // Icon based on type
50
- const icon =
51
- prompt.type === "agent" ? "🤖" : prompt.type === "skill" ? "⚡" : "🔄";
39
+ const icon = prompt.type === "agent" ? "🤖" : prompt.type === "skill" ? "⚡" : "🔄";
52
40
 
53
41
  logger.info(`${CYAN}${icon} ${prompt.type.toUpperCase()}/${prompt.id}${NC}`);
54
42
  logger.info("");
@@ -67,21 +55,13 @@ export async function info(target) {
67
55
  if (hasDeps) {
68
56
  logger.info(` ${YELLOW}📦 Dependências:${NC}`);
69
57
  if (deps.rules.length)
70
- logger.info(
71
- ` ${BLUE}Rules:${NC} ${DIM}${deps.rules.join(", ")}${NC}`,
72
- );
58
+ logger.info(` ${BLUE}Rules:${NC} ${DIM}${deps.rules.join(", ")}${NC}`);
73
59
  if (deps.templates.length)
74
- logger.info(
75
- ` ${BLUE}Templates:${NC} ${DIM}${deps.templates.join(", ")}${NC}`,
76
- );
60
+ logger.info(` ${BLUE}Templates:${NC} ${DIM}${deps.templates.join(", ")}${NC}`);
77
61
  if (deps.agents.length)
78
- logger.info(
79
- ` ${BLUE}Agents:${NC} ${DIM}${deps.agents.join(", ")}${NC}`,
80
- );
62
+ logger.info(` ${BLUE}Agents:${NC} ${DIM}${deps.agents.join(", ")}${NC}`);
81
63
  if (deps.skills.length)
82
- logger.info(
83
- ` ${BLUE}Skills:${NC} ${DIM}${deps.skills.join(", ")}${NC}`,
84
- );
64
+ logger.info(` ${BLUE}Skills:${NC} ${DIM}${deps.skills.join(", ")}${NC}`);
85
65
  logger.info("");
86
66
  }
87
67
  }
@@ -10,17 +10,7 @@ import {
10
10
  getWorkflowsFolder,
11
11
  isIDESupported,
12
12
  } from "../lib/config/ide-config.js";
13
- import {
14
- showBanner,
15
- RED,
16
- GREEN,
17
- BLUE,
18
- YELLOW,
19
- CYAN,
20
- DIM,
21
- BOLD,
22
- NC,
23
- } from "../lib/utils/ui.js";
13
+ import { showBanner, RED, GREEN, BLUE, YELLOW, CYAN, DIM, BOLD, NC } from "../lib/utils/ui.js";
24
14
  import { getPackageInfo } from "../lib/utils/paths.js";
25
15
  import { logger, configureFromFlags } from "../lib/utils/logger.js";
26
16
 
@@ -40,7 +30,9 @@ export async function init(flags) {
40
30
  if (!isIDESupported(flags.ide)) {
41
31
  logger.error(`${RED}❌ IDE inválida: ${flags.ide}${NC}`);
42
32
  logger.info(
43
- `${YELLOW}IDEs disponíveis: ${IDES.filter((i) => i.supported).map((i) => i.value).join(", ")}${NC}\n`,
33
+ `${YELLOW}IDEs disponíveis: ${IDES.filter((i) => i.supported)
34
+ .map((i) => i.value)
35
+ .join(", ")}${NC}\n`
44
36
  );
45
37
  return;
46
38
  }
@@ -55,9 +47,7 @@ export async function init(flags) {
55
47
  if (ideObj.supported) {
56
48
  logger.info(` ${GREEN}${index + 1}${NC}) ${ideObj.name}`);
57
49
  } else {
58
- logger.info(
59
- ` ${DIM}${index + 1}) ${ideObj.name} (não suportado)${NC}`,
60
- );
50
+ logger.info(` ${DIM}${index + 1}) ${ideObj.name} (não suportado)${NC}`);
61
51
  }
62
52
  });
63
53
  logger.info("");
@@ -69,10 +59,7 @@ export async function init(flags) {
69
59
 
70
60
  let choice;
71
61
  while (true) {
72
- choice = await ask(
73
- rl,
74
- `${BLUE}Digite o número da sua escolha (1-${IDES.length}): ${NC}`,
75
- );
62
+ choice = await ask(rl, `${BLUE}Digite o número da sua escolha (1-${IDES.length}): ${NC}`);
76
63
  const choiceNum = parseInt(choice, 10);
77
64
 
78
65
  if (choiceNum >= 1 && choiceNum <= IDES.length) {
@@ -80,9 +67,7 @@ export async function init(flags) {
80
67
  if (selectedIde.supported) {
81
68
  ide = selectedIde.value;
82
69
  logger.info("");
83
- logger.info(
84
- `${GREEN}Interface selecionada: ${selectedIde.name}${NC}`,
85
- );
70
+ logger.info(`${GREEN}Interface selecionada: ${selectedIde.name}${NC}`);
86
71
  logger.info(`${DIM}Pasta destino: .${getIDEFolder(ide)}${NC}`);
87
72
  logger.info("");
88
73
  break;
@@ -91,7 +76,7 @@ export async function init(flags) {
91
76
  }
92
77
  } else {
93
78
  logger.info(
94
- `${RED}Opção inválida. Por favor, escolha um número entre 1 e ${IDES.length}.${NC}\n`,
79
+ `${RED}Opção inválida. Por favor, escolha um número entre 1 e ${IDES.length}.${NC}\n`
95
80
  );
96
81
  }
97
82
  }
@@ -114,7 +99,7 @@ export async function init(flags) {
114
99
  });
115
100
  const confirm = await ask(
116
101
  rl,
117
- `Deseja reinstalar? Isso irá sobrescrever a instalação existente. (s/N): `,
102
+ `Deseja reinstalar? Isso irá sobrescrever a instalação existente. (s/N): `
118
103
  );
119
104
  rl.close();
120
105
 
@@ -127,9 +112,7 @@ export async function init(flags) {
127
112
  }
128
113
 
129
114
  const ideConfig = getIDEConfig(ide);
130
- logger.info(
131
- `${BLUE}Configurando ambiente para ${ideConfig?.name}...${NC}`,
132
- );
115
+ logger.info(`${BLUE}Configurando ambiente para ${ideConfig?.name}...${NC}`);
133
116
  logger.info("");
134
117
  const result = syncAssets(cwd, ide, {
135
118
  force: forceSync,
@@ -146,16 +129,16 @@ export async function init(flags) {
146
129
  logger.error(`${RED} ✗ ${item}${NC}`);
147
130
  }
148
131
 
149
- const jarvisRoot = join(cwd, '.jarvis');
150
- for (const area of ['eng', 'prod', 'qa']) {
151
- mkdirSync(join(jarvisRoot, 'sessions', area), { recursive: true });
132
+ const jarvisRoot = join(cwd, ".jarvis");
133
+ for (const area of ["eng", "prod", "qa"]) {
134
+ mkdirSync(join(jarvisRoot, "sessions", area), { recursive: true });
152
135
  }
153
- const gitignore = join(cwd, '.gitignore');
154
- const ignoreLine = '.jarvis/';
136
+ const gitignore = join(cwd, ".gitignore");
137
+ const ignoreLine = ".jarvis/";
155
138
  if (existsSync(gitignore)) {
156
- const text = readFileSync(gitignore, 'utf8');
157
- if (!text.split('\n').some((l) => l.trim() === ignoreLine || l.trim() === '.jarvis')) {
158
- appendFileSync(gitignore, `${text.endsWith('\n') ? '' : '\n'}${ignoreLine}\n`);
139
+ const text = readFileSync(gitignore, "utf8");
140
+ if (!text.split("\n").some((l) => l.trim() === ignoreLine || l.trim() === ".jarvis")) {
141
+ appendFileSync(gitignore, `${text.endsWith("\n") ? "" : "\n"}${ignoreLine}\n`);
159
142
  }
160
143
  } else {
161
144
  writeFileSync(gitignore, `${ignoreLine}\n`);
@@ -165,22 +148,16 @@ export async function init(flags) {
165
148
 
166
149
  logger.info("");
167
150
  logger.info(`${GREEN}✓ Configuração concluída!${NC}`);
168
- logger.info(
169
- `${BOLD}${CYAN} versão: ${pkg.name} v${pkg.version}${NC}`,
170
- );
151
+ logger.info(`${BOLD}${CYAN} versão: ${pkg.name} v${pkg.version}${NC}`);
171
152
  logger.info(`${DIM} origem: ${pkg.root}${NC}`);
172
153
  logger.info(`${DIM} pasta criada: ${ideDir}${NC}`);
173
154
  logger.info("");
174
155
 
175
156
  const all = discoverAll();
176
157
 
177
- logger.info(
178
- `${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`,
179
- );
158
+ logger.info(`${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`);
180
159
  logger.info(`${CYAN} 🏁 PRÓXIMO PASSO${NC}`);
181
- logger.info(
182
- `${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`,
183
- );
160
+ logger.info(`${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`);
184
161
  logger.info("");
185
162
 
186
163
  if (ide === "codex") {
@@ -213,14 +190,10 @@ export async function init(flags) {
213
190
  }
214
191
 
215
192
  logger.info("");
216
- logger.info(
217
- `${DIM} Isso irá criar o arquivo ENV.md com as configurações${NC}`,
218
- );
193
+ logger.info(`${DIM} Isso irá criar o arquivo ENV.md com as configurações${NC}`);
219
194
  logger.info(`${DIM} necessárias para o funcionamento do JARVIS.${NC}`);
220
195
  logger.info("");
221
- logger.info(
222
- `${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`,
223
- );
196
+ logger.info(`${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`);
224
197
  logger.info("");
225
198
  logger.info(`${GREEN}✓ Instalação completa! 🎉${NC}`);
226
199
  logger.info("");
@@ -233,5 +206,4 @@ export async function init(flags) {
233
206
  logger.info(`${BLUE}📖 Para ver todos os prompts disponíveis:${NC}`);
234
207
  logger.info(` ${YELLOW}jarvis list${NC}`);
235
208
  logger.info("");
236
-
237
209
  }
@@ -40,7 +40,9 @@ export async function installRtk(flags) {
40
40
  return;
41
41
  } catch {}
42
42
  } else {
43
- logger.info(`${YELLOW}⚠ RTK encontrado mas não é o Token Killer (Rust Type Kit detectado)${NC}`);
43
+ logger.info(
44
+ `${YELLOW}⚠ RTK encontrado mas não é o Token Killer (Rust Type Kit detectado)${NC}`
45
+ );
44
46
  logger.info(`${DIM} Sobrescrevendo com Token Killer...${NC}`);
45
47
  logger.info("");
46
48
  }
@@ -95,12 +97,16 @@ export async function installRtk(flags) {
95
97
  logger.info(`${GREEN}✓ RTK instalado com sucesso: ${version}${NC}`);
96
98
  logger.info("");
97
99
  logger.info(`${YELLOW}Próximo passo:${NC}`);
98
- logger.info(` Execute ${GREEN}jarvis init${NC} (ou atualize o ENV.md) para ativar ${GREEN}RTK_ENABLED=true${NC}`);
100
+ logger.info(
101
+ ` Execute ${GREEN}jarvis init${NC} (ou atualize o ENV.md) para ativar ${GREEN}RTK_ENABLED=true${NC}`
102
+ );
99
103
  logger.info(` A rule de economia de tokens será ativada automaticamente.`);
100
104
  logger.info("");
101
105
  } else {
102
106
  logger.error(`${RED}✗ RTK instalado mas não é o Token Killer${NC}`);
103
- logger.info(`${DIM} Possível conflito: crate 'rtk' no crates.io é Rust Type Kit, não Token Killer${NC}`);
107
+ logger.info(
108
+ `${DIM} Possível conflito: crate 'rtk' no crates.io é Rust Type Kit, não Token Killer${NC}`
109
+ );
104
110
  logger.info(`${DIM} Use: cargo install brokk-rtk${NC}`);
105
111
  logger.info("");
106
112
  process.exit(1);
@@ -1,13 +1,5 @@
1
1
  import { discoverAll } from "../lib/core/scanner.js";
2
- import {
3
- showBanner,
4
- GREEN,
5
- BLUE,
6
- YELLOW,
7
- CYAN,
8
- DIM,
9
- NC,
10
- } from "../lib/utils/ui.js";
2
+ import { showBanner, GREEN, BLUE, YELLOW, CYAN, DIM, NC } from "../lib/utils/ui.js";
11
3
  import { logger } from "../lib/utils/logger.js";
12
4
 
13
5
  export async function list(flags) {
@@ -25,20 +17,15 @@ export async function list(flags) {
25
17
  logger.info(`${DIM}${"─".repeat(80)}${NC}`);
26
18
  for (const item of items) {
27
19
  const desc =
28
- item.description.length > 45
29
- ? item.description.slice(0, 45) + "..."
30
- : item.description;
20
+ item.description.length > 45 ? item.description.slice(0, 45) + "..." : item.description;
31
21
  logger.info(` ${GREEN}${item.id.padEnd(30)}${NC} ${DIM}${desc}${NC}`);
32
22
  }
33
23
  logger.info("");
34
24
  }
35
25
 
36
- if (!filter || filter === "agent")
37
- printSection("AGENTS", all.agents, "🤖");
38
- if (!filter || filter === "skill")
39
- printSection("SKILLS", all.skills, "⚡");
40
- if (!filter || filter === "workflow")
41
- printSection("WORKFLOWS", all.workflows, "🔄");
26
+ if (!filter || filter === "agent") printSection("AGENTS", all.agents, "🤖");
27
+ if (!filter || filter === "skill") printSection("SKILLS", all.skills, "⚡");
28
+ if (!filter || filter === "workflow") printSection("WORKFLOWS", all.workflows, "🔄");
42
29
 
43
30
  const total = all.agents.length + all.skills.length + all.workflows.length;
44
31
  logger.info(`${BLUE}📦 Total: ${GREEN}${total}${BLUE} prompts disponíveis${NC}`);
@@ -0,0 +1,58 @@
1
+ import {
2
+ buildGraph,
3
+ forwardTree,
4
+ reverseEdges,
5
+ suggest,
6
+ DEFAULT_DEPTH,
7
+ } from "../lib/flow-map/tree.js";
8
+ import { renderTree, renderReverse } from "../lib/flow-map/render.js";
9
+ import { getFrameworkRoot } from "../lib/utils/paths.js";
10
+ import { logger } from "../lib/utils/logger.js";
11
+
12
+ const USAGE =
13
+ "Uso: jarvis map <nome> [--depth N] [--reverse] (nome de um workflow, skill ou agente)";
14
+
15
+ /**
16
+ * Monta a saída do mapa. Separado de `map` para ser testável.
17
+ * @param {string | undefined} name
18
+ * @param {Record<string, unknown>} flags
19
+ * @param {string} [root]
20
+ * @returns {{ code: number, lines: string[] }}
21
+ */
22
+ export function runMap(name, flags = {}, root = getFrameworkRoot()) {
23
+ if (!name)
24
+ return { code: 1, lines: ["❌ Informe o nome de um workflow, skill ou agente.", USAGE] };
25
+
26
+ let depth = DEFAULT_DEPTH;
27
+ if (flags.depth !== undefined) {
28
+ depth = Number.parseInt(String(flags.depth), 10);
29
+ if (!Number.isInteger(depth) || depth < 1)
30
+ return {
31
+ code: 1,
32
+ lines: ["❌ --depth precisa ser um número inteiro maior que zero.", USAGE],
33
+ };
34
+ }
35
+
36
+ const graph = buildGraph(root);
37
+ if (!graph.items.has(name)) {
38
+ const similar = suggest(graph.items, name);
39
+ const lines = [`❌ Não encontrado: ${name}`];
40
+ if (similar.length) lines.push("Você quis dizer:", ...similar.map((s) => ` - ${s}`));
41
+ lines.push("Use `jarvis list` para ver o que existe.");
42
+ return { code: 1, lines };
43
+ }
44
+
45
+ if (flags.reverse) {
46
+ return {
47
+ code: 0,
48
+ lines: renderReverse(name, graph.items.get(name).type, reverseEdges(graph, name)),
49
+ };
50
+ }
51
+ return { code: 0, lines: renderTree(forwardTree(graph, name, { depth })) };
52
+ }
53
+
54
+ export async function map(flags) {
55
+ const { code, lines } = runMap(flags._?.[0], flags);
56
+ for (const line of lines) (code === 0 ? logger.info : logger.error)(line);
57
+ if (code !== 0) process.exit(code);
58
+ }