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.
- package/AGENTS.md +416 -0
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/agents/AGENTS.md +234 -0
- package/agents/README.md +309 -0
- package/agents/engineering/data/eng.data-engineer.agent.md +309 -0
- package/agents/engineering/eng.agent.md +303 -0
- package/agents/engineering/eng.bug-hunter.md +386 -0
- package/agents/engineering/eng.cybersecurity.agent.md +503 -0
- package/agents/engineering/eng.dev-code-reviewer.md +148 -0
- package/agents/engineering/eng.docs-writer.md +152 -0
- package/agents/engineering/eng.frontend.agent.md +117 -0
- package/agents/engineering/eng.rpa.agent.md +215 -0
- package/agents/engineering/eng.tech-analyst.agent.md +102 -0
- package/agents/engineering/eng.ux-designer.agent.md +193 -0
- package/agents/engineering/qa/eng.qa.cypress-specialist.md +109 -0
- package/agents/engineering/qa/eng.qa.quality-champion-task-agent.md +85 -0
- package/agents/engineering/qa/eng.qa.quality-strategist.md +111 -0
- package/agents/engineering/qa/eng.qa.test-architect.md +400 -0
- package/agents/engineering/qa/eng.qa.test-planner.md +477 -0
- package/agents/engineering/qa/eng.qa.testing-engineer.md +339 -0
- package/agents/product/prod.pm-checker.md +52 -0
- package/bin/commands/docs-publish.js +184 -0
- package/bin/commands/docs-sync.js +139 -0
- package/bin/commands/info.js +87 -0
- package/bin/commands/init.js +237 -0
- package/bin/commands/install-rtk.js +90 -0
- package/bin/commands/list.js +48 -0
- package/bin/commands/qa-signoff.js +112 -0
- package/bin/commands/whoami.js +43 -0
- package/bin/jarvis.js +159 -0
- package/bin/lib/auth/session.js +56 -0
- package/bin/lib/config/constants.js +123 -0
- package/bin/lib/config/ide-config.js +233 -0
- package/bin/lib/core/scanner.js +124 -0
- package/bin/lib/core/sync-engine.js +551 -0
- package/bin/lib/docs/fetch-file.sh +41 -0
- package/bin/lib/docs/publish-file.sh +284 -0
- package/bin/lib/docs/validate-frontmatter.js +157 -0
- package/bin/lib/env-loader.js +198 -0
- package/bin/lib/tasks/comment.js +131 -0
- package/bin/lib/utils/git-parser.js +145 -0
- package/bin/lib/utils/logger.js +104 -0
- package/bin/lib/utils/npmrc-parser.js +106 -0
- package/bin/lib/utils/paths.js +55 -0
- package/bin/lib/utils/ui.js +59 -0
- package/bin/lib/vcs/api.js +312 -0
- package/bin/lib/vcs/create-issue.js +43 -0
- package/bin/lib/vcs/create-merge.js +43 -0
- package/bin/lib/vcs/fetch-raw.js +30 -0
- package/bin/postinstall.js +41 -0
- package/members.md +25 -0
- package/package.json +55 -0
- package/rules/AGENTS.md +205 -0
- package/rules/engineering/data/data-rules.md +200 -0
- package/rules/engineering/eng-rules.md +243 -0
- package/rules/engineering/eng-security-rules.md +186 -0
- package/rules/engineering/eng.breakdown-subtasks-rules.md +585 -0
- package/rules/engineering/eng.bump-rules.md +27 -0
- package/rules/engineering/eng.docs-scraping-rules.md +64 -0
- package/rules/engineering/eng.downstream-flow-rules.md +297 -0
- package/rules/engineering/eng.integrations-rules.md +73 -0
- package/rules/engineering/eng.plan-rules.md +333 -0
- package/rules/engineering/eng.pr-rules.md +359 -0
- package/rules/engineering/eng.pre-pr-rules.md +103 -0
- package/rules/engineering/eng.start-rules.md +246 -0
- package/rules/engineering/eng.tech-spec-rules.md +968 -0
- package/rules/engineering/eng.work-rules.md +312 -0
- package/rules/engineering/frontend/eng.frontend-rules.md +147 -0
- package/rules/engineering/qa/eng.qa.cypress-standards-rules.md +259 -0
- package/rules/engineering/qa/eng.qa.exploratory-session-rules.md +137 -0
- package/rules/engineering/qa/eng.qa.quality-gate-scoring-rules.md +181 -0
- package/rules/engineering/qa/eng.qa.tech-spec-validation-criteria-rules.md +120 -0
- package/rules/engineering/rpa/eng.rpa-rules.md +230 -0
- package/rules/product/README.md +24 -0
- package/rules/product/prod-rules.md +151 -0
- package/rules/rtk-rules.md +68 -0
- package/skills/AGENTS.md +290 -0
- package/skills/SKILLS-ROADMAP.md +333 -0
- package/skills/churn-audit/SKILL.md +385 -0
- package/skills/context-detect/SKILL.md +399 -0
- package/skills/context-detect/assets/context-profile-template.md +127 -0
- package/skills/docs-central/README.md +310 -0
- package/skills/docs-central/SKILL.md +423 -0
- package/skills/docs-index/SKILL.md +377 -0
- package/skills/eng-ai-engineer/SKILL.md +296 -0
- package/skills/eng-arch-c4/SKILL.md +358 -0
- package/skills/eng-arch-c4/assets/example-code.md +189 -0
- package/skills/eng-arch-c4/assets/example-component.md +105 -0
- package/skills/eng-arch-c4/assets/example-container.md +104 -0
- package/skills/eng-arch-c4/assets/example-context.md +81 -0
- package/skills/eng-backend/SKILL.md +776 -0
- package/skills/eng-browser-extension-builder/SKILL.md +385 -0
- package/skills/eng-cybersecurity/SKILL.md +645 -0
- package/skills/eng-data-bi/SKILL.md +199 -0
- package/skills/eng-data-debug/SKILL.md +307 -0
- package/skills/eng-data-engineer/SKILL.md +256 -0
- package/skills/eng-data-onboard/SKILL.md +310 -0
- package/skills/eng-data-orchestrator/SKILL.md +426 -0
- package/skills/eng-design-system/SKILL.md +619 -0
- package/skills/eng-docs-write/SKILL.md +312 -0
- package/skills/eng-frontend/SKILL.md +913 -0
- package/skills/eng-jira-comment/SKILL.md +17 -0
- package/skills/eng-microfrontend/SKILL.md +602 -0
- package/skills/eng-ms-trace/SKILL.md +469 -0
- package/skills/eng-nestjs/SKILL.md +791 -0
- package/skills/eng-performance-engineer/SKILL.md +312 -0
- package/skills/eng-pr/SKILL.md +339 -0
- package/skills/eng-qa-a11y-audit/SKILL.md +269 -0
- package/skills/eng-qa-bug-report/SKILL.md +1088 -0
- package/skills/eng-qa-bug-report/TASK_MANAGERS.md +138 -0
- package/skills/eng-qa-cypress-e2e/SKILL.md +177 -0
- package/skills/eng-qa-dev-guide/SKILL.md +164 -0
- package/skills/eng-qa-e2e/SKILL.md +400 -0
- package/skills/eng-qa-e2e-spec-writer/SKILL.md +322 -0
- package/skills/eng-qa-exploratory/SKILL.md +188 -0
- package/skills/eng-qa-gate/SKILL.md +370 -0
- package/skills/eng-qa-gate/assets/checklist-validacao.md +291 -0
- package/skills/eng-qa-graphql-contract/SKILL.md +256 -0
- package/skills/eng-qa-quality-report/SKILL.md +412 -0
- package/skills/eng-qa-test-plan/SKILL.md +466 -0
- package/skills/eng-qa-test-plan/assets/test-coverage-template.md +92 -0
- package/skills/eng-qa-test-plan/assets/test-patterns.md +178 -0
- package/skills/eng-qa-testsprite/SKILL.md +325 -0
- package/skills/eng-qa-testsprite/references/testsprite-mcp.md +224 -0
- package/skills/eng-qa-unit-test/SKILL.md +471 -0
- package/skills/eng-rabbitmq/SKILL.md +661 -0
- package/skills/eng-scraper/SKILL.md +683 -0
- package/skills/eng-scraper-robot-builder/SKILL.md +370 -0
- package/skills/eng-security-patch/SKILL.md +378 -0
- package/skills/eng-security-triage/SKILL.md +266 -0
- package/skills/eng-task-comment/SKILL.md +60 -0
- package/skills/eng-tech-analyst/SKILL.md +529 -0
- package/skills/eng-threat-model/SKILL.md +161 -0
- package/skills/init-jarvis/SKILL.md +1304 -0
- package/skills/init-jarvis/assets/mcp-configs.md +389 -0
- package/skills/init-jarvis/assets/onboarding-checklist.md +104 -0
- package/skills/init-jarvis/assets/setup-guide.md +360 -0
- package/skills/lovable-prompt-generator/SKILL.md +304 -0
- package/skills/prod-roadmap-report/README.md +303 -0
- package/skills/prod-roadmap-report/SKILL.md +198 -0
- package/skills/prod-roadmap-report/commands/status.compiled.single.team.md +23 -0
- package/skills/prod-roadmap-report/commands/status.list.projects.md +17 -0
- package/skills/prod-roadmap-report/commands/status.memory.md +192 -0
- package/skills/prod-roadmap-report/commands/status.roadmap.preview.md +94 -0
- package/skills/prod-roadmap-report/references/detailed-guide.md +236 -0
- package/skills/prod-roadmap-report/rules/detailed-guide.md +237 -0
- package/skills/prod-roadmap-report/rules/status-report-rules.md +44 -0
- package/skills/prod-roadmap-report/templates/template-multiple-teams-compiled-status.md +53 -0
- package/skills/prod-roadmap-report/templates/template-projects-list.md +23 -0
- package/skills/prod-roadmap-report/templates/template-single-team-compiled-status.md +60 -0
- package/skills/prod-roadmap-report/templates/template-single-team-status.md +49 -0
- package/skills/prod-specs/SKILL.md +108 -0
- package/skills/prod-specs/references/prod.spec.clarify.md +176 -0
- package/skills/prod-specs/references/prod.spec.epic.md +107 -0
- package/skills/prod-specs/references/prod.spec.frd.md +135 -0
- package/skills/prod-specs/references/prod.spec.issue.md +145 -0
- package/skills/prod-specs/references/prod.spec.prd.md +118 -0
- package/skills/prod-specs/rules/prod-spec-rules.md +186 -0
- package/skills/prod-specs/templates/prod-breakdown-template.md +136 -0
- package/skills/prod-specs/templates/prod-epic-template.md +76 -0
- package/skills/prod-specs/templates/prod-frd-template.md +172 -0
- package/skills/prod-specs/templates/prod-issue-template.md +68 -0
- package/skills/prod-specs/templates/prod-prd-full-template.md +159 -0
- package/skills/prod-specs/templates/prod-prd-template.md +173 -0
- package/skills/prod-specs-update/SKILL.md +272 -0
- package/skills/report-issue/SKILL.md +156 -0
- package/taxonomy.md +270 -0
- package/templates/AGENTS.md +189 -0
- package/templates/CDD aplicado a Prompts.md +182 -0
- package/templates/ENV-template.md +187 -0
- package/templates/engineering/AGENTS-template.md +71 -0
- package/templates/engineering/ARD-template.md +193 -0
- package/templates/engineering/CONTACTS-template.md +135 -0
- package/templates/engineering/PR-template.md +40 -0
- package/templates/engineering/RFC-Playbook.md +325 -0
- package/templates/engineering/RFC-template.md +199 -0
- package/templates/engineering/architecture-template.md +277 -0
- package/templates/engineering/breakdown-subtasks-template.md +582 -0
- package/templates/engineering/c4-model-template.md +516 -0
- package/templates/engineering/data-contract-template.md +135 -0
- package/templates/engineering/data-pipeline-template.md +163 -0
- package/templates/engineering/plan-template.md +255 -0
- package/templates/engineering/qa/eng.qa.quality-gate-examples-template.md +311 -0
- package/templates/engineering/qa/eng.qa.quality-gate-report-template.md +249 -0
- package/templates/engineering/qa/qa.cypress-test-template.md +172 -0
- package/templates/engineering/qa/qa.exploratory-session-template.md +148 -0
- package/templates/engineering/qa/qa.quality-report-template.md +130 -0
- package/templates/engineering/qa/qa.release-signoff-template.md +54 -0
- package/templates/engineering/qa/qa.sprint-plan-template.md +49 -0
- package/templates/engineering/swagger-template.md +145 -0
- package/templates/engineering/tech-spec-template.md +497 -0
- package/templates/engineering/work-progress-template.md +155 -0
- package/workflows/AGENTS.md +240 -0
- package/workflows/README.md +160 -0
- package/workflows/all-tools.md +11 -0
- package/workflows/engineering/data/data.contract.md +202 -0
- package/workflows/engineering/data/data.new-pipeline.md +234 -0
- package/workflows/engineering/eng.breakdown-subtasks.md +420 -0
- package/workflows/engineering/eng.bug-audit.md +591 -0
- package/workflows/engineering/eng.build-tech-spec.md +1116 -0
- package/workflows/engineering/eng.create-ard-from-code.md +259 -0
- package/workflows/engineering/eng.create-ard.md +382 -0
- package/workflows/engineering/eng.create-rfc.md +245 -0
- package/workflows/engineering/eng.debug.md +479 -0
- package/workflows/engineering/eng.docs.md +40 -0
- package/workflows/engineering/eng.light-arch.md +84 -0
- package/workflows/engineering/eng.plan.md +213 -0
- package/workflows/engineering/eng.pr.md +466 -0
- package/workflows/engineering/eng.pre-pr.md +167 -0
- package/workflows/engineering/eng.review.md +185 -0
- package/workflows/engineering/eng.rpa.robot.md +342 -0
- package/workflows/engineering/eng.security-audit.md +312 -0
- package/workflows/engineering/eng.security-incident.md +275 -0
- package/workflows/engineering/eng.security-pipeline.md +210 -0
- package/workflows/engineering/eng.security-review.md +235 -0
- package/workflows/engineering/eng.start.md +494 -0
- package/workflows/engineering/eng.work.md +558 -0
- package/workflows/engineering/frontend/eng.frontend-component.md +190 -0
- package/workflows/engineering/frontend/eng.frontend-perf-audit.md +375 -0
- package/workflows/engineering/frontend/eng.frontend-review.md +185 -0
- package/workflows/engineering/qa/eng.qa-dev-quality-guide.md +51 -0
- package/workflows/engineering/qa/eng.qa-e2e-test-generation.md +51 -0
- package/workflows/engineering/qa/eng.qa-exploratory-session.md +60 -0
- package/workflows/engineering/qa/eng.qa-quality-gate-validation.md +202 -0
- package/workflows/engineering/qa/eng.qa-quality-report.md +83 -0
- package/workflows/engineering/qa/eng.qa-refinement-entry.md +83 -0
- package/workflows/engineering/qa/eng.qa-release-signoff.md +170 -0
- package/workflows/engineering/qa/eng.qa-sprint-planning.md +100 -0
- package/workflows/engineering/ta/eng.ta.atendimento.md +93 -0
- package/workflows/product/prod.roadmap.preview.md +110 -0
- package/workflows/product/prod.spec.breakdown.md +163 -0
- package/workflows/product/prod.spec.clarify.md +178 -0
- package/workflows/product/prod.spec.epic.md +154 -0
- package/workflows/product/prod.spec.frd.md +96 -0
- package/workflows/product/prod.spec.issue.md +145 -0
- package/workflows/product/prod.spec.md +60 -0
- package/workflows/product/prod.spec.prd.md +100 -0
- package/workflows/taxonomy.md +92 -0
- 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
|
+
|