jarvis-ai-framework 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +22 -122
- package/agents/AGENTS.md +20 -24
- package/agents/README.md +25 -129
- package/agents/engineering/data/eng.data-engineer.agent.md +12 -35
- package/agents/engineering/eng.agent.md +18 -30
- package/agents/engineering/eng.bug-hunter.md +9 -12
- package/agents/engineering/eng.dev-code-reviewer.md +5 -1
- package/agents/engineering/eng.docs-writer.md +3 -3
- package/agents/engineering/eng.frontend.agent.md +13 -8
- package/agents/engineering/eng.rpa.agent.md +5 -13
- package/agents/engineering/eng.ux-designer.agent.md +4 -0
- package/agents/engineering/qa/eng.qa.quality-champion-task-agent.md +4 -0
- package/agents/engineering/qa/eng.qa.quality-strategist.md +13 -8
- package/agents/engineering/qa/eng.qa.test-architect.md +16 -15
- package/agents/engineering/qa/eng.qa.test-planner.md +22 -17
- package/agents/engineering/qa/eng.qa.testing-engineer.md +99 -15
- package/agents/product/prod.discovery-interviewer.md +22 -3
- package/agents/product/prod.pm-checker.md +4 -0
- package/bin/README.md +142 -0
- package/bin/commands/docs-publish.js +105 -141
- package/bin/commands/docs-sync.js +66 -104
- package/bin/commands/info.js +7 -27
- package/bin/commands/init.js +23 -51
- package/bin/commands/install-rtk.js +9 -3
- package/bin/commands/list.js +5 -18
- package/bin/commands/map.js +58 -0
- package/bin/commands/qa-signoff.js +58 -55
- package/bin/commands/tokens.js +90 -0
- package/bin/commands/whoami.js +30 -26
- package/bin/jarvis.js +9 -153
- package/bin/lib/auth/session.js +20 -20
- package/bin/lib/cli/program.js +219 -0
- package/bin/lib/cli/shared-options.js +29 -0
- package/bin/lib/config/constants.js +70 -2
- package/bin/lib/config/ide-config.js +4 -8
- package/bin/lib/core/profile-filter.js +116 -0
- package/bin/lib/core/scanner.js +5 -31
- package/bin/lib/core/sync-engine.js +21 -14
- package/bin/lib/core/token-report.js +100 -0
- package/bin/lib/docs/fetch-file.js +39 -0
- package/bin/lib/docs/publish-file.js +194 -0
- package/bin/lib/docs/redis-cache.js +49 -0
- package/bin/lib/docs/validate-frontmatter.js +9 -39
- package/bin/lib/env-loader.js +11 -34
- package/bin/lib/flow-map/index.js +65 -0
- package/bin/lib/flow-map/parse.js +223 -0
- package/bin/lib/flow-map/render.js +89 -0
- package/bin/lib/flow-map/tree.js +248 -0
- package/bin/lib/tasks/comment.js +40 -35
- package/bin/lib/utils/frontmatter.js +57 -0
- package/bin/lib/utils/git-parser.js +4 -6
- package/bin/lib/utils/npmrc-parser.js +6 -13
- package/bin/lib/utils/paths.js +2 -4
- package/bin/lib/utils/ui.js +3 -9
- package/bin/lib/vcs/api.js +25 -41
- package/bin/lib/vcs/create-issue.js +49 -33
- package/bin/lib/vcs/create-merge.js +47 -31
- package/bin/lib/vcs/fetch-raw.js +35 -23
- package/members.md +1 -1
- package/package.json +15 -4
- package/rules/AGENTS.md +18 -7
- package/rules/engineering/eng-rules.md +3 -13
- package/rules/engineering/eng-security-rules.md +19 -18
- package/rules/engineering/eng.bump-rules.md +3 -2
- package/rules/engineering/eng.docs-scraping-rules.md +4 -4
- package/rules/engineering/eng.integrations-rules.md +3 -7
- package/rules/engineering/eng.skills-rules.md +1 -5
- package/rules/engineering/eng.specializations-rules.md +18 -8
- package/rules/engineering/frontend/eng.frontend-rules.md +1 -4
- package/rules/engineering/qa/eng.qa.cypress-standards-rules.md +1 -1
- package/rules/engineering/rpa/eng.rpa-rules.md +4 -9
- package/rules/product/README.md +1 -0
- package/rules/product/prod-rules.md +1 -4
- package/rules/product/prod.spec-rules.md +0 -4
- package/rules/rtk-rules.md +0 -1
- package/{rules → rules-on-demand}/engineering/eng.breakdown-subtasks-rules.md +0 -4
- package/{rules → rules-on-demand}/engineering/eng.plan-rules.md +0 -4
- package/{rules → rules-on-demand}/engineering/eng.pr-rules.md +0 -4
- package/{rules → rules-on-demand}/engineering/eng.pre-pr-rules.md +0 -4
- package/{rules → rules-on-demand}/engineering/eng.start-rules.md +0 -4
- package/{rules → rules-on-demand}/engineering/eng.tech-spec-rules.md +1 -2
- package/{rules → rules-on-demand}/engineering/eng.work-rules.md +0 -4
- package/skills/AGENTS.md +69 -106
- package/skills/SKILLS-ROADMAP.md +47 -132
- package/skills/eng-ai/SKILL.md +270 -0
- package/skills/eng-ai/references/1-fundamentos-ml.md +24 -0
- package/skills/eng-ai/references/10-arquitetura-solucoes-ia.md +24 -0
- package/skills/eng-ai/references/11-governanca-ia.md +24 -0
- package/skills/eng-ai/references/12-seguranca-ia-responsavel.md +25 -0
- package/skills/eng-ai/references/2-matematica-estatistica.md +24 -0
- package/skills/eng-ai/references/3-dados-para-ia.md +24 -0
- package/skills/eng-ai/references/4-deep-learning-fundacionais.md +24 -0
- package/skills/eng-ai/references/5-llms-chatbots-agentes-rag.md +25 -0
- package/skills/eng-ai/references/6-avaliacao-experimentacao.md +24 -0
- package/skills/eng-ai/references/7-engenharia-sistemas-ia.md +24 -0
- package/skills/eng-ai/references/8-mlops-plataforma.md +24 -0
- package/skills/eng-ai/references/9-produto-ia.md +24 -0
- package/skills/eng-ai/references/especializacoes.md +17 -0
- package/skills/eng-automation/SKILL.md +290 -0
- package/skills/eng-automation/references/1-fundamentos-automacao.md +25 -0
- package/skills/eng-automation/references/10-ingestao-dados.md +25 -0
- package/skills/eng-automation/references/11-captcha-antibot.md +25 -0
- package/skills/eng-automation/references/12-limites-taxa-sessoes.md +25 -0
- package/skills/eng-automation/references/13-agendamento-orquestracao.md +24 -0
- package/skills/eng-automation/references/14-retentativa-erros.md +25 -0
- package/skills/eng-automation/references/15-autenticacao-credenciais.md +24 -0
- package/skills/eng-automation/references/16-observabilidade-confiabilidade.md +24 -0
- package/skills/eng-automation/references/2-aquisicao-dados.md +25 -0
- package/skills/eng-automation/references/3-automacao-navegador.md +24 -0
- package/skills/eng-automation/references/4-scraping-crawling.md +25 -0
- package/skills/eng-automation/references/5-apis-rest-graphql-soap.md +26 -0
- package/skills/eng-automation/references/6-webhooks-integracao.md +25 -0
- package/skills/eng-automation/references/7-rpa.md +25 -0
- package/skills/eng-automation/references/8-extracao-estruturada.md +25 -0
- package/skills/eng-automation/references/9-extracao-documentos.md +25 -0
- package/skills/eng-automation/references/especializacoes.md +18 -0
- package/skills/eng-backend/SKILL.md +6 -0
- package/skills/eng-backend-arch-c4/SKILL.md +10 -4
- package/skills/eng-backend-microservices-trace/SKILL.md +6 -0
- package/skills/eng-backend-nestjs/SKILL.md +17 -462
- package/skills/eng-backend-nestjs/references/1-arquitetura-modulos.md +54 -0
- package/skills/eng-backend-nestjs/references/2-guards-autenticacao.md +118 -0
- package/skills/eng-backend-nestjs/references/3-interceptors-pipes-filters.md +113 -0
- package/skills/eng-backend-nestjs/references/4-config-logging.md +61 -0
- package/skills/eng-backend-nestjs/references/5-testes.md +83 -0
- package/skills/eng-backend-nestjs/references/6-problemas-comuns.md +53 -0
- package/skills/eng-backend-rabbitmq/SKILL.md +15 -298
- package/skills/eng-backend-rabbitmq/references/1-referencia-endpoints.md +28 -0
- package/skills/eng-backend-rabbitmq/references/2-codigo-consumer-producer.md +90 -0
- package/skills/eng-backend-rabbitmq/references/3-arquiteturas-comuns.md +101 -0
- package/skills/eng-backend-rabbitmq/references/4-troubleshooting.md +93 -0
- package/skills/eng-data/SKILL.md +271 -0
- package/skills/eng-data/references/1-fundamentos-dados.md +24 -0
- package/skills/eng-data/references/10-ciencia-dados.md +24 -0
- package/skills/eng-data/references/11-dataops-plataforma.md +24 -0
- package/skills/eng-data/references/12-seguranca-privacidade.md +24 -0
- package/skills/eng-data/references/2-modelagem-dados.md +24 -0
- package/skills/eng-data/references/3-bancos-dados.md +24 -0
- package/skills/eng-data/references/4-arquitetura-dados.md +24 -0
- package/skills/eng-data/references/5-pipelines-integracao.md +24 -0
- package/skills/eng-data/references/6-qualidade-dados.md +24 -0
- package/skills/eng-data/references/7-governanca-metadados.md +24 -0
- package/skills/eng-data/references/8-estatistica-analise.md +24 -0
- package/skills/eng-data/references/9-analytics-bi.md +24 -0
- package/skills/eng-data/references/especializacoes.md +20 -0
- package/skills/eng-frontend/SKILL.md +18 -5
- package/skills/eng-frontend/references/13-design-system.md +48 -0
- package/skills/eng-frontend/references/14-microfrontend.md +46 -0
- package/skills/eng-global-docs-write/SKILL.md +10 -5
- package/skills/eng-global-pr/SKILL.md +7 -1
- package/skills/eng-global-task-comment/SKILL.md +8 -2
- package/skills/eng-platform/SKILL.md +331 -0
- package/skills/eng-platform/references/1-fundamentos-sistemas.md +23 -0
- package/skills/eng-platform/references/10-resiliencia-arquitetura.md +24 -0
- package/skills/eng-platform/references/11-plataforma-devex.md +24 -0
- package/skills/eng-platform/references/12-finops-custos.md +24 -0
- package/skills/eng-platform/references/13-seguranca-fundamentos.md +26 -0
- package/skills/eng-platform/references/14-profiling-performance.md +23 -0
- package/skills/eng-platform/references/15-testes-carga-chaos.md +23 -0
- package/skills/eng-platform/references/16-cache-multicamada.md +22 -0
- package/skills/eng-platform/references/2-redes.md +23 -0
- package/skills/eng-platform/references/3-cloud.md +24 -0
- package/skills/eng-platform/references/4-iac-automacao.md +24 -0
- package/skills/eng-platform/references/5-containers-orquestracao.md +25 -0
- package/skills/eng-platform/references/6-cicd-entrega.md +24 -0
- package/skills/eng-platform/references/7-observabilidade.md +24 -0
- package/skills/eng-platform/references/8-confiabilidade-sre.md +24 -0
- package/skills/eng-platform/references/9-seguranca-infra.md +26 -0
- package/skills/eng-platform/references/especializacoes.md +34 -0
- package/skills/eng-qa/SKILL.md +283 -0
- package/skills/eng-qa/references/1-fundamentos-qualidade.md +25 -0
- package/skills/eng-qa/references/10-confiabilidade.md +25 -0
- package/skills/eng-qa/references/11-seguranca.md +24 -0
- package/skills/eng-qa/references/12-acessibilidade.md +24 -0
- package/skills/eng-qa/references/13-dados-testes.md +24 -0
- package/skills/eng-qa/references/14-gestao-testes-defeitos.md +25 -0
- package/skills/eng-qa/references/15-arquitetura-qa.md +25 -0
- package/skills/eng-qa/references/2-estrategia-planejamento.md +25 -0
- package/skills/eng-qa/references/3-design-testes.md +25 -0
- package/skills/eng-qa/references/4-manual-exploratorio.md +24 -0
- package/skills/eng-qa/references/5-automacao-testes.md +25 -0
- package/skills/eng-qa/references/6-api-integracao.md +25 -0
- package/skills/eng-qa/references/7-contrato.md +24 -0
- package/skills/eng-qa/references/8-interface-compat-mobile.md +24 -0
- package/skills/eng-qa/references/9-performance.md +24 -0
- package/skills/eng-qa/references/especializacoes.md +29 -0
- package/skills/eng-qa-planner/SKILL.md +264 -0
- package/skills/jarvis-context-detect/SKILL.md +7 -1
- package/skills/jarvis-context-detect/assets/context-profile-template.md +1 -1
- package/skills/jarvis-create-specialization/SKILL.md +14 -0
- package/skills/jarvis-docs-central/README.md +31 -28
- package/skills/jarvis-docs-central/SKILL.md +11 -5
- package/skills/jarvis-docs-index/SKILL.md +10 -2
- package/skills/jarvis-evolution-architect/SKILL.md +6 -0
- package/skills/jarvis-init/SKILL.md +22 -15
- package/skills/jarvis-init/assets/passo-adicionar-stacks.md +47 -18
- package/skills/jarvis-list-specializations/SKILL.md +36 -17
- package/skills/jarvis-report-issue/SKILL.md +7 -1
- package/skills/product-roadmap-report/SKILL.md +8 -0
- package/skills/product-specs/SKILL.md +9 -0
- package/skills/product-specs-update/SKILL.md +6 -0
- package/taxonomy.md +16 -28
- package/templates/AGENTS.md +2 -0
- package/templates/ENV-template.md +10 -2
- package/templates/engineering/qa/qa.sprint-plan-template.md +1 -1
- package/templates/engineering/tech-spec-delivery-template.md +179 -0
- package/workflows/AGENTS.md +14 -2
- package/workflows/README.md +8 -16
- package/workflows/all-tools.md +7 -1
- package/workflows/engineering/data/data.contract.md +8 -0
- package/workflows/engineering/data/data.new-pipeline.md +15 -4
- package/workflows/engineering/eng.breakdown-subtasks.md +9 -0
- package/workflows/engineering/eng.bug-audit.md +10 -13
- package/workflows/engineering/eng.build-tech-spec.md +17 -146
- package/workflows/engineering/eng.create-ard-from-code.md +8 -0
- package/workflows/engineering/eng.create-ard.md +8 -0
- package/workflows/engineering/eng.create-rfc.md +7 -0
- package/workflows/engineering/eng.debug.md +5 -21
- package/workflows/engineering/eng.docs.md +9 -0
- package/workflows/engineering/eng.light-arch.md +7 -0
- package/workflows/engineering/eng.plan.md +15 -2
- package/workflows/engineering/eng.pr.md +24 -30
- package/workflows/engineering/eng.pre-pr.md +33 -15
- package/workflows/engineering/eng.review.md +18 -11
- package/workflows/engineering/eng.rpa.robot.md +17 -7
- package/workflows/engineering/eng.start.md +33 -12
- package/workflows/engineering/eng.work.md +25 -17
- package/workflows/engineering/frontend/eng.frontend-component.md +7 -0
- package/workflows/engineering/frontend/eng.frontend-perf-audit.md +8 -0
- package/workflows/engineering/frontend/eng.frontend-review.md +8 -0
- package/workflows/engineering/qa/eng.qa-refinement-entry.md +7 -0
- package/workflows/engineering/qa/eng.qa-release-signoff.md +6 -0
- package/workflows/engineering/qa/eng.qa-sprint-planning.md +7 -1
- package/workflows/product/prod.roadmap.preview.md +9 -0
- package/workflows/product/prod.spec.ard.md +97 -0
- package/workflows/product/prod.spec.breakdown.md +10 -0
- package/workflows/product/prod.spec.clarify.md +8 -2
- package/workflows/product/prod.spec.discovery.md +11 -1
- package/workflows/product/prod.spec.epic.md +8 -0
- package/workflows/product/prod.spec.frd.md +7 -0
- package/workflows/product/prod.spec.issue.md +6 -0
- package/workflows/product/prod.spec.md +15 -1
- package/workflows/product/prod.spec.prd.md +7 -0
- package/workflows/taxonomy.md +58 -6
- package/workflows/warm-up.md +47 -60
- package/agents/engineering/eng.cybersecurity.agent.md +0 -488
- package/agents/engineering/qa/eng.qa.cypress-specialist.md +0 -109
- package/bin/lib/docs/fetch-file.sh +0 -41
- package/bin/lib/docs/publish-file.sh +0 -284
- package/rules/engineering/eng.downstream-flow-rules.md +0 -297
- package/rules/engineering/qa/eng.qa.exploratory-session-rules.md +0 -137
- package/rules/engineering/qa/eng.qa.quality-gate-scoring-rules.md +0 -181
- package/rules/engineering/qa/eng.qa.tech-spec-validation-criteria-rules.md +0 -120
- package/skills/eng-ai-engineer/SKILL.md +0 -297
- package/skills/eng-data-bi/SKILL.md +0 -200
- package/skills/eng-data-debug/SKILL.md +0 -308
- package/skills/eng-data-engineer/SKILL.md +0 -257
- package/skills/eng-data-onboard/SKILL.md +0 -311
- package/skills/eng-data-orchestrator/SKILL.md +0 -427
- package/skills/eng-devops-performance-engineer/SKILL.md +0 -313
- package/skills/eng-frontend-design-system/SKILL.md +0 -621
- package/skills/eng-frontend-microfrontend/SKILL.md +0 -604
- package/skills/eng-global-browser-extension-builder/SKILL.md +0 -386
- package/skills/eng-global-jira-comment/SKILL.md +0 -21
- package/skills/eng-qa-a11y-audit/SKILL.md +0 -270
- package/skills/eng-qa-bug-report/SKILL.md +0 -1089
- package/skills/eng-qa-bug-report/TASK_MANAGERS.md +0 -138
- package/skills/eng-qa-cypress-e2e/SKILL.md +0 -178
- package/skills/eng-qa-dev-guide/SKILL.md +0 -165
- package/skills/eng-qa-e2e/SKILL.md +0 -401
- package/skills/eng-qa-e2e-spec-writer/SKILL.md +0 -323
- package/skills/eng-qa-exploratory/SKILL.md +0 -189
- package/skills/eng-qa-gate/SKILL.md +0 -371
- package/skills/eng-qa-gate/assets/checklist-validacao.md +0 -291
- package/skills/eng-qa-graphql-contract/SKILL.md +0 -257
- package/skills/eng-qa-quality-report/SKILL.md +0 -413
- package/skills/eng-qa-test-plan/SKILL.md +0 -467
- package/skills/eng-qa-testsprite/SKILL.md +0 -326
- package/skills/eng-qa-testsprite/references/testsprite-mcp.md +0 -224
- package/skills/eng-qa-unit-test/SKILL.md +0 -472
- package/skills/eng-scraper/SKILL.md +0 -684
- package/skills/eng-scraper-robot-builder/SKILL.md +0 -371
- package/skills/eng-security-cybersecurity/SKILL.md +0 -646
- package/skills/eng-security-patch/SKILL.md +0 -382
- package/skills/eng-security-threat-model/SKILL.md +0 -165
- package/skills/eng-security-triage/SKILL.md +0 -270
- package/templates/engineering/qa/eng.qa.quality-gate-examples-template.md +0 -311
- package/templates/engineering/qa/eng.qa.quality-gate-report-template.md +0 -249
- package/templates/engineering/qa/qa.cypress-test-template.md +0 -172
- package/templates/engineering/qa/qa.exploratory-session-template.md +0 -148
- package/templates/engineering/qa/qa.quality-report-template.md +0 -130
- package/workflows/engineering/eng.security-audit.md +0 -312
- package/workflows/engineering/eng.security-incident.md +0 -275
- package/workflows/engineering/eng.security-pipeline.md +0 -210
- package/workflows/engineering/eng.security-review.md +0 -235
- package/workflows/engineering/qa/eng.qa-dev-quality-guide.md +0 -51
- package/workflows/engineering/qa/eng.qa-e2e-test-generation.md +0 -51
- package/workflows/engineering/qa/eng.qa-exploratory-session.md +0 -60
- package/workflows/engineering/qa/eng.qa-quality-gate-validation.md +0 -202
- package/workflows/engineering/qa/eng.qa-quality-report.md +0 -78
- /package/skills/{eng-qa-test-plan → eng-qa-planner}/assets/test-coverage-template.md +0 -0
- /package/skills/{eng-qa-test-plan → eng-qa-planner}/assets/test-patterns.md +0 -0
- /package/templates/{CDD aplicado a Prompts.md → cdd-aplicado-a-prompts.md} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { existsSync, readdirSync, readFileSync } from
|
|
2
|
-
import { join } from
|
|
3
|
-
import { loadEnv, resolveEnvPath } from
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
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[
|
|
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(
|
|
24
|
-
branch = execSync(
|
|
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 =
|
|
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,
|
|
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,
|
|
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(
|
|
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,
|
|
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
|
|
77
|
-
if (
|
|
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
|
|
83
|
-
const
|
|
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() !==
|
|
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(
|
|
104
|
-
|
|
105
|
-
|
|
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(
|
|
111
|
-
|
|
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
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { buildReport } from "../lib/core/token-report.js";
|
|
2
|
+
import { resolveEnvPath, loadEnv } from "../lib/env-loader.js";
|
|
3
|
+
import { getFrameworkRoot } from "../lib/utils/paths.js";
|
|
4
|
+
import { showBanner, RED, GREEN, BLUE, YELLOW, CYAN, DIM, NC } from "../lib/utils/ui.js";
|
|
5
|
+
import { logger } from "../lib/utils/logger.js";
|
|
6
|
+
|
|
7
|
+
const AXES = ["HUB", "POSITION", "AREA", "SQUAD"];
|
|
8
|
+
|
|
9
|
+
/** Perfil: as flags (`--hub` etc.) mandam; o que faltar vem do ENV.md. */
|
|
10
|
+
function resolveProfile(flags) {
|
|
11
|
+
const profile = {};
|
|
12
|
+
for (const axis of AXES) {
|
|
13
|
+
const value = flags[axis.toLowerCase()];
|
|
14
|
+
if (typeof value === "string") profile[axis] = value;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let rtkEnabled = flags.rtk === true || flags.rtk === "true";
|
|
18
|
+
// O ENV.md só entra quando falta algum eixo; com os 4 eixos nas flags, o RTK vem só da flag.
|
|
19
|
+
if (AXES.some((axis) => !profile[axis])) {
|
|
20
|
+
try {
|
|
21
|
+
const { path } = resolveEnvPath(process.cwd(), flags);
|
|
22
|
+
const env = loadEnv(process.cwd(), path);
|
|
23
|
+
for (const axis of AXES) {
|
|
24
|
+
if (!profile[axis] && env[axis]) profile[axis] = env[axis];
|
|
25
|
+
}
|
|
26
|
+
if (flags.rtk === undefined) rtkEnabled = env.RTK_ENABLED === "true";
|
|
27
|
+
} catch {
|
|
28
|
+
// sem ENV.md: valem só as flags
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const missing = AXES.filter((axis) => !profile[axis]);
|
|
33
|
+
return { profile, rtkEnabled, missing };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const kb = (bytes) => (bytes / 1000).toFixed(1);
|
|
37
|
+
|
|
38
|
+
export async function tokens(flags) {
|
|
39
|
+
const { profile, rtkEnabled, missing } = resolveProfile(flags);
|
|
40
|
+
|
|
41
|
+
if (missing.length > 0) {
|
|
42
|
+
logger.error(`${RED}❌ Perfil incompleto: faltam ${missing.join(", ")}${NC}`);
|
|
43
|
+
logger.info(
|
|
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`
|
|
48
|
+
);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const report = buildReport(getFrameworkRoot(), profile, { rtkEnabled });
|
|
53
|
+
|
|
54
|
+
if (flags.json) {
|
|
55
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
showBanner();
|
|
60
|
+
logger.info(`${CYAN}📏 Custo estimado no início da sessão${NC}`);
|
|
61
|
+
logger.info(
|
|
62
|
+
`${DIM}Perfil: HUB=${profile.HUB} | POSITION=${profile.POSITION} | AREA=${profile.AREA} | SQUAD=${profile.SQUAD}` +
|
|
63
|
+
` | RTK=${rtkEnabled ? "ligado" : "desligado"}${NC}`
|
|
64
|
+
);
|
|
65
|
+
logger.info(`${DIM}${report.estimate}${NC}`);
|
|
66
|
+
logger.info("");
|
|
67
|
+
logger.info(
|
|
68
|
+
`${DIM}${"Tipo".padEnd(26)}${"Arquivos".padStart(9)}${"KB".padStart(10)}${"Tokens (≈)".padStart(13)}${NC}`
|
|
69
|
+
);
|
|
70
|
+
logger.info(`${DIM}${"─".repeat(58)}${NC}`);
|
|
71
|
+
|
|
72
|
+
for (const c of report.categories) {
|
|
73
|
+
logger.info(
|
|
74
|
+
`${GREEN}${c.label.padEnd(26)}${NC}${String(c.files.length).padStart(9)}` +
|
|
75
|
+
`${kb(c.bytes).padStart(10)}${String(c.tokens).padStart(13)}`
|
|
76
|
+
);
|
|
77
|
+
if (c.files[0]) {
|
|
78
|
+
logger.info(
|
|
79
|
+
` ${DIM}maior: ${c.files[0].path} (${kb(c.files[0].bytes)} KB) — ${c.note}${NC}`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
logger.info(`${DIM}${"─".repeat(58)}${NC}`);
|
|
85
|
+
logger.info(
|
|
86
|
+
`${BLUE}${"Total".padEnd(26)}${NC}${"".padStart(9)}` +
|
|
87
|
+
`${kb(report.total.bytes).padStart(10)}${String(report.total.tokens).padStart(13)}`
|
|
88
|
+
);
|
|
89
|
+
logger.info("");
|
|
90
|
+
}
|
package/bin/commands/whoami.js
CHANGED
|
@@ -1,43 +1,47 @@
|
|
|
1
|
-
import { resolveUser, readSession, clearSession } from
|
|
2
|
-
import { loadEnv, resolveEnvPath } from
|
|
3
|
-
import { logger, configureFromFlags } from
|
|
4
|
-
import { GREEN, YELLOW, BLUE, DIM, NC } from
|
|
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(
|
|
13
|
-
|
|
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(
|
|
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
|
}
|
package/bin/jarvis.js
CHANGED
|
@@ -1,159 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
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";
|
|
3
|
+
import { buildProgram } from "./lib/cli/program.js";
|
|
18
4
|
|
|
19
|
-
const
|
|
20
|
-
const __dirname = dirname(__filename);
|
|
21
|
-
const args = argv.slice(2);
|
|
22
|
-
const command = args[0];
|
|
5
|
+
const program = buildProgram();
|
|
23
6
|
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
);
|
|
31
|
-
_version = packageJson.version;
|
|
32
|
-
}
|
|
33
|
-
return _version;
|
|
7
|
+
// Sem comando: mostra a ajuda e sai com sucesso (não é um erro de uso).
|
|
8
|
+
// O default do commander para esse caso é process.exit(1); aqui replicamos
|
|
9
|
+
// o comportamento do dispatcher antigo, que apenas chamava help() e seguia.
|
|
10
|
+
if (process.argv.length <= 2) {
|
|
11
|
+
program.outputHelp();
|
|
12
|
+
process.exit(0);
|
|
34
13
|
}
|
|
35
14
|
|
|
36
|
-
|
|
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}/jarvis-init${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
|
-
}
|
|
15
|
+
await program.parseAsync(process.argv);
|
package/bin/lib/auth/session.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { existsSync, readFileSync, unlinkSync } from
|
|
2
|
-
import { execSync } from
|
|
3
|
-
import { join } from
|
|
4
|
-
import { homedir, userInfo } from
|
|
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
5
|
|
|
6
|
-
const SESSION_FILE = join(homedir(),
|
|
6
|
+
const SESSION_FILE = join(homedir(), ".jarvis", "auth.json");
|
|
7
7
|
|
|
8
8
|
export function readSession() {
|
|
9
|
-
if (!existsSync(SESSION_FILE)) return null
|
|
9
|
+
if (!existsSync(SESSION_FILE)) return null;
|
|
10
10
|
try {
|
|
11
|
-
return JSON.parse(readFileSync(SESSION_FILE,
|
|
11
|
+
return JSON.parse(readFileSync(SESSION_FILE, "utf-8"));
|
|
12
12
|
} catch {
|
|
13
|
-
return null
|
|
13
|
+
return null;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function clearSession() {
|
|
18
18
|
if (existsSync(SESSION_FILE)) {
|
|
19
|
-
unlinkSync(SESSION_FILE)
|
|
19
|
+
unlinkSync(SESSION_FILE);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -25,32 +25,32 @@ export function clearSession() {
|
|
|
25
25
|
* Order: ENV.md USER → git user.email → OS username → "local"
|
|
26
26
|
*/
|
|
27
27
|
export function resolveUser(env = {}) {
|
|
28
|
-
const envUser = typeof env.USER ===
|
|
29
|
-
if (envUser) return { id: envUser, source:
|
|
28
|
+
const envUser = typeof env.USER === "string" ? env.USER.trim() : "";
|
|
29
|
+
if (envUser) return { id: envUser, source: "ENV.md" };
|
|
30
30
|
|
|
31
31
|
try {
|
|
32
|
-
const email = execSync(
|
|
33
|
-
encoding:
|
|
34
|
-
stdio: [
|
|
35
|
-
}).trim()
|
|
36
|
-
if (email) return { id: email, source:
|
|
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
37
|
} catch {
|
|
38
38
|
// ignore
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
try {
|
|
42
|
-
const username = userInfo().username
|
|
43
|
-
if (username) return { id: username, source:
|
|
42
|
+
const username = userInfo().username;
|
|
43
|
+
if (username) return { id: username, source: "os" };
|
|
44
44
|
} catch {
|
|
45
45
|
// ignore
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
return { id:
|
|
48
|
+
return { id: "local", source: "fallback" };
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Identity used as dev_id. Never requires jarvis login.
|
|
53
53
|
*/
|
|
54
54
|
export function getAuthUser(env = {}) {
|
|
55
|
-
return resolveUser(env).id
|
|
55
|
+
return resolveUser(env).id;
|
|
56
56
|
}
|