jarvis-ai-framework 1.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 (240) hide show
  1. package/AGENTS.md +416 -0
  2. package/LICENSE +21 -0
  3. package/README.md +190 -0
  4. package/agents/AGENTS.md +234 -0
  5. package/agents/README.md +309 -0
  6. package/agents/engineering/data/eng.data-engineer.agent.md +309 -0
  7. package/agents/engineering/eng.agent.md +303 -0
  8. package/agents/engineering/eng.bug-hunter.md +386 -0
  9. package/agents/engineering/eng.cybersecurity.agent.md +503 -0
  10. package/agents/engineering/eng.dev-code-reviewer.md +148 -0
  11. package/agents/engineering/eng.docs-writer.md +152 -0
  12. package/agents/engineering/eng.frontend.agent.md +117 -0
  13. package/agents/engineering/eng.rpa.agent.md +215 -0
  14. package/agents/engineering/eng.tech-analyst.agent.md +102 -0
  15. package/agents/engineering/eng.ux-designer.agent.md +193 -0
  16. package/agents/engineering/qa/eng.qa.cypress-specialist.md +109 -0
  17. package/agents/engineering/qa/eng.qa.quality-champion-task-agent.md +85 -0
  18. package/agents/engineering/qa/eng.qa.quality-strategist.md +111 -0
  19. package/agents/engineering/qa/eng.qa.test-architect.md +400 -0
  20. package/agents/engineering/qa/eng.qa.test-planner.md +477 -0
  21. package/agents/engineering/qa/eng.qa.testing-engineer.md +339 -0
  22. package/agents/product/prod.pm-checker.md +52 -0
  23. package/bin/commands/docs-publish.js +184 -0
  24. package/bin/commands/docs-sync.js +139 -0
  25. package/bin/commands/info.js +87 -0
  26. package/bin/commands/init.js +237 -0
  27. package/bin/commands/install-rtk.js +90 -0
  28. package/bin/commands/list.js +48 -0
  29. package/bin/commands/qa-signoff.js +112 -0
  30. package/bin/commands/whoami.js +43 -0
  31. package/bin/jarvis.js +159 -0
  32. package/bin/lib/auth/session.js +56 -0
  33. package/bin/lib/config/constants.js +123 -0
  34. package/bin/lib/config/ide-config.js +233 -0
  35. package/bin/lib/core/scanner.js +124 -0
  36. package/bin/lib/core/sync-engine.js +551 -0
  37. package/bin/lib/docs/fetch-file.sh +41 -0
  38. package/bin/lib/docs/publish-file.sh +284 -0
  39. package/bin/lib/docs/validate-frontmatter.js +157 -0
  40. package/bin/lib/env-loader.js +198 -0
  41. package/bin/lib/tasks/comment.js +131 -0
  42. package/bin/lib/utils/git-parser.js +145 -0
  43. package/bin/lib/utils/logger.js +104 -0
  44. package/bin/lib/utils/npmrc-parser.js +106 -0
  45. package/bin/lib/utils/paths.js +55 -0
  46. package/bin/lib/utils/ui.js +59 -0
  47. package/bin/lib/vcs/api.js +312 -0
  48. package/bin/lib/vcs/create-issue.js +43 -0
  49. package/bin/lib/vcs/create-merge.js +43 -0
  50. package/bin/lib/vcs/fetch-raw.js +30 -0
  51. package/bin/postinstall.js +41 -0
  52. package/members.md +25 -0
  53. package/package.json +55 -0
  54. package/rules/AGENTS.md +205 -0
  55. package/rules/engineering/data/data-rules.md +200 -0
  56. package/rules/engineering/eng-rules.md +243 -0
  57. package/rules/engineering/eng-security-rules.md +186 -0
  58. package/rules/engineering/eng.breakdown-subtasks-rules.md +585 -0
  59. package/rules/engineering/eng.bump-rules.md +27 -0
  60. package/rules/engineering/eng.docs-scraping-rules.md +64 -0
  61. package/rules/engineering/eng.downstream-flow-rules.md +297 -0
  62. package/rules/engineering/eng.integrations-rules.md +73 -0
  63. package/rules/engineering/eng.plan-rules.md +333 -0
  64. package/rules/engineering/eng.pr-rules.md +359 -0
  65. package/rules/engineering/eng.pre-pr-rules.md +103 -0
  66. package/rules/engineering/eng.start-rules.md +246 -0
  67. package/rules/engineering/eng.tech-spec-rules.md +968 -0
  68. package/rules/engineering/eng.work-rules.md +312 -0
  69. package/rules/engineering/frontend/eng.frontend-rules.md +147 -0
  70. package/rules/engineering/qa/eng.qa.cypress-standards-rules.md +259 -0
  71. package/rules/engineering/qa/eng.qa.exploratory-session-rules.md +137 -0
  72. package/rules/engineering/qa/eng.qa.quality-gate-scoring-rules.md +181 -0
  73. package/rules/engineering/qa/eng.qa.tech-spec-validation-criteria-rules.md +120 -0
  74. package/rules/engineering/rpa/eng.rpa-rules.md +230 -0
  75. package/rules/product/README.md +24 -0
  76. package/rules/product/prod-rules.md +151 -0
  77. package/rules/rtk-rules.md +68 -0
  78. package/skills/AGENTS.md +290 -0
  79. package/skills/SKILLS-ROADMAP.md +333 -0
  80. package/skills/churn-audit/SKILL.md +385 -0
  81. package/skills/context-detect/SKILL.md +399 -0
  82. package/skills/context-detect/assets/context-profile-template.md +127 -0
  83. package/skills/docs-central/README.md +310 -0
  84. package/skills/docs-central/SKILL.md +423 -0
  85. package/skills/docs-index/SKILL.md +377 -0
  86. package/skills/eng-ai-engineer/SKILL.md +296 -0
  87. package/skills/eng-arch-c4/SKILL.md +358 -0
  88. package/skills/eng-arch-c4/assets/example-code.md +189 -0
  89. package/skills/eng-arch-c4/assets/example-component.md +105 -0
  90. package/skills/eng-arch-c4/assets/example-container.md +104 -0
  91. package/skills/eng-arch-c4/assets/example-context.md +81 -0
  92. package/skills/eng-backend/SKILL.md +776 -0
  93. package/skills/eng-browser-extension-builder/SKILL.md +385 -0
  94. package/skills/eng-cybersecurity/SKILL.md +645 -0
  95. package/skills/eng-data-bi/SKILL.md +199 -0
  96. package/skills/eng-data-debug/SKILL.md +307 -0
  97. package/skills/eng-data-engineer/SKILL.md +256 -0
  98. package/skills/eng-data-onboard/SKILL.md +310 -0
  99. package/skills/eng-data-orchestrator/SKILL.md +426 -0
  100. package/skills/eng-design-system/SKILL.md +619 -0
  101. package/skills/eng-docs-write/SKILL.md +312 -0
  102. package/skills/eng-frontend/SKILL.md +913 -0
  103. package/skills/eng-jira-comment/SKILL.md +17 -0
  104. package/skills/eng-microfrontend/SKILL.md +602 -0
  105. package/skills/eng-ms-trace/SKILL.md +469 -0
  106. package/skills/eng-nestjs/SKILL.md +791 -0
  107. package/skills/eng-performance-engineer/SKILL.md +312 -0
  108. package/skills/eng-pr/SKILL.md +339 -0
  109. package/skills/eng-qa-a11y-audit/SKILL.md +269 -0
  110. package/skills/eng-qa-bug-report/SKILL.md +1088 -0
  111. package/skills/eng-qa-bug-report/TASK_MANAGERS.md +138 -0
  112. package/skills/eng-qa-cypress-e2e/SKILL.md +177 -0
  113. package/skills/eng-qa-dev-guide/SKILL.md +164 -0
  114. package/skills/eng-qa-e2e/SKILL.md +400 -0
  115. package/skills/eng-qa-e2e-spec-writer/SKILL.md +322 -0
  116. package/skills/eng-qa-exploratory/SKILL.md +188 -0
  117. package/skills/eng-qa-gate/SKILL.md +370 -0
  118. package/skills/eng-qa-gate/assets/checklist-validacao.md +291 -0
  119. package/skills/eng-qa-graphql-contract/SKILL.md +256 -0
  120. package/skills/eng-qa-quality-report/SKILL.md +412 -0
  121. package/skills/eng-qa-test-plan/SKILL.md +466 -0
  122. package/skills/eng-qa-test-plan/assets/test-coverage-template.md +92 -0
  123. package/skills/eng-qa-test-plan/assets/test-patterns.md +178 -0
  124. package/skills/eng-qa-testsprite/SKILL.md +325 -0
  125. package/skills/eng-qa-testsprite/references/testsprite-mcp.md +224 -0
  126. package/skills/eng-qa-unit-test/SKILL.md +471 -0
  127. package/skills/eng-rabbitmq/SKILL.md +661 -0
  128. package/skills/eng-scraper/SKILL.md +683 -0
  129. package/skills/eng-scraper-robot-builder/SKILL.md +370 -0
  130. package/skills/eng-security-patch/SKILL.md +378 -0
  131. package/skills/eng-security-triage/SKILL.md +266 -0
  132. package/skills/eng-task-comment/SKILL.md +60 -0
  133. package/skills/eng-tech-analyst/SKILL.md +529 -0
  134. package/skills/eng-threat-model/SKILL.md +161 -0
  135. package/skills/init-jarvis/SKILL.md +1304 -0
  136. package/skills/init-jarvis/assets/mcp-configs.md +389 -0
  137. package/skills/init-jarvis/assets/onboarding-checklist.md +104 -0
  138. package/skills/init-jarvis/assets/setup-guide.md +360 -0
  139. package/skills/lovable-prompt-generator/SKILL.md +304 -0
  140. package/skills/prod-roadmap-report/README.md +303 -0
  141. package/skills/prod-roadmap-report/SKILL.md +198 -0
  142. package/skills/prod-roadmap-report/commands/status.compiled.single.team.md +23 -0
  143. package/skills/prod-roadmap-report/commands/status.list.projects.md +17 -0
  144. package/skills/prod-roadmap-report/commands/status.memory.md +192 -0
  145. package/skills/prod-roadmap-report/commands/status.roadmap.preview.md +94 -0
  146. package/skills/prod-roadmap-report/references/detailed-guide.md +236 -0
  147. package/skills/prod-roadmap-report/rules/detailed-guide.md +237 -0
  148. package/skills/prod-roadmap-report/rules/status-report-rules.md +44 -0
  149. package/skills/prod-roadmap-report/templates/template-multiple-teams-compiled-status.md +53 -0
  150. package/skills/prod-roadmap-report/templates/template-projects-list.md +23 -0
  151. package/skills/prod-roadmap-report/templates/template-single-team-compiled-status.md +60 -0
  152. package/skills/prod-roadmap-report/templates/template-single-team-status.md +49 -0
  153. package/skills/prod-specs/SKILL.md +108 -0
  154. package/skills/prod-specs/references/prod.spec.clarify.md +176 -0
  155. package/skills/prod-specs/references/prod.spec.epic.md +107 -0
  156. package/skills/prod-specs/references/prod.spec.frd.md +135 -0
  157. package/skills/prod-specs/references/prod.spec.issue.md +145 -0
  158. package/skills/prod-specs/references/prod.spec.prd.md +118 -0
  159. package/skills/prod-specs/rules/prod-spec-rules.md +186 -0
  160. package/skills/prod-specs/templates/prod-breakdown-template.md +136 -0
  161. package/skills/prod-specs/templates/prod-epic-template.md +76 -0
  162. package/skills/prod-specs/templates/prod-frd-template.md +172 -0
  163. package/skills/prod-specs/templates/prod-issue-template.md +68 -0
  164. package/skills/prod-specs/templates/prod-prd-full-template.md +159 -0
  165. package/skills/prod-specs/templates/prod-prd-template.md +173 -0
  166. package/skills/prod-specs-update/SKILL.md +272 -0
  167. package/skills/report-issue/SKILL.md +156 -0
  168. package/taxonomy.md +270 -0
  169. package/templates/AGENTS.md +189 -0
  170. package/templates/CDD aplicado a Prompts.md +182 -0
  171. package/templates/ENV-template.md +187 -0
  172. package/templates/engineering/AGENTS-template.md +71 -0
  173. package/templates/engineering/ARD-template.md +193 -0
  174. package/templates/engineering/CONTACTS-template.md +135 -0
  175. package/templates/engineering/PR-template.md +40 -0
  176. package/templates/engineering/RFC-Playbook.md +325 -0
  177. package/templates/engineering/RFC-template.md +199 -0
  178. package/templates/engineering/architecture-template.md +277 -0
  179. package/templates/engineering/breakdown-subtasks-template.md +582 -0
  180. package/templates/engineering/c4-model-template.md +516 -0
  181. package/templates/engineering/data-contract-template.md +135 -0
  182. package/templates/engineering/data-pipeline-template.md +163 -0
  183. package/templates/engineering/plan-template.md +255 -0
  184. package/templates/engineering/qa/eng.qa.quality-gate-examples-template.md +311 -0
  185. package/templates/engineering/qa/eng.qa.quality-gate-report-template.md +249 -0
  186. package/templates/engineering/qa/qa.cypress-test-template.md +172 -0
  187. package/templates/engineering/qa/qa.exploratory-session-template.md +148 -0
  188. package/templates/engineering/qa/qa.quality-report-template.md +130 -0
  189. package/templates/engineering/qa/qa.release-signoff-template.md +54 -0
  190. package/templates/engineering/qa/qa.sprint-plan-template.md +49 -0
  191. package/templates/engineering/swagger-template.md +145 -0
  192. package/templates/engineering/tech-spec-template.md +497 -0
  193. package/templates/engineering/work-progress-template.md +155 -0
  194. package/workflows/AGENTS.md +240 -0
  195. package/workflows/README.md +160 -0
  196. package/workflows/all-tools.md +11 -0
  197. package/workflows/engineering/data/data.contract.md +202 -0
  198. package/workflows/engineering/data/data.new-pipeline.md +234 -0
  199. package/workflows/engineering/eng.breakdown-subtasks.md +420 -0
  200. package/workflows/engineering/eng.bug-audit.md +591 -0
  201. package/workflows/engineering/eng.build-tech-spec.md +1116 -0
  202. package/workflows/engineering/eng.create-ard-from-code.md +259 -0
  203. package/workflows/engineering/eng.create-ard.md +382 -0
  204. package/workflows/engineering/eng.create-rfc.md +245 -0
  205. package/workflows/engineering/eng.debug.md +479 -0
  206. package/workflows/engineering/eng.docs.md +40 -0
  207. package/workflows/engineering/eng.light-arch.md +84 -0
  208. package/workflows/engineering/eng.plan.md +213 -0
  209. package/workflows/engineering/eng.pr.md +466 -0
  210. package/workflows/engineering/eng.pre-pr.md +167 -0
  211. package/workflows/engineering/eng.review.md +185 -0
  212. package/workflows/engineering/eng.rpa.robot.md +342 -0
  213. package/workflows/engineering/eng.security-audit.md +312 -0
  214. package/workflows/engineering/eng.security-incident.md +275 -0
  215. package/workflows/engineering/eng.security-pipeline.md +210 -0
  216. package/workflows/engineering/eng.security-review.md +235 -0
  217. package/workflows/engineering/eng.start.md +494 -0
  218. package/workflows/engineering/eng.work.md +558 -0
  219. package/workflows/engineering/frontend/eng.frontend-component.md +190 -0
  220. package/workflows/engineering/frontend/eng.frontend-perf-audit.md +375 -0
  221. package/workflows/engineering/frontend/eng.frontend-review.md +185 -0
  222. package/workflows/engineering/qa/eng.qa-dev-quality-guide.md +51 -0
  223. package/workflows/engineering/qa/eng.qa-e2e-test-generation.md +51 -0
  224. package/workflows/engineering/qa/eng.qa-exploratory-session.md +60 -0
  225. package/workflows/engineering/qa/eng.qa-quality-gate-validation.md +202 -0
  226. package/workflows/engineering/qa/eng.qa-quality-report.md +83 -0
  227. package/workflows/engineering/qa/eng.qa-refinement-entry.md +83 -0
  228. package/workflows/engineering/qa/eng.qa-release-signoff.md +170 -0
  229. package/workflows/engineering/qa/eng.qa-sprint-planning.md +100 -0
  230. package/workflows/engineering/ta/eng.ta.atendimento.md +93 -0
  231. package/workflows/product/prod.roadmap.preview.md +110 -0
  232. package/workflows/product/prod.spec.breakdown.md +163 -0
  233. package/workflows/product/prod.spec.clarify.md +178 -0
  234. package/workflows/product/prod.spec.epic.md +154 -0
  235. package/workflows/product/prod.spec.frd.md +96 -0
  236. package/workflows/product/prod.spec.issue.md +145 -0
  237. package/workflows/product/prod.spec.md +60 -0
  238. package/workflows/product/prod.spec.prd.md +100 -0
  239. package/workflows/taxonomy.md +92 -0
  240. package/workflows/warm-up.md +574 -0
@@ -0,0 +1,112 @@
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'
6
+
7
+ /**
8
+ * Verifica se existe um sign-off QA válido para a branch atual (ou informada).
9
+ * Retorna 0 (válido) ou 1 (inválido/ausente) — usado pelo CI.
10
+ *
11
+ * @param {Object} flags
12
+ * @param {string} flags.branch - Branch a verificar (padrão: lido do git)
13
+ * @param {string} flags['max-age'] - Validade máxima em horas (padrão: 24)
14
+ */
15
+ export async function qaSignoff(flags = {}) {
16
+ const cwd = process.cwd()
17
+ const maxAgeHours = parseInt(flags['max-age'] ?? '24', 10)
18
+
19
+ // Resolver branch
20
+ let branch = flags.branch
21
+ if (!branch) {
22
+ try {
23
+ const { execSync } = await import('node:child_process')
24
+ branch = execSync('git branch --show-current', { cwd, encoding: 'utf-8' }).trim()
25
+ } 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)
29
+ }
30
+ }
31
+
32
+ if (!branch) {
33
+ logger.error(`${RED}❌ Branch não identificada.${NC}`)
34
+ process.exit(1)
35
+ }
36
+
37
+ // Carregar ENV.md para descobrir DOCS_FOLDER
38
+ let docsFolder = 'docs'
39
+ try {
40
+ const resolved = resolveEnvPath(cwd, flags)
41
+ const env = loadEnv(cwd, resolved.path)
42
+ if (env.DOCS_FOLDER) docsFolder = env.DOCS_FOLDER
43
+ } catch {
44
+ // Se não encontrar ENV.md, usa default
45
+ }
46
+
47
+ const signoffsDir = join(cwd, docsFolder, 'engineering', 'qa', 'signoffs')
48
+
49
+ 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)
53
+ }
54
+
55
+ // Normalizar slug da branch para busca nos nomes de arquivo
56
+ const branchSlug = branch.replace(/\//g, '-').replace(/[^a-zA-Z0-9-_]/g, '-')
57
+
58
+ // Buscar arquivos de sign-off que correspondam à branch
59
+ const files = readdirSync(signoffsDir)
60
+ .filter(f => f.endsWith('.md') && f.includes(branchSlug))
61
+ .sort()
62
+ .reverse() // mais recente primeiro
63
+
64
+ 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)
68
+ }
69
+
70
+ // Ler o sign-off mais recente
71
+ const latestFile = files[0]
72
+ const filePath = join(signoffsDir, latestFile)
73
+ const content = readFileSync(filePath, 'utf-8')
74
+
75
+ // 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)
80
+ }
81
+
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, '') ?? ''
88
+
89
+ // 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)
94
+ }
95
+
96
+ // Verificar validade (max-age)
97
+ if (dateStr) {
98
+ const signoffDate = new Date(dateStr)
99
+ const now = new Date()
100
+ const ageHours = (now - signoffDate) / (1000 * 60 * 60)
101
+
102
+ 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)
106
+ }
107
+ }
108
+
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)
112
+ }
@@ -0,0 +1,43 @@
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
+
6
+ export async function whoami(flags) {
7
+ configureFromFlags(flags)
8
+
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
14
+ }
15
+
16
+ let env = {}
17
+ try {
18
+ const cwd = process.cwd()
19
+ const resolved = resolveEnvPath(cwd, flags)
20
+ env = loadEnv(cwd, resolved.path)
21
+ } catch {
22
+ // sem ENV.md ainda — resolve via git/os
23
+ }
24
+
25
+ const { id, source } = resolveUser(env)
26
+
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}`)
34
+
35
+ const leftover = readSession()
36
+ 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}`)
40
+ }
41
+
42
+ logger.info('')
43
+ }
package/bin/jarvis.js ADDED
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { argv, exit } from "node:process";
4
+ import { readFileSync } from "node:fs";
5
+ import { dirname, join } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { init } from "./commands/init.js";
8
+ import { list } from "./commands/list.js";
9
+ import { info } from "./commands/info.js";
10
+ import { whoami } from "./commands/whoami.js";
11
+ import { docsSync } from "./commands/docs-sync.js";
12
+ import { docsPublish } from "./commands/docs-publish.js"
13
+ import { qaSignoff } from "./commands/qa-signoff.js";
14
+ import { installRtk } from "./commands/install-rtk.js";
15
+ import { formatIDEsList } from "./lib/config/ide-config.js";
16
+ import { showBanner, BLUE, GREEN, YELLOW, DIM, NC } from "./lib/utils/ui.js";
17
+ import { logger } from "./lib/utils/logger.js";
18
+
19
+ const __filename = fileURLToPath(import.meta.url);
20
+ const __dirname = dirname(__filename);
21
+ const args = argv.slice(2);
22
+ const command = args[0];
23
+
24
+ // Lazy loading do package.json (só quando necessário)
25
+ let _version = null;
26
+ function getVersion() {
27
+ if (_version === null) {
28
+ const packageJson = JSON.parse(
29
+ readFileSync(join(__dirname, "../package.json"), "utf-8"),
30
+ );
31
+ _version = packageJson.version;
32
+ }
33
+ return _version;
34
+ }
35
+
36
+ function help() {
37
+ showBanner();
38
+
39
+ logger.info(`${BLUE}📚 Ajuda${NC}\n`);
40
+
41
+ logger.info(`${YELLOW}Uso:${NC}`);
42
+ logger.info(
43
+ ` ${GREEN}jarvis init${NC} [--ide <ide>] Bootstrap framework no workspace`,
44
+ );
45
+ logger.info(
46
+ ` ${GREEN}jarvis list${NC} Listar agents, skills & workflows`,
47
+ );
48
+ logger.info(
49
+ ` ${GREEN}jarvis info${NC} <type/name> Detalhes de um prompt`,
50
+ );
51
+ logger.info(
52
+ ` ${GREEN}jarvis whoami${NC} Exibir identidade (ENV.md / git / SO)`,
53
+ );
54
+ logger.info(
55
+ ` ${GREEN}jarvis logout${NC} Remover auth.json legado`,
56
+ );
57
+ logger.info(
58
+ ` ${GREEN}jarvis docs sync${NC} [--silent] [--verbose] Sincronizar docs do central-docs`,
59
+ );
60
+ logger.info(
61
+ ` ${GREEN}jarvis docs publish${NC} --file <path> --tipo <tipo> --feature <slug> [--squad <squad>] [--workspace <workspace>]`,
62
+ );
63
+ logger.info(
64
+ ` ${GREEN}jarvis install-rtk${NC} Instalar RTK (token killer — economia 60-90%)`,
65
+ );
66
+ logger.info(
67
+ ` ${GREEN}jarvis qa-signoff${NC} [--branch <branch>] [--max-age <horas>] Verificar sign-off QA (usado pelo CI)`,
68
+ );
69
+ logger.info(
70
+ ` ${GREEN}jarvis --version${NC} Versão instalada`,
71
+ );
72
+ logger.info("");
73
+
74
+ logger.info(`${YELLOW}IDEs Suportadas:${NC}`);
75
+ logger.info(` ${formatIDEsList()}`);
76
+ logger.info("");
77
+
78
+ logger.info(`${YELLOW}🚀 Começar:${NC}`);
79
+ logger.info(
80
+ ` ${DIM}1.${NC} npm install -g ${GREEN}/caminho/para/jarvis${NC}`,
81
+ );
82
+ logger.info(` ${DIM}2.${NC} ${GREEN}jarvis init${NC} --ide cursor`);
83
+ logger.info(` ${DIM}3.${NC} No chat da IDE: ${GREEN}/init-jarvis${NC}`);
84
+ logger.info("");
85
+
86
+ logger.info(`${BLUE}📖 Exemplos:${NC}`);
87
+ logger.info(
88
+ ` ${GREEN}jarvis list${NC} Listar todos os prompts`,
89
+ );
90
+ logger.info(
91
+ ` ${GREEN}jarvis info agent/eng${NC} Detalhes do agent eng`,
92
+ );
93
+ logger.info(
94
+ ` ${GREEN}jarvis docs sync${NC} Sincronizar docs do central-docs`,
95
+ );
96
+ logger.info(
97
+ ` ${GREEN}jarvis docs publish --file ./docs/ard.md --tipo ard --feature auth-jwt${NC}`,
98
+ );
99
+ logger.info("");
100
+ }
101
+
102
+ function parseFlags(args) {
103
+ const flags = {};
104
+ for (let i = 0; i < args.length; i++) {
105
+ if (args[i].startsWith("--")) {
106
+ const key = args[i].slice(2);
107
+ flags[key] =
108
+ args[i + 1] && !args[i + 1].startsWith("--") ? args[++i] : true;
109
+ } else {
110
+ flags._ = flags._ || [];
111
+ flags._.push(args[i]);
112
+ }
113
+ }
114
+ return flags;
115
+ }
116
+
117
+ const flags = parseFlags(args.slice(1));
118
+
119
+ const commands = {
120
+ init: () => init(flags),
121
+ list: () => list(flags),
122
+ ls: () => list(flags),
123
+ info: () => info(flags._?.[0], flags),
124
+ logout: () => whoami({ ...flags, logout: true }),
125
+ whoami: () => whoami(flags),
126
+ docs: () => {
127
+ const subcommand = flags._?.[0];
128
+ if (subcommand === "sync") {
129
+ return docsSync(flags);
130
+ } else if (subcommand === "publish") {
131
+ return docsPublish(flags);
132
+ } else {
133
+ logger.error("\n Subcomando inválido para docs\n");
134
+ logger.info("Uso:");
135
+ logger.info(` ${GREEN}jarvis docs sync${NC} [--silent] [--verbose]`);
136
+ logger.info(
137
+ ` ${GREEN}jarvis docs publish${NC} --file <path> --tipo <prd|frd|ard|rfc> --feature <slug> [--squad <squad>] [--workspace <workspace>]`,
138
+ );
139
+ logger.info("");
140
+ exit(1);
141
+ }
142
+ },
143
+ "install-rtk": () => installRtk(flags),
144
+ "qa-signoff": () => qaSignoff(flags),
145
+ "--version": () => logger.info(getVersion()),
146
+ "-v": () => logger.info(getVersion()),
147
+ "--help": () => help(),
148
+ "-h": () => help(),
149
+ };
150
+
151
+ if (command in commands) {
152
+ await commands[command]();
153
+ } else if (!command) {
154
+ help();
155
+ } else {
156
+ logger.error(`\n Unknown command: ${command}\n`);
157
+ help();
158
+ exit(1);
159
+ }
@@ -0,0 +1,56 @@
1
+ import { existsSync, readFileSync, unlinkSync } from 'node:fs'
2
+ import { execSync } from 'node:child_process'
3
+ import { join } from 'node:path'
4
+ import { homedir, userInfo } from 'node:os'
5
+
6
+ const SESSION_FILE = join(homedir(), '.jarvis', 'auth.json')
7
+
8
+ export function readSession() {
9
+ if (!existsSync(SESSION_FILE)) return null
10
+ try {
11
+ return JSON.parse(readFileSync(SESSION_FILE, 'utf-8'))
12
+ } catch {
13
+ return null
14
+ }
15
+ }
16
+
17
+ export function clearSession() {
18
+ if (existsSync(SESSION_FILE)) {
19
+ unlinkSync(SESSION_FILE)
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Resolve local identity without OAuth.
25
+ * Order: ENV.md USER → git user.email → OS username → "local"
26
+ */
27
+ export function resolveUser(env = {}) {
28
+ const envUser = typeof env.USER === 'string' ? env.USER.trim() : ''
29
+ if (envUser) return { id: envUser, source: 'ENV.md' }
30
+
31
+ try {
32
+ const email = execSync('git config --get user.email', {
33
+ encoding: 'utf8',
34
+ stdio: ['ignore', 'pipe', 'ignore'],
35
+ }).trim()
36
+ if (email) return { id: email, source: 'git' }
37
+ } catch {
38
+ // ignore
39
+ }
40
+
41
+ try {
42
+ const username = userInfo().username
43
+ if (username) return { id: username, source: 'os' }
44
+ } catch {
45
+ // ignore
46
+ }
47
+
48
+ return { id: 'local', source: 'fallback' }
49
+ }
50
+
51
+ /**
52
+ * Identity used as dev_id. Never requires jarvis login.
53
+ */
54
+ export function getAuthUser(env = {}) {
55
+ return resolveUser(env).id
56
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @fileoverview Constantes globais do sistema
3
+ * @module config/constants
4
+ */
5
+
6
+ /** @constant {string} Nome do pacote NPM */
7
+ export const CLI_NAME = "jarvis-framework";
8
+
9
+ /** @constant {string} Nome do arquivo de lock */
10
+ export const LOCK_FILE = "jarvis-lock.json";
11
+
12
+ /**
13
+ * Diretórios que devem ser sincronizados do framework para a IDE
14
+ * @constant {ReadonlyArray<string>}
15
+ */
16
+ export const SYNC_DIRS = Object.freeze([
17
+ "agents",
18
+ "skills",
19
+ "workflows",
20
+ "templates",
21
+ "rules",
22
+ "scripts",
23
+ ]);
24
+
25
+ /**
26
+ * Arquivos da raiz que devem ser sincronizados
27
+ * @constant {ReadonlyArray<string>}
28
+ */
29
+ export const SYNC_ROOT_FILES = Object.freeze(["taxonomy.md", "AGENTS.md", "members.md"]);
30
+
31
+ /**
32
+ * Mapeamento de model do Jarvis para formato OpenCode (provider/model-id)
33
+ * @constant {Readonly<Record<string, string>>}
34
+ */
35
+ export const OPENCODE_MODEL_MAP = Object.freeze({
36
+ // Anthropic — shorthands usados no Jarvis
37
+ opus: "anthropic/claude-opus-4-6",
38
+ sonnet: "anthropic/claude-sonnet-4-6",
39
+ haiku: "anthropic/claude-haiku-4-5-20250414",
40
+ // Anthropic — IDs completos
41
+ "claude-opus-4-6-20250529": "anthropic/claude-opus-4-6",
42
+ "claude-sonnet-4-6-20250514": "anthropic/claude-sonnet-4-6",
43
+ "claude-sonnet-4-20250514": "anthropic/claude-sonnet-4-6",
44
+ "claude-haiku-4-5-20250414": "anthropic/claude-haiku-4-5-20250414",
45
+ // OpenAI
46
+ "gpt-4o": "openai/gpt-4o",
47
+ "gpt-4o-mini": "openai/gpt-4o-mini",
48
+ "gpt-4.1": "openai/gpt-4.1",
49
+ "gpt-4.1-mini": "openai/gpt-4.1-mini",
50
+ "gpt-4.1-nano": "openai/gpt-4.1-nano",
51
+ "o3": "openai/o3",
52
+ "o3-mini": "openai/o3-mini",
53
+ "o4-mini": "openai/o4-mini",
54
+ // Google
55
+ "gemini-2.5-pro": "google/gemini-2.5-pro",
56
+ "gemini-2.5-flash": "google/gemini-2.5-flash",
57
+ "gemini-2.0-flash": "google/gemini-2.0-flash",
58
+ });
59
+
60
+ /**
61
+ * Permissões padrão para agents OpenCode
62
+ * @constant {Readonly<Record<string, string>>}
63
+ */
64
+ export const OPENCODE_DEFAULT_PERMISSIONS = Object.freeze({
65
+ edit: "allow",
66
+ bash: "allow",
67
+ read: "allow",
68
+ glob: "allow",
69
+ grep: "allow",
70
+ task: "allow",
71
+ });
72
+
73
+ /**
74
+ * Campos de frontmatter Jarvis-only que devem ser removidos para OpenCode commands
75
+ * @constant {ReadonlyArray<string>}
76
+ */
77
+ export const OPENCODE_STRIP_FIELDS = Object.freeze([
78
+ "auto_execution_mode",
79
+ "rules_file",
80
+ "template_file",
81
+ "model_tier",
82
+ "model_justification",
83
+ "recommended_model",
84
+ "env_file",
85
+ "globs",
86
+ ]);
87
+
88
+ /**
89
+ * Campos de frontmatter Jarvis-only que devem ser removidos para steering files Kiro
90
+ * @constant {ReadonlyArray<string>}
91
+ */
92
+ export const KIRO_STRIP_FIELDS = Object.freeze([
93
+ "trigger",
94
+ "auto_execution_mode",
95
+ "rules_file",
96
+ "template_file",
97
+ "model_tier",
98
+ "model_justification",
99
+ "recommended_model",
100
+ "env_file",
101
+ "globs",
102
+ "agent",
103
+ "allowed-tools",
104
+ "disable-model-invocation",
105
+ "compatibility",
106
+ "license",
107
+ "metadata",
108
+ "argument-hint",
109
+ ]);
110
+
111
+ /**
112
+ * Mapeamento de HUB Jarvis para fileMatchPattern do Kiro
113
+ * Usado para gerar steering files de rules com inclusion: fileMatch
114
+ * @constant {Readonly<Record<string, string>>}
115
+ */
116
+ export const KIRO_HUB_FILE_PATTERNS = Object.freeze({
117
+ FRONTEND: "**/*.tsx,**/*.ts,**/*.jsx,**/*.js,**/*.css,**/*.scss",
118
+ BACKEND: "**/*.ts,**/*.js",
119
+ QA: "**/*.test.ts,**/*.spec.ts,**/*.cy.ts,**/*.test.js,**/*.spec.js",
120
+ DATA: "**/*.py,**/*.sql,**/*.ipynb",
121
+ AI: "**/*.ts,**/*.py",
122
+ });
123
+