jarvis-ai-framework 6.1.0 → 8.1.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 +6 -6
- package/README.md +9 -34
- package/agents/engineering/data/eng.data-engineer.agent.md +3 -3
- package/agents/engineering/eng.docs-consolidator.agent.md +3 -3
- package/agents/engineering/qa/eng.qa.quality-champion-task-agent.md +2 -2
- package/agents/engineering/qa/eng.qa.test-planner.md +2 -2
- package/bin/README.md +13 -10
- package/bin/commands/docs-publish.js +1 -1
- package/bin/commands/init.js +159 -13
- package/bin/lib/cli/program.js +26 -15
- package/bin/lib/config/ide-config.js +56 -0
- package/bin/lib/core/docs-migrate.js +17 -5
- package/bin/lib/core/env-upgrade.js +56 -10
- package/bin/lib/core/mcp-config.js +197 -0
- package/bin/lib/core/sync-engine.js +1 -1
- package/bin/lib/core/workspace-mode.js +13 -2
- package/bin/lib/docs/fetch-file.js +4 -1
- package/bin/lib/docs/storage/filesystem.js +31 -8
- package/bin/lib/integrations/cli-runner.js +412 -0
- package/bin/lib/integrations/vendors.json +243 -0
- package/bin/lib/tasks/comment.js +133 -109
- package/bin/lib/utils/frontmatter.js +1 -1
- package/bin/lib/utils/git-parser.js +36 -56
- package/bin/lib/utils/paths.js +2 -1
- package/bin/lib/utils/version.js +65 -0
- package/bin/lib/vcs/api.js +102 -158
- package/bin/lib/vcs/create-issue.js +33 -26
- package/bin/lib/vcs/create-merge.js +64 -15
- package/bin/postinstall.js +7 -31
- package/package.json +4 -3
- package/rules/AGENTS.md +3 -2
- package/rules/engineering/data/data-rules.md +2 -2
- package/rules/engineering/eng-rules.md +3 -2
- package/rules/engineering/eng-security-rules.md +1 -1
- package/rules/engineering/eng.integrations-rules.md +26 -23
- package/rules/rtk-rules.md +1 -1
- package/rules-on-demand/doc-links-rules.md +103 -0
- package/rules-on-demand/engineering/eng.breakdown-subtasks-rules.md +1 -1
- package/rules-on-demand/engineering/eng.pr-rules.md +8 -6
- package/rules-on-demand/engineering/eng.pre-pr-rules.md +3 -1
- package/rules-on-demand/engineering/eng.start-rules.md +1 -1
- package/rules-on-demand/engineering/eng.tech-spec-rules.md +9 -7
- package/rules-on-demand/engineering/eng.transitions-rules.md +3 -3
- package/skills/AGENTS.md +6 -6
- package/skills/SKILLS-ROADMAP.md +2 -2
- package/skills/eng-backend-arch-c4/assets/example-container.md +4 -4
- package/skills/eng-backend-arch-c4/assets/example-context.md +6 -6
- package/skills/eng-backend-microservices-trace/SKILL.md +8 -9
- package/skills/eng-global-investigation/SKILL.md +4 -0
- package/skills/eng-global-investigation/references/caso-investigar.md +1 -1
- package/skills/eng-global-pr/SKILL.md +16 -13
- package/skills/eng-global-task-comment/SKILL.md +74 -27
- package/skills/eng-global-tech-spec/references/delivery-spec.md +28 -21
- package/skills/jarvis-docs-central/README.md +6 -9
- package/skills/jarvis-docs-central/SKILL.md +7 -4
- package/skills/jarvis-init/SKILL.md +132 -97
- package/skills/jarvis-init/assets/mcp-configs.md +57 -75
- package/skills/jarvis-init/assets/onboarding-checklist.md +6 -6
- package/skills/jarvis-init/assets/setup-guide.md +46 -23
- package/skills/jarvis-report-issue/SKILL.md +68 -19
- package/skills/product-roadmap-report/SKILL.md +2 -2
- package/skills/product-roadmap-report/commands/status.memory.md +1 -1
- package/skills/product-roadmap-report/commands/status.roadmap.preview.md +2 -2
- package/skills/product-specs/SKILL.md +1 -1
- package/templates/ENV-template.md +32 -26
- package/templates/cdd-aplicado-a-prompts.md +1 -1
- package/templates/cdd-mind-map-template.md +1 -1
- package/templates/engineering/AGENTS-template.md +2 -2
- package/templates/engineering/ARD-template.md +2 -2
- package/templates/engineering/CONTACTS-template.md +1 -1
- package/templates/engineering/PR-template.md +6 -2
- package/templates/engineering/advisor-template.md +2 -2
- package/templates/engineering/architecture-template.md +14 -8
- package/templates/engineering/data-contract-template.md +1 -1
- package/templates/engineering/plan-template.md +4 -2
- package/templates/engineering/tech-spec-delivery-template.md +8 -8
- package/templates/engineering/tech-spec-template.md +12 -12
- package/templates/product/prod-frd-template.md +22 -20
- package/templates/product/prod-prd-template.md +33 -31
- package/workflows/AGENTS.md +1 -1
- package/workflows/README.md +1 -1
- package/workflows/engineering/data/data.contract.md +12 -8
- package/workflows/engineering/eng.breakdown-subtasks.md +4 -2
- package/workflows/engineering/eng.build-tech-spec.md +3 -1
- package/workflows/engineering/eng.create-ard-from-code.md +5 -5
- package/workflows/engineering/eng.create-ard.md +5 -5
- package/workflows/engineering/eng.create-rfc.md +7 -5
- package/workflows/engineering/eng.debug.md +3 -1
- package/workflows/engineering/eng.docs.md +3 -1
- package/workflows/engineering/eng.light-arch.md +3 -1
- package/workflows/engineering/eng.plan.md +4 -2
- package/workflows/engineering/eng.pr.md +46 -37
- package/workflows/engineering/eng.pre-pr.md +50 -13
- package/workflows/engineering/eng.review.md +2 -0
- package/workflows/engineering/eng.rpa.robot.md +3 -0
- package/workflows/engineering/eng.spec-consolidate.md +6 -4
- package/workflows/engineering/eng.start.md +15 -9
- package/workflows/engineering/eng.work.md +6 -4
- package/workflows/engineering/qa/eng.qa-refinement-entry.md +3 -3
- package/workflows/engineering/qa/eng.qa-release-signoff.md +1 -66
- package/workflows/product/prod.roadmap.preview.md +10 -14
- package/workflows/product/prod.spec.ard.md +4 -2
- package/workflows/product/prod.spec.breakdown.md +4 -2
- package/workflows/product/prod.spec.clarify.md +2 -0
- package/workflows/product/prod.spec.discovery.md +2 -0
- package/workflows/product/prod.spec.epic.md +6 -4
- package/workflows/product/prod.spec.frd.md +5 -3
- package/workflows/product/prod.spec.issue.md +5 -3
- package/workflows/product/prod.spec.prd.md +7 -5
- package/workflows/warm-up.md +1 -1
- package/bin/commands/qa-signoff.js +0 -115
- package/bin/lib/utils/npmrc-parser.js +0 -99
package/AGENTS.md
CHANGED
|
@@ -62,8 +62,8 @@ prompts/
|
|
|
62
62
|
│ │ ├── product-specs-update/
|
|
63
63
|
│ │ ├── eng-qa/ # Base neutra de QA (+ especializações em QA_SPECIALIZATIONS)
|
|
64
64
|
│ │ ├── eng-qa-planner/ # Planejamento de testes e análise de gaps de cobertura
|
|
65
|
-
│ │ ├── jarvis-report-issue/ # Auto-report de bugs no repo do Jarvis (
|
|
66
|
-
│ │ ├── eng-global-task-comment/ # Comentário no card (Jira/
|
|
65
|
+
│ │ ├── jarvis-report-issue/ # Auto-report de bugs no repo do Jarvis (CLI do host: gh)
|
|
66
|
+
│ │ ├── eng-global-task-comment/ # Comentário no card (Jira/GitHub/GitLab, pela CLI do vendor)
|
|
67
67
|
│ │ ├── jarvis-list-specializations/ # Lista especializações de stack instaladas e registradas
|
|
68
68
|
│ │ ├── jarvis-create-specialization/ # Cria uma especialização de stack a partir do código do projeto e a registra
|
|
69
69
|
│ │ ├── jarvis-evolution-architect/ # Mentor de arquitetura para a evolução do Jarvis
|
|
@@ -78,7 +78,7 @@ prompts/
|
|
|
78
78
|
│ │ │ └── frontend/ # eng.frontend-rules.md (HUB: FRONTEND)
|
|
79
79
|
│ │ └── product/ # prod-rules.md (AREA=PRODUCT)
|
|
80
80
|
│ │
|
|
81
|
-
│ ├── rules-on-demand/ # Rules de uma etapa
|
|
81
|
+
│ ├── rules-on-demand/ # Rules lidas pelo workflow que as usa (as de uma etapa, como start, plan e pr, e as transversais, como doc-links e warm-up)
|
|
82
82
|
│ │
|
|
83
83
|
│ ├── scripts/ # Scripts utilitarios
|
|
84
84
|
│ └── docs/ # Documentacao adicional
|
|
@@ -219,7 +219,7 @@ Quando atuar em um projeto alvo, detectar comandos em:
|
|
|
219
219
|
2. `$IDE/ENV.md` - Contexto do ambiente
|
|
220
220
|
3. `$IDE/JARVIS.md` - Guia principal de uso
|
|
221
221
|
4. `$IDE/rules/` - Regras especificas por dominio (carregadas no inicio)
|
|
222
|
-
`$IDE/rules-on-demand/` - Regras de uma etapa
|
|
222
|
+
`$IDE/rules-on-demand/` - Regras de uma etapa ou transversais, lidas pelo workflow que as usa
|
|
223
223
|
5. `$IDE/agents/` - Definicoes de agentes
|
|
224
224
|
6. `$IDE/skills/` - Playbooks operacionais
|
|
225
225
|
7. `$IDE/workflows/` - Templates de execucao
|
|
@@ -255,7 +255,7 @@ Cada pasta pode ter seu proprio AGENTS.md com instrucoes especificas:
|
|
|
255
255
|
/eng.plan "feature" # Plano de execucao faseado (somente planejamento)
|
|
256
256
|
/eng.work "feature" # Implementacao e testes (commit por fase, sem push/PR)
|
|
257
257
|
/eng.pre-pr # Validacao pre-PR
|
|
258
|
-
/eng.pr #
|
|
258
|
+
/eng.pr # Push e PR, depois da pergunta (regra de ouro)
|
|
259
259
|
```
|
|
260
260
|
|
|
261
261
|
### Documentacao
|
|
@@ -285,7 +285,7 @@ Tabela completa de mapeamento comando/trigger → skill: ver `$IDE/skills/AGENTS
|
|
|
285
285
|
|------|---------|-----------|
|
|
286
286
|
| Planejamento | `eng.start`, `eng.plan` | Somente analise, sem codigo |
|
|
287
287
|
| Implementacao | `eng.work` | Codigo e testes, commit por fase, sem push nem PR |
|
|
288
|
-
| Entrega | `eng.pr` |
|
|
288
|
+
| Entrega | `eng.pr` | Push e PR, depois da pergunta (regra de ouro) |
|
|
289
289
|
|
|
290
290
|
---
|
|
291
291
|
|
package/README.md
CHANGED
|
@@ -14,18 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
### 1. Instale
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
O Jarvis é instalado **só global** (comando `jarvis` no PATH):
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
npm install -g jarvis-ai-framework
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
**
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
cd workspace-squad/
|
|
27
|
-
npm install jarvis-ai-framework --save-dev
|
|
28
|
-
```
|
|
23
|
+
Não instale o pacote dentro do projeto: o `jarvis init` roda **dentro do projeto** e copia os assets do Jarvis global para a pasta da IDE. Se ele achar uma cópia local (`node_modules` ou dependência no `package.json`), avisa que ela é ignorada.
|
|
29
24
|
|
|
30
25
|
Confira **onde** o binário ficou no PATH (útil se houver mais de uma instalação):
|
|
31
26
|
|
|
@@ -42,8 +37,6 @@ jarvis --version
|
|
|
42
37
|
jarvis init --ide cursor
|
|
43
38
|
```
|
|
44
39
|
|
|
45
|
-
Se instalou só com `--save-dev`, use `npx jarvis init --ide cursor`.
|
|
46
|
-
|
|
47
40
|
IDEs: `windsurf` · `claude` · `cursor` · `codex` · `opencode` · `gemini` · `kiro`
|
|
48
41
|
|
|
49
42
|
### 3. No chat da IDE
|
|
@@ -76,13 +69,6 @@ Global (comando `jarvis` no PATH):
|
|
|
76
69
|
npm install -g /caminho/para/jarvis
|
|
77
70
|
```
|
|
78
71
|
|
|
79
|
-
**Só neste workspace** (não sobe no PATH):
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
cd workspace-squad/
|
|
83
|
-
npm install /caminho/para/jarvis --save-dev
|
|
84
|
-
```
|
|
85
|
-
|
|
86
72
|
**`npm link`** (útil se você altera o clone e quer refletir na hora):
|
|
87
73
|
|
|
88
74
|
```bash
|
|
@@ -90,12 +76,7 @@ cd /caminho/para/jarvis
|
|
|
90
76
|
npm link
|
|
91
77
|
```
|
|
92
78
|
|
|
93
|
-
Isso já registra o comando `jarvis` no global.
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
cd workspace-squad/
|
|
97
|
-
npm link jarvis-ai-framework
|
|
98
|
-
```
|
|
79
|
+
Isso já registra o comando `jarvis` no global. Não rode `npm link jarvis-ai-framework` dentro do workspace: isso cria uma cópia local em `node_modules`, que o `jarvis init` ignora (e avisa).
|
|
99
80
|
|
|
100
81
|
Confira **onde** o binário ficou no PATH (útil se houver mais de uma instalação):
|
|
101
82
|
|
|
@@ -137,12 +118,6 @@ git pull
|
|
|
137
118
|
npm install -g /caminho/para/jarvis
|
|
138
119
|
```
|
|
139
120
|
|
|
140
|
-
**Só no workspace (`--save-dev`):**
|
|
141
|
-
```bash
|
|
142
|
-
cd workspace-squad/
|
|
143
|
-
npm install /caminho/para/jarvis --save-dev
|
|
144
|
-
```
|
|
145
|
-
|
|
146
121
|
**Com `npm link`:** o `git pull` no clone já basta — o link aponta para a pasta.
|
|
147
122
|
|
|
148
123
|
Antes de seguir, confira se o `jarvis` do PATH é o que você acabou de atualizar:
|
|
@@ -164,7 +139,7 @@ jarvis init --ide cursor
|
|
|
164
139
|
|
|
165
140
|
Isso copia de novo `agents/`, `skills/`, `workflows/`, `rules/`, `templates/` para `.$IDE/` e atualiza o `jarvis-lock.json`.
|
|
166
141
|
|
|
167
|
-
|
|
142
|
+
Esse é o único caminho de atualização dos assets: o `npm install -g` não sincroniza nenhum projeto sozinho. Quando os assets do projeto estão atrás do Jarvis global, o `/jarvis-init` avisa no início e oferece o `jarvis init --upgrade`.
|
|
168
143
|
|
|
169
144
|
### 4. ENV.md (só se houver variáveis novas)
|
|
170
145
|
|
|
@@ -183,11 +158,11 @@ Escolha **Upgrade (C)** — adiciona chaves novas do template sem apagar os valo
|
|
|
183
158
|
| Passo | O que muda |
|
|
184
159
|
|-------|------------|
|
|
185
160
|
| `git pull` | Código do framework no clone |
|
|
186
|
-
| `npm install -g`
|
|
187
|
-
| `jarvis init`
|
|
161
|
+
| `npm install -g` | Binário `jarvis` + pacote que o `init` lê |
|
|
162
|
+
| `jarvis init` | Arquivos em `.$IDE/` (skills, agents, workflows…) e o Context7 no arquivo de MCP da IDE (ex.: `.mcp.json` no Claude Code; só acrescenta, sem apagar outros servidores) |
|
|
188
163
|
| `/jarvis-init` Upgrade | Só `$IDE/ENV.md` (variáveis faltantes) e, se você aceitar o passo opcional "adicionar as stacks", as listas de especializações |
|
|
189
164
|
|
|
190
|
-
`ENV.md`, `.jarvis/sessions/` e o `.gitignore` do workspace **não** são sobrescritos pelo sync de assets.
|
|
165
|
+
`ENV.md`, `.jarvis/sessions/` e o `.gitignore` do workspace **não** são sobrescritos pelo sync de assets. O `.gitignore` só é criado ou alterado quando a raiz tem `.git`; sem `.git` (como no modo workspace) a raiz não é versionada e o init não o toca.
|
|
191
166
|
|
|
192
167
|
| Papel | Descricao | Link |
|
|
193
168
|
|-------|-----------|------|
|
|
@@ -212,7 +187,7 @@ O `/jarvis-init` pergunta o `ARTIFACT_STYLE` (variável do `ENV.md`):
|
|
|
212
187
|
| Valor | O que acontece |
|
|
213
188
|
|---|---|
|
|
214
189
|
| `ai-generated` (padrão) | Como sempre: metadados, links de rastreabilidade e padrões da ferramenta |
|
|
215
|
-
| `human-generated` | Nada do que o Jarvis publica (commit, PR/MR, comentário no card, issue) leva marca de IA ou da IDE: o `/eng.pr` confere e limpa antes do push. Todo documento gerado pergunta, no fim, se você quer a versão humanizada, gravada ao lado como `{nome}.public.md` para repassar a clientes ou stakeholders |
|
|
190
|
+
| `human-generated` | Nada do que o Jarvis publica (commit, PR/MR, comentário no card, issue; sempre depois da pergunta) leva marca de IA ou da IDE: o `/eng.pr` confere e limpa antes do push. Todo documento gerado pergunta, no fim, se você quer a versão humanizada, gravada ao lado como `{nome}.public.md` para repassar a clientes ou stakeholders |
|
|
216
191
|
|
|
217
192
|
Com `human-generated`, o `/jarvis-init` copia a rule `rules/artifact-style-rules.md` (eixo `ARTIFACT_STYLE` do `Applies to`); com `ai-generated`, ela nem existe na sessão. Trocou o valor à mão? Rode `/jarvis-init upgrade`.
|
|
218
193
|
|
|
@@ -253,6 +228,6 @@ Precisa de ajuda?
|
|
|
253
228
|
- **Engenharia (um guia por comando `eng.*`)** — [`docs/engenharia/`](docs/engenharia/README.md)
|
|
254
229
|
- **Indice de docs/** — [`docs/README.md`](docs/README.md)
|
|
255
230
|
- **Instrucoes para agentes / mapa de skills** — `AGENTS.md`
|
|
256
|
-
- **Issues/Feedback** — skill `jarvis-report-issue`
|
|
231
|
+
- **Issues/Feedback** — skill `jarvis-report-issue` (pergunta antes de abrir; sem a CLI do host (`gh`), sem login, sem rede ou com o seu Não, a issue fica em `.jarvis/issues/issue-{desc}.md` para abrir à mão)
|
|
257
232
|
- **Duvidas sobre comandos** — Pergunte diretamente ao agent:
|
|
258
233
|
`"Como funciona /eng.start?"` | `"Qual a diferenca entre /eng.work e /pr?"` | `"O que e CDD?"`
|
|
@@ -66,7 +66,7 @@ Ativado quando há suspeita de dado incorreto, queda de volume ou falha de pipel
|
|
|
66
66
|
- Identificar causa raiz: fonte, transformação ou carga
|
|
67
67
|
- Verificar logs de execução e checks de qualidade
|
|
68
68
|
- Propor correção e plano de reprocessamento idempotente
|
|
69
|
-
- Alertar squads afetadas com contexto claro
|
|
69
|
+
- Alertar squads afetadas com contexto claro (mostrando a mensagem e perguntando antes de enviar, regra de ouro)
|
|
70
70
|
|
|
71
71
|
**Skill integrada**: `$IDE/skills/eng-data/SKILL.md` + `DATA_SPECIALIZATIONS`
|
|
72
72
|
|
|
@@ -126,7 +126,7 @@ CONTEXT_PROFILE:
|
|
|
126
126
|
|
|
127
127
|
| Sinal | Urgência | Comportamento |
|
|
128
128
|
|-------|----------|---------------|
|
|
129
|
-
| `dado errado em produção`, `dashboard parado`, `pipeline falhou` | **CRÍTICA** | Fast track: diagnóstico imediato, isolar causa, comunicar squads afetadas |
|
|
129
|
+
| `dado errado em produção`, `dashboard parado`, `pipeline falhou` | **CRÍTICA** | Fast track: diagnóstico imediato, isolar causa, comunicar squads afetadas (texto pronto; o envio só depois da pergunta, regra de ouro) |
|
|
130
130
|
| `atraso`, `dado desatualizado`, `queda de volume` | **ALTA** | Investigação ágil, reprocessar com idempotência |
|
|
131
131
|
| `nova feature`, `novo pipeline`, `contrato de dados` | **NORMAL** | Fluxo completo: documentar antes, implementar, validar |
|
|
132
132
|
| `melhoria`, `refactoring de query`, `otimização` | **BAIXA** | Análise cuidadosa de impacto antes de qualquer mudança |
|
|
@@ -226,7 +226,7 @@ Para detecção automática de contexto de tarefas:
|
|
|
226
226
|
### 3. Qualidade e Monitoramento
|
|
227
227
|
|
|
228
228
|
- Bloquear promoção de camada quando falha de qualidade ocorre
|
|
229
|
-
- Alertar no canal do time de Data quando falha afeta `gold`
|
|
229
|
+
- Alertar no canal do time de Data quando falha afeta `gold` (depois da pergunta, regra de ouro; o alerta automático de pipeline é do runtime)
|
|
230
230
|
- Manter tabela `gold.pipeline_audit` com metadados de execução
|
|
231
231
|
|
|
232
232
|
### 4. Política de Dados Sensíveis
|
|
@@ -15,7 +15,7 @@ tools: Read, Glob, Grep, Bash, Write, Edit
|
|
|
15
15
|
|
|
16
16
|
Você transforma o que foi **implementado** num registro que dure. Duas pessoas vão ler o que você escreve:
|
|
17
17
|
- **humanos:** outro squad, alguém novo no time, a própria pessoa daqui a seis meses;
|
|
18
|
-
- **IAs:** o `/warm-up`, o `/eng.start` e os `/prod.spec.*` consultam o Central docs como verdade sobre o
|
|
18
|
+
- **IAs:** o `/warm-up`, o `/eng.start` e os `/prod.spec.*` consultam o Central docs como verdade sobre o que está implementado.
|
|
19
19
|
|
|
20
20
|
Por isso o texto tem de ser **completo, autossuficiente e sem ambiguidade**.
|
|
21
21
|
|
|
@@ -33,7 +33,7 @@ Por isso o texto tem de ser **completo, autossuficiente e sem ambiguidade**.
|
|
|
33
33
|
- Sugira o slug da funcionalidade em kebab-case, curto e pelo nome que o negócio usa (ex.: `feature-checkout-pix`, não `feature-task-123`).
|
|
34
34
|
- Os títulos dizem o que a funcionalidade é.
|
|
35
35
|
6. **Referências sempre com URL:**
|
|
36
|
-
- card pelo `TASK_MANAGER` do `ENV.md`, com a URL no padrão da `eng.integrations-rules.md` (Jira `/browse/`,
|
|
36
|
+
- card pelo `TASK_MANAGER` do `ENV.md`, com a URL no padrão da `eng.integrations-rules.md` (Jira `/browse/`, GitHub `/issues/`, GitLab `/-/issues/`); no modo freelance, o número de controle, sem URL;
|
|
37
37
|
- PR/MR pelo `VERSION_CONTROL` ou pelo `remote origin` (número + URL).
|
|
38
38
|
7. **Nunca inventar.** Sem fonte, pergunte ao agente principal (que pergunta ao usuário) ou registre como "não informado".
|
|
39
39
|
8. **Sem dados sensíveis.** Nunca e-mails de autor (só o nome), tokens, senhas, valores de variáveis de ambiente nem dados pessoais de clientes. Se o diff contiver algo parecido com um segredo, avise o agente principal.
|
|
@@ -46,7 +46,7 @@ Por isso o texto tem de ser **completo, autossuficiente e sem ambiguidade**.
|
|
|
46
46
|
4. `git log {base}..HEAD --format='%h|%an|%ad|%s' --date=short` e `git diff --stat {base}...HEAD`.
|
|
47
47
|
5. O código alterado, só leitura, para confirmar o comportamento real.
|
|
48
48
|
6. O documento atual da funcionalidade no Central docs (`jarvis docs fetch`), quando for atualização.
|
|
49
|
-
7. O `gate-checklist.md` e o `pull-request.md` da sessão, se existirem.
|
|
49
|
+
7. O `gate-checklist.md` (a rodada mais recente; as anteriores, `gate-checklist-rodada-{N}.md`, são histórico) e o `pull-request.md` da sessão, se existirem.
|
|
50
50
|
|
|
51
51
|
## O que você produz
|
|
52
52
|
|
|
@@ -39,7 +39,7 @@ Você opera estritamente dentro do **contexto de tarefas Jira e especificações
|
|
|
39
39
|
- Casos extremos não cobertos
|
|
40
40
|
- Riscos potenciais, ambiguidades ou complexidade oculta
|
|
41
41
|
|
|
42
|
-
5. Comentar melhorias
|
|
42
|
+
5. Comentar melhorias no Jira pelo `/eng-global-task-comment`, que mostra o texto e pergunta antes de enviar (regra de ouro, `eng.integrations-rules.md`):
|
|
43
43
|
- Sugerir redação mais clara
|
|
44
44
|
- Propor critérios de aceitação faltantes
|
|
45
45
|
- Recomendar cenários de teste adicionais
|
|
@@ -54,7 +54,7 @@ Você opera estritamente dentro do **contexto de tarefas Jira e especificações
|
|
|
54
54
|
|
|
55
55
|
### Formato de Saída (Sempre Estruturado)
|
|
56
56
|
|
|
57
|
-
Use o seguinte formato
|
|
57
|
+
Use o seguinte formato nos comentários Jira (eles só saem depois da pergunta, regra de ouro):
|
|
58
58
|
|
|
59
59
|
**Resumo da Revisão de Qualidade**
|
|
60
60
|
|
|
@@ -15,7 +15,7 @@ Antes de qualquer ação, determine qual modo aplicar:
|
|
|
15
15
|
|
|
16
16
|
**Modo A — Estratégia a partir da Tech Spec (pré-código)**
|
|
17
17
|
Aplicar quando invocado via `eng.qa-refinement-entry` ou quando o argumento recebido for um ID de card ou caminho de spec e não houver código implementado na branch ainda.
|
|
18
|
-
- Fonte de dados: card no $TASK_MANAGER
|
|
18
|
+
- Fonte de dados: card no $TASK_MANAGER, lido pela CLI do vendor (ação `view` do catálogo `bin/lib/integrations/vendors.json`: `gh issue view`, `glab issue view` ou `acli jira workitem view`) ou pelo conteúdo colado pelo usuário
|
|
19
19
|
- Não executar `git diff`, `git log` ou qualquer comando que dependa de código
|
|
20
20
|
- Saída: `$ENG_DOCS/qa/strategies/{task-id}-test-strategy.md`
|
|
21
21
|
|
|
@@ -125,7 +125,7 @@ Usar quando: invocado via `eng.qa-refinement-entry`, ou quando git diff retornar
|
|
|
125
125
|
|
|
126
126
|
### A.1. Buscar o Card
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
Buscar o card pelo ID recebido como argumento, pela CLI do vendor (ação `view` do catálogo `bin/lib/integrations/vendors.json`: `gh issue view`, `glab issue view` ou `acli jira workitem view`) ou pelo conteúdo colado pelo usuário.
|
|
129
129
|
Extrair: título, descrição, critérios de aceite, análise técnica, dependências e qualquer anexo de spec.
|
|
130
130
|
|
|
131
131
|
Se a integração não estiver disponível, solicitar ao usuário que cole o conteúdo da spec diretamente.
|
package/bin/README.md
CHANGED
|
@@ -7,20 +7,23 @@ Fonte do binário `jarvis` (instalado via `npm install -g jarvis-ai-framework`,
|
|
|
7
7
|
```
|
|
8
8
|
bin/
|
|
9
9
|
├── jarvis.js # Entrypoint (shebang). ~10 linhas, não cresce.
|
|
10
|
-
├── postinstall.js # Roda no `npm install` (
|
|
10
|
+
├── postinstall.js # Roda no `npm install` (só imprime as dicas de uso)
|
|
11
11
|
├── commands/ # Um arquivo por comando. Lógica pura, zero commander.
|
|
12
12
|
│ ├── init.js, list.js, info.js, whoami.js, ...
|
|
13
13
|
│ ├── docs-sync.js, docs-publish.js
|
|
14
|
-
│ └──
|
|
14
|
+
│ └── install-rtk.js, tokens.js, map.js
|
|
15
15
|
└── lib/
|
|
16
16
|
├── cli/
|
|
17
17
|
│ ├── program.js # Único lugar que monta o commander — ver "Arquitetura"
|
|
18
18
|
│ └── shared-options.js # .option() repetidos entre comandos (--ide, --quiet, etc.)
|
|
19
|
-
├──
|
|
20
|
-
│ ├──
|
|
19
|
+
├── integrations/ # Board e git pela CLI oficial do vendor (FRD-006)
|
|
20
|
+
│ ├── vendors.json # Catálogo: vendors (jira/acli, github/gh, gitlab/glab), comandos por ação e variáveis
|
|
21
|
+
│ └── cli-runner.js # checkCli, buildArgs, runAction (execFile sem shell), códigos de saída 0/1/3/4
|
|
22
|
+
├── vcs/ # GitHub/GitLab pela CLI (gh pr create, glab mr create, issue create)
|
|
23
|
+
│ ├── api.js # createIssue, createMergeRequest, cardUrl (sobre o cli-runner)
|
|
21
24
|
│ ├── create-merge.js, create-issue.js # função exportada + CLI direto (ver abaixo)
|
|
22
25
|
├── tasks/
|
|
23
|
-
│ └── comment.js #
|
|
26
|
+
│ └── comment.js # Comentário no card (jira/github/gitlab) pelo cli-runner — mesmo padrão
|
|
24
27
|
├── config/ # ide-config.js (fonte de verdade de IDEs), constants.js
|
|
25
28
|
├── core/ # scanner.js, sync-engine.js, profile-filter.js, token-report.js
|
|
26
29
|
├── docs/ # Central docs: fetch/publish pelo adaptador + validação de frontmatter
|
|
@@ -28,7 +31,7 @@ bin/
|
|
|
28
31
|
│ ├── fetch-file.js # openStorageFromEnv() + fetchFile() — `docs sync`/`docs fetch`/`docs publish`
|
|
29
32
|
│ ├── publish-file.js # tipos, resolveDestPath() e publishFile() — `docs publish`
|
|
30
33
|
│ └── storage/ # adaptadores (CENTRAL_DOCS_STORAGE): index.js (fábrica), filesystem.js (pasta + git), build-index.js
|
|
31
|
-
├── utils/ # logger.js, ui.js, paths.js, frontmatter.js, git-parser.js
|
|
34
|
+
├── utils/ # logger.js, ui.js, paths.js, frontmatter.js, git-parser.js
|
|
32
35
|
├── flow-map/ # `jarvis map` — grafo de chamadas entre workflows/skills/agents
|
|
33
36
|
├── auth/ # session.js (auth.json legado, hoje só `jarvis logout` o lê)
|
|
34
37
|
└── env-loader.js # Resolve e lê o ENV.md ($IDE/ENV.md)
|
|
@@ -116,12 +119,12 @@ if (fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
|
116
119
|
|
|
117
120
|
## Variáveis de ambiente lidas diretamente (fora do ENV.md)
|
|
118
121
|
|
|
119
|
-
`bin/lib/tasks/comment.js` e `bin/lib/vcs/*.js` leem `process.env` direto (`TASK_MANAGER`, `
|
|
122
|
+
`bin/lib/tasks/comment.js` e `bin/lib/vcs/*.js` leem `process.env` direto (`TASK_MANAGER`, `TASK_MANAGER_ACCESS`, `TASK_MANAGER_URL_BASE`, `VERSION_CONTROL`, etc.; nenhum token: o login é o da CLI do vendor) — não passam pelo `env-loader.js`/ENV.md. O `jarvis tasks comment` e o `jarvis vcs create-merge` completam o que faltar no ambiente lendo o `$IDE/ENV.md` do workspace (`readFileEnv`/`resolveFileEnv` em `integrations/cli-runner.js`, com `--ide`/`--env-file`; o ambiente do processo vence; `setting` tira aspas e comentário de fim de linha), então os skills não precisam exportar nada nem usar `eval`. O `accessGate` decide antes de qualquer envio: só `cli` (ou vazio, com aviso) segue; `manual`, valor inválido e ENV.md ilegível saem com 3. O ENV.md lido é repassado ao `createMergeRequest` (`fileEnvResult`), inclusive pelo Central docs. Se um comando novo precisar ler o `ENV.md` diretamente, use `env-loader.js#resolveEnvPath`/`loadEnv` (ver `whoami.js` e `tokens.js` como exemplo) em vez de `process.env`.
|
|
120
123
|
|
|
121
124
|
## Testes
|
|
122
125
|
|
|
123
126
|
- `npm run test:comandos` — valida que toda referência a comando/skill nos workflows e skills existe de fato (não testa o CLI em runtime).
|
|
124
|
-
- `npm run test:filtro` — testes unitários de `profile-filter.js`, `token-report.js`, `flow-map`, `env-loader.js`, `sync-engine.js
|
|
127
|
+
- `npm run test:filtro` — testes unitários de `profile-filter.js`, `token-report.js`, `flow-map`, `env-loader.js`, `sync-engine.js`, `vcs/api.js`, `tasks/comment.js`, `integrations/` (catálogo e runner) e do upgrade.
|
|
125
128
|
- Não há teste automatizado de ponta a ponta do CLI (`jarvis <comando>` real) — a camada de dispatch (`program.js`, `bin/commands/*.js`) não é cobrida pelos testes unitários. Qualquer mudança ali precisa de validação manual dos comandos afetados.
|
|
126
129
|
|
|
127
130
|
### Como testar código que lê `fs`/rede sem mockar módulo
|
|
@@ -130,10 +133,10 @@ Os 3 arquivos mais críticos sem cobertura até pouco tempo atrás (`env-loader.
|
|
|
130
133
|
|
|
131
134
|
- **`env-loader.js`** (e `flow-map.test.js`, mais antigo): `mkdtempSync(join(tmpdir(), "jarvis-..."))` monta um workspace fake com `.{ide}/ENV.md`, roda a função contra ele, `rmSync` no `finally`.
|
|
132
135
|
- **`sync-engine.js`**: `getFrameworkRoot()` (`utils/paths.js`) já tem um escape hatch — `process.env.JARVIS_ROOT`, se definido e existir, vence sobre o framework real. O teste aponta `JARVIS_ROOT` para um fixture mínimo (`agents/`, `skills/`, etc. com 1 arquivo cada) em vez de sincronizar o framework inteiro.
|
|
133
|
-
- **`vcs/api.js
|
|
136
|
+
- **`integrations/cli-runner.js`, `vcs/api.js`, `tasks/comment.js`**: o `exec` (que roda a CLI do vendor) é injetável pelo último parâmetro (`deps`); o teste passa uma CLI falsa que responde por subcomando (ver `fakeExec` em `cli-runner.test.js`), sem chamar `gh`/`glab`/`acli` de verdade nem depender do login da máquina. No `jarvis init --upgrade` (teste por subprocesso), `JARVIS_SKIP_CLI_CHECK=1` desliga a descoberta, e o teste dela põe uma CLI falsa no `PATH`.
|
|
134
137
|
- **`docs/` (Central docs)**: tudo em pasta temporária (`mkdtempSync`). A camada git do adaptador `filesystem` usa um repositório `git init --bare` local como `origin` (sem rede), e o `createMergeRequest` é injetado pelo parâmetro `deps` de `getStorage` (ver `docs-storage.test.js`).
|
|
135
138
|
|
|
136
|
-
**Armadilha com `async`**: o helper `withEnv(vars, fn)` (em `vcs-api.test.js`) precisa de `return **await** fn()`, não `return fn()`, dentro do `try`. Sem o `await`, o `finally` que restaura a env var roda assim que `fn()` retorna uma Promise pendente — ou seja, **antes** da função terminar. Isso só não quebra quando a leitura da env var acontece antes do primeiro `await` de `fn` (ex:
|
|
139
|
+
**Armadilha com `async`**: o helper `withEnv(vars, fn)` (em `vcs-api.test.js`) precisa de `return **await** fn()`, não `return fn()`, dentro do `try`. Sem o `await`, o `finally` que restaura a env var roda assim que `fn()` retorna uma Promise pendente — ou seja, **antes** da função terminar. Isso só não quebra quando a leitura da env var acontece antes do primeiro `await` de `fn` (ex: uma função que lê `process.env` antes do primeiro `await`); quebra silenciosamente em qualquer função com mais de um `await` antes de ler a variável.
|
|
137
140
|
|
|
138
141
|
Ao escrever um teste novo para um arquivo que toca `fs`/rede, prefira um desses padrões a mockar o módulo inteiro ou refatorar pra injeção de dependência — nenhum dos arquivos acima precisou mudar uma linha de lógica de produção para ganhar teste.
|
|
139
142
|
|
|
@@ -108,7 +108,7 @@ export async function docsPublish(flags = {}) {
|
|
|
108
108
|
"\n💡 Central docs com git: confira se a pasta está limpa (git status), se você tem permissão de push"
|
|
109
109
|
);
|
|
110
110
|
logger.error(
|
|
111
|
-
" e se
|
|
111
|
+
" e se a CLI do host está logada (gh auth login, glab auth login)."
|
|
112
112
|
);
|
|
113
113
|
}
|
|
114
114
|
process.exit(1);
|
package/bin/commands/init.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync,
|
|
2
|
-
import { join, dirname, basename } from "node:path";
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync } from "node:fs";
|
|
2
|
+
import { join, dirname, basename, resolve, sep } from "node:path";
|
|
3
3
|
import { createInterface } from "node:readline";
|
|
4
4
|
import { syncAssets } from "../lib/core/sync-engine.js";
|
|
5
5
|
import { discoverAll } from "../lib/core/scanner.js";
|
|
@@ -16,24 +16,51 @@ import { getPackageInfo, getFrameworkRoot } from "../lib/utils/paths.js";
|
|
|
16
16
|
import { logger, configureFromFlags } from "../lib/utils/logger.js";
|
|
17
17
|
import { resolveEnvPath } from "../lib/env-loader.js";
|
|
18
18
|
import { LOCK_FILE } from "../lib/config/constants.js";
|
|
19
|
+
import { compareVersions, localInstall } from "../lib/utils/version.js";
|
|
19
20
|
import {
|
|
20
21
|
findStaleSkills,
|
|
21
22
|
registeredSpecializations,
|
|
22
23
|
removeStaleSkills,
|
|
23
24
|
} from "../lib/core/stale-skills.js";
|
|
24
25
|
import { parseEnvEntries, planEnvUpgrade, applyEnvUpgrade } from "../lib/core/env-upgrade.js";
|
|
26
|
+
import { checkCli, getVendor } from "../lib/integrations/cli-runner.js";
|
|
25
27
|
import {
|
|
26
28
|
expandEnv,
|
|
27
29
|
planDocsMigration,
|
|
28
30
|
applyDocsMigration,
|
|
29
31
|
rewriteRelatedDiscovery,
|
|
30
32
|
declineEnvValues,
|
|
33
|
+
ensureGitignore,
|
|
31
34
|
} from "../lib/core/docs-migrate.js";
|
|
35
|
+
import { rootIsRepo } from "../lib/core/workspace-mode.js";
|
|
36
|
+
import { ensureContext7 } from "../lib/core/mcp-config.js";
|
|
32
37
|
|
|
33
38
|
function ask(rl, question) {
|
|
34
39
|
return new Promise((resolve) => rl.question(question, resolve));
|
|
35
40
|
}
|
|
36
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Grava o Context7 (MCP obrigatório) no arquivo de MCP da IDE e mostra o que falta.
|
|
44
|
+
* Só avisa: problema no arquivo de MCP não muda o código de saída (instalação e --upgrade).
|
|
45
|
+
*/
|
|
46
|
+
function setupMcp(workspaceDir, ide) {
|
|
47
|
+
const mcp = ensureContext7(workspaceDir, ide);
|
|
48
|
+
logger.info(`${BLUE}🔌 MCP (Context7):${NC}`);
|
|
49
|
+
for (const p of mcp.written) logger.info(` ${GREEN}✓ ${p}${NC} (Context7 adicionado)`);
|
|
50
|
+
for (const p of mcp.present) logger.info(`${DIM} ↳ ${p} (Context7 já configurado)${NC}`);
|
|
51
|
+
for (const m of mcp.manual) {
|
|
52
|
+
const why = m.reason
|
|
53
|
+
? `${m.path}: ${m.reason}. Nada alterado; inclua à mão:`
|
|
54
|
+
: `Config só global: inclua em ${m.path}:`;
|
|
55
|
+
logger.info(`${YELLOW} ⚠️ ${why}${NC}`);
|
|
56
|
+
for (const line of m.snippet.trimEnd().split("\n")) logger.info(`${DIM} ${line}${NC}`);
|
|
57
|
+
}
|
|
58
|
+
for (const e of mcp.errors) logger.info(`${YELLOW} ⚠️ ${e} (nada alterado)${NC}`);
|
|
59
|
+
const note = getIDEConfig(ide)?.mcpNote;
|
|
60
|
+
if (note && (mcp.written.length || mcp.manual.length)) logger.info(`${DIM} ${note}${NC}`);
|
|
61
|
+
logger.info("");
|
|
62
|
+
}
|
|
63
|
+
|
|
37
64
|
export async function init(flags) {
|
|
38
65
|
configureFromFlags(flags);
|
|
39
66
|
|
|
@@ -107,6 +134,10 @@ export async function init(flags) {
|
|
|
107
134
|
|
|
108
135
|
const ideDir = join(cwd, `.${getIDEFolder(ide)}`);
|
|
109
136
|
|
|
137
|
+
// Avisos de versão antes da pergunta de reinstalação: quem responde "s" (ou usa --force)
|
|
138
|
+
// já sabe se vai rebaixar os assets.
|
|
139
|
+
warnVersionMismatch(cwd);
|
|
140
|
+
|
|
110
141
|
// Reinstall: --force ou confirmação "s" devem sobrescrever assets (cpSync force:true).
|
|
111
142
|
let forceSync = !!flags.force;
|
|
112
143
|
|
|
@@ -154,20 +185,16 @@ export async function init(flags) {
|
|
|
154
185
|
for (const area of ["eng", "prod", "qa"]) {
|
|
155
186
|
mkdirSync(join(jarvisRoot, "sessions", area), { recursive: true });
|
|
156
187
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const text = readFileSync(gitignore, "utf8");
|
|
161
|
-
if (!text.split("\n").some((l) => l.trim() === ignoreLine || l.trim() === ".jarvis")) {
|
|
162
|
-
appendFileSync(gitignore, `${text.endsWith("\n") ? "" : "\n"}${ignoreLine}\n`);
|
|
163
|
-
}
|
|
164
|
-
} else {
|
|
165
|
-
writeFileSync(gitignore, `${ignoreLine}\n`);
|
|
188
|
+
// .gitignore só numa raiz versionada (com .git): no modo workspace a raiz não é um repositório.
|
|
189
|
+
if (rootIsRepo(cwd)) {
|
|
190
|
+
ensureGitignore(cwd, ".jarvis/");
|
|
166
191
|
}
|
|
167
192
|
|
|
193
|
+
logger.info("");
|
|
194
|
+
setupMcp(cwd, ide);
|
|
195
|
+
|
|
168
196
|
const pkg = getPackageInfo();
|
|
169
197
|
|
|
170
|
-
logger.info("");
|
|
171
198
|
logger.info(`${GREEN}✓ Configuração concluída!${NC}`);
|
|
172
199
|
logger.info(`${BOLD}${CYAN} versão: ${pkg.name} v${pkg.version}${NC}`);
|
|
173
200
|
logger.info(`${DIM} origem: ${pkg.root}${NC}`);
|
|
@@ -235,6 +262,53 @@ function ideFromEnvPath(envPath) {
|
|
|
235
262
|
return getIDEValues().find((v) => `.${getIDEFolder(v)}` === folder);
|
|
236
263
|
}
|
|
237
264
|
|
|
265
|
+
/**
|
|
266
|
+
* Avisos de versão antes do sync. O Jarvis é instalado só global:
|
|
267
|
+
* - cópia local no projeto (`node_modules` ou dependência no `package.json`) é ignorada;
|
|
268
|
+
* se é ela que está rodando (`npx jarvis`, `./node_modules/.bin/jarvis`), o aviso diz isso;
|
|
269
|
+
* - lock do projeto mais novo que o Jarvis em uso: o sync rebaixaria os assets.
|
|
270
|
+
* Recebe o lock lido antes do `syncAssets`, que o reescreve.
|
|
271
|
+
* @param {string} workspaceDir
|
|
272
|
+
* @param {string} [lock] - versão do `jarvis-lock.json` do projeto
|
|
273
|
+
* @returns {{ downgrade: boolean, running: string }} `downgrade` = lock mais novo que o Jarvis em uso
|
|
274
|
+
*/
|
|
275
|
+
export function warnVersionMismatch(workspaceDir, lock = readLockVersion(workspaceDir)) {
|
|
276
|
+
const running = getPackageInfo().version;
|
|
277
|
+
// Caminhos reais dos dois lados: o Node já resolve o link do script (`import.meta.url`),
|
|
278
|
+
// então uma cópia por `npm link` em node_modules só bate com o realpath.
|
|
279
|
+
const real = (p) => {
|
|
280
|
+
try {
|
|
281
|
+
return realpathSync(p);
|
|
282
|
+
} catch {
|
|
283
|
+
return resolve(p);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
const root = real(getFrameworkRoot());
|
|
287
|
+
const localDir = join(workspaceDir, "node_modules", "jarvis-ai-framework");
|
|
288
|
+
const runningLocal =
|
|
289
|
+
(root + sep).startsWith(real(join(workspaceDir, "node_modules")) + sep) ||
|
|
290
|
+
(existsSync(localDir) && root === real(localDir));
|
|
291
|
+
const local = localInstall(workspaceDir);
|
|
292
|
+
if (runningLocal) {
|
|
293
|
+
logger.info(
|
|
294
|
+
`${BLUE}ℹ️ O Jarvis em uso (${running}) é o mesmo de node_modules (cópia local do projeto). O Jarvis é instalado global: npm install -g jarvis-ai-framework, rode \`jarvis\` (sem npx) e remova a cópia local.${NC}`
|
|
295
|
+
);
|
|
296
|
+
} else if (local) {
|
|
297
|
+
logger.info(
|
|
298
|
+
`${BLUE}ℹ️ O Jarvis é instalado global (npm install -g jarvis-ai-framework). A cópia local deste projeto (${local.version} em ${local.source}) é ignorada: pode removê-la.${NC}`
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
const downgrade = compareVersions(lock, running) === 1;
|
|
302
|
+
if (downgrade) {
|
|
303
|
+
const who = runningLocal ? "o Jarvis em uso (cópia local)" : "o seu jarvis global";
|
|
304
|
+
logger.info(
|
|
305
|
+
`${YELLOW}⚠️ Os assets deste projeto são da ${lock}, mas ${who} é a ${running}. Atualize o global: npm install -g jarvis-ai-framework${NC}`
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
if (runningLocal || local || downgrade) logger.info("");
|
|
309
|
+
return { downgrade, running };
|
|
310
|
+
}
|
|
311
|
+
|
|
238
312
|
function readLockVersion(workspaceDir) {
|
|
239
313
|
try {
|
|
240
314
|
return (
|
|
@@ -245,6 +319,31 @@ function readLockVersion(workspaceDir) {
|
|
|
245
319
|
}
|
|
246
320
|
}
|
|
247
321
|
|
|
322
|
+
/**
|
|
323
|
+
* Descoberta da CLI de cada eixo (só leitura: binário no PATH + `auth status`).
|
|
324
|
+
* Não pergunta nada: a confirmação do acesso e as variáveis ficam no `/jarvis-init` (Q2 da #181).
|
|
325
|
+
* `JARVIS_SKIP_CLI_CHECK=1` pula a descoberta (CI, sem rede).
|
|
326
|
+
*/
|
|
327
|
+
async function reportCliDiscovery(entries) {
|
|
328
|
+
const axes = [
|
|
329
|
+
["TASK_MANAGER", "Board de cards"],
|
|
330
|
+
["VERSION_CONTROL", "Controle de versão"],
|
|
331
|
+
];
|
|
332
|
+
const targets = axes
|
|
333
|
+
.map(([key, label]) => ({ key, label, vendor: (entries.get(key) || "").toLowerCase() }))
|
|
334
|
+
.filter((t) => getVendor(t.vendor));
|
|
335
|
+
if (!targets.length) return;
|
|
336
|
+
if (process.env.JARVIS_SKIP_CLI_CHECK) {
|
|
337
|
+
logger.info(`${DIM} • Descoberta da CLI pulada (JARVIS_SKIP_CLI_CHECK)${NC}`);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
for (const t of targets) {
|
|
341
|
+
const r = await checkCli(t.vendor);
|
|
342
|
+
const mark = r.installed && r.loggedIn ? GREEN : YELLOW;
|
|
343
|
+
logger.info(`${mark} • ${t.label} (${t.key}=${t.vendor}): ${r.reason}${NC}`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
248
347
|
/**
|
|
249
348
|
* `jarvis init --upgrade`: atualiza um projeto já configurado em uma passada.
|
|
250
349
|
* 1. arquivos do framework (como o --force, sem perguntar); 2. só as chaves novas do ENV;
|
|
@@ -272,6 +371,27 @@ async function runUpgrade(cwd, flags) {
|
|
|
272
371
|
const workspaceDir = resolved.root;
|
|
273
372
|
const envPath = resolved.path;
|
|
274
373
|
const previousVersion = readLockVersion(workspaceDir);
|
|
374
|
+
const { downgrade, running } = warnVersionMismatch(workspaceDir, previousVersion);
|
|
375
|
+
if (downgrade && !flags.yes) {
|
|
376
|
+
let go = false;
|
|
377
|
+
if (process.stdin.isTTY) {
|
|
378
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
379
|
+
const answer = await ask(
|
|
380
|
+
rl,
|
|
381
|
+
`Seguir e rebaixar os assets de ${previousVersion} para ${running}? (s/N): `
|
|
382
|
+
);
|
|
383
|
+
rl.close();
|
|
384
|
+
go = answer.trim().toLowerCase() === "s";
|
|
385
|
+
} else {
|
|
386
|
+
logger.info(`${DIM} Sem terminal interativo e sem --yes: nada será rebaixado.${NC}`);
|
|
387
|
+
}
|
|
388
|
+
if (!go) {
|
|
389
|
+
logger.info(
|
|
390
|
+
`${YELLOW}Upgrade interrompido: atualize o global (npm install -g jarvis-ai-framework) e rode de novo.${NC}\n`
|
|
391
|
+
);
|
|
392
|
+
return 1;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
275
395
|
|
|
276
396
|
// 1. Arquivos do framework (o ENV.md não está entre os sincronizados)
|
|
277
397
|
logger.info(`${BLUE}⬆️ Upgrade do Jarvis em .${getIDEFolder(ide)}/${NC}\n`);
|
|
@@ -281,6 +401,7 @@ async function runUpgrade(cwd, flags) {
|
|
|
281
401
|
keepEnvValues: true,
|
|
282
402
|
});
|
|
283
403
|
for (const item of sync.errors) logger.error(`${RED} ✗ ${item}${NC}`);
|
|
404
|
+
setupMcp(workspaceDir, ide);
|
|
284
405
|
|
|
285
406
|
// 2. Variáveis novas (só acrescenta)
|
|
286
407
|
const envText = readFileSync(envPath, "utf-8");
|
|
@@ -390,7 +511,32 @@ async function runUpgrade(cwd, flags) {
|
|
|
390
511
|
`${YELLOW} ⚠️ WORKSPACE_MODE: a raiz é um repositório e há subpastas com .git (submódulos?): gravado como project; confira no ENV.md${NC}`
|
|
391
512
|
);
|
|
392
513
|
}
|
|
514
|
+
for (const key of envPlan.filledApplied || []) {
|
|
515
|
+
logger.info(` • ${key} estava vazio: preenchido com o repositório oficial do Jarvis`);
|
|
516
|
+
}
|
|
517
|
+
if (envPlan.warnings.includes("TOKEN_TASK_MANAGER")) {
|
|
518
|
+
logger.info(
|
|
519
|
+
`${YELLOW} ⚠️ TOKEN_TASK_MANAGER não é mais usado: o Jarvis usa o login da CLI do vendor. Faça o login da CLI e remova a linha pelo /jarvis-init upgrade (o valor não foi lido nem copiado)${NC}`
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
for (const w of envPlan.warnings.filter((x) => x.startsWith("UNSUPPORTED:"))) {
|
|
523
|
+
const [, key, vendor] = w.split(":");
|
|
524
|
+
logger.info(
|
|
525
|
+
`${YELLOW} ⚠️ ${key}=${vendor} não é suportado (jira, github, gitlab): o eixo fica em freelance e as ações viram .md${NC}`
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
await reportCliDiscovery(futureEntries);
|
|
529
|
+
|
|
530
|
+
// Eixos com vendor do catálogo e sem forma de acesso definida: a confirmação é no /jarvis-init.
|
|
531
|
+
const pendingAxes = ["TASK_MANAGER", "VERSION_CONTROL"].filter((key) => {
|
|
532
|
+
const access = (futureEntries.get(`${key}_ACCESS`) || "").trim();
|
|
533
|
+
return getVendor(futureEntries.get(key)) && (!access || /^\[.*\]$/.test(access));
|
|
534
|
+
});
|
|
393
535
|
logger.info("");
|
|
394
|
-
logger.info(
|
|
536
|
+
logger.info(
|
|
537
|
+
pendingAxes.length
|
|
538
|
+
? `${CYAN}➡️ Agora rode ${BOLD}/jarvis-init upgrade${NC}${CYAN} na IDE para confirmar o acesso de ${pendingAxes.join(" e ")} (e as variáveis).${NC}\n`
|
|
539
|
+
: `${CYAN}➡️ Agora rode ${BOLD}/jarvis-init upgrade${NC}${CYAN} na IDE.${NC}\n`
|
|
540
|
+
);
|
|
395
541
|
return sync.errors.length || moveErrors.length || staleErrors.length ? 1 : 0;
|
|
396
542
|
}
|