oxe-cc 0.3.2 → 0.3.3
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/.github/copilot-instructions.md +2 -1
- package/AGENTS.md +1 -0
- package/README.md +8 -0
- package/bin/banner.txt +1 -1
- package/bin/oxe-cc.js +164 -11
- package/oxe/workflows/help.md +2 -0
- package/package.json +1 -1
|
@@ -31,7 +31,8 @@ Se o utilizador mencionar **OXE**, **oxe**, **/oxe-**, ou pedidos como “mapear
|
|
|
31
31
|
## Cursor vs Copilot
|
|
32
32
|
|
|
33
33
|
- **Cursor:** slash commands em `.cursor/commands/oxe-*.md` apontam para os mesmos workflows.
|
|
34
|
-
- **Copilot:** prompt files em `.github/prompts/oxe-*.prompt.md`; cada um indica o workflow em `oxe/workflows/<passo>.md` na raiz do repo. **`oxe-review-pr`** existe só como prompt Copilot (não há slash command Cursor correspondente).
|
|
34
|
+
- **Copilot (VS Code Chat):** prompt files em `.github/prompts/oxe-*.prompt.md`; cada um indica o workflow em `oxe/workflows/<passo>.md` na raiz do repo. **`oxe-review-pr`** existe só como prompt Copilot (não há slash command Cursor correspondente).
|
|
35
|
+
- **Copilot CLI (terminal, experimental):** com `oxe-cc --copilot-cli`, os mesmos textos são copiados para **`.claude/commands/oxe-*.md`** — versões recentes do CLI podem expor **`/oxe-scan`**, etc. Isto depende da versão do `copilot`; não faz parte do contrato estável do OXE.
|
|
35
36
|
|
|
36
37
|
## Manutenção deste pacote (oxe-build)
|
|
37
38
|
|
package/AGENTS.md
CHANGED
|
@@ -7,5 +7,6 @@ Este repositório empacota o fluxo **OXE** (spec-driven, artefatos em `.oxe/`).
|
|
|
7
7
|
- **Workflows canónicos:** [oxe/workflows/](oxe/workflows/) — editar aqui primeiro; Cursor e Copilot apontam para estes ficheiros (inclui `quick.md`, `execute.md`).
|
|
8
8
|
- **CLI:** `oxe-cc` instala assets e bootstrap (`.oxe/STATE.md`, `config.json`, `codebase/`); `oxe-cc doctor` valida workflows, JSON de config e mapa scan; `oxe-cc init-oxe` só inicializa `.oxe/`.
|
|
9
9
|
- **Prompt files (Copilot / VS Code):** [.github/prompts/*.prompt.md](.github/prompts/) — invocar com `/` no chat (ex. `/oxe-scan`, `/oxe-review-pr` para diff tipo PR) após `chat.promptFiles` estar ativo.
|
|
10
|
+
- **Copilot CLI (experimental):** `oxe-cc --copilot-cli` → `.claude/commands/oxe-*.md` para testar `/oxe-scan` no terminal.
|
|
10
11
|
|
|
11
12
|
Quando o utilizador pedir uma etapa OXE por linguagem natural, segue o ficheiro `oxe/workflows/<passo>.md` correspondente sem atalhar passos.
|
package/README.md
CHANGED
|
@@ -41,6 +41,10 @@ npx oxe-cc@latest
|
|
|
41
41
|
|
|
42
42
|
Isto copia, entre outros: **`oxe/`** (workflows + templates), **`.cursor/`** (slash commands), **`.github/`** (instruções Copilot + prompt files), **`commands/oxe/`** (atalhos estilo `oxe:*` para outros clientes), **`AGENTS.md`**, e cria um **`.oxe/`** mínimo (`STATE.md`, `config.json` a partir de template, pasta `codebase/`) — salvo flags como `--no-init-oxe`.
|
|
43
43
|
|
|
44
|
+
Em **terminal interativo**, no fim pergunta se queres instalar o **`oxe-cc` globalmente** (`npm install -g`) ou continuar só com **`npx`**. Em CI ou scripts usa **`--no-global-cli`** / **`-l`**, ou define **`OXE_NO_PROMPT=1`**. Para instalar o CLI sem pergunta: **`--global-cli`** / **`-g`**.
|
|
45
|
+
|
|
46
|
+
**GitHub Copilot CLI (experimental):** para testar slash commands no terminal, instala com **`--copilot-cli`** — copia **`.cursor/commands/*.md`** para **`.claude/commands/`** (ficheiros `oxe-scan.md`, etc., sem `prompt` no nome). Usa na raiz do repo: `npx oxe-cc@latest --force --copilot --copilot-cli`. Depois, na sessão do Copilot CLI, experimenta **`/oxe-scan`**. O suporte depende da versão do CLI; vê [discussão no copilot-cli](https://github.com/github/copilot-cli/issues/1113).
|
|
47
|
+
|
|
44
48
|
**Confirmar instalação no agente**
|
|
45
49
|
|
|
46
50
|
| Onde | O que correr |
|
|
@@ -62,6 +66,9 @@ Isto copia, entre outros: **`oxe/`** (workflows + templates), **`.cursor/`** (sl
|
|
|
62
66
|
| `--cursor` / `--copilot` | Instala só uma das stacks |
|
|
63
67
|
| `--oxe-only` | Só a pasta `oxe/` (workflows) |
|
|
64
68
|
| `--no-init-oxe` | Não cria `.oxe/` no fim |
|
|
69
|
+
| `--global-cli` / `-g` | Após copiar: `npm install -g oxe-cc@versão` (sem pergunta) |
|
|
70
|
+
| `--no-global-cli` / `-l` | Não pergunta nem instala o CLI global (útil em CI) |
|
|
71
|
+
| `--copilot-cli` | Copia comandos OXE para `.claude/commands/` (teste com GitHub Copilot CLI) |
|
|
65
72
|
| `--vscode` | Copia `.vscode/settings.json` de exemplo |
|
|
66
73
|
| `--no-commands` | Omite `commands/oxe/` |
|
|
67
74
|
| `--no-agents` | Omite `AGENTS.md` |
|
|
@@ -199,6 +206,7 @@ Preferências do projeto em **`.oxe/config.json`** (criado no bootstrap a partir
|
|
|
199
206
|
|----------|----------------|
|
|
200
207
|
| Comandos não aparecem no Cursor | Confirma que `.cursor/commands/` existe; reinicia o Cursor |
|
|
201
208
|
| Prompts `/oxe-*` não aparecem no Copilot | Ativa `"chat.promptFiles": true`; confirma `.github/prompts/*.prompt.md` |
|
|
209
|
+
| Slash `/oxe-*` no **Copilot CLI** | Instala com **`--copilot-cli`** (pasta `.claude/commands/`); atualiza o CLI; comportamento ainda experimental |
|
|
202
210
|
| **`ETARGET`** / versão não encontrada no `npx` | `npm cache clean --force`, `npx clear-npx-cache`, ou fixa versão: `npx oxe-cc@0.3.0`. Verifica `npm config get registry` |
|
|
203
211
|
| **404** no `npm view oxe-cc` | Pacote com outro nome (scope) ou ainda não publicado — usa `npm link` ou `node …/bin/oxe-cc.js` |
|
|
204
212
|
| Ficheiros não atualizam | Reinstala com **`--force`** |
|
package/bin/banner.txt
CHANGED
package/bin/oxe-cc.js
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
const fs = require('fs');
|
|
11
11
|
const path = require('path');
|
|
12
|
+
const readline = require('readline');
|
|
13
|
+
const { spawnSync } = require('child_process');
|
|
12
14
|
|
|
13
15
|
const PKG_ROOT = path.join(__dirname, '..');
|
|
14
16
|
|
|
@@ -20,6 +22,9 @@ const red = '\x1b[31m';
|
|
|
20
22
|
const bold = '\x1b[1m';
|
|
21
23
|
const reset = '\x1b[0m';
|
|
22
24
|
|
|
25
|
+
/** @type {string} */
|
|
26
|
+
const RULE = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━';
|
|
27
|
+
|
|
23
28
|
/** Plain banner if banner.txt is missing (keep in sync with bin/banner.txt style). */
|
|
24
29
|
const DEFAULT_BANNER = ` .============================================.
|
|
25
30
|
| OXE · spec-driven workflow CLI |
|
|
@@ -34,6 +39,18 @@ function useAnsiColors() {
|
|
|
34
39
|
return process.stdout.isTTY === true;
|
|
35
40
|
}
|
|
36
41
|
|
|
42
|
+
/** Section header (GSD-inspired). */
|
|
43
|
+
function printSection(title) {
|
|
44
|
+
const c = useAnsiColors();
|
|
45
|
+
if (!c) {
|
|
46
|
+
console.log(`\n${title}\n${'─'.repeat(50)}\n`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
console.log(`\n${dim}${RULE}${reset}`);
|
|
50
|
+
console.log(` ${cyan}${bold}${title}${reset}`);
|
|
51
|
+
console.log(`${dim}${RULE}${reset}\n`);
|
|
52
|
+
}
|
|
53
|
+
|
|
37
54
|
/** Print branded header; skip with OXE_NO_BANNER=1. Not used for --version (scripts). */
|
|
38
55
|
function printBanner() {
|
|
39
56
|
if (process.env.OXE_NO_BANNER === '1' || process.env.OXE_NO_BANNER === 'true') return;
|
|
@@ -49,6 +66,7 @@ function printBanner() {
|
|
|
49
66
|
}
|
|
50
67
|
}
|
|
51
68
|
const text = raw.replace(/\{version\}/g, ver).replace(/\r\n/g, '\n').trimEnd();
|
|
69
|
+
if (color) console.log(`${dim}${RULE}${reset}\n`);
|
|
52
70
|
if (!color) {
|
|
53
71
|
console.log(text + '\n');
|
|
54
72
|
return;
|
|
@@ -58,10 +76,11 @@ function printBanner() {
|
|
|
58
76
|
if (line.includes(`v${ver}`)) console.log(`${dim}${line}${reset}`);
|
|
59
77
|
else console.log(`${cyan}${bold}${line}${reset}`);
|
|
60
78
|
}
|
|
61
|
-
console.log(
|
|
79
|
+
if (color) console.log(`\n${dim}${RULE}${reset}\n`);
|
|
80
|
+
else console.log('');
|
|
62
81
|
}
|
|
63
82
|
|
|
64
|
-
/** @typedef {{ help: boolean, version: boolean, cursor: boolean, copilot: boolean, vscode: boolean, commands: boolean, agents: boolean, force: boolean, dryRun: boolean, dir: string, all: boolean, noInitOxe: boolean, oxeOnly: boolean, parseError: boolean, unknownFlag: string }} InstallOpts */
|
|
83
|
+
/** @typedef {{ help: boolean, version: boolean, cursor: boolean, copilot: boolean, copilotCli: boolean, vscode: boolean, commands: boolean, agents: boolean, force: boolean, dryRun: boolean, dir: string, all: boolean, noInitOxe: boolean, oxeOnly: boolean, globalCli: boolean, noGlobalCli: boolean, parseError: boolean, unknownFlag: string, conflictFlags: string }} InstallOpts */
|
|
65
84
|
|
|
66
85
|
/**
|
|
67
86
|
* @param {string[]} argv
|
|
@@ -74,6 +93,7 @@ function parseInstallArgs(argv) {
|
|
|
74
93
|
version: false,
|
|
75
94
|
cursor: false,
|
|
76
95
|
copilot: false,
|
|
96
|
+
copilotCli: false,
|
|
77
97
|
vscode: false,
|
|
78
98
|
commands: true,
|
|
79
99
|
agents: true,
|
|
@@ -83,8 +103,11 @@ function parseInstallArgs(argv) {
|
|
|
83
103
|
all: false,
|
|
84
104
|
noInitOxe: false,
|
|
85
105
|
oxeOnly: false,
|
|
106
|
+
globalCli: false,
|
|
107
|
+
noGlobalCli: false,
|
|
86
108
|
parseError: false,
|
|
87
109
|
unknownFlag: '',
|
|
110
|
+
conflictFlags: '',
|
|
88
111
|
restPositional: [],
|
|
89
112
|
};
|
|
90
113
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -93,6 +116,7 @@ function parseInstallArgs(argv) {
|
|
|
93
116
|
else if (a === '-v' || a === '--version') out.version = true;
|
|
94
117
|
else if (a === '--cursor') out.cursor = true;
|
|
95
118
|
else if (a === '--copilot') out.copilot = true;
|
|
119
|
+
else if (a === '--copilot-cli') out.copilotCli = true;
|
|
96
120
|
else if (a === '--vscode') out.vscode = true;
|
|
97
121
|
else if (a === '--no-commands') out.commands = false;
|
|
98
122
|
else if (a === '--no-agents') out.agents = false;
|
|
@@ -101,22 +125,28 @@ function parseInstallArgs(argv) {
|
|
|
101
125
|
else if (a === '--all' || a === '-a') out.all = true;
|
|
102
126
|
else if (a === '--no-init-oxe') out.noInitOxe = true;
|
|
103
127
|
else if (a === '--oxe-only') out.oxeOnly = true;
|
|
128
|
+
else if (a === '--global-cli' || a === '-g') out.globalCli = true;
|
|
129
|
+
else if (a === '--no-global-cli' || a === '-l') out.noGlobalCli = true;
|
|
104
130
|
else if (a === '--dir' && argv[i + 1]) {
|
|
105
131
|
out.dir = path.resolve(argv[++i]);
|
|
106
|
-
}
|
|
132
|
+
} else if (!a.startsWith('-')) out.restPositional.push(a);
|
|
107
133
|
else {
|
|
108
134
|
out.parseError = true;
|
|
109
135
|
out.unknownFlag = a;
|
|
110
136
|
break;
|
|
111
137
|
}
|
|
112
138
|
}
|
|
139
|
+
if (out.globalCli && out.noGlobalCli) {
|
|
140
|
+
out.conflictFlags = 'Cannot use both --global-cli (-g) and --no-global-cli (-l)';
|
|
141
|
+
}
|
|
113
142
|
if (out.oxeOnly) {
|
|
114
143
|
out.cursor = false;
|
|
115
144
|
out.copilot = false;
|
|
145
|
+
out.copilotCli = false;
|
|
116
146
|
out.vscode = false;
|
|
117
147
|
out.commands = false;
|
|
118
148
|
out.agents = false;
|
|
119
|
-
} else if (out.all || (!out.cursor && !out.copilot)) {
|
|
149
|
+
} else if (out.all || (!out.cursor && !out.copilot && !out.copilotCli)) {
|
|
120
150
|
out.cursor = true;
|
|
121
151
|
out.copilot = true;
|
|
122
152
|
}
|
|
@@ -134,6 +164,16 @@ function readPkgVersion() {
|
|
|
134
164
|
}
|
|
135
165
|
}
|
|
136
166
|
|
|
167
|
+
function readPkgName() {
|
|
168
|
+
try {
|
|
169
|
+
const p = path.join(PKG_ROOT, 'package.json');
|
|
170
|
+
const j = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
171
|
+
return typeof j.name === 'string' ? j.name : 'oxe-cc';
|
|
172
|
+
} catch {
|
|
173
|
+
return 'oxe-cc';
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
137
177
|
function readMinNode() {
|
|
138
178
|
try {
|
|
139
179
|
const p = path.join(PKG_ROOT, 'package.json');
|
|
@@ -228,10 +268,12 @@ function bootstrapOxe(target, opts) {
|
|
|
228
268
|
|
|
229
269
|
/** @param {string} target */
|
|
230
270
|
function runDoctor(target) {
|
|
271
|
+
printSection('OXE ▸ doctor');
|
|
231
272
|
const v = process.versions.node;
|
|
232
273
|
const major = parseInt(v.split('.')[0], 10);
|
|
233
274
|
const minNode = readMinNode();
|
|
234
|
-
|
|
275
|
+
const c = useAnsiColors();
|
|
276
|
+
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${target}${c ? reset : ''}`);
|
|
235
277
|
console.log(`Node.js ${v} (require >= ${minNode})`);
|
|
236
278
|
if (major < minNode) {
|
|
237
279
|
console.log(`${red}FAIL${reset} Node.js version below package engines`);
|
|
@@ -310,6 +352,87 @@ function runDoctor(target) {
|
|
|
310
352
|
console.log(`\n${green}Doctor finished.${reset}`);
|
|
311
353
|
}
|
|
312
354
|
|
|
355
|
+
/**
|
|
356
|
+
* npm install -g oxe-cc@version (same version as this running CLI).
|
|
357
|
+
* @returns {boolean}
|
|
358
|
+
*/
|
|
359
|
+
function installGlobalCliPackage() {
|
|
360
|
+
const name = readPkgName();
|
|
361
|
+
const ver = readPkgVersion();
|
|
362
|
+
const spec = `${name}@${ver}`;
|
|
363
|
+
const c = useAnsiColors();
|
|
364
|
+
const dimOrEmpty = c ? dim : '';
|
|
365
|
+
const resetOrEmpty = c ? reset : '';
|
|
366
|
+
console.log(`\n ${dimOrEmpty}npm install -g ${spec}${resetOrEmpty}\n`);
|
|
367
|
+
const r = spawnSync('npm', ['install', '-g', spec], {
|
|
368
|
+
stdio: 'inherit',
|
|
369
|
+
shell: true,
|
|
370
|
+
env: process.env,
|
|
371
|
+
});
|
|
372
|
+
if (r.status === 0) {
|
|
373
|
+
console.log(
|
|
374
|
+
`\n ${c ? green : ''}✓${c ? reset : ''} ${c ? cyan : ''}oxe-cc${c ? reset : ''} disponível globalmente (corre ${c ? cyan : ''}oxe-cc --help${c ? reset : ''} em qualquer pasta).\n`
|
|
375
|
+
);
|
|
376
|
+
return true;
|
|
377
|
+
}
|
|
378
|
+
console.log(
|
|
379
|
+
`\n ${c ? yellow : ''}⚠${c ? reset : ''} npm install -g falhou. Tenta manualmente: ${c ? cyan : ''}npm install -g ${spec}${c ? reset : ''}\n`
|
|
380
|
+
);
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* After copying OXE into the project: optionally install the CLI globally (like GSD’s “where to install” choice).
|
|
386
|
+
* @param {InstallOpts} opts
|
|
387
|
+
*/
|
|
388
|
+
function maybePromptGlobalCli(opts) {
|
|
389
|
+
if (opts.oxeOnly) return;
|
|
390
|
+
if (opts.dryRun) {
|
|
391
|
+
if (useAnsiColors()) console.log(`${dim} (dry-run — pergunta do CLI global ignorada)${reset}`);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
if (opts.globalCli) {
|
|
395
|
+
installGlobalCliPackage();
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (opts.noGlobalCli) return;
|
|
399
|
+
if (process.env.OXE_NO_PROMPT === '1' || process.env.OXE_NO_PROMPT === 'true') return;
|
|
400
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
401
|
+
const c = useAnsiColors();
|
|
402
|
+
if (c) {
|
|
403
|
+
console.log(
|
|
404
|
+
`\n ${yellow}Terminal não interativo${reset} — sem pergunta de CLI global. Usa ${cyan}npx oxe-cc@latest${reset} ou ${cyan}--global-cli${reset}.\n`
|
|
405
|
+
);
|
|
406
|
+
} else {
|
|
407
|
+
console.log('\nNon-interactive terminal — skipping global CLI prompt. Use npx oxe-cc@latest or --global-cli.\n');
|
|
408
|
+
}
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const c = useAnsiColors();
|
|
413
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
414
|
+
|
|
415
|
+
console.log(
|
|
416
|
+
` ${c ? yellow : ''}Instalar o comando oxe-cc globalmente?${c ? reset : ''}
|
|
417
|
+
(Os ficheiros OXE já foram copiados para o projeto.)
|
|
418
|
+
|
|
419
|
+
${c ? cyan : ''}1${c ? reset : ''}) ${c ? dim : ''}Não — uso ${c ? reset : ''}${c ? cyan : ''}npx oxe-cc@latest${c ? reset : ''}${c ? dim : ''} para atualizar (recomendado em CI)${c ? reset : ''}
|
|
420
|
+
${c ? cyan : ''}2${c ? reset : ''}) ${c ? dim : ''}Sim — ${c ? reset : ''}${c ? cyan : ''}npm install -g ${readPkgName()}@${readPkgVersion()}${c ? reset : ''}${c ? dim : ''} (${c ? reset : ''}${c ? cyan : ''}oxe-cc${c ? reset : ''}${c ? dim : ''} no PATH)${c ? reset : ''}
|
|
421
|
+
`
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
rl.question(` ${c ? cyan : ''}Escolha${c ? reset : ''} ${c ? dim : ''}[1]${c ? reset : ''}: `, (answer) => {
|
|
425
|
+
rl.close();
|
|
426
|
+
const choice = (answer || '1').trim();
|
|
427
|
+
if (choice === '2') installGlobalCliPackage();
|
|
428
|
+
else {
|
|
429
|
+
console.log(
|
|
430
|
+
`\n ${c ? green : ''}✓${c ? reset : ''} Para atualizar workflows: ${c ? cyan : ''}npx oxe-cc@latest --force${c ? reset : ''} na raiz do projeto.\n`
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
|
|
313
436
|
function usage() {
|
|
314
437
|
console.log(`
|
|
315
438
|
${cyan}oxe-cc${reset} — install OXE workflows (Cursor + GitHub Copilot) into a project
|
|
@@ -323,12 +446,15 @@ ${green}Usage:${reset}
|
|
|
323
446
|
${green}Install options:${reset}
|
|
324
447
|
--cursor Install .cursor/commands and .cursor/rules (default with --all)
|
|
325
448
|
--copilot Install .github/copilot-instructions.md and .github/prompts
|
|
449
|
+
--copilot-cli Copy .cursor/commands → .claude/commands (Copilot CLI slash /oxe-* — experimental)
|
|
326
450
|
--vscode Also copy .vscode/settings.json (chat.promptFiles)
|
|
327
451
|
--all, -a Cursor + Copilot (default when neither --cursor nor --copilot)
|
|
328
452
|
--no-commands Skip commands/oxe (Claude-style frontmatter)
|
|
329
453
|
--no-agents Skip AGENTS.md
|
|
330
454
|
--no-init-oxe Do not create .oxe/STATE.md + .oxe/codebase/ after install
|
|
331
455
|
--oxe-only Only copy oxe/ (skip Cursor, Copilot, commands, AGENTS.md)
|
|
456
|
+
--global-cli, -g After install: npm install -g oxe-cc@<version> (no prompt)
|
|
457
|
+
--no-global-cli, -l Skip the interactive “CLI global?” step (default in CI)
|
|
332
458
|
--force, -f Overwrite existing files
|
|
333
459
|
--dry-run Print actions without writing
|
|
334
460
|
--dir <path> Target directory (default: cwd)
|
|
@@ -344,6 +470,7 @@ ${green}Examples:${reset}
|
|
|
344
470
|
npx oxe-cc@latest
|
|
345
471
|
npx oxe-cc@latest ./my-app
|
|
346
472
|
npx oxe-cc@latest --cursor --dry-run
|
|
473
|
+
npx oxe-cc@latest --copilot --copilot-cli
|
|
347
474
|
npx oxe-cc doctor
|
|
348
475
|
npx oxe-cc init-oxe --dir ./my-app
|
|
349
476
|
`);
|
|
@@ -356,8 +483,10 @@ function runInstall(opts) {
|
|
|
356
483
|
process.exit(1);
|
|
357
484
|
}
|
|
358
485
|
|
|
359
|
-
|
|
360
|
-
|
|
486
|
+
printSection('OXE ▸ Copiar workflows para o projeto');
|
|
487
|
+
const c = useAnsiColors();
|
|
488
|
+
console.log(` ${c ? green : ''}Destino:${c ? reset : ''} ${c ? cyan : ''}${target}${c ? reset : ''}`);
|
|
489
|
+
if (opts.dryRun) console.log(` ${c ? yellow : ''}(dry-run)${c ? reset : ''}`);
|
|
361
490
|
|
|
362
491
|
const copyOpts = { dryRun: opts.dryRun, force: opts.force };
|
|
363
492
|
|
|
@@ -370,6 +499,20 @@ function runInstall(opts) {
|
|
|
370
499
|
if (fs.existsSync(cRules)) copyDir(cRules, path.join(target, '.cursor', 'rules'), copyOpts);
|
|
371
500
|
}
|
|
372
501
|
|
|
502
|
+
if (opts.copilotCli) {
|
|
503
|
+
const cCmd = path.join(PKG_ROOT, '.cursor', 'commands');
|
|
504
|
+
const dest = path.join(target, '.claude', 'commands');
|
|
505
|
+
const c = useAnsiColors();
|
|
506
|
+
if (fs.existsSync(cCmd)) {
|
|
507
|
+
console.log(
|
|
508
|
+
` ${c ? green : ''}cli${c ? reset : ''} ${c ? dim : ''}Copilot CLI:${c ? reset : ''} ${c ? cyan : ''}.claude/commands/${c ? reset : ''}${c ? dim : ''} (experimental — teste /oxe-scan na sessão)${c ? reset : ''}`
|
|
509
|
+
);
|
|
510
|
+
copyDir(cCmd, dest, copyOpts);
|
|
511
|
+
} else {
|
|
512
|
+
console.warn(`${yellow}warn:${reset} missing ${cCmd} — skip --copilot-cli`);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
373
516
|
if (opts.copilot) {
|
|
374
517
|
const gh = path.join(PKG_ROOT, '.github');
|
|
375
518
|
const inst = path.join(gh, 'copilot-instructions.md');
|
|
@@ -416,7 +559,7 @@ function runInstall(opts) {
|
|
|
416
559
|
if (!opts.noInitOxe) bootstrapOxe(target, { dryRun: opts.dryRun, force: opts.force });
|
|
417
560
|
|
|
418
561
|
console.log(
|
|
419
|
-
`\n${green}
|
|
562
|
+
`\n ${c ? green : ''}✓${c ? reset : ''} Ficheiros OXE instalados. Abre no Cursor (${c ? cyan : ''}/oxe-scan${c ? reset : ''}) ou VS Code + Copilot (prompt ${c ? cyan : ''}/oxe-scan${c ? reset : ''}).`
|
|
420
563
|
);
|
|
421
564
|
}
|
|
422
565
|
|
|
@@ -435,6 +578,13 @@ function main() {
|
|
|
435
578
|
process.exit(0);
|
|
436
579
|
}
|
|
437
580
|
|
|
581
|
+
if (opts.conflictFlags) {
|
|
582
|
+
printBanner();
|
|
583
|
+
console.error(`${red}${opts.conflictFlags}${reset}`);
|
|
584
|
+
usage();
|
|
585
|
+
process.exit(1);
|
|
586
|
+
}
|
|
587
|
+
|
|
438
588
|
if (opts.parseError) {
|
|
439
589
|
printBanner();
|
|
440
590
|
console.error(`${red}Unknown option:${reset} ${opts.unknownFlag}`);
|
|
@@ -465,14 +615,17 @@ function main() {
|
|
|
465
615
|
console.error(`${yellow}Target directory does not exist: ${target}${reset}`);
|
|
466
616
|
process.exit(1);
|
|
467
617
|
}
|
|
468
|
-
|
|
469
|
-
|
|
618
|
+
printSection('OXE ▸ init-oxe');
|
|
619
|
+
const c0 = useAnsiColors();
|
|
620
|
+
console.log(` ${c0 ? green : ''}Destino:${c0 ? reset : ''} ${c0 ? cyan : ''}${target}${c0 ? reset : ''}`);
|
|
621
|
+
if (opts.dryRun) console.log(` ${c0 ? yellow : ''}(dry-run)${c0 ? reset : ''}`);
|
|
470
622
|
bootstrapOxe(target, { dryRun: opts.dryRun, force: opts.force });
|
|
471
|
-
console.log(`\n${green}
|
|
623
|
+
console.log(`\n ${c0 ? green : ''}✓${c0 ? reset : ''} Concluído.\n`);
|
|
472
624
|
return;
|
|
473
625
|
}
|
|
474
626
|
|
|
475
627
|
runInstall(opts);
|
|
628
|
+
maybePromptGlobalCli(opts);
|
|
476
629
|
}
|
|
477
630
|
|
|
478
631
|
main();
|
package/oxe/workflows/help.md
CHANGED
|
@@ -49,4 +49,6 @@ Slash commands: `/oxe-scan`, `/oxe-spec`, `/oxe-discuss`, `/oxe-plan`, `/oxe-ver
|
|
|
49
49
|
Quando o utilizador disser “oxe scan”, “oxe quick”, “executar onda OXE”, “revisar PR”, “diff entre branches”, etc., seguir o workflow correspondente em `oxe/workflows/*.md`.
|
|
50
50
|
|
|
51
51
|
**Nota:** **`oxe-review-pr`** não tem homólogo em `.cursor/commands/`; no Cursor podes pedir em linguagem natural seguindo `oxe/workflows/review-pr.md` ou abrir o mesmo ficheiro como contexto.
|
|
52
|
+
|
|
53
|
+
**Copilot CLI (experimental):** `oxe-cc --copilot-cli` copia os mesmos Markdown de `.cursor/commands/` para **`.claude/commands/`** — para testar **`/oxe-scan`**, etc., conforme a versão do GitHub Copilot CLI.
|
|
52
54
|
</output>
|