oxe-cc 1.3.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/.cursor/commands/oxe-ask.md +4 -2
  2. package/.cursor/commands/oxe-capabilities.md +4 -2
  3. package/.cursor/commands/oxe-checkpoint.md +4 -2
  4. package/.cursor/commands/oxe-compact.md +4 -2
  5. package/.cursor/commands/oxe-dashboard.md +4 -2
  6. package/.cursor/commands/oxe-debug.md +4 -2
  7. package/.cursor/commands/oxe-discuss.md +4 -2
  8. package/.cursor/commands/oxe-execute.md +5 -3
  9. package/.cursor/commands/oxe-forensics.md +4 -2
  10. package/.cursor/commands/oxe-help.md +4 -2
  11. package/.cursor/commands/oxe-loop.md +4 -2
  12. package/.cursor/commands/oxe-milestone.md +4 -2
  13. package/.cursor/commands/oxe-next.md +4 -2
  14. package/.cursor/commands/oxe-obs.md +4 -2
  15. package/.cursor/commands/oxe-plan-agent.md +4 -2
  16. package/.cursor/commands/oxe-plan.md +4 -2
  17. package/.cursor/commands/oxe-project.md +4 -2
  18. package/.cursor/commands/oxe-quick.md +4 -2
  19. package/.cursor/commands/oxe-research.md +4 -2
  20. package/.cursor/commands/oxe-retro.md +4 -2
  21. package/.cursor/commands/oxe-review-pr.md +4 -2
  22. package/.cursor/commands/oxe-route.md +4 -2
  23. package/.cursor/commands/oxe-scan.md +4 -2
  24. package/.cursor/commands/oxe-security.md +4 -2
  25. package/.cursor/commands/oxe-session.md +5 -3
  26. package/.cursor/commands/oxe-ship.md +4 -2
  27. package/.cursor/commands/oxe-skill.md +4 -2
  28. package/.cursor/commands/oxe-spec.md +4 -2
  29. package/.cursor/commands/oxe-ui-review.md +4 -2
  30. package/.cursor/commands/oxe-ui-spec.md +4 -2
  31. package/.cursor/commands/oxe-update.md +4 -2
  32. package/.cursor/commands/oxe-validate-gaps.md +4 -2
  33. package/.cursor/commands/oxe-verify.md +4 -2
  34. package/.cursor/commands/oxe-workstream.md +4 -2
  35. package/.cursor/commands/oxe.md +6 -2
  36. package/.github/prompts/oxe-ask.prompt.md +4 -2
  37. package/.github/prompts/oxe-capabilities.prompt.md +4 -2
  38. package/.github/prompts/oxe-checkpoint.prompt.md +4 -2
  39. package/.github/prompts/oxe-compact.prompt.md +4 -2
  40. package/.github/prompts/oxe-dashboard.prompt.md +4 -2
  41. package/.github/prompts/oxe-debug.prompt.md +4 -2
  42. package/.github/prompts/oxe-discuss.prompt.md +6 -2
  43. package/.github/prompts/oxe-execute.prompt.md +5 -3
  44. package/.github/prompts/oxe-forensics.prompt.md +4 -2
  45. package/.github/prompts/oxe-help.prompt.md +6 -2
  46. package/.github/prompts/oxe-loop.prompt.md +4 -2
  47. package/.github/prompts/oxe-milestone.prompt.md +4 -2
  48. package/.github/prompts/oxe-next.prompt.md +6 -2
  49. package/.github/prompts/oxe-obs.prompt.md +4 -2
  50. package/.github/prompts/oxe-plan-agent.prompt.md +4 -2
  51. package/.github/prompts/oxe-plan.prompt.md +4 -2
  52. package/.github/prompts/oxe-project.prompt.md +4 -2
  53. package/.github/prompts/oxe-quick.prompt.md +4 -2
  54. package/.github/prompts/oxe-research.prompt.md +4 -2
  55. package/.github/prompts/oxe-retro.prompt.md +4 -2
  56. package/.github/prompts/oxe-review-pr.prompt.md +4 -2
  57. package/.github/prompts/oxe-route.prompt.md +4 -2
  58. package/.github/prompts/oxe-scan.prompt.md +4 -2
  59. package/.github/prompts/oxe-security.prompt.md +4 -2
  60. package/.github/prompts/oxe-session.prompt.md +5 -3
  61. package/.github/prompts/oxe-ship.prompt.md +4 -2
  62. package/.github/prompts/oxe-skill.prompt.md +4 -2
  63. package/.github/prompts/oxe-spec.prompt.md +4 -2
  64. package/.github/prompts/oxe-ui-review.prompt.md +4 -2
  65. package/.github/prompts/oxe-ui-spec.prompt.md +4 -2
  66. package/.github/prompts/oxe-update.prompt.md +4 -2
  67. package/.github/prompts/oxe-validate-gaps.prompt.md +4 -2
  68. package/.github/prompts/oxe-verify.prompt.md +4 -2
  69. package/.github/prompts/oxe-workstream.prompt.md +4 -2
  70. package/.github/prompts/oxe.prompt.md +6 -2
  71. package/.github/workflows/ci.yml +56 -20
  72. package/.github/workflows/release.yml +93 -0
  73. package/AGENTS.md +5 -3
  74. package/CHANGELOG.md +388 -345
  75. package/LICENSE +21 -674
  76. package/README.md +66 -14
  77. package/bin/banner.txt +5 -5
  78. package/bin/lib/oxe-agent-install.cjs +127 -107
  79. package/bin/lib/oxe-runtime-semantics.cjs +68 -24
  80. package/bin/oxe-cc.js +393 -155
  81. package/commands/oxe/ask.md +7 -3
  82. package/commands/oxe/capabilities.md +6 -2
  83. package/commands/oxe/checkpoint.md +5 -1
  84. package/commands/oxe/compact.md +6 -2
  85. package/commands/oxe/dashboard.md +6 -2
  86. package/commands/oxe/debug.md +6 -2
  87. package/commands/oxe/discuss.md +6 -2
  88. package/commands/oxe/execute.md +6 -2
  89. package/commands/oxe/forensics.md +6 -2
  90. package/commands/oxe/help.md +6 -2
  91. package/commands/oxe/loop.md +6 -2
  92. package/commands/oxe/milestone.md +6 -2
  93. package/commands/oxe/next.md +6 -2
  94. package/commands/oxe/obs.md +6 -2
  95. package/commands/oxe/oxe.md +6 -2
  96. package/commands/oxe/plan-agent.md +6 -2
  97. package/commands/oxe/plan.md +6 -2
  98. package/commands/oxe/project.md +6 -2
  99. package/commands/oxe/quick.md +6 -2
  100. package/commands/oxe/research.md +6 -2
  101. package/commands/oxe/retro.md +6 -2
  102. package/commands/oxe/review-pr.md +6 -2
  103. package/commands/oxe/route.md +6 -2
  104. package/commands/oxe/scan.md +6 -2
  105. package/commands/oxe/security.md +6 -2
  106. package/commands/oxe/session.md +6 -2
  107. package/commands/oxe/ship.md +6 -2
  108. package/commands/oxe/skill.md +6 -2
  109. package/commands/oxe/spec.md +6 -2
  110. package/commands/oxe/ui-review.md +6 -2
  111. package/commands/oxe/ui-spec.md +6 -2
  112. package/commands/oxe/update.md +6 -2
  113. package/commands/oxe/validate-gaps.md +6 -2
  114. package/commands/oxe/verify.md +6 -2
  115. package/commands/oxe/workstream.md +6 -2
  116. package/lib/sdk/README.md +19 -7
  117. package/oxe/workflows/plan.md +51 -20
  118. package/package.json +3 -3
  119. package/packages/runtime/package.json +5 -4
  120. package/vscode-extension/LICENSE +21 -0
  121. package/vscode-extension/oxe-agents-1.4.0.vsix +0 -0
  122. package/vscode-extension/package.json +2 -2
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![npm](https://img.shields.io/npm/v/oxe-cc.svg?style=flat-square)](https://www.npmjs.com/package/oxe-cc)
8
8
  [![license](https://img.shields.io/npm/l/oxe-cc.svg?style=flat-square)](LICENSE)
9
9
 
10
- **Versão:** `1.3.0` · [package.json](package.json)
10
+ **Versão:** `1.4.1` · [package.json](package.json)
11
11
 
12
12
  **Framework OXE — Orchestrated eXperience Engineering**
13
13
 
@@ -25,10 +25,10 @@ npx oxe-cc@latest
25
25
 
26
26
  OXE é o **Framework OXE — Orchestrated eXperience Engineering**: um framework de desenvolvimento assistido por IA orientado por artefatos, contexto em disco e execução verificável. Funciona identicamente em Cursor, GitHub Copilot, Claude Code, Gemini CLI, Windsurf e qualquer outro agente — o estado fica em `.oxe/` no seu projeto, não preso a nenhuma IDE.
27
27
 
28
- No momento atual, o OXE opera em duas camadas complementares:
28
+ No momento atual, o OXE opera em duas camadas complementares já prontas para publicação:
29
29
 
30
30
  - **framework de método** — `spec -> plan -> execute -> verify`, sessões, workstreams, lessons loop e contratos de raciocínio multi-runtime
31
- - **runtime enterprise incremental** — `ExecutionGraph`, `canonical_state`, context packs, evidence store, verification manifest, gates, policy, promotion e auditoria operacional
31
+ - **runtime enterprise** — `ExecutionGraph`, `canonical_state`, context packs, evidence store, verification manifest, gates, policy, promotion, recovery e auditoria operacional
32
32
 
33
33
  Ele se apoia em três princípios:
34
34
 
@@ -76,6 +76,28 @@ Em termos práticos, o estado operacional real agora passa por:
76
76
  - `.oxe/execution/GATES.json`
77
77
  - `OXE-EVENTS.ndjson`
78
78
 
79
+ Contrato estável desta release:
80
+
81
+ - `execute` e `verify` são `runtime-first` quando `oxe-cc runtime` está disponível
82
+ - `status`, `doctor`, dashboard e CLI de runtime leem o mesmo estado canónico
83
+ - `multi-agent` é GA apenas com isolamento real (`git_worktree`); `inplace` não é backend válido para coordenação paralela
84
+ - `pr_draft` é o alvo remoto estável de promotion nesta publicação
85
+
86
+ → [Guia por papel](docs/ROLES.md) — executor, reviewer, operador de gate, mantenedor do pacote
87
+
88
+ ---
89
+
90
+ ## Para times
91
+
92
+ | Recurso | Link |
93
+ |---------|------|
94
+ | Primeiros 15 minutos | [QUICKSTART.md](QUICKSTART.md) |
95
+ | Guia por papel (executor / reviewer / operador) | [docs/ROLES.md](docs/ROLES.md) |
96
+ | Fluxo recomendado para times | [docs/TEAM-ADOPTION.md](docs/TEAM-ADOPTION.md) |
97
+ | Exemplo completo reproduzível | [docs/WALKTHROUGH.md](docs/WALKTHROUGH.md) |
98
+ | Incidentes e gates | [docs/INCIDENT-PLAYBOOK.md](docs/INCIDENT-PLAYBOOK.md) |
99
+ | Suporte por runtime (Cursor, Copilot, Claude Code…) | [docs/RUNTIME-SMOKE-MATRIX.md](docs/RUNTIME-SMOKE-MATRIX.md) |
100
+
79
101
  ---
80
102
 
81
103
  ## Modos de uso
@@ -382,6 +404,22 @@ Complexidade: S | M | L | XL
382
404
 
383
405
  Tarefas `XL` bloqueiam o gate sem sub-tarefas ou justificativa. `/oxe-obs` propaga automaticamente constraints para os R-IDs e Tns afetados.
384
406
 
407
+ #### Iteração correta do plano
408
+
409
+ Se o usuário quiser chamar `/oxe-plan` várias vezes até ficar satisfeito, o fluxo esperado é este:
410
+
411
+ - **Mesmo escopo e mesma `SPEC.md`, mas quer refinar tarefas, ondas, dependências, riscos ou validação**: usar `/oxe-plan --replan`
412
+ - **Mudou a estratégia técnica**: voltar para `/oxe-discuss` e depois `/oxe-plan --replan`
413
+ - **Mudou requisitos, critérios, prioridades ou aceite**: voltar para `/oxe-spec` e depois `/oxe-plan`
414
+
415
+ Regra prática:
416
+
417
+ - `spec` muda o **que** será entregue
418
+ - `discuss` muda o **como** ou o **porquê** da estratégia
419
+ - `plan --replan` muda **como quebrar e executar** a mesma entrega
420
+
421
+ Se já existir `PLAN.md` no escopo atual e o usuário chamar `/oxe-plan` de novo sem alterar a spec, o OXE deve tratar isso como **replan implícito**, preservando a seção **Replanejamento** e o histórico útil do plano anterior.
422
+
385
423
  ### Runtime operacional e checkpoints
386
424
 
387
425
  - `PLAN.md` continua estratégico.
@@ -402,19 +440,32 @@ oxe-cc status --full # health + coverage matrix + readiness gate no terminal
402
440
  oxe-cc runtime status # run ativo, cursor, onda atual
403
441
  oxe-cc runtime verify # verify enterprise: suite + evidence + manifest + risk ledger
404
442
  oxe-cc runtime gates list
443
+ oxe-cc runtime agents --json
405
444
  oxe-cc runtime promote --target pr_draft
406
445
  ```
407
446
 
408
- O `status --full` mostra em ANSI: readiness do ciclo, autoavaliação do plano, health lógico, contexto, gates pendentes, verify enterprise, quotas, audit trail e promotion state.
447
+ O `status --full` mostra em ANSI: readiness do ciclo, autoavaliação do plano, health lógico, contexto, gates pendentes, verify enterprise, quotas, audit trail, recovery state, multi-agent e promotion state.
409
448
 
410
449
  ### Dashboard web — opt-in para revisões de equipe
411
450
 
412
- - `oxe-cc dashboard` sobe uma interface web local em `localhost` para revisar o plano antes da execução — indicado para apresentações ou revisões em equipe, não para uso diário.
451
+ - `oxe-cc dashboard` sobe uma interface web local em `localhost` para revisar o plano antes da execução — indicado para apresentações, operação de gates e revisões em equipe, não para substituir o terminal no dia a dia.
413
452
  - A UI lê os artefatos OXE reais; ela não substitui `PLAN.md`, `STATE.md` ou `VERIFY.md`.
414
- - A visão inclui ciclo principal, mapa de artefatos, active run, trace log, trilha de ondas, handoffs, checkpoints, agentes, evidências, gates, quotas, audit summary e promotion state sem criar uma segunda fonte de verdade.
415
- - `oxe-cc runtime <start|pause|resume|replay|status|compile|verify|project|ci|promote|recover|gates>` controla explicitamente `ACTIVE-RUN.json`, `runs/`, `GATES.json`, manifests de verify e `OXE-EVENTS.ndjson` no mesmo contrato consumido pelo dashboard.
453
+ - A visão inclui ciclo principal, mapa de artefatos, active run, trace log, trilha de ondas, handoffs, checkpoints, agentes, evidências, gates, quotas, audit summary, recovery state e promotion state sem criar uma segunda fonte de verdade.
454
+ - `oxe-cc runtime <start|pause|resume|replay|status|compile|verify|project|ci|promote|recover|gates|agents>` controla explicitamente `ACTIVE-RUN.json`, `runs/`, `GATES.json`, manifests de verify, artefatos de recovery, `multi-agent-state.json` e `OXE-EVENTS.ndjson` no mesmo contrato consumido pelo dashboard.
416
455
  - A aprovação visual persiste em `plan_review_status` no `STATE.md`, em `PLAN-REVIEW.md` e em `plan-review-comments.json`.
417
456
 
457
+ ### Critérios de publicação desta release
458
+
459
+ O pacote está pronto para uma publicação robusta quando estes sinais estiverem verdes no repositório da release:
460
+
461
+ - `npm test`
462
+ - `npm run scan:assets`
463
+ - `npm run build:vscode-ext`
464
+ - `node bin/oxe-cc.js doctor`
465
+ - `node bin/oxe-cc.js status --full`
466
+
467
+ Não há outro bloqueador funcional do plano runtime core para esta publicação. O que sobra depois dela é evolução de ergonomia e expansão de targets, não correção estrutural do contrato atual.
468
+
418
469
  ### `/oxe-retro` — loop de aprendizado
419
470
 
420
471
  ```
@@ -511,18 +562,19 @@ node bin/oxe-cc.js --help
511
562
  | `oxe-cc doctor` | Diagnóstico completo: Node, workflows, config, bootstrap `.oxe/`, sessão ativa, autoavaliação do plano, saúde lógica (`healthy` \| `warning` \| `broken`), drift semântico multi-runtime e workflows sem contrato no registry |
512
563
  | `oxe-cc status` | Próximo passo sugerido + saúde lógica do fluxo |
513
564
  | `oxe-cc status --full` | Coverage matrix + readiness gate + active run no terminal (ANSI) |
514
- | `oxe-cc status --json` | Mesmo, em JSON (schema v5), com `healthStatus`, `activeSession`, `planSelfEvaluation`, `contextPacks`, `contextQuality`, `semanticsDrift`, `verificationSummary`, `residualRiskSummary`, `evidenceCoverage`, `pendingGates`, `policyDecisionSummary`, `quotaSummary`, `auditSummary` e `promotionSummary` |
565
+ | `oxe-cc status --json` | Mesmo, em JSON (schema v5), com `healthStatus`, `activeSession`, `planSelfEvaluation`, `contextPacks`, `contextQuality`, `semanticsDrift`, `verificationSummary`, `residualRiskSummary`, `evidenceCoverage`, `pendingGates`, `policyDecisionSummary`, `quotaSummary`, `auditSummary`, `promotionSummary`, `runtimeMode`, `fallbackMode`, `gateQueue`, `policyCoverage`, `promotionReadiness`, `recoveryState`, `multiAgent` e `providerCatalog` |
515
566
  | `oxe-cc context build [--workflow <slug>] [--tier <minimal\|standard\|full>]` | Gera context pack(s) em `.oxe/context/packs/` — seleção determinística de artefatos por contrato de workflow |
516
567
  | `oxe-cc context inspect [--workflow <slug>]` | Inspeciona um context pack existente ou resolve sob demanda (sem escrita); útil para diagnóstico antes de iniciar um passo |
517
568
  | `oxe-cc update` | Atualiza workflows para a versão mais recente |
518
569
  | `oxe-cc init-oxe` | Bootstrap do `.oxe/` (STATE, config, codebase/, context/, install/) |
519
570
  | `oxe-cc dashboard` | Interface web local para revisão, comentários e aprovação do plano (inclui aba Context com quality score e drift semântico) |
520
- | `oxe-cc runtime <status\|start\|pause\|resume\|replay\|compile\|verify\|project\|ci\|promote\|recover\|gates>` | Controla o runtime enterprise: run ativo, grafo compilado, verify executável, gates, promoção remota, recovery e tracing operacional |
521
- | `oxe-cc runtime replay [--run <id>] [--from <event-id>] [--wave <n>] [--write]` | Timeline de eventos com deltas; `--write` gera `REPLAY-SESSION.md` |
571
+ | `oxe-cc runtime <status\|start\|pause\|resume\|replay\|compile\|verify\|project\|ci\|promote\|recover\|gates\|agents>` | Controla o runtime enterprise: run ativo, grafo compilado, verify executável, gates, promoção remota, recovery, multi-agent e tracing operacional |
572
+ | `oxe-cc runtime replay [--run <id>] [--from <event-id>] [--wave <n>] [--write] [--json]` | Timeline operacional estruturada; `--write` gera `REPLAY-SESSION.md` com divergências e deltas |
522
573
  | `oxe-cc runtime verify` | Executa `compileVerification + executeSuite + EvidenceStore + manifest + residual risk + projections` para a run ativa |
523
- | `oxe-cc runtime gates <list\|show\|resolve>` | Lista, inspeciona e resolve gates operacionais persistidos |
524
- | `oxe-cc runtime promote --target <pr_draft\|branch_push>` | Promoção remota explícita, separada de `ship`, governada por verify, gates, risk e coverage |
525
- | `oxe-cc runtime recover` | Reidrata journal, gates, policy decisions, evidence refs e estado canónico da run ativa |
574
+ | `oxe-cc runtime gates <list\|show\|resolve>` | Lista, inspeciona e resolve gates operacionais persistidos; `list` aceita `--run`, `--status`, `--scope`, `--task` e `--json` |
575
+ | `oxe-cc runtime agents status [--run <id>] [--json]` | Inspeciona ownership, handoffs, heartbeats, timeouts e failover multi-agent |
576
+ | `oxe-cc runtime promote --target pr_draft` | Promoção remota explícita, separada de `ship`, governada por verify, gates, risk e coverage; `pr_draft` é o alvo estável desta release |
577
+ | `oxe-cc runtime recover [--run <id>] [--json]` | Reidrata journal, gates, policy decisions, evidence refs, verification artifacts e estado canónico da run |
526
578
  | `oxe-cc capabilities <list\|install\|remove\|update>` | Mantém o catálogo nativo de capabilities em `.oxe/` |
527
579
  | `oxe-cc plugins <list\|install\|remove>` | Gerencia plugins de lifecycle; `install npm:<pkg>` instala em `.oxe/plugins/_npm/` |
528
580
  | `oxe-cc uninstall` | Remove integrações OXE do HOME e do repo |
@@ -607,4 +659,4 @@ TypeScript: [`lib/sdk/index.d.ts`](lib/sdk/index.d.ts) · Docs: [`lib/sdk/README
607
659
 
608
660
  ## Licença
609
661
 
610
- [GPL-3.0](LICENSE)
662
+ [MIT](LICENSE)
package/bin/banner.txt CHANGED
@@ -7,11 +7,11 @@
7
7
 
8
8
  ══════════════════════════════════════════════════════
9
9
 
10
- 🌵 OXE CLI · Spec-driven workflow
11
- "Do jeito nordestino de fazer software"
12
-
13
- ⚙️ Context Engineering
14
- 🤖 Multi-IDE · Cursor · Copilot · +CLIs
10
+ 🌵 OXE CLI · Runtime Enterprise
11
+ "Spec-driven workflow com estado canónico"
12
+
13
+ ⚙️ Context Engineering · Evidence-first Verify
14
+ 🤖 Multi-IDE · Copilot · Cursor · +CLIs
15
15
 
16
16
  ══════════════════════════════════════════════════════
17
17
 
@@ -13,8 +13,13 @@ const path = require('path');
13
13
  const os = require('os');
14
14
  const runtimeSemantics = require('./oxe-runtime-semantics.cjs');
15
15
 
16
- const OXE_MANAGED_HTML = '<!-- oxe-cc managed -->';
17
- const OXE_MANAGED_TOML = '# oxe-cc managed';
16
+ const OXE_MANAGED_HTML = '<!-- oxe-cc managed -->';
17
+ const OXE_MANAGED_TOML = '# oxe-cc managed';
18
+
19
+ /** @param {string} name */
20
+ function isOxeCommandMarkdownName(name) {
21
+ return (name === 'oxe.md' || name.startsWith('oxe-')) && name.endsWith('.md');
22
+ }
18
23
 
19
24
  function expandTilde(p) {
20
25
  if (typeof p !== 'string') return p;
@@ -223,13 +228,13 @@ function installSkillTreeFromCursorCommands(cCmdSrc, skillsRoot, opts, pathRewri
223
228
  * Copia .md dos comandos Cursor para pastas OpenCode (markdown nativo).
224
229
  * @param {AgentInstallPaths} paths
225
230
  */
226
- function installOpenCodeCommands(cCmdSrc, paths, opts, pathRewriteNested, logOmitido, logWrite) {
227
- if (!fs.existsSync(cCmdSrc)) return;
228
- for (const destDir of paths.opencodeCommandDirs) {
229
- for (const name of fs.readdirSync(cCmdSrc)) {
230
- if (!name.startsWith('oxe-') || !name.endsWith('.md')) continue;
231
- const src = path.join(cCmdSrc, name);
232
- const dest = path.join(destDir, name);
231
+ function installOpenCodeCommands(cCmdSrc, paths, opts, pathRewriteNested, logOmitido, logWrite) {
232
+ if (!fs.existsSync(cCmdSrc)) return;
233
+ for (const destDir of paths.opencodeCommandDirs) {
234
+ for (const name of fs.readdirSync(cCmdSrc)) {
235
+ if (!isOxeCommandMarkdownName(name)) continue;
236
+ const src = path.join(cCmdSrc, name);
237
+ const dest = path.join(destDir, name);
233
238
  if (opts.dryRun) {
234
239
  if (logWrite) logWrite(`opencode ${src} → ${dest}`);
235
240
  continue;
@@ -345,13 +350,13 @@ function installWindsurfGlobalWorkflows(cCmdSrc, paths, opts, pathRewriteNested,
345
350
  * Codex: prompts em ~/.codex/prompts ou ./.codex/prompts (local).
346
351
  * @param {AgentInstallPaths} paths
347
352
  */
348
- function installCodexPrompts(cCmdSrc, paths, opts, pathRewriteNested, logOmitido, logWrite) {
349
- if (!fs.existsSync(cCmdSrc)) return;
350
- const destDir = paths.codexPromptsDir;
351
- for (const name of fs.readdirSync(cCmdSrc)) {
352
- if (!name.startsWith('oxe-') || !name.endsWith('.md')) continue;
353
- const src = path.join(cCmdSrc, name);
354
- const dest = path.join(destDir, name);
353
+ function installCodexPrompts(cCmdSrc, paths, opts, pathRewriteNested, logOmitido, logWrite) {
354
+ if (!fs.existsSync(cCmdSrc)) return;
355
+ const destDir = paths.codexPromptsDir;
356
+ for (const name of fs.readdirSync(cCmdSrc)) {
357
+ if (!isOxeCommandMarkdownName(name)) continue;
358
+ const src = path.join(cCmdSrc, name);
359
+ const dest = path.join(destDir, name);
355
360
  if (opts.dryRun) {
356
361
  if (logWrite) logWrite(`codex prompts ${src} → ${dest}`);
357
362
  continue;
@@ -385,8 +390,10 @@ function installCodexPrompts(cCmdSrc, paths, opts, pathRewriteNested, logOmitido
385
390
  * @param {{ dryRun: boolean }} u
386
391
  * @param {AgentInstallPaths} [paths] omissão = instalação global (HOME)
387
392
  */
388
- function cleanupMarkedUnifiedArtifacts(u, paths) {
389
- const p = paths || buildAgentInstallPaths(true, process.cwd());
393
+ function cleanupMarkedUnifiedArtifacts(u, paths) {
394
+ const p = paths || buildAgentInstallPaths(true, process.cwd());
395
+ const targets = u && typeof u === 'object' && u.targets && typeof u.targets === 'object' ? u.targets : null;
396
+ const shouldClean = (name) => !targets || targets[name] !== false;
390
397
 
391
398
  const unlinkQuiet = (filePath) => {
392
399
  if (!fs.existsSync(filePath)) return;
@@ -416,92 +423,104 @@ function cleanupMarkedUnifiedArtifacts(u, paths) {
416
423
  }
417
424
  };
418
425
 
419
- for (const dir of p.opencodeCommandDirs) {
420
- if (!fs.existsSync(dir)) continue;
421
- for (const name of fs.readdirSync(dir)) {
422
- if (!name.startsWith('oxe-') || !name.endsWith('.md')) continue;
423
- const filePath = path.join(dir, name);
424
- let txt = '';
425
- try {
426
- txt = fs.readFileSync(filePath, 'utf8');
427
- } catch {
428
- continue;
429
- }
430
- if (txt.includes(OXE_MANAGED_HTML)) unlinkQuiet(filePath);
431
- }
432
- }
433
-
434
- const gBase = p.geminiCommandsBase;
435
- const oxeToml = path.join(gBase, 'oxe.toml');
436
- if (fs.existsSync(oxeToml)) {
437
- try {
438
- if (fs.readFileSync(oxeToml, 'utf8').includes(OXE_MANAGED_TOML)) unlinkQuiet(oxeToml);
439
- } catch {
440
- /* ignore */
441
- }
442
- }
443
- const oxeSub = path.join(gBase, 'oxe');
444
- if (fs.existsSync(oxeSub)) {
445
- for (const name of fs.readdirSync(oxeSub)) {
446
- if (!name.endsWith('.toml')) continue;
447
- const filePath = path.join(oxeSub, name);
448
- try {
449
- if (fs.readFileSync(filePath, 'utf8').includes(OXE_MANAGED_TOML)) unlinkQuiet(filePath);
450
- } catch {
451
- /* ignore */
452
- }
453
- }
454
- try {
455
- if (!u.dryRun && fs.existsSync(oxeSub) && fs.readdirSync(oxeSub).length === 0) fs.rmdirSync(oxeSub);
456
- } catch {
457
- /* ignore */
458
- }
459
- }
460
-
461
- const wfDir = p.windsurfWorkflowsDir;
462
- if (fs.existsSync(wfDir)) {
463
- for (const name of fs.readdirSync(wfDir)) {
464
- if (name !== 'oxe.md' && !(name.startsWith('oxe-') && name.endsWith('.md'))) continue;
465
- const filePath = path.join(wfDir, name);
466
- try {
467
- if (fs.readFileSync(filePath, 'utf8').includes(OXE_MANAGED_HTML)) unlinkQuiet(filePath);
468
- } catch {
469
- /* ignore */
470
- }
471
- }
472
- }
473
-
474
- const cpDir = p.codexPromptsDir;
475
- if (fs.existsSync(cpDir)) {
476
- for (const name of fs.readdirSync(cpDir)) {
477
- if (!name.startsWith('oxe-') || !name.endsWith('.md')) continue;
478
- const filePath = path.join(cpDir, name);
479
- try {
480
- if (fs.readFileSync(filePath, 'utf8').includes(OXE_MANAGED_HTML)) unlinkQuiet(filePath);
481
- } catch {
482
- /* ignore */
483
- }
484
- }
485
- }
486
-
487
- const agRoot = p.antigravitySkillsRoot;
488
- if (fs.existsSync(agRoot)) {
489
- for (const name of fs.readdirSync(agRoot, { withFileTypes: true })) {
490
- if (!name.isDirectory()) continue;
491
- if (!/^oxe($|-)/.test(name.name)) continue;
492
- rmDirIfOxeSkill(path.join(agRoot, name.name));
493
- }
494
- }
495
-
496
- const cxRoot = p.codexAgentsSkillsRoot;
497
- if (fs.existsSync(cxRoot)) {
498
- for (const name of fs.readdirSync(cxRoot, { withFileTypes: true })) {
499
- if (!name.isDirectory()) continue;
500
- if (!/^oxe($|-)/.test(name.name)) continue;
501
- rmDirIfOxeSkill(path.join(cxRoot, name.name));
502
- }
503
- }
504
- }
426
+ if (shouldClean('opencode')) {
427
+ for (const dir of p.opencodeCommandDirs) {
428
+ if (!fs.existsSync(dir)) continue;
429
+ for (const name of fs.readdirSync(dir)) {
430
+ if (!isOxeCommandMarkdownName(name)) continue;
431
+ const filePath = path.join(dir, name);
432
+ let txt = '';
433
+ try {
434
+ txt = fs.readFileSync(filePath, 'utf8');
435
+ } catch {
436
+ continue;
437
+ }
438
+ if (txt.includes(OXE_MANAGED_HTML)) unlinkQuiet(filePath);
439
+ }
440
+ }
441
+ }
442
+
443
+ if (shouldClean('gemini')) {
444
+ const gBase = p.geminiCommandsBase;
445
+ const oxeToml = path.join(gBase, 'oxe.toml');
446
+ if (fs.existsSync(oxeToml)) {
447
+ try {
448
+ if (fs.readFileSync(oxeToml, 'utf8').includes(OXE_MANAGED_TOML)) unlinkQuiet(oxeToml);
449
+ } catch {
450
+ /* ignore */
451
+ }
452
+ }
453
+ const oxeSub = path.join(gBase, 'oxe');
454
+ if (fs.existsSync(oxeSub)) {
455
+ for (const name of fs.readdirSync(oxeSub)) {
456
+ if (!name.endsWith('.toml')) continue;
457
+ const filePath = path.join(oxeSub, name);
458
+ try {
459
+ if (fs.readFileSync(filePath, 'utf8').includes(OXE_MANAGED_TOML)) unlinkQuiet(filePath);
460
+ } catch {
461
+ /* ignore */
462
+ }
463
+ }
464
+ try {
465
+ if (!u.dryRun && fs.existsSync(oxeSub) && fs.readdirSync(oxeSub).length === 0) fs.rmdirSync(oxeSub);
466
+ } catch {
467
+ /* ignore */
468
+ }
469
+ }
470
+ }
471
+
472
+ if (shouldClean('windsurf')) {
473
+ const wfDir = p.windsurfWorkflowsDir;
474
+ if (fs.existsSync(wfDir)) {
475
+ for (const name of fs.readdirSync(wfDir)) {
476
+ if (!isOxeCommandMarkdownName(name)) continue;
477
+ const filePath = path.join(wfDir, name);
478
+ try {
479
+ if (fs.readFileSync(filePath, 'utf8').includes(OXE_MANAGED_HTML)) unlinkQuiet(filePath);
480
+ } catch {
481
+ /* ignore */
482
+ }
483
+ }
484
+ }
485
+ }
486
+
487
+ if (shouldClean('codex')) {
488
+ const cpDir = p.codexPromptsDir;
489
+ if (fs.existsSync(cpDir)) {
490
+ for (const name of fs.readdirSync(cpDir)) {
491
+ if (!isOxeCommandMarkdownName(name)) continue;
492
+ const filePath = path.join(cpDir, name);
493
+ try {
494
+ if (fs.readFileSync(filePath, 'utf8').includes(OXE_MANAGED_HTML)) unlinkQuiet(filePath);
495
+ } catch {
496
+ /* ignore */
497
+ }
498
+ }
499
+ }
500
+ }
501
+
502
+ if (shouldClean('antigravity')) {
503
+ const agRoot = p.antigravitySkillsRoot;
504
+ if (fs.existsSync(agRoot)) {
505
+ for (const name of fs.readdirSync(agRoot, { withFileTypes: true })) {
506
+ if (!name.isDirectory()) continue;
507
+ if (!/^oxe($|-)/.test(name.name)) continue;
508
+ rmDirIfOxeSkill(path.join(agRoot, name.name));
509
+ }
510
+ }
511
+ }
512
+
513
+ if (shouldClean('codex')) {
514
+ const cxRoot = p.codexAgentsSkillsRoot;
515
+ if (fs.existsSync(cxRoot)) {
516
+ for (const name of fs.readdirSync(cxRoot, { withFileTypes: true })) {
517
+ if (!name.isDirectory()) continue;
518
+ if (!/^oxe($|-)/.test(name.name)) continue;
519
+ rmDirIfOxeSkill(path.join(cxRoot, name.name));
520
+ }
521
+ }
522
+ }
523
+ }
505
524
 
506
525
  module.exports = {
507
526
  OXE_MANAGED_HTML,
@@ -520,6 +539,7 @@ module.exports = {
520
539
  geminiUserDir,
521
540
  codexAgentsSkillsRoot,
522
541
  codexPromptsDir,
523
- antigravitySkillsRoot,
524
- cleanupMarkedUnifiedArtifacts,
525
- };
542
+ antigravitySkillsRoot,
543
+ isOxeCommandMarkdownName,
544
+ cleanupMarkedUnifiedArtifacts,
545
+ };
@@ -253,13 +253,23 @@ function humanizeValue(value) {
253
253
  return labels[key] || key.replace(/_/g, ' ');
254
254
  }
255
255
 
256
- function buildContextPackPaths(slug) {
257
- return {
258
- markdown: `.oxe/context/packs/${slug}.md`,
259
- json: `.oxe/context/packs/${slug}.json`,
260
- inspectCommand: `oxe-cc context inspect --workflow ${slug} --json`,
261
- };
262
- }
256
+ function buildContextPackPaths(slug) {
257
+ return {
258
+ markdown: `.oxe/context/packs/${slug}.md`,
259
+ json: `.oxe/context/packs/${slug}.json`,
260
+ inspectCommand: `oxe-cc context inspect --workflow ${slug} --json`,
261
+ };
262
+ }
263
+
264
+ function buildWorkflowResolutionBlock(slug) {
265
+ return [
266
+ '<!-- oxe-workflow-resolution:start -->',
267
+ '',
268
+ `**Resolução do workflow canónico:** a partir do CWD atual, subir diretórios até encontrar .oxe/workflows/${slug}.md ou oxe/workflows/${slug}.md. Ler e aplicar integralmente o primeiro ficheiro encontrado. Não assumir que o CWD já é a raiz do repositório. Se nenhum existir, reportar os paths tentados e parar.`,
269
+ '',
270
+ '<!-- oxe-workflow-resolution:end -->',
271
+ ].join('\n');
272
+ }
263
273
 
264
274
  function buildReasoningContractBlock(meta, options = {}) {
265
275
  const includeReference = options.includeReference !== false;
@@ -336,13 +346,14 @@ function parseFrontmatterMap(raw) {
336
346
  return out;
337
347
  }
338
348
 
339
- function auditWrapperText(slug, raw) {
340
- const frontmatter = parseFrontmatterMap(raw);
341
- const expected = getRuntimeMetadataForSlug(slug);
342
- const expectedPack = buildContextPackPaths(slug);
343
- const issues = [];
344
- for (const key of RUNTIME_METADATA_KEYS) {
345
- if ((frontmatter[key] || '') !== (expected[key] || '')) {
349
+ function auditWrapperText(slug, raw) {
350
+ const frontmatter = parseFrontmatterMap(raw);
351
+ const expected = getRuntimeMetadataForSlug(slug);
352
+ const expectedPack = buildContextPackPaths(slug);
353
+ const workflowResolution = buildWorkflowResolutionBlock(slug);
354
+ const issues = [];
355
+ for (const key of RUNTIME_METADATA_KEYS) {
356
+ if ((frontmatter[key] || '') !== (expected[key] || '')) {
346
357
  issues.push({ key, expected: expected[key] || '', actual: frontmatter[key] || '' });
347
358
  }
348
359
  }
@@ -355,11 +366,43 @@ function auditWrapperText(slug, raw) {
355
366
  if (!String(raw || '').includes(expectedPack.markdown) || !String(raw || '').includes(expectedPack.json)) {
356
367
  issues.push({ key: 'oxe_context_pack_entry', expected: `${expectedPack.markdown} + ${expectedPack.json}`, actual: 'missing' });
357
368
  }
358
- if (!String(raw || '').includes('Regra pack-first')) {
359
- issues.push({ key: 'oxe_pack_first_rule', expected: 'present', actual: 'missing' });
360
- }
361
- return {
362
- slug,
369
+ if (!String(raw || '').includes('Regra pack-first')) {
370
+ issues.push({ key: 'oxe_pack_first_rule', expected: 'present', actual: 'missing' });
371
+ }
372
+ if (!String(raw || '').includes('<!-- oxe-workflow-resolution:start -->')) {
373
+ issues.push({ key: 'oxe_workflow_resolution_block', expected: 'present', actual: 'missing' });
374
+ } else {
375
+ if (!String(raw || '').includes(`.oxe/workflows/${slug}.md`) || !String(raw || '').includes(`oxe/workflows/${slug}.md`)) {
376
+ issues.push({
377
+ key: 'oxe_workflow_resolution_paths',
378
+ expected: workflowResolution,
379
+ actual: 'missing_path_reference',
380
+ });
381
+ }
382
+ if (!/subir diretórios até encontrar/i.test(String(raw || ''))) {
383
+ issues.push({
384
+ key: 'oxe_workflow_resolution_walkup',
385
+ expected: 'subir diretórios até encontrar',
386
+ actual: 'missing',
387
+ });
388
+ }
389
+ }
390
+ if (/\*\*Workflow can[óôo]nic[oa]:\*\*/i.test(String(raw || ''))) {
391
+ issues.push({
392
+ key: 'legacy_workflow_anchor',
393
+ expected: 'absent',
394
+ actual: 'present',
395
+ });
396
+ }
397
+ if (/raiz do projeto atual \(CWD\)|na raiz do repositório em contexto|na raiz do repositório em que estás a trabalhar/i.test(String(raw || ''))) {
398
+ issues.push({
399
+ key: 'legacy_fixed_root_instruction',
400
+ expected: 'absent',
401
+ actual: 'present',
402
+ });
403
+ }
404
+ return {
405
+ slug,
363
406
  frontmatter,
364
407
  expected,
365
408
  issues,
@@ -453,11 +496,12 @@ module.exports = {
453
496
  REQUIRED_CONTRACT_FIELDS,
454
497
  RUNTIME_METADATA_KEYS,
455
498
  auditRuntimeTargets,
456
- auditWrapperText,
457
- buildContextPackPaths,
458
- buildContextTiers,
459
- buildReasoningContractBlock,
460
- computeSemanticsHash,
499
+ auditWrapperText,
500
+ buildContextPackPaths,
501
+ buildContextTiers,
502
+ buildReasoningContractBlock,
503
+ buildWorkflowResolutionBlock,
504
+ computeSemanticsHash,
461
505
  getAllWorkflowContracts,
462
506
  getRuntimeMetadataForSlug,
463
507
  getWorkflowContract,