jarvis-ai-framework 2.1.1 → 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 (259) hide show
  1. package/AGENTS.md +14 -115
  2. package/agents/AGENTS.md +11 -23
  3. package/agents/README.md +25 -129
  4. package/agents/engineering/data/eng.data-engineer.agent.md +11 -34
  5. package/agents/engineering/eng.agent.md +14 -24
  6. package/agents/engineering/eng.bug-hunter.md +7 -15
  7. package/agents/engineering/eng.dev-code-reviewer.md +1 -1
  8. package/agents/engineering/eng.frontend.agent.md +3 -7
  9. package/agents/engineering/eng.rpa.agent.md +2 -8
  10. package/agents/engineering/qa/eng.qa.quality-strategist.md +6 -11
  11. package/agents/engineering/qa/eng.qa.test-architect.md +8 -18
  12. package/agents/engineering/qa/eng.qa.test-planner.md +10 -14
  13. package/agents/engineering/qa/eng.qa.testing-engineer.md +91 -24
  14. package/agents/product/prod.discovery-interviewer.md +3 -3
  15. package/bin/README.md +142 -0
  16. package/bin/commands/docs-publish.js +105 -141
  17. package/bin/commands/docs-sync.js +66 -104
  18. package/bin/commands/info.js +7 -27
  19. package/bin/commands/init.js +23 -51
  20. package/bin/commands/install-rtk.js +9 -3
  21. package/bin/commands/list.js +5 -18
  22. package/bin/commands/map.js +20 -5
  23. package/bin/commands/qa-signoff.js +58 -55
  24. package/bin/commands/tokens.js +14 -17
  25. package/bin/commands/whoami.js +30 -26
  26. package/bin/jarvis.js +9 -163
  27. package/bin/lib/auth/session.js +20 -20
  28. package/bin/lib/cli/program.js +219 -0
  29. package/bin/lib/cli/shared-options.js +29 -0
  30. package/bin/lib/config/constants.js +59 -2
  31. package/bin/lib/config/ide-config.js +4 -8
  32. package/bin/lib/core/profile-filter.js +4 -1
  33. package/bin/lib/core/scanner.js +3 -29
  34. package/bin/lib/core/sync-engine.js +21 -14
  35. package/bin/lib/core/token-report.js +12 -2
  36. package/bin/lib/docs/fetch-file.js +39 -0
  37. package/bin/lib/docs/publish-file.js +194 -0
  38. package/bin/lib/docs/redis-cache.js +49 -0
  39. package/bin/lib/docs/validate-frontmatter.js +9 -39
  40. package/bin/lib/env-loader.js +11 -34
  41. package/bin/lib/flow-map/parse.js +11 -5
  42. package/bin/lib/flow-map/render.js +5 -2
  43. package/bin/lib/flow-map/tree.js +59 -10
  44. package/bin/lib/tasks/comment.js +40 -35
  45. package/bin/lib/utils/frontmatter.js +57 -0
  46. package/bin/lib/utils/git-parser.js +4 -6
  47. package/bin/lib/utils/npmrc-parser.js +6 -13
  48. package/bin/lib/utils/paths.js +2 -4
  49. package/bin/lib/utils/ui.js +3 -9
  50. package/bin/lib/vcs/api.js +25 -41
  51. package/bin/lib/vcs/create-issue.js +49 -33
  52. package/bin/lib/vcs/create-merge.js +47 -31
  53. package/bin/lib/vcs/fetch-raw.js +35 -23
  54. package/package.json +14 -5
  55. package/rules/engineering/eng-rules.md +1 -1
  56. package/rules/engineering/eng-security-rules.md +18 -16
  57. package/rules/engineering/eng.bump-rules.md +3 -2
  58. package/rules/engineering/eng.docs-scraping-rules.md +4 -4
  59. package/rules/engineering/eng.integrations-rules.md +3 -3
  60. package/rules/engineering/eng.skills-rules.md +1 -1
  61. package/rules/engineering/eng.specializations-rules.md +18 -4
  62. package/rules/engineering/frontend/eng.frontend-rules.md +1 -4
  63. package/rules/engineering/qa/eng.qa.cypress-standards-rules.md +1 -1
  64. package/rules/engineering/rpa/eng.rpa-rules.md +4 -9
  65. package/skills/AGENTS.md +52 -87
  66. package/skills/SKILLS-ROADMAP.md +47 -128
  67. package/skills/eng-ai/SKILL.md +270 -0
  68. package/skills/eng-ai/references/1-fundamentos-ml.md +24 -0
  69. package/skills/eng-ai/references/10-arquitetura-solucoes-ia.md +24 -0
  70. package/skills/eng-ai/references/11-governanca-ia.md +24 -0
  71. package/skills/eng-ai/references/12-seguranca-ia-responsavel.md +25 -0
  72. package/skills/eng-ai/references/2-matematica-estatistica.md +24 -0
  73. package/skills/eng-ai/references/3-dados-para-ia.md +24 -0
  74. package/skills/eng-ai/references/4-deep-learning-fundacionais.md +24 -0
  75. package/skills/eng-ai/references/5-llms-chatbots-agentes-rag.md +25 -0
  76. package/skills/eng-ai/references/6-avaliacao-experimentacao.md +24 -0
  77. package/skills/eng-ai/references/7-engenharia-sistemas-ia.md +24 -0
  78. package/skills/eng-ai/references/8-mlops-plataforma.md +24 -0
  79. package/skills/eng-ai/references/9-produto-ia.md +24 -0
  80. package/skills/eng-ai/references/especializacoes.md +17 -0
  81. package/skills/eng-automation/SKILL.md +290 -0
  82. package/skills/eng-automation/references/1-fundamentos-automacao.md +25 -0
  83. package/skills/eng-automation/references/10-ingestao-dados.md +25 -0
  84. package/skills/eng-automation/references/11-captcha-antibot.md +25 -0
  85. package/skills/eng-automation/references/12-limites-taxa-sessoes.md +25 -0
  86. package/skills/eng-automation/references/13-agendamento-orquestracao.md +24 -0
  87. package/skills/eng-automation/references/14-retentativa-erros.md +25 -0
  88. package/skills/eng-automation/references/15-autenticacao-credenciais.md +24 -0
  89. package/skills/eng-automation/references/16-observabilidade-confiabilidade.md +24 -0
  90. package/skills/eng-automation/references/2-aquisicao-dados.md +25 -0
  91. package/skills/eng-automation/references/3-automacao-navegador.md +24 -0
  92. package/skills/eng-automation/references/4-scraping-crawling.md +25 -0
  93. package/skills/eng-automation/references/5-apis-rest-graphql-soap.md +26 -0
  94. package/skills/eng-automation/references/6-webhooks-integracao.md +25 -0
  95. package/skills/eng-automation/references/7-rpa.md +25 -0
  96. package/skills/eng-automation/references/8-extracao-estruturada.md +25 -0
  97. package/skills/eng-automation/references/9-extracao-documentos.md +25 -0
  98. package/skills/eng-automation/references/especializacoes.md +18 -0
  99. package/skills/eng-backend-nestjs/SKILL.md +1 -1
  100. package/skills/eng-data/SKILL.md +271 -0
  101. package/skills/eng-data/references/1-fundamentos-dados.md +24 -0
  102. package/skills/eng-data/references/10-ciencia-dados.md +24 -0
  103. package/skills/eng-data/references/11-dataops-plataforma.md +24 -0
  104. package/skills/eng-data/references/12-seguranca-privacidade.md +24 -0
  105. package/skills/eng-data/references/2-modelagem-dados.md +24 -0
  106. package/skills/eng-data/references/3-bancos-dados.md +24 -0
  107. package/skills/eng-data/references/4-arquitetura-dados.md +24 -0
  108. package/skills/eng-data/references/5-pipelines-integracao.md +24 -0
  109. package/skills/eng-data/references/6-qualidade-dados.md +24 -0
  110. package/skills/eng-data/references/7-governanca-metadados.md +24 -0
  111. package/skills/eng-data/references/8-estatistica-analise.md +24 -0
  112. package/skills/eng-data/references/9-analytics-bi.md +24 -0
  113. package/skills/eng-data/references/especializacoes.md +20 -0
  114. package/skills/eng-frontend/SKILL.md +12 -5
  115. package/skills/eng-frontend/references/13-design-system.md +48 -0
  116. package/skills/eng-frontend/references/14-microfrontend.md +46 -0
  117. package/skills/eng-global-task-comment/SKILL.md +2 -2
  118. package/skills/eng-platform/SKILL.md +331 -0
  119. package/skills/eng-platform/references/1-fundamentos-sistemas.md +23 -0
  120. package/skills/eng-platform/references/10-resiliencia-arquitetura.md +24 -0
  121. package/skills/eng-platform/references/11-plataforma-devex.md +24 -0
  122. package/skills/eng-platform/references/12-finops-custos.md +24 -0
  123. package/skills/eng-platform/references/13-seguranca-fundamentos.md +26 -0
  124. package/skills/eng-platform/references/14-profiling-performance.md +23 -0
  125. package/skills/eng-platform/references/15-testes-carga-chaos.md +23 -0
  126. package/skills/eng-platform/references/16-cache-multicamada.md +22 -0
  127. package/skills/eng-platform/references/2-redes.md +23 -0
  128. package/skills/eng-platform/references/3-cloud.md +24 -0
  129. package/skills/eng-platform/references/4-iac-automacao.md +24 -0
  130. package/skills/eng-platform/references/5-containers-orquestracao.md +25 -0
  131. package/skills/eng-platform/references/6-cicd-entrega.md +24 -0
  132. package/skills/eng-platform/references/7-observabilidade.md +24 -0
  133. package/skills/eng-platform/references/8-confiabilidade-sre.md +24 -0
  134. package/skills/eng-platform/references/9-seguranca-infra.md +26 -0
  135. package/skills/eng-platform/references/especializacoes.md +34 -0
  136. package/skills/eng-qa/SKILL.md +283 -0
  137. package/skills/eng-qa/references/1-fundamentos-qualidade.md +25 -0
  138. package/skills/eng-qa/references/10-confiabilidade.md +25 -0
  139. package/skills/eng-qa/references/11-seguranca.md +24 -0
  140. package/skills/eng-qa/references/12-acessibilidade.md +24 -0
  141. package/skills/eng-qa/references/13-dados-testes.md +24 -0
  142. package/skills/eng-qa/references/14-gestao-testes-defeitos.md +25 -0
  143. package/skills/eng-qa/references/15-arquitetura-qa.md +25 -0
  144. package/skills/eng-qa/references/2-estrategia-planejamento.md +25 -0
  145. package/skills/eng-qa/references/3-design-testes.md +25 -0
  146. package/skills/eng-qa/references/4-manual-exploratorio.md +24 -0
  147. package/skills/eng-qa/references/5-automacao-testes.md +25 -0
  148. package/skills/eng-qa/references/6-api-integracao.md +25 -0
  149. package/skills/eng-qa/references/7-contrato.md +24 -0
  150. package/skills/eng-qa/references/8-interface-compat-mobile.md +24 -0
  151. package/skills/eng-qa/references/9-performance.md +24 -0
  152. package/skills/eng-qa/references/especializacoes.md +29 -0
  153. package/skills/eng-qa-planner/SKILL.md +264 -0
  154. package/skills/jarvis-context-detect/SKILL.md +1 -1
  155. package/skills/jarvis-context-detect/assets/context-profile-template.md +1 -1
  156. package/skills/jarvis-create-specialization/SKILL.md +8 -0
  157. package/skills/jarvis-docs-central/README.md +31 -28
  158. package/skills/jarvis-docs-central/SKILL.md +5 -5
  159. package/skills/jarvis-init/SKILL.md +8 -8
  160. package/skills/jarvis-init/assets/passo-adicionar-stacks.md +47 -18
  161. package/skills/jarvis-list-specializations/SKILL.md +30 -17
  162. package/skills/jarvis-report-issue/SKILL.md +1 -1
  163. package/taxonomy.md +4 -16
  164. package/templates/ENV-template.md +10 -2
  165. package/templates/engineering/qa/qa.sprint-plan-template.md +1 -1
  166. package/workflows/AGENTS.md +3 -1
  167. package/workflows/README.md +0 -10
  168. package/workflows/engineering/data/data.new-pipeline.md +6 -5
  169. package/workflows/engineering/eng.bug-audit.md +4 -14
  170. package/workflows/engineering/eng.debug.md +4 -20
  171. package/workflows/engineering/eng.pr.md +10 -28
  172. package/workflows/engineering/eng.pre-pr.md +11 -19
  173. package/workflows/engineering/eng.review.md +7 -13
  174. package/workflows/engineering/eng.rpa.robot.md +3 -9
  175. package/workflows/engineering/eng.start.md +16 -11
  176. package/workflows/engineering/eng.work.md +10 -18
  177. package/workflows/engineering/qa/eng.qa-sprint-planning.md +1 -1
  178. package/workflows/product/prod.spec.discovery.md +2 -2
  179. package/workflows/warm-up.md +35 -63
  180. package/agents/engineering/eng.cybersecurity.agent.md +0 -486
  181. package/agents/engineering/qa/eng.qa.cypress-specialist.md +0 -112
  182. package/bin/lib/docs/fetch-file.sh +0 -41
  183. package/bin/lib/docs/publish-file.sh +0 -284
  184. package/rules/engineering/qa/eng.qa.exploratory-session-rules.md +0 -137
  185. package/rules/engineering/qa/eng.qa.quality-gate-scoring-rules.md +0 -181
  186. package/rules/engineering/qa/eng.qa.tech-spec-validation-criteria-rules.md +0 -120
  187. package/skills/eng-ai-engineer/SKILL.md +0 -303
  188. package/skills/eng-data-bi/SKILL.md +0 -206
  189. package/skills/eng-data-debug/SKILL.md +0 -314
  190. package/skills/eng-data-engineer/SKILL.md +0 -266
  191. package/skills/eng-data-onboard/SKILL.md +0 -317
  192. package/skills/eng-data-orchestrator/SKILL.md +0 -433
  193. package/skills/eng-devops-performance-engineer/SKILL.md +0 -319
  194. package/skills/eng-frontend-design-system/SKILL.md +0 -155
  195. package/skills/eng-frontend-design-system/references/1-estrutura-pacote.md +0 -57
  196. package/skills/eng-frontend-design-system/references/2-tokens.md +0 -116
  197. package/skills/eng-frontend-design-system/references/3-componentes.md +0 -165
  198. package/skills/eng-frontend-design-system/references/4-storybook.md +0 -85
  199. package/skills/eng-frontend-design-system/references/5-auditoria-versionamento.md +0 -76
  200. package/skills/eng-frontend-microfrontend/SKILL.md +0 -164
  201. package/skills/eng-frontend-microfrontend/references/1-criando-remote.md +0 -109
  202. package/skills/eng-frontend-microfrontend/references/2-configurando-shell.md +0 -70
  203. package/skills/eng-frontend-microfrontend/references/3-contratos-interface.md +0 -73
  204. package/skills/eng-frontend-microfrontend/references/4-shared-dependencies.md +0 -48
  205. package/skills/eng-frontend-microfrontend/references/5-event-bus.md +0 -59
  206. package/skills/eng-frontend-microfrontend/references/6-monorepo-deploy.md +0 -77
  207. package/skills/eng-frontend-microfrontend/references/7-troubleshooting.md +0 -45
  208. package/skills/eng-global-browser-extension-builder/SKILL.md +0 -392
  209. package/skills/eng-global-jira-comment/SKILL.md +0 -27
  210. package/skills/eng-qa-a11y-audit/SKILL.md +0 -276
  211. package/skills/eng-qa-bug-report/SKILL.md +0 -877
  212. package/skills/eng-qa-bug-report/TASK_MANAGERS.md +0 -138
  213. package/skills/eng-qa-bug-report/references/1-integracao-task-managers.md +0 -148
  214. package/skills/eng-qa-bug-report/references/2-exemplos-de-uso.md +0 -46
  215. package/skills/eng-qa-bug-report/references/3-bug-to-test.md +0 -45
  216. package/skills/eng-qa-cypress-e2e/SKILL.md +0 -184
  217. package/skills/eng-qa-dev-guide/SKILL.md +0 -173
  218. package/skills/eng-qa-e2e/SKILL.md +0 -407
  219. package/skills/eng-qa-e2e-spec-writer/SKILL.md +0 -329
  220. package/skills/eng-qa-exploratory/SKILL.md +0 -196
  221. package/skills/eng-qa-gate/SKILL.md +0 -377
  222. package/skills/eng-qa-gate/assets/checklist-validacao.md +0 -291
  223. package/skills/eng-qa-graphql-contract/SKILL.md +0 -263
  224. package/skills/eng-qa-quality-report/SKILL.md +0 -419
  225. package/skills/eng-qa-test-plan/SKILL.md +0 -473
  226. package/skills/eng-qa-testsprite/SKILL.md +0 -332
  227. package/skills/eng-qa-testsprite/references/testsprite-mcp.md +0 -224
  228. package/skills/eng-qa-unit-test/SKILL.md +0 -478
  229. package/skills/eng-scraper/SKILL.md +0 -260
  230. package/skills/eng-scraper/references/1-puppeteer.md +0 -140
  231. package/skills/eng-scraper/references/2-playwright-cheerio-pdf.md +0 -82
  232. package/skills/eng-scraper/references/3-anti-bot.md +0 -94
  233. package/skills/eng-scraper/references/4-resiliencia-etl-monitoramento.md +0 -137
  234. package/skills/eng-scraper-robot-builder/SKILL.md +0 -377
  235. package/skills/eng-security-cybersecurity/SKILL.md +0 -250
  236. package/skills/eng-security-cybersecurity/references/1-owasp-top-10.md +0 -331
  237. package/skills/eng-security-cybersecurity/references/2-secrets-management.md +0 -31
  238. package/skills/eng-security-cybersecurity/references/3-input-validation.md +0 -43
  239. package/skills/eng-security-cybersecurity/references/4-compliance.md +0 -20
  240. package/skills/eng-security-patch/SKILL.md +0 -388
  241. package/skills/eng-security-threat-model/SKILL.md +0 -171
  242. package/skills/eng-security-triage/SKILL.md +0 -276
  243. package/templates/engineering/qa/eng.qa.quality-gate-examples-template.md +0 -311
  244. package/templates/engineering/qa/eng.qa.quality-gate-report-template.md +0 -249
  245. package/templates/engineering/qa/qa.cypress-test-template.md +0 -172
  246. package/templates/engineering/qa/qa.exploratory-session-template.md +0 -148
  247. package/templates/engineering/qa/qa.quality-report-template.md +0 -130
  248. package/workflows/engineering/eng.security-audit.md +0 -319
  249. package/workflows/engineering/eng.security-incident.md +0 -281
  250. package/workflows/engineering/eng.security-pipeline.md +0 -219
  251. package/workflows/engineering/eng.security-review.md +0 -241
  252. package/workflows/engineering/qa/eng.qa-dev-quality-guide.md +0 -57
  253. package/workflows/engineering/qa/eng.qa-e2e-test-generation.md +0 -57
  254. package/workflows/engineering/qa/eng.qa-exploratory-session.md +0 -68
  255. package/workflows/engineering/qa/eng.qa-quality-gate-validation.md +0 -209
  256. package/workflows/engineering/qa/eng.qa-quality-report.md +0 -85
  257. /package/skills/{eng-qa-test-plan → eng-qa-planner}/assets/test-coverage-template.md +0 -0
  258. /package/skills/{eng-qa-test-plan → eng-qa-planner}/assets/test-patterns.md +0 -0
  259. /package/templates/{CDD aplicado a Prompts.md → cdd-aplicado-a-prompts.md} +0 -0
@@ -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}`);
@@ -1,9 +1,16 @@
1
- import { buildGraph, forwardTree, reverseEdges, suggest, DEFAULT_DEPTH } from "../lib/flow-map/tree.js";
1
+ import {
2
+ buildGraph,
3
+ forwardTree,
4
+ reverseEdges,
5
+ suggest,
6
+ DEFAULT_DEPTH,
7
+ } from "../lib/flow-map/tree.js";
2
8
  import { renderTree, renderReverse } from "../lib/flow-map/render.js";
3
9
  import { getFrameworkRoot } from "../lib/utils/paths.js";
4
10
  import { logger } from "../lib/utils/logger.js";
5
11
 
6
- const USAGE = "Uso: jarvis map <nome> [--depth N] [--reverse] (nome de um workflow, skill ou agente)";
12
+ const USAGE =
13
+ "Uso: jarvis map <nome> [--depth N] [--reverse] (nome de um workflow, skill ou agente)";
7
14
 
8
15
  /**
9
16
  * Monta a saída do mapa. Separado de `map` para ser testável.
@@ -13,12 +20,17 @@ const USAGE = "Uso: jarvis map <nome> [--depth N] [--reverse] (nome de um work
13
20
  * @returns {{ code: number, lines: string[] }}
14
21
  */
15
22
  export function runMap(name, flags = {}, root = getFrameworkRoot()) {
16
- if (!name) return { code: 1, lines: ["❌ Informe o nome de um workflow, skill ou agente.", USAGE] };
23
+ if (!name)
24
+ return { code: 1, lines: ["❌ Informe o nome de um workflow, skill ou agente.", USAGE] };
17
25
 
18
26
  let depth = DEFAULT_DEPTH;
19
27
  if (flags.depth !== undefined) {
20
28
  depth = Number.parseInt(String(flags.depth), 10);
21
- if (!Number.isInteger(depth) || depth < 1) return { code: 1, lines: ["❌ --depth precisa ser um número inteiro maior que zero.", USAGE] };
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
+ };
22
34
  }
23
35
 
24
36
  const graph = buildGraph(root);
@@ -31,7 +43,10 @@ export function runMap(name, flags = {}, root = getFrameworkRoot()) {
31
43
  }
32
44
 
33
45
  if (flags.reverse) {
34
- return { code: 0, lines: renderReverse(name, graph.items.get(name).type, reverseEdges(graph, name)) };
46
+ return {
47
+ code: 0,
48
+ lines: renderReverse(name, graph.items.get(name).type, reverseEdges(graph, name)),
49
+ };
35
50
  }
36
51
  return { code: 0, lines: renderTree(forwardTree(graph, name, { depth })) };
37
52
  }
@@ -1,8 +1,9 @@
1
- import { existsSync, readdirSync, readFileSync } from 'node:fs'
2
- import { join } from 'node:path'
3
- import { loadEnv, resolveEnvPath } from '../lib/env-loader.js'
4
- import { GREEN, RED, YELLOW, DIM, NC } from '../lib/utils/ui.js'
5
- import { logger } from '../lib/utils/logger.js'
1
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { loadEnv, resolveEnvPath } from "../lib/env-loader.js";
4
+ import { extractFrontmatterBlock } from "../lib/utils/frontmatter.js";
5
+ import { GREEN, RED, YELLOW, DIM, NC } from "../lib/utils/ui.js";
6
+ import { logger } from "../lib/utils/logger.js";
6
7
 
7
8
  /**
8
9
  * Verifica se existe um sign-off QA válido para a branch atual (ou informada).
@@ -13,100 +14,102 @@ import { logger } from '../lib/utils/logger.js'
13
14
  * @param {string} flags['max-age'] - Validade máxima em horas (padrão: 24)
14
15
  */
15
16
  export async function qaSignoff(flags = {}) {
16
- const cwd = process.cwd()
17
- const maxAgeHours = parseInt(flags['max-age'] ?? '24', 10)
17
+ const cwd = process.cwd();
18
+ const maxAgeHours = parseInt(flags["max-age"] ?? "24", 10);
18
19
 
19
20
  // Resolver branch
20
- let branch = flags.branch
21
+ let branch = flags.branch;
21
22
  if (!branch) {
22
23
  try {
23
- const { execSync } = await import('node:child_process')
24
- branch = execSync('git branch --show-current', { cwd, encoding: 'utf-8' }).trim()
24
+ const { execSync } = await import("node:child_process");
25
+ branch = execSync("git branch --show-current", { cwd, encoding: "utf-8" }).trim();
25
26
  } catch {
26
- logger.error(`${RED}❌ Não foi possível detectar a branch atual.${NC}`)
27
- logger.info(`${YELLOW}Passe a branch via --branch <nome>${NC}`)
28
- process.exit(1)
27
+ logger.error(`${RED}❌ Não foi possível detectar a branch atual.${NC}`);
28
+ logger.info(`${YELLOW}Passe a branch via --branch <nome>${NC}`);
29
+ process.exit(1);
29
30
  }
30
31
  }
31
32
 
32
33
  if (!branch) {
33
- logger.error(`${RED}❌ Branch não identificada.${NC}`)
34
- process.exit(1)
34
+ logger.error(`${RED}❌ Branch não identificada.${NC}`);
35
+ process.exit(1);
35
36
  }
36
37
 
37
38
  // Carregar ENV.md para descobrir DOCS_FOLDER
38
- let docsFolder = 'docs'
39
+ let docsFolder = "docs";
39
40
  try {
40
- const resolved = resolveEnvPath(cwd, flags)
41
- const env = loadEnv(cwd, resolved.path)
42
- if (env.DOCS_FOLDER) docsFolder = env.DOCS_FOLDER
41
+ const resolved = resolveEnvPath(cwd, flags);
42
+ const env = loadEnv(cwd, resolved.path);
43
+ if (env.DOCS_FOLDER) docsFolder = env.DOCS_FOLDER;
43
44
  } catch {
44
45
  // Se não encontrar ENV.md, usa default
45
46
  }
46
47
 
47
- const signoffsDir = join(cwd, docsFolder, 'engineering', 'qa', 'signoffs')
48
+ const signoffsDir = join(cwd, docsFolder, "engineering", "qa", "signoffs");
48
49
 
49
50
  if (!existsSync(signoffsDir)) {
50
- logger.error(`${RED}❌ Nenhum sign-off QA encontrado para a branch: ${branch}${NC}`)
51
- logger.info(`${YELLOW}Execute o workflow qa.release-signoff antes do deploy.${NC}`)
52
- process.exit(1)
51
+ logger.error(`${RED}❌ Nenhum sign-off QA encontrado para a branch: ${branch}${NC}`);
52
+ logger.info(`${YELLOW}Execute o workflow qa.release-signoff antes do deploy.${NC}`);
53
+ process.exit(1);
53
54
  }
54
55
 
55
56
  // Normalizar slug da branch para busca nos nomes de arquivo
56
- const branchSlug = branch.replace(/\//g, '-').replace(/[^a-zA-Z0-9-_]/g, '-')
57
+ const branchSlug = branch.replace(/\//g, "-").replace(/[^a-zA-Z0-9-_]/g, "-");
57
58
 
58
59
  // Buscar arquivos de sign-off que correspondam à branch
59
60
  const files = readdirSync(signoffsDir)
60
- .filter(f => f.endsWith('.md') && f.includes(branchSlug))
61
+ .filter((f) => f.endsWith(".md") && f.includes(branchSlug))
61
62
  .sort()
62
- .reverse() // mais recente primeiro
63
+ .reverse(); // mais recente primeiro
63
64
 
64
65
  if (files.length === 0) {
65
- logger.error(`${RED}❌ Nenhum sign-off QA encontrado para a branch: ${branch}${NC}`)
66
- logger.info(`${YELLOW}Execute o workflow qa.release-signoff antes do deploy.${NC}`)
67
- process.exit(1)
66
+ logger.error(`${RED}❌ Nenhum sign-off QA encontrado para a branch: ${branch}${NC}`);
67
+ logger.info(`${YELLOW}Execute o workflow qa.release-signoff antes do deploy.${NC}`);
68
+ process.exit(1);
68
69
  }
69
70
 
70
71
  // Ler o sign-off mais recente
71
- const latestFile = files[0]
72
- const filePath = join(signoffsDir, latestFile)
73
- const content = readFileSync(filePath, 'utf-8')
72
+ const latestFile = files[0];
73
+ const filePath = join(signoffsDir, latestFile);
74
+ const content = readFileSync(filePath, "utf-8");
74
75
 
75
76
  // Extrair frontmatter
76
- const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/)
77
- if (!frontmatterMatch) {
78
- logger.error(`${RED}❌ Sign-off inválido: frontmatter ausente em ${latestFile}${NC}`)
79
- process.exit(1)
77
+ const frontmatter = extractFrontmatterBlock(content);
78
+ if (frontmatter === null) {
79
+ logger.error(`${RED}❌ Sign-off inválido: frontmatter ausente em ${latestFile}${NC}`);
80
+ process.exit(1);
80
81
  }
82
+ const statusMatch = frontmatter.match(/^status:\s*(.+)$/m);
83
+ const dateMatch = frontmatter.match(/^date:\s*(.+)$/m);
81
84
 
82
- const frontmatter = frontmatterMatch[1]
83
- const statusMatch = frontmatter.match(/^status:\s*(.+)$/m)
84
- const dateMatch = frontmatter.match(/^date:\s*(.+)$/m)
85
-
86
- const status = statusMatch?.[1]?.trim().replace(/['"]/g, '') ?? ''
87
- const dateStr = dateMatch?.[1]?.trim().replace(/['"]/g, '') ?? ''
85
+ const status = statusMatch?.[1]?.trim().replace(/['"]/g, "") ?? "";
86
+ const dateStr = dateMatch?.[1]?.trim().replace(/['"]/g, "") ?? "";
88
87
 
89
88
  // Verificar status
90
- if (status.toUpperCase() !== 'GO') {
91
- logger.error(`${RED}❌ Sign-off com status ${status} — deploy bloqueado.${NC}`)
92
- logger.info(`${DIM}Arquivo: ${latestFile}${NC}`)
93
- process.exit(1)
89
+ if (status.toUpperCase() !== "GO") {
90
+ logger.error(`${RED}❌ Sign-off com status ${status} — deploy bloqueado.${NC}`);
91
+ logger.info(`${DIM}Arquivo: ${latestFile}${NC}`);
92
+ process.exit(1);
94
93
  }
95
94
 
96
95
  // Verificar validade (max-age)
97
96
  if (dateStr) {
98
- const signoffDate = new Date(dateStr)
99
- const now = new Date()
100
- const ageHours = (now - signoffDate) / (1000 * 60 * 60)
97
+ const signoffDate = new Date(dateStr);
98
+ const now = new Date();
99
+ const ageHours = (now - signoffDate) / (1000 * 60 * 60);
101
100
 
102
101
  if (ageHours > maxAgeHours) {
103
- logger.error(`${RED}❌ Sign-off expirado: criado há ${Math.round(ageHours)}h (máximo: ${maxAgeHours}h).${NC}`)
104
- logger.info(`${YELLOW}Execute qa.release-signoff novamente antes do deploy.${NC}`)
105
- process.exit(1)
102
+ logger.error(
103
+ `${RED}❌ Sign-off expirado: criado há ${Math.round(ageHours)}h (máximo: ${maxAgeHours}h).${NC}`
104
+ );
105
+ logger.info(`${YELLOW}Execute qa.release-signoff novamente antes do deploy.${NC}`);
106
+ process.exit(1);
106
107
  }
107
108
  }
108
109
 
109
- logger.info(`${GREEN}✅ Sign-off QA válido para branch: ${branch}${NC}`)
110
- logger.info(`${DIM}Arquivo: ${latestFile} | Status: GO | Válido por mais ${Math.round(maxAgeHours - ((new Date() - new Date(dateStr)) / (1000 * 60 * 60)))}h${NC}`)
111
- process.exit(0)
110
+ logger.info(`${GREEN}✅ Sign-off QA válido para branch: ${branch}${NC}`);
111
+ logger.info(
112
+ `${DIM}Arquivo: ${latestFile} | Status: GO | Válido por mais ${Math.round(maxAgeHours - (new Date() - new Date(dateStr)) / (1000 * 60 * 60))}h${NC}`
113
+ );
114
+ process.exit(0);
112
115
  }
@@ -1,16 +1,7 @@
1
1
  import { buildReport } from "../lib/core/token-report.js";
2
2
  import { resolveEnvPath, loadEnv } from "../lib/env-loader.js";
3
3
  import { getFrameworkRoot } from "../lib/utils/paths.js";
4
- import {
5
- showBanner,
6
- RED,
7
- GREEN,
8
- BLUE,
9
- YELLOW,
10
- CYAN,
11
- DIM,
12
- NC,
13
- } from "../lib/utils/ui.js";
4
+ import { showBanner, RED, GREEN, BLUE, YELLOW, CYAN, DIM, NC } from "../lib/utils/ui.js";
14
5
  import { logger } from "../lib/utils/logger.js";
15
6
 
16
7
  const AXES = ["HUB", "POSITION", "AREA", "SQUAD"];
@@ -50,9 +41,11 @@ export async function tokens(flags) {
50
41
  if (missing.length > 0) {
51
42
  logger.error(`${RED}❌ Perfil incompleto: faltam ${missing.join(", ")}${NC}`);
52
43
  logger.info(
53
- `${YELLOW}Uso: jarvis tokens [--hub X --position Y --area Z --squad W] [--rtk] [--json]${NC}`,
44
+ `${YELLOW}Uso: jarvis tokens [--hub X --position Y --area Z --squad W] [--rtk] [--json]${NC}`
45
+ );
46
+ logger.info(
47
+ `${DIM}Sem flags, o perfil vem do ENV.md do workspace (use --ide <ide> se houver mais de um).${NC}\n`
54
48
  );
55
- logger.info(`${DIM}Sem flags, o perfil vem do ENV.md do workspace (use --ide <ide> se houver mais de um).${NC}\n`);
56
49
  process.exit(1);
57
50
  }
58
51
 
@@ -67,27 +60,31 @@ export async function tokens(flags) {
67
60
  logger.info(`${CYAN}📏 Custo estimado no início da sessão${NC}`);
68
61
  logger.info(
69
62
  `${DIM}Perfil: HUB=${profile.HUB} | POSITION=${profile.POSITION} | AREA=${profile.AREA} | SQUAD=${profile.SQUAD}` +
70
- ` | RTK=${rtkEnabled ? "ligado" : "desligado"}${NC}`,
63
+ ` | RTK=${rtkEnabled ? "ligado" : "desligado"}${NC}`
71
64
  );
72
65
  logger.info(`${DIM}${report.estimate}${NC}`);
73
66
  logger.info("");
74
- logger.info(`${DIM}${"Tipo".padEnd(26)}${"Arquivos".padStart(9)}${"KB".padStart(10)}${"Tokens (≈)".padStart(13)}${NC}`);
67
+ logger.info(
68
+ `${DIM}${"Tipo".padEnd(26)}${"Arquivos".padStart(9)}${"KB".padStart(10)}${"Tokens (≈)".padStart(13)}${NC}`
69
+ );
75
70
  logger.info(`${DIM}${"─".repeat(58)}${NC}`);
76
71
 
77
72
  for (const c of report.categories) {
78
73
  logger.info(
79
74
  `${GREEN}${c.label.padEnd(26)}${NC}${String(c.files.length).padStart(9)}` +
80
- `${kb(c.bytes).padStart(10)}${String(c.tokens).padStart(13)}`,
75
+ `${kb(c.bytes).padStart(10)}${String(c.tokens).padStart(13)}`
81
76
  );
82
77
  if (c.files[0]) {
83
- logger.info(` ${DIM}maior: ${c.files[0].path} (${kb(c.files[0].bytes)} KB) — ${c.note}${NC}`);
78
+ logger.info(
79
+ ` ${DIM}maior: ${c.files[0].path} (${kb(c.files[0].bytes)} KB) — ${c.note}${NC}`
80
+ );
84
81
  }
85
82
  }
86
83
 
87
84
  logger.info(`${DIM}${"─".repeat(58)}${NC}`);
88
85
  logger.info(
89
86
  `${BLUE}${"Total".padEnd(26)}${NC}${"".padStart(9)}` +
90
- `${kb(report.total.bytes).padStart(10)}${String(report.total.tokens).padStart(13)}`,
87
+ `${kb(report.total.bytes).padStart(10)}${String(report.total.tokens).padStart(13)}`
91
88
  );
92
89
  logger.info("");
93
90
  }
@@ -1,43 +1,47 @@
1
- import { resolveUser, readSession, clearSession } from '../lib/auth/session.js'
2
- import { loadEnv, resolveEnvPath } from '../lib/env-loader.js'
3
- import { logger, configureFromFlags } from '../lib/utils/logger.js'
4
- import { GREEN, YELLOW, BLUE, DIM, NC } from '../lib/utils/ui.js'
1
+ import { resolveUser, readSession, clearSession } from "../lib/auth/session.js";
2
+ import { loadEnv, resolveEnvPath } from "../lib/env-loader.js";
3
+ import { logger, configureFromFlags } from "../lib/utils/logger.js";
4
+ import { GREEN, YELLOW, BLUE, DIM, NC } from "../lib/utils/ui.js";
5
5
 
6
6
  export async function whoami(flags) {
7
- configureFromFlags(flags)
7
+ configureFromFlags(flags);
8
8
 
9
9
  if (flags.logout) {
10
- clearSession()
11
- logger.info(`${GREEN}✓ ~/.jarvis/auth.json removido${NC}`)
12
- logger.info(`${DIM}Login não é mais necessário — identidade vem de USER= no ENV.md, git ou SO.${NC}`)
13
- return
10
+ clearSession();
11
+ logger.info(`${GREEN}✓ ~/.jarvis/auth.json removido${NC}`);
12
+ logger.info(
13
+ `${DIM}Login não é mais necessário — identidade vem de USER= no ENV.md, git ou SO.${NC}`
14
+ );
15
+ return;
14
16
  }
15
17
 
16
- let env = {}
18
+ let env = {};
17
19
  try {
18
- const cwd = process.cwd()
19
- const resolved = resolveEnvPath(cwd, flags)
20
- env = loadEnv(cwd, resolved.path)
20
+ const cwd = process.cwd();
21
+ const resolved = resolveEnvPath(cwd, flags);
22
+ env = loadEnv(cwd, resolved.path);
21
23
  } catch {
22
24
  // sem ENV.md ainda — resolve via git/os
23
25
  }
24
26
 
25
- const { id, source } = resolveUser(env)
27
+ const { id, source } = resolveUser(env);
26
28
 
27
- logger.info('')
28
- logger.info(`${BLUE}👤 Identidade${NC}`)
29
- logger.info('')
30
- logger.info(` ${BLUE}USER:${NC} ${id}`)
31
- logger.info(` ${BLUE}Fonte:${NC} ${source}`)
32
- logger.info('')
33
- logger.info(`${DIM}Sem login. Ordem: ENV.md (USER=) → git config user.email → usuário do SO.${NC}`)
29
+ logger.info("");
30
+ logger.info(`${BLUE}👤 Identidade${NC}`);
31
+ logger.info("");
32
+ logger.info(` ${BLUE}USER:${NC} ${id}`);
33
+ logger.info(` ${BLUE}Fonte:${NC} ${source}`);
34
+ logger.info("");
35
+ logger.info(
36
+ `${DIM}Sem login. Ordem: ENV.md (USER=) → git config user.email → usuário do SO.${NC}`
37
+ );
34
38
 
35
- const leftover = readSession()
39
+ const leftover = readSession();
36
40
  if (leftover?.email) {
37
- logger.info('')
38
- logger.info(` ${YELLOW}⚠ ~/.jarvis/auth.json legado (${leftover.email}) — não é usado.${NC}`)
39
- logger.info(` ${DIM}Remova com: jarvis logout${NC}`)
41
+ logger.info("");
42
+ logger.info(` ${YELLOW}⚠ ~/.jarvis/auth.json legado (${leftover.email}) — não é usado.${NC}`);
43
+ logger.info(` ${DIM}Remova com: jarvis logout${NC}`);
40
44
  }
41
45
 
42
- logger.info('')
46
+ logger.info("");
43
47
  }