jarvis-ai-framework 2.1.1 → 3.2.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 +14 -115
- package/agents/AGENTS.md +11 -23
- package/agents/README.md +27 -129
- package/agents/engineering/data/eng.data-engineer.agent.md +11 -34
- package/agents/engineering/eng.advisor.agent.md +56 -0
- package/agents/engineering/eng.agent.md +14 -24
- package/agents/engineering/eng.bug-hunter.md +7 -15
- package/agents/engineering/eng.dev-code-reviewer.md +1 -1
- package/agents/engineering/eng.frontend.agent.md +3 -7
- package/agents/engineering/eng.rpa.agent.md +2 -8
- package/agents/engineering/qa/eng.qa.quality-strategist.md +6 -11
- package/agents/engineering/qa/eng.qa.test-architect.md +8 -18
- package/agents/engineering/qa/eng.qa.test-planner.md +10 -14
- package/agents/engineering/qa/eng.qa.testing-engineer.md +91 -24
- package/agents/product/prod.discovery-interviewer.md +3 -3
- 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 +20 -5
- package/bin/commands/qa-signoff.js +58 -55
- package/bin/commands/tokens.js +14 -17
- package/bin/commands/whoami.js +30 -26
- package/bin/jarvis.js +9 -163
- 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 +59 -2
- package/bin/lib/config/ide-config.js +4 -8
- package/bin/lib/core/profile-filter.js +4 -1
- package/bin/lib/core/scanner.js +3 -29
- package/bin/lib/core/sync-engine.js +21 -14
- package/bin/lib/core/token-report.js +12 -2
- 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/parse.js +11 -5
- package/bin/lib/flow-map/render.js +5 -2
- package/bin/lib/flow-map/tree.js +59 -10
- 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/package.json +14 -5
- package/rules/engineering/eng-rules.md +1 -1
- package/rules/engineering/eng-security-rules.md +18 -16
- 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 +6 -4
- package/rules/engineering/eng.skills-rules.md +1 -1
- package/rules/engineering/eng.specializations-rules.md +18 -4
- 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-on-demand/engineering/eng.pre-pr-rules.md +1 -1
- package/rules-on-demand/engineering/eng.start-rules.md +2 -0
- package/skills/AGENTS.md +52 -87
- package/skills/SKILLS-ROADMAP.md +47 -128
- 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-nestjs/SKILL.md +1 -1
- 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 +12 -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-task-comment/SKILL.md +3 -3
- 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 +1 -1
- package/skills/jarvis-context-detect/assets/context-profile-template.md +1 -1
- package/skills/jarvis-create-specialization/SKILL.md +8 -0
- package/skills/jarvis-docs-central/README.md +31 -28
- package/skills/jarvis-docs-central/SKILL.md +5 -5
- package/skills/jarvis-init/SKILL.md +9 -8
- package/skills/jarvis-init/assets/passo-adicionar-stacks.md +47 -18
- package/skills/jarvis-list-specializations/SKILL.md +30 -17
- package/skills/jarvis-report-issue/SKILL.md +1 -1
- package/taxonomy.md +4 -16
- package/templates/AGENTS.md +2 -0
- package/templates/ENV-template.md +20 -2
- package/templates/engineering/advisor-template.md +65 -0
- package/templates/engineering/architecture-template.md +52 -4
- package/templates/engineering/qa/qa.sprint-plan-template.md +1 -1
- package/workflows/AGENTS.md +3 -1
- package/workflows/README.md +0 -10
- package/workflows/engineering/data/data.new-pipeline.md +6 -5
- package/workflows/engineering/eng.bug-audit.md +4 -14
- package/workflows/engineering/eng.debug.md +4 -20
- package/workflows/engineering/eng.plan.md +4 -26
- package/workflows/engineering/eng.pr.md +13 -63
- package/workflows/engineering/eng.pre-pr.md +14 -51
- package/workflows/engineering/eng.review.md +7 -13
- package/workflows/engineering/eng.rpa.robot.md +3 -9
- package/workflows/engineering/eng.start.md +37 -32
- package/workflows/engineering/eng.work.md +17 -40
- package/workflows/engineering/qa/eng.qa-sprint-planning.md +1 -1
- package/workflows/product/prod.spec.discovery.md +2 -2
- package/workflows/warm-up.md +35 -63
- package/agents/engineering/eng.cybersecurity.agent.md +0 -486
- package/agents/engineering/qa/eng.qa.cypress-specialist.md +0 -112
- package/bin/lib/docs/fetch-file.sh +0 -41
- package/bin/lib/docs/publish-file.sh +0 -284
- 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 -303
- package/skills/eng-data-bi/SKILL.md +0 -206
- package/skills/eng-data-debug/SKILL.md +0 -314
- package/skills/eng-data-engineer/SKILL.md +0 -266
- package/skills/eng-data-onboard/SKILL.md +0 -317
- package/skills/eng-data-orchestrator/SKILL.md +0 -433
- package/skills/eng-devops-performance-engineer/SKILL.md +0 -319
- package/skills/eng-frontend-design-system/SKILL.md +0 -155
- package/skills/eng-frontend-design-system/references/1-estrutura-pacote.md +0 -57
- package/skills/eng-frontend-design-system/references/2-tokens.md +0 -116
- package/skills/eng-frontend-design-system/references/3-componentes.md +0 -165
- package/skills/eng-frontend-design-system/references/4-storybook.md +0 -85
- package/skills/eng-frontend-design-system/references/5-auditoria-versionamento.md +0 -76
- package/skills/eng-frontend-microfrontend/SKILL.md +0 -164
- package/skills/eng-frontend-microfrontend/references/1-criando-remote.md +0 -109
- package/skills/eng-frontend-microfrontend/references/2-configurando-shell.md +0 -70
- package/skills/eng-frontend-microfrontend/references/3-contratos-interface.md +0 -73
- package/skills/eng-frontend-microfrontend/references/4-shared-dependencies.md +0 -48
- package/skills/eng-frontend-microfrontend/references/5-event-bus.md +0 -59
- package/skills/eng-frontend-microfrontend/references/6-monorepo-deploy.md +0 -77
- package/skills/eng-frontend-microfrontend/references/7-troubleshooting.md +0 -45
- package/skills/eng-global-browser-extension-builder/SKILL.md +0 -392
- package/skills/eng-global-jira-comment/SKILL.md +0 -27
- package/skills/eng-qa-a11y-audit/SKILL.md +0 -276
- package/skills/eng-qa-bug-report/SKILL.md +0 -877
- package/skills/eng-qa-bug-report/TASK_MANAGERS.md +0 -138
- package/skills/eng-qa-bug-report/references/1-integracao-task-managers.md +0 -148
- package/skills/eng-qa-bug-report/references/2-exemplos-de-uso.md +0 -46
- package/skills/eng-qa-bug-report/references/3-bug-to-test.md +0 -45
- package/skills/eng-qa-cypress-e2e/SKILL.md +0 -184
- package/skills/eng-qa-dev-guide/SKILL.md +0 -173
- package/skills/eng-qa-e2e/SKILL.md +0 -407
- package/skills/eng-qa-e2e-spec-writer/SKILL.md +0 -329
- package/skills/eng-qa-exploratory/SKILL.md +0 -196
- package/skills/eng-qa-gate/SKILL.md +0 -377
- package/skills/eng-qa-gate/assets/checklist-validacao.md +0 -291
- package/skills/eng-qa-graphql-contract/SKILL.md +0 -263
- package/skills/eng-qa-quality-report/SKILL.md +0 -419
- package/skills/eng-qa-test-plan/SKILL.md +0 -473
- package/skills/eng-qa-testsprite/SKILL.md +0 -332
- package/skills/eng-qa-testsprite/references/testsprite-mcp.md +0 -224
- package/skills/eng-qa-unit-test/SKILL.md +0 -478
- package/skills/eng-scraper/SKILL.md +0 -260
- package/skills/eng-scraper/references/1-puppeteer.md +0 -140
- package/skills/eng-scraper/references/2-playwright-cheerio-pdf.md +0 -82
- package/skills/eng-scraper/references/3-anti-bot.md +0 -94
- package/skills/eng-scraper/references/4-resiliencia-etl-monitoramento.md +0 -137
- package/skills/eng-scraper-robot-builder/SKILL.md +0 -377
- package/skills/eng-security-cybersecurity/SKILL.md +0 -250
- package/skills/eng-security-cybersecurity/references/1-owasp-top-10.md +0 -331
- package/skills/eng-security-cybersecurity/references/2-secrets-management.md +0 -31
- package/skills/eng-security-cybersecurity/references/3-input-validation.md +0 -43
- package/skills/eng-security-cybersecurity/references/4-compliance.md +0 -20
- package/skills/eng-security-patch/SKILL.md +0 -388
- package/skills/eng-security-threat-model/SKILL.md +0 -171
- package/skills/eng-security-triage/SKILL.md +0 -276
- 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 -319
- package/workflows/engineering/eng.security-incident.md +0 -281
- package/workflows/engineering/eng.security-pipeline.md +0 -219
- package/workflows/engineering/eng.security-review.md +0 -241
- package/workflows/engineering/qa/eng.qa-dev-quality-guide.md +0 -57
- package/workflows/engineering/qa/eng.qa-e2e-test-generation.md +0 -57
- package/workflows/engineering/qa/eng.qa-exploratory-session.md +0 -68
- package/workflows/engineering/qa/eng.qa-quality-gate-validation.md +0 -209
- package/workflows/engineering/qa/eng.qa-quality-report.md +0 -85
- /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
|
@@ -48,7 +48,8 @@ function describe(node) {
|
|
|
48
48
|
export function renderTree(root) {
|
|
49
49
|
const lines = [describe(root)];
|
|
50
50
|
if (root.status === "selfContained") lines.push("└── (autocontido: não chama nenhum outro item)");
|
|
51
|
-
else if (root.status === "undeclared")
|
|
51
|
+
else if (root.status === "undeclared")
|
|
52
|
+
lines.push("└── (sem declaração de chamadas: o item não segue a tabela padronizada)");
|
|
52
53
|
|
|
53
54
|
function walk(node, prefix) {
|
|
54
55
|
node.children.forEach((child, i) => {
|
|
@@ -80,7 +81,9 @@ export function renderReverse(name, type, edges) {
|
|
|
80
81
|
const condition = summarizeCondition(e.condicao);
|
|
81
82
|
if (condition) notes.push(condition);
|
|
82
83
|
if (e.via) notes.push(`via ${e.via}`);
|
|
83
|
-
lines.push(
|
|
84
|
+
lines.push(
|
|
85
|
+
`${i === edges.length - 1 ? "└── " : "├── "}${e.from} [${TYPE_LABEL[e.type]}]${notes.length ? ` (${notes.join("; ")})` : ""}`
|
|
86
|
+
);
|
|
84
87
|
});
|
|
85
88
|
return lines;
|
|
86
89
|
}
|
package/bin/lib/flow-map/tree.js
CHANGED
|
@@ -53,7 +53,16 @@ export function forwardTree(graph, name, opts = {}) {
|
|
|
53
53
|
const expanded = new Set([name]);
|
|
54
54
|
|
|
55
55
|
function base(partial) {
|
|
56
|
-
return {
|
|
56
|
+
return {
|
|
57
|
+
passo: null,
|
|
58
|
+
condicao: "",
|
|
59
|
+
via: null,
|
|
60
|
+
marker: null,
|
|
61
|
+
available: false,
|
|
62
|
+
status: null,
|
|
63
|
+
children: [],
|
|
64
|
+
...partial,
|
|
65
|
+
};
|
|
57
66
|
}
|
|
58
67
|
|
|
59
68
|
function childrenOf(itemName, level, ancestors) {
|
|
@@ -61,12 +70,22 @@ export function forwardTree(graph, name, opts = {}) {
|
|
|
61
70
|
const children = [];
|
|
62
71
|
for (const row of d.rows) {
|
|
63
72
|
if (row.targets.length === 0) continue;
|
|
64
|
-
const grouped =
|
|
73
|
+
const grouped =
|
|
74
|
+
row.targets.filter((t) => t.kind === "internal" || t.kind === "agent").length > 1;
|
|
65
75
|
// Em menu, a condição fica no nó do menu e não se repete em cada alvo.
|
|
66
|
-
const nodes = row.targets.map((t) =>
|
|
76
|
+
const nodes = row.targets.map((t) =>
|
|
77
|
+
targetNode(t, grouped ? { ...row, condicao: "", via: null } : row, level + 1, ancestors)
|
|
78
|
+
);
|
|
67
79
|
if (grouped) {
|
|
68
80
|
children.push(
|
|
69
|
-
base({
|
|
81
|
+
base({
|
|
82
|
+
name: `menu (${nodes.length} opções)`,
|
|
83
|
+
kind: "menu",
|
|
84
|
+
passo: row.passo,
|
|
85
|
+
condicao: row.condicao,
|
|
86
|
+
via: row.via,
|
|
87
|
+
children: nodes,
|
|
88
|
+
})
|
|
70
89
|
);
|
|
71
90
|
} else {
|
|
72
91
|
children.push(...nodes);
|
|
@@ -76,13 +95,25 @@ export function forwardTree(graph, name, opts = {}) {
|
|
|
76
95
|
}
|
|
77
96
|
|
|
78
97
|
function targetNode(target, row, level, ancestors) {
|
|
79
|
-
const common = {
|
|
98
|
+
const common = {
|
|
99
|
+
passo: row.passo,
|
|
100
|
+
condicao: row.condicao,
|
|
101
|
+
via: row.via,
|
|
102
|
+
marker: row.marker,
|
|
103
|
+
available: row.available,
|
|
104
|
+
};
|
|
80
105
|
|
|
81
106
|
if (["cli", "mcp", "external", "unresolved"].includes(target.kind)) {
|
|
82
107
|
return base({ name: target.name, kind: target.kind, ...common });
|
|
83
108
|
}
|
|
84
109
|
const item = graph.items.get(target.name);
|
|
85
|
-
if (!item)
|
|
110
|
+
if (!item)
|
|
111
|
+
return base({
|
|
112
|
+
name: target.name,
|
|
113
|
+
kind: "broken",
|
|
114
|
+
...common,
|
|
115
|
+
marker: row.marker ?? "quebrada",
|
|
116
|
+
});
|
|
86
117
|
|
|
87
118
|
const node = base({ name: item.name, kind: item.type, ...common });
|
|
88
119
|
if (ancestors.has(item.name)) node.status = "cycle";
|
|
@@ -132,7 +163,14 @@ export function suggest(items, name) {
|
|
|
132
163
|
return [...items.keys()]
|
|
133
164
|
.map((candidate) => {
|
|
134
165
|
const c = candidate.toLowerCase();
|
|
135
|
-
const score =
|
|
166
|
+
const score =
|
|
167
|
+
c.startsWith(lower) || lower.startsWith(c)
|
|
168
|
+
? 0
|
|
169
|
+
: c.includes(lower) || lower.includes(c)
|
|
170
|
+
? 1
|
|
171
|
+
: levenshtein(lower, c) <= Math.max(1, Math.floor(Math.min(lower.length, c.length) / 4))
|
|
172
|
+
? 2
|
|
173
|
+
: null;
|
|
136
174
|
return { candidate, score };
|
|
137
175
|
})
|
|
138
176
|
.filter((s) => s.score !== null)
|
|
@@ -152,7 +190,9 @@ export function reverseEdges(graph, name) {
|
|
|
152
190
|
for (const [from, d] of graph.decl) {
|
|
153
191
|
if (from === name) continue;
|
|
154
192
|
for (const row of d.rows) {
|
|
155
|
-
if (
|
|
193
|
+
if (
|
|
194
|
+
row.targets.some((t) => (t.kind === "internal" || t.kind === "agent") && t.name === name)
|
|
195
|
+
) {
|
|
156
196
|
edges.push({
|
|
157
197
|
from,
|
|
158
198
|
type: graph.items.get(from).type,
|
|
@@ -186,7 +226,12 @@ export function findBrokenReferences(graph) {
|
|
|
186
226
|
warnings.push({ file, name: t.name, reason: `referência ${row.marker}` });
|
|
187
227
|
} else if ((t.kind === "internal" || t.kind === "agent") && !graph.items.has(t.name)) {
|
|
188
228
|
if (row.marker) warnings.push({ file, name: t.name, reason: `referência ${row.marker}` });
|
|
189
|
-
else
|
|
229
|
+
else
|
|
230
|
+
errors.push({
|
|
231
|
+
file,
|
|
232
|
+
name: t.name,
|
|
233
|
+
reason: "não existe como workflow, skill ou agente",
|
|
234
|
+
});
|
|
190
235
|
}
|
|
191
236
|
}
|
|
192
237
|
}
|
|
@@ -195,5 +240,9 @@ export function findBrokenReferences(graph) {
|
|
|
195
240
|
}
|
|
196
241
|
|
|
197
242
|
function duplicatesOf(graph) {
|
|
198
|
-
return graph.duplicates.map((name) => ({
|
|
243
|
+
return graph.duplicates.map((name) => ({
|
|
244
|
+
file: name,
|
|
245
|
+
name,
|
|
246
|
+
reason: "nome repetido entre os artefatos",
|
|
247
|
+
}));
|
|
199
248
|
}
|
package/bin/lib/tasks/comment.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
1
2
|
import { cardUrl } from "../vcs/api.js";
|
|
2
3
|
|
|
3
4
|
function env(name) {
|
|
@@ -13,9 +14,7 @@ async function commentJira(cardKey, message) {
|
|
|
13
14
|
const token = env("TOKEN_TASK_MANAGER");
|
|
14
15
|
const email = env("USER");
|
|
15
16
|
if (!base || !token) {
|
|
16
|
-
throw new Error(
|
|
17
|
-
"Jira: preencha TASK_MANAGER_URL_BASE e TOKEN_TASK_MANAGER no ENV.md",
|
|
18
|
-
);
|
|
17
|
+
throw new Error("Jira: preencha TASK_MANAGER_URL_BASE e TOKEN_TASK_MANAGER no ENV.md");
|
|
19
18
|
}
|
|
20
19
|
const auth = email
|
|
21
20
|
? `Basic ${Buffer.from(`${email}:${token}`).toString("base64")}`
|
|
@@ -68,28 +67,24 @@ async function commentLinear(cardKey, message) {
|
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
async function commentGithub(cardKey, message) {
|
|
71
|
-
const token =
|
|
72
|
-
env("TOKEN_TASK_MANAGER") || env("GITHUB_TOKEN") || env("GH_TOKEN");
|
|
70
|
+
const token = env("TOKEN_TASK_MANAGER") || env("GITHUB_TOKEN") || env("GH_TOKEN");
|
|
73
71
|
const base = env("TASK_MANAGER_URL_BASE").replace(/\/$/, "");
|
|
74
72
|
if (!token || !base) {
|
|
75
73
|
throw new Error(
|
|
76
|
-
"GitHub Issues: TASK_MANAGER_URL_BASE (https://github.com/org/repo) e TOKEN_TASK_MANAGER/GITHUB_TOKEN"
|
|
74
|
+
"GitHub Issues: TASK_MANAGER_URL_BASE (https://github.com/org/repo) e TOKEN_TASK_MANAGER/GITHUB_TOKEN"
|
|
77
75
|
);
|
|
78
76
|
}
|
|
79
77
|
const path = new URL(base).pathname.replace(/^\/+|\/+$/g, "");
|
|
80
78
|
const number = String(cardKey).replace(/^#/, "");
|
|
81
|
-
const res = await fetch(
|
|
82
|
-
|
|
83
|
-
{
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Accept: "application/vnd.github+json",
|
|
88
|
-
"Content-Type": "application/json",
|
|
89
|
-
},
|
|
90
|
-
body: JSON.stringify({ body: message }),
|
|
79
|
+
const res = await fetch(`https://api.github.com/repos/${path}/issues/${number}/comments`, {
|
|
80
|
+
method: "POST",
|
|
81
|
+
headers: {
|
|
82
|
+
Authorization: `Bearer ${token}`,
|
|
83
|
+
Accept: "application/vnd.github+json",
|
|
84
|
+
"Content-Type": "application/json",
|
|
91
85
|
},
|
|
92
|
-
|
|
86
|
+
body: JSON.stringify({ body: message }),
|
|
87
|
+
});
|
|
93
88
|
if (!res.ok) throw new Error(`GitHub ${res.status}: ${await res.text()}`);
|
|
94
89
|
}
|
|
95
90
|
|
|
@@ -107,25 +102,35 @@ async function commentAsana(cardKey, message) {
|
|
|
107
102
|
if (!res.ok) throw new Error(`Asana ${res.status}: ${await res.text()}`);
|
|
108
103
|
}
|
|
109
104
|
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Comenta num card do task manager configurado em TASK_MANAGER (jira/linear/github/asana).
|
|
107
|
+
* Usada por `jarvis tasks comment` e pelo skill `eng-global-task-comment`.
|
|
108
|
+
* @param {string} cardKey - Chave/ID do card (ex: `TASK-123`, ou número de issue no GitHub)
|
|
109
|
+
* @param {string} message - Texto do comentário
|
|
110
|
+
*/
|
|
111
|
+
export async function runComment(cardKey, message) {
|
|
112
|
+
if (!cardKey || !message) {
|
|
113
|
+
console.error("Uso: jarvis tasks comment <TASK_MANAGER_KEY> <mensagem>");
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const tm = taskManager();
|
|
118
|
+
try {
|
|
119
|
+
if (tm === "linear") await commentLinear(cardKey, message);
|
|
120
|
+
else if (tm === "github") await commentGithub(cardKey, message);
|
|
121
|
+
else if (tm === "asana") await commentAsana(cardKey, message);
|
|
122
|
+
else await commentJira(cardKey, message);
|
|
112
123
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
124
|
+
const url = cardUrl(tm, env("TASK_MANAGER_URL_BASE"), cardKey);
|
|
125
|
+
console.log(`💬 Comentário adicionado em ${cardKey} (${tm})`);
|
|
126
|
+
if (url !== cardKey) console.log(` ${url}`);
|
|
127
|
+
} catch (err) {
|
|
128
|
+
console.error(`⚠️ Não foi possível comentar no card ${cardKey}: ${err.message}`);
|
|
129
|
+
process.exit(2);
|
|
130
|
+
}
|
|
116
131
|
}
|
|
117
132
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
else if (tm === "github") await commentGithub(cardKey, message);
|
|
122
|
-
else if (tm === "asana") await commentAsana(cardKey, message);
|
|
123
|
-
else await commentJira(cardKey, message);
|
|
124
|
-
|
|
125
|
-
const url = cardUrl(tm, env("TASK_MANAGER_URL_BASE"), cardKey);
|
|
126
|
-
console.log(`💬 Comentário adicionado em ${cardKey} (${tm})`);
|
|
127
|
-
if (url !== cardKey) console.log(` ${url}`);
|
|
128
|
-
} catch (err) {
|
|
129
|
-
console.error(`⚠️ Não foi possível comentar no card ${cardKey}: ${err.message}`);
|
|
130
|
-
process.exit(2);
|
|
133
|
+
// Compatibilidade: continua funcionando como `node bin/lib/tasks/comment.js <key> <mensagem>`
|
|
134
|
+
if (fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
135
|
+
await runComment(process.argv[2], process.argv.slice(3).join(" "));
|
|
131
136
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Leitura de frontmatter YAML (`---\n...\n---`) compartilhada
|
|
3
|
+
* entre scanner.js, validate-frontmatter.js, qa-signoff.js e sync-engine.js —
|
|
4
|
+
* cada um tinha sua própria cópia da mesma regex de bloco.
|
|
5
|
+
* @module utils/frontmatter
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const BLOCK_PATTERN = /^---\s*\n([\s\S]*?)\n---/;
|
|
9
|
+
|
|
10
|
+
// Exige a chave começando na coluna 0 (sem indentação) — por design, não
|
|
11
|
+
// desce em blocos aninhados (ex: `metadata:\n area: x`). As 4 implementações
|
|
12
|
+
// que este módulo substitui já assumiam isso (`^\w`, sem flag multiline por
|
|
13
|
+
// linha); manter a mesma regra evita "vazar" uma chave aninhada como se fosse
|
|
14
|
+
// de nível raiz.
|
|
15
|
+
// Unicode-aware (`u` flag) para aceitar chaves acentuadas, como "Versão" e
|
|
16
|
+
// "Autor" usadas no frontmatter de ARD/RFC.
|
|
17
|
+
const KEY_VALUE_PATTERN = /^([\p{L}\p{N}_][\p{L}\p{N}_-]*):\s*(.+)$/u;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Extrai o conteúdo bruto entre as cercas `---` do frontmatter.
|
|
21
|
+
* @param {string} content - Conteúdo completo do arquivo
|
|
22
|
+
* @returns {string | null} O bloco (sem as cercas), ou null se não houver frontmatter
|
|
23
|
+
*/
|
|
24
|
+
export function extractFrontmatterBlock(content) {
|
|
25
|
+
const match = content.match(BLOCK_PATTERN);
|
|
26
|
+
return match ? match[1] : null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Parseia um bloco de frontmatter YAML simples (`chave: valor`, uma por linha,
|
|
31
|
+
* sem indentação). Não suporta estruturas aninhadas, listas ou blocos
|
|
32
|
+
* multilinha (`>`/`|`) — para isso, veja `sync-engine.js#parseSkillFrontmatter`,
|
|
33
|
+
* que extrai campos específicos com necessidades diferentes.
|
|
34
|
+
* @param {string} content - Conteúdo completo do arquivo (com ou sem frontmatter)
|
|
35
|
+
* @returns {Record<string, string>} Metadados; `{}` se não houver frontmatter
|
|
36
|
+
*/
|
|
37
|
+
export function parseFrontmatter(content) {
|
|
38
|
+
const block = extractFrontmatterBlock(content);
|
|
39
|
+
if (block === null) return {};
|
|
40
|
+
|
|
41
|
+
const metadata = {};
|
|
42
|
+
for (const line of block.split("\n")) {
|
|
43
|
+
const kv = line.match(KEY_VALUE_PATTERN);
|
|
44
|
+
if (!kv) continue;
|
|
45
|
+
|
|
46
|
+
let value = kv[2].trim();
|
|
47
|
+
if (
|
|
48
|
+
(value.startsWith('"') && value.endsWith('"')) ||
|
|
49
|
+
(value.startsWith("'") && value.endsWith("'"))
|
|
50
|
+
) {
|
|
51
|
+
value = value.slice(1, -1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
metadata[kv[1]] = value;
|
|
55
|
+
}
|
|
56
|
+
return metadata;
|
|
57
|
+
}
|
|
@@ -67,7 +67,7 @@ export function parseRepoUrl(url) {
|
|
|
67
67
|
} catch {
|
|
68
68
|
throw new Error(
|
|
69
69
|
`URL inválida: ${url}\n` +
|
|
70
|
-
"Formatos: https://github.com/org/repo.git | https://gitlab.com/grupo/repo.git | https://bitbucket.org/ws/repo.git"
|
|
70
|
+
"Formatos: https://github.com/org/repo.git | https://gitlab.com/grupo/repo.git | https://bitbucket.org/ws/repo.git"
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -82,7 +82,7 @@ export function parseRepoUrl(url) {
|
|
|
82
82
|
if (!vendor) {
|
|
83
83
|
throw new Error(
|
|
84
84
|
`Não foi possível detectar o vendor de ${host}.\n` +
|
|
85
|
-
"Defina VERSION_CONTROL=gitlab|github|bitbucket no ENV.md."
|
|
85
|
+
"Defina VERSION_CONTROL=gitlab|github|bitbucket no ENV.md."
|
|
86
86
|
);
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -108,16 +108,14 @@ export function parseGitLabUrl(url) {
|
|
|
108
108
|
const parsed = parseRepoUrl(url);
|
|
109
109
|
if (parsed.vendor !== "gitlab") {
|
|
110
110
|
throw new Error(
|
|
111
|
-
`URL não é GitLab (${parsed.vendor}): ${url}\n` +
|
|
112
|
-
"Use parseRepoUrl() para GitHub/Bitbucket.",
|
|
111
|
+
`URL não é GitLab (${parsed.vendor}): ${url}\n` + "Use parseRepoUrl() para GitHub/Bitbucket."
|
|
113
112
|
);
|
|
114
113
|
}
|
|
115
114
|
return parsed;
|
|
116
115
|
}
|
|
117
116
|
|
|
118
117
|
export function buildApiUrl(repoUrl, endpoint) {
|
|
119
|
-
const { vendor, apiBase, projectPathEncoded, owner, repo } =
|
|
120
|
-
parseRepoUrl(repoUrl);
|
|
118
|
+
const { vendor, apiBase, projectPathEncoded, owner, repo } = parseRepoUrl(repoUrl);
|
|
121
119
|
if (vendor === "gitlab") {
|
|
122
120
|
return `${apiBase}/projects/${projectPathEncoded}/${endpoint}`;
|
|
123
121
|
}
|
|
@@ -5,9 +5,7 @@ import { execSync } from "node:child_process";
|
|
|
5
5
|
|
|
6
6
|
function readNpmrcToken(hostFragment, cwd = process.cwd()) {
|
|
7
7
|
const paths = [join(cwd, ".npmrc"), join(homedir(), ".npmrc")];
|
|
8
|
-
const re = new RegExp(
|
|
9
|
-
`//[^\\s]*${hostFragment.replace(".", "\\.")}[^\\s]*:_authToken=([^\\s]+)`,
|
|
10
|
-
);
|
|
8
|
+
const re = new RegExp(`//[^\\s]*${hostFragment.replace(".", "\\.")}[^\\s]*:_authToken=([^\\s]+)`);
|
|
11
9
|
|
|
12
10
|
for (const path of paths) {
|
|
13
11
|
if (!existsSync(path)) continue;
|
|
@@ -54,31 +52,26 @@ export function getVcsToken(vendor, cwd = process.cwd()) {
|
|
|
54
52
|
if (token) return token;
|
|
55
53
|
throw new Error(
|
|
56
54
|
"Token GitHub não encontrado.\n" +
|
|
57
|
-
"Use `gh auth login`, ou defina GITHUB_TOKEN, ou //npm.pkg.github.com/:_authToken= no .npmrc."
|
|
55
|
+
"Use `gh auth login`, ou defina GITHUB_TOKEN, ou //npm.pkg.github.com/:_authToken= no .npmrc."
|
|
58
56
|
);
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
if (v === "bitbucket") {
|
|
62
|
-
const token =
|
|
63
|
-
process.env.BITBUCKET_TOKEN ||
|
|
64
|
-
readNpmrcToken("bitbucket.org", cwd);
|
|
60
|
+
const token = process.env.BITBUCKET_TOKEN || readNpmrcToken("bitbucket.org", cwd);
|
|
65
61
|
if (token) return token;
|
|
66
62
|
throw new Error(
|
|
67
|
-
"Token Bitbucket não encontrado.\n" +
|
|
68
|
-
"Defina BITBUCKET_TOKEN (App Password) no ambiente.",
|
|
63
|
+
"Token Bitbucket não encontrado.\n" + "Defina BITBUCKET_TOKEN (App Password) no ambiente."
|
|
69
64
|
);
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
const token =
|
|
73
|
-
process.env.GITLAB_TOKEN ||
|
|
74
|
-
readNpmrcToken("gitlab.com", cwd) ||
|
|
75
|
-
readNpmrcToken("gitlab", cwd);
|
|
68
|
+
process.env.GITLAB_TOKEN || readNpmrcToken("gitlab.com", cwd) || readNpmrcToken("gitlab", cwd);
|
|
76
69
|
if (token) return token;
|
|
77
70
|
throw new Error(
|
|
78
71
|
"Token GitLab não encontrado no .npmrc\n" +
|
|
79
72
|
"Configure:\n" +
|
|
80
73
|
" //gitlab.com/api/v4/packages/npm/:_authToken=seu-token\n" +
|
|
81
|
-
"Ou GITLAB_TOKEN no ambiente."
|
|
74
|
+
"Ou GITLAB_TOKEN no ambiente."
|
|
82
75
|
);
|
|
83
76
|
}
|
|
84
77
|
|
package/bin/lib/utils/paths.js
CHANGED
|
@@ -18,8 +18,7 @@ export function getFrameworkRoot() {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
throw new Error(
|
|
21
|
-
"Could not locate framework assets.\n" +
|
|
22
|
-
"Run: npm install jarvis-framework --save-dev",
|
|
21
|
+
"Could not locate framework assets.\n" + "Run: npm install jarvis-framework --save-dev"
|
|
23
22
|
);
|
|
24
23
|
}
|
|
25
24
|
|
|
@@ -48,8 +47,7 @@ export function detectIDE(cwd) {
|
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
export function detectAllIDEs(cwd) {
|
|
51
|
-
return IDES
|
|
52
|
-
.filter((ide) => ide.supported)
|
|
50
|
+
return IDES.filter((ide) => ide.supported)
|
|
53
51
|
.filter((ide) => existsSync(join(cwd, `.${ide.folderName || ide.value}`)))
|
|
54
52
|
.map((ide) => ide.value);
|
|
55
53
|
}
|
package/bin/lib/utils/ui.js
CHANGED
|
@@ -35,21 +35,15 @@ export function showBanner() {
|
|
|
35
35
|
console.log("");
|
|
36
36
|
console.log(" ──────── J . A . R . V . I . S ────────");
|
|
37
37
|
console.log(NC);
|
|
38
|
-
console.log(
|
|
39
|
-
`${DIM}Framework Jarvis para desenvolvimento assistido por IA${NC}`,
|
|
40
|
-
);
|
|
38
|
+
console.log(`${DIM}Framework Jarvis para desenvolvimento assistido por IA${NC}`);
|
|
41
39
|
|
|
42
40
|
try {
|
|
43
41
|
const pkg = getPackageInfo();
|
|
44
42
|
console.log("");
|
|
45
|
-
console.log(
|
|
46
|
-
`${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`,
|
|
47
|
-
);
|
|
43
|
+
console.log(`${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`);
|
|
48
44
|
console.log(`${BOLD}${CYAN} ${pkg.name} v${pkg.version}${NC}`);
|
|
49
45
|
console.log(`${DIM} origem: ${pkg.root}${NC}`);
|
|
50
|
-
console.log(
|
|
51
|
-
`${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`,
|
|
52
|
-
);
|
|
46
|
+
console.log(`${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`);
|
|
53
47
|
} catch {
|
|
54
48
|
// banner sem versão se assets não forem encontrados
|
|
55
49
|
}
|
package/bin/lib/vcs/api.js
CHANGED
|
@@ -89,12 +89,10 @@ export async function createMergeRequest(repoUrl, opts) {
|
|
|
89
89
|
description,
|
|
90
90
|
remove_source_branch: true,
|
|
91
91
|
},
|
|
92
|
-
}
|
|
92
|
+
}
|
|
93
93
|
);
|
|
94
94
|
if (!ok || !json?.web_url) {
|
|
95
|
-
throw new Error(
|
|
96
|
-
`Falha ao criar MR GitLab (${status}): ${JSON.stringify(json)}`,
|
|
97
|
-
);
|
|
95
|
+
throw new Error(`Falha ao criar MR GitLab (${status}): ${JSON.stringify(json)}`);
|
|
98
96
|
}
|
|
99
97
|
return { vendor: "gitlab", iid: json.iid, url: json.web_url };
|
|
100
98
|
}
|
|
@@ -111,12 +109,10 @@ export async function createMergeRequest(repoUrl, opts) {
|
|
|
111
109
|
base: target,
|
|
112
110
|
body: description,
|
|
113
111
|
},
|
|
114
|
-
}
|
|
112
|
+
}
|
|
115
113
|
);
|
|
116
114
|
if (!ok || !json?.html_url) {
|
|
117
|
-
throw new Error(
|
|
118
|
-
`Falha ao criar PR GitHub (${status}): ${JSON.stringify(json)}`,
|
|
119
|
-
);
|
|
115
|
+
throw new Error(`Falha ao criar PR GitHub (${status}): ${JSON.stringify(json)}`);
|
|
120
116
|
}
|
|
121
117
|
return { vendor: "github", iid: json.number, url: json.html_url };
|
|
122
118
|
}
|
|
@@ -133,12 +129,10 @@ export async function createMergeRequest(repoUrl, opts) {
|
|
|
133
129
|
destination: { branch: { name: target } },
|
|
134
130
|
close_source_branch: true,
|
|
135
131
|
},
|
|
136
|
-
}
|
|
132
|
+
}
|
|
137
133
|
);
|
|
138
134
|
if (!ok || !json?.links?.html?.href) {
|
|
139
|
-
throw new Error(
|
|
140
|
-
`Falha ao criar PR Bitbucket (${status}): ${JSON.stringify(json)}`,
|
|
141
|
-
);
|
|
135
|
+
throw new Error(`Falha ao criar PR Bitbucket (${status}): ${JSON.stringify(json)}`);
|
|
142
136
|
}
|
|
143
137
|
return {
|
|
144
138
|
vendor: "bitbucket",
|
|
@@ -174,12 +168,10 @@ export async function commitFiles(repoUrl, opts) {
|
|
|
174
168
|
encoding: "base64",
|
|
175
169
|
})),
|
|
176
170
|
},
|
|
177
|
-
}
|
|
171
|
+
}
|
|
178
172
|
);
|
|
179
173
|
if (!ok || !json?.id) {
|
|
180
|
-
throw new Error(
|
|
181
|
-
`Falha no commit GitLab (${status}): ${JSON.stringify(json)}`,
|
|
182
|
-
);
|
|
174
|
+
throw new Error(`Falha no commit GitLab (${status}): ${JSON.stringify(json)}`);
|
|
183
175
|
}
|
|
184
176
|
return { sha: json.id };
|
|
185
177
|
}
|
|
@@ -187,22 +179,17 @@ export async function commitFiles(repoUrl, opts) {
|
|
|
187
179
|
if (repo.vendor === "github") {
|
|
188
180
|
const refRes = await request(
|
|
189
181
|
`${repo.apiBase}/repos/${repo.owner}/${repo.repo}/git/ref/heads/${startBranch}`,
|
|
190
|
-
{ headers }
|
|
182
|
+
{ headers }
|
|
191
183
|
);
|
|
192
184
|
if (!refRes.ok) {
|
|
193
|
-
throw new Error(
|
|
194
|
-
`Branch ${startBranch} não encontrada no GitHub (${refRes.status})`,
|
|
195
|
-
);
|
|
185
|
+
throw new Error(`Branch ${startBranch} não encontrada no GitHub (${refRes.status})`);
|
|
196
186
|
}
|
|
197
187
|
const sha = refRes.json.object.sha;
|
|
198
|
-
await request(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
body: { ref: `refs/heads/${branch}`, sha },
|
|
204
|
-
},
|
|
205
|
-
);
|
|
188
|
+
await request(`${repo.apiBase}/repos/${repo.owner}/${repo.repo}/git/refs`, {
|
|
189
|
+
method: "POST",
|
|
190
|
+
headers,
|
|
191
|
+
body: { ref: `refs/heads/${branch}`, sha },
|
|
192
|
+
});
|
|
206
193
|
let lastSha = sha;
|
|
207
194
|
for (const file of files) {
|
|
208
195
|
const put = await request(
|
|
@@ -215,11 +202,11 @@ export async function commitFiles(repoUrl, opts) {
|
|
|
215
202
|
content: file.contentBase64,
|
|
216
203
|
branch,
|
|
217
204
|
},
|
|
218
|
-
}
|
|
205
|
+
}
|
|
219
206
|
);
|
|
220
207
|
if (!put.ok) {
|
|
221
208
|
throw new Error(
|
|
222
|
-
`Falha ao escrever ${file.path} no GitHub (${put.status}): ${JSON.stringify(put.json)}
|
|
209
|
+
`Falha ao escrever ${file.path} no GitHub (${put.status}): ${JSON.stringify(put.json)}`
|
|
223
210
|
);
|
|
224
211
|
}
|
|
225
212
|
lastSha = put.json.commit?.sha || lastSha;
|
|
@@ -235,14 +222,11 @@ export async function commitFiles(repoUrl, opts) {
|
|
|
235
222
|
const buf = Buffer.from(file.contentBase64, "base64");
|
|
236
223
|
form.set(file.path, new Blob([buf]));
|
|
237
224
|
}
|
|
238
|
-
const res = await fetch(
|
|
239
|
-
|
|
240
|
-
{
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
body: form,
|
|
244
|
-
},
|
|
245
|
-
);
|
|
225
|
+
const res = await fetch(`${repo.apiBase}/repositories/${repo.owner}/${repo.repo}/src`, {
|
|
226
|
+
method: "POST",
|
|
227
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
228
|
+
body: form,
|
|
229
|
+
});
|
|
246
230
|
if (!res.ok) {
|
|
247
231
|
throw new Error(`Falha no commit Bitbucket (${res.status}): ${await res.text()}`);
|
|
248
232
|
}
|
|
@@ -262,7 +246,7 @@ export async function createIssue(repoUrl, opts) {
|
|
|
262
246
|
method: "POST",
|
|
263
247
|
headers,
|
|
264
248
|
body: { title, description: body, labels: labels.join(",") },
|
|
265
|
-
}
|
|
249
|
+
}
|
|
266
250
|
);
|
|
267
251
|
if (!ok || !json?.web_url) {
|
|
268
252
|
throw new Error(`Issue GitLab (${status}): ${JSON.stringify(json)}`);
|
|
@@ -277,7 +261,7 @@ export async function createIssue(repoUrl, opts) {
|
|
|
277
261
|
method: "POST",
|
|
278
262
|
headers,
|
|
279
263
|
body: { title, body, labels },
|
|
280
|
-
}
|
|
264
|
+
}
|
|
281
265
|
);
|
|
282
266
|
if (!ok || !json?.html_url) {
|
|
283
267
|
throw new Error(`Issue GitHub (${status}): ${JSON.stringify(json)}`);
|
|
@@ -291,7 +275,7 @@ export async function createIssue(repoUrl, opts) {
|
|
|
291
275
|
method: "POST",
|
|
292
276
|
headers,
|
|
293
277
|
body: { title, content: { raw: body } },
|
|
294
|
-
}
|
|
278
|
+
}
|
|
295
279
|
);
|
|
296
280
|
if (!ok || !json?.links?.html?.href) {
|
|
297
281
|
throw new Error(`Issue Bitbucket (${status}): ${JSON.stringify(json)}`);
|