@nio-cli/cli 0.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/README.md +280 -0
- package/dist/adapters/supabase/allocation-gateway.js +236 -0
- package/dist/adapters/supabase/allocation-gateway.js.map +1 -0
- package/dist/adapters/supabase/analytics-gateway.js +18 -0
- package/dist/adapters/supabase/analytics-gateway.js.map +1 -0
- package/dist/adapters/supabase/client.js +96 -0
- package/dist/adapters/supabase/client.js.map +1 -0
- package/dist/adapters/supabase/context-gateway.js +23 -0
- package/dist/adapters/supabase/context-gateway.js.map +1 -0
- package/dist/adapters/supabase/gateway.js +18 -0
- package/dist/adapters/supabase/gateway.js.map +1 -0
- package/dist/adapters/supabase/task-gateway.js +450 -0
- package/dist/adapters/supabase/task-gateway.js.map +1 -0
- package/dist/auth.js +118 -0
- package/dist/auth.js.map +1 -0
- package/dist/brand.js +91 -0
- package/dist/brand.js.map +1 -0
- package/dist/cli/commands/auth.js +128 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/clean.js +120 -0
- package/dist/cli/commands/clean.js.map +1 -0
- package/dist/cli/commands/completion.js +114 -0
- package/dist/cli/commands/completion.js.map +1 -0
- package/dist/cli/commands/exec.js +59 -0
- package/dist/cli/commands/exec.js.map +1 -0
- package/dist/cli/commands/init/auth-step.js +49 -0
- package/dist/cli/commands/init/auth-step.js.map +1 -0
- package/dist/cli/commands/init/clients-step.js +76 -0
- package/dist/cli/commands/init/clients-step.js.map +1 -0
- package/dist/cli/commands/init/context-step.js +71 -0
- package/dist/cli/commands/init/context-step.js.map +1 -0
- package/dist/cli/commands/init/index.js +76 -0
- package/dist/cli/commands/init/index.js.map +1 -0
- package/dist/cli/commands/init/project-step.js +105 -0
- package/dist/cli/commands/init/project-step.js.map +1 -0
- package/dist/cli/commands/init/provision-step.js +103 -0
- package/dist/cli/commands/init/provision-step.js.map +1 -0
- package/dist/cli/commands/plan.js +45 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/skills.js +23 -0
- package/dist/cli/commands/skills.js.map +1 -0
- package/dist/cli/commands/sync.js +296 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/commands/validate-plan.js +42 -0
- package/dist/cli/commands/validate-plan.js.map +1 -0
- package/dist/cli/copy/auth.json +6 -0
- package/dist/cli/copy/flows.json +6 -0
- package/dist/cli/copy/init.json +19 -0
- package/dist/cli/copy/sync.json +3 -0
- package/dist/cli/copy.js +23 -0
- package/dist/cli/copy.js.map +1 -0
- package/dist/cli/flows/clients.js +130 -0
- package/dist/cli/flows/clients.js.map +1 -0
- package/dist/cli/flows/completion.js +63 -0
- package/dist/cli/flows/completion.js.map +1 -0
- package/dist/cli/flows/dependencies.js +114 -0
- package/dist/cli/flows/dependencies.js.map +1 -0
- package/dist/cli/flows/sections.js +85 -0
- package/dist/cli/flows/sections.js.map +1 -0
- package/dist/cli/flows/user-config.js +37 -0
- package/dist/cli/flows/user-config.js.map +1 -0
- package/dist/cli/ui/render.js +237 -0
- package/dist/cli/ui/render.js.map +1 -0
- package/dist/cli/ui/report.js +117 -0
- package/dist/cli/ui/report.js.map +1 -0
- package/dist/cli.js +36 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +280 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.js +9 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/ports.js +2 -0
- package/dist/core/ports.js.map +1 -0
- package/dist/core/types.js +7 -0
- package/dist/core/types.js.map +1 -0
- package/dist/database.types.js +11 -0
- package/dist/database.types.js.map +1 -0
- package/dist/lib/active-project.js +28 -0
- package/dist/lib/active-project.js.map +1 -0
- package/dist/lib/autopull.js +13 -0
- package/dist/lib/autopull.js.map +1 -0
- package/dist/lib/client-configs.js +191 -0
- package/dist/lib/client-configs.js.map +1 -0
- package/dist/lib/client-install.js +40 -0
- package/dist/lib/client-install.js.map +1 -0
- package/dist/lib/colors.js +93 -0
- package/dist/lib/colors.js.map +1 -0
- package/dist/lib/cowork-extension.js +143 -0
- package/dist/lib/cowork-extension.js.map +1 -0
- package/dist/lib/dependencies.js +145 -0
- package/dist/lib/dependencies.js.map +1 -0
- package/dist/lib/dependency-install.js +163 -0
- package/dist/lib/dependency-install.js.map +1 -0
- package/dist/lib/duration.js +5 -0
- package/dist/lib/duration.js.map +1 -0
- package/dist/lib/exec-delegate.js +167 -0
- package/dist/lib/exec-delegate.js.map +1 -0
- package/dist/lib/exec-engines.js +72 -0
- package/dist/lib/exec-engines.js.map +1 -0
- package/dist/lib/file-merge.js +33 -0
- package/dist/lib/file-merge.js.map +1 -0
- package/dist/lib/harness.js +90 -0
- package/dist/lib/harness.js.map +1 -0
- package/dist/lib/hooks.js +217 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/patterns.js +61 -0
- package/dist/lib/patterns.js.map +1 -0
- package/dist/lib/plan-delegate.js +106 -0
- package/dist/lib/plan-delegate.js.map +1 -0
- package/dist/lib/project-context.js +151 -0
- package/dist/lib/project-context.js.map +1 -0
- package/dist/lib/prompts.js +69 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/provision-apply.js +220 -0
- package/dist/lib/provision-apply.js.map +1 -0
- package/dist/lib/provision-collect.js +47 -0
- package/dist/lib/provision-collect.js.map +1 -0
- package/dist/lib/provision.js +45 -0
- package/dist/lib/provision.js.map +1 -0
- package/dist/lib/require-config.js +32 -0
- package/dist/lib/require-config.js.map +1 -0
- package/dist/lib/rules.js +99 -0
- package/dist/lib/rules.js.map +1 -0
- package/dist/lib/sections.js +89 -0
- package/dist/lib/sections.js.map +1 -0
- package/dist/lib/skill-serve.js +129 -0
- package/dist/lib/skill-serve.js.map +1 -0
- package/dist/lib/skills-cache.js +99 -0
- package/dist/lib/skills-cache.js.map +1 -0
- package/dist/lib/skills.js +236 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/lib/targets.js +151 -0
- package/dist/lib/targets.js.map +1 -0
- package/dist/lib/task-history.js +15 -0
- package/dist/lib/task-history.js.map +1 -0
- package/dist/lib/telemetry.js +51 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/lib/tool-result.js +12 -0
- package/dist/lib/tool-result.js.map +1 -0
- package/dist/lib/validate-plan-delegate.js +107 -0
- package/dist/lib/validate-plan-delegate.js.map +1 -0
- package/dist/lib/version-check.js +89 -0
- package/dist/lib/version-check.js.map +1 -0
- package/dist/matrix-logo.js +122 -0
- package/dist/matrix-logo.js.map +1 -0
- package/dist/mcp-server.js +189 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/session-factory.js +19 -0
- package/dist/session-factory.js.map +1 -0
- package/dist/spinner.js +12 -0
- package/dist/spinner.js.map +1 -0
- package/dist/tools/comment-task.js +72 -0
- package/dist/tools/comment-task.js.map +1 -0
- package/dist/tools/create-task.js +129 -0
- package/dist/tools/create-task.js.map +1 -0
- package/dist/tools/delegate-exec.js +63 -0
- package/dist/tools/delegate-exec.js.map +1 -0
- package/dist/tools/end-allocation.js +38 -0
- package/dist/tools/end-allocation.js.map +1 -0
- package/dist/tools/end-task-allocation.js +37 -0
- package/dist/tools/end-task-allocation.js.map +1 -0
- package/dist/tools/exec-status.js +43 -0
- package/dist/tools/exec-status.js.map +1 -0
- package/dist/tools/get-active-allocation.js +69 -0
- package/dist/tools/get-active-allocation.js.map +1 -0
- package/dist/tools/get-context.js +48 -0
- package/dist/tools/get-context.js.map +1 -0
- package/dist/tools/get-task.js +137 -0
- package/dist/tools/get-task.js.map +1 -0
- package/dist/tools/index.js +44 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-my-allocations.js +71 -0
- package/dist/tools/list-my-allocations.js.map +1 -0
- package/dist/tools/list-projects.js +38 -0
- package/dist/tools/list-projects.js.map +1 -0
- package/dist/tools/list-tasks.js +93 -0
- package/dist/tools/list-tasks.js.map +1 -0
- package/dist/tools/move-task.js +82 -0
- package/dist/tools/move-task.js.map +1 -0
- package/dist/tools/plan.js +56 -0
- package/dist/tools/plan.js.map +1 -0
- package/dist/tools/record-delivery.js +71 -0
- package/dist/tools/record-delivery.js.map +1 -0
- package/dist/tools/set-project.js +52 -0
- package/dist/tools/set-project.js.map +1 -0
- package/dist/tools/start-allocation.js +32 -0
- package/dist/tools/start-allocation.js.map +1 -0
- package/dist/tools/start-task-allocation.js +75 -0
- package/dist/tools/start-task-allocation.js.map +1 -0
- package/dist/tools/update-task.js +139 -0
- package/dist/tools/update-task.js.map +1 -0
- package/dist/tools/validate-plan.js +58 -0
- package/dist/tools/validate-plan.js.map +1 -0
- package/dist/version.js +16 -0
- package/dist/version.js.map +1 -0
- package/package.json +64 -0
package/dist/auth.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile, chmod, rm } from 'node:fs/promises';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { CREDENTIALS_FILE, PAT_REGEX, SUPABASE_ANON_KEY, TOKEN_EXCHANGE_URL, } from './constants.js';
|
|
4
|
+
import { env } from './brand.js';
|
|
5
|
+
export async function loadCredentials(file = CREDENTIALS_FILE) {
|
|
6
|
+
const stored = await readCredentialsFile(file);
|
|
7
|
+
// Precedência pro ambiente: usado por Desktop Extensions / Cowork, onde o PAT
|
|
8
|
+
// chega via user_config (NIO_PAT) em vez de `nio login`.
|
|
9
|
+
const envPat = env('PAT')?.trim();
|
|
10
|
+
if (envPat) {
|
|
11
|
+
// Cache do arquivo só serve se for do mesmo PAT.
|
|
12
|
+
return stored?.pat === envPat ? stored : { pat: envPat };
|
|
13
|
+
}
|
|
14
|
+
return stored;
|
|
15
|
+
}
|
|
16
|
+
async function readCredentialsFile(file) {
|
|
17
|
+
try {
|
|
18
|
+
const raw = await readFile(file, 'utf8');
|
|
19
|
+
const parsed = JSON.parse(raw);
|
|
20
|
+
if (!parsed || typeof parsed.pat !== 'string') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return parsed;
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
if (err.code === 'ENOENT') {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function saveCredentials(creds, file = CREDENTIALS_FILE) {
|
|
33
|
+
await mkdir(dirname(file), { recursive: true });
|
|
34
|
+
await writeFile(file, JSON.stringify(creds, null, 2) + '\n', 'utf8');
|
|
35
|
+
try {
|
|
36
|
+
await chmod(file, 0o600);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// chmod pode falhar em Windows — ignoramos silenciosamente.
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Identidade do cache quando houver; senão uma troca de PAT, populando o cache.
|
|
44
|
+
* 401/403 invalida o cache e propaga o erro (o chamador pede re-login).
|
|
45
|
+
*/
|
|
46
|
+
export async function resolveIdentity(creds, opts = {}) {
|
|
47
|
+
const file = opts.file ?? CREDENTIALS_FILE;
|
|
48
|
+
if (!opts.refresh && creds.user && creds.fetched_at) {
|
|
49
|
+
return { ...creds.user, fetched_at: creds.fetched_at };
|
|
50
|
+
}
|
|
51
|
+
let result;
|
|
52
|
+
try {
|
|
53
|
+
result = await exchangePatForJwt(creds.pat);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
const status = err.status;
|
|
57
|
+
if (status === 401 || status === 403) {
|
|
58
|
+
await patchCachedUser(file, null);
|
|
59
|
+
}
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
const identity = { ...result.user, fetched_at: new Date().toISOString() };
|
|
63
|
+
await patchCachedUser(file, identity);
|
|
64
|
+
return identity;
|
|
65
|
+
}
|
|
66
|
+
// Só mexe num arquivo já existente: ambiente com PAT via env e sem credencial
|
|
67
|
+
// gravada responde sem persistir nada.
|
|
68
|
+
async function patchCachedUser(file, identity) {
|
|
69
|
+
const creds = await readCredentialsFile(file).catch(() => null);
|
|
70
|
+
if (!creds)
|
|
71
|
+
return;
|
|
72
|
+
if (identity) {
|
|
73
|
+
const { fetched_at, ...user } = identity;
|
|
74
|
+
creds.user = user;
|
|
75
|
+
creds.fetched_at = fetched_at;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
delete creds.user;
|
|
79
|
+
delete creds.fetched_at;
|
|
80
|
+
}
|
|
81
|
+
await saveCredentials(creds, file).catch(() => {
|
|
82
|
+
// filesystem read-only — cache é conveniência, segue sem persistir.
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
export async function clearCredentials() {
|
|
86
|
+
await rm(CREDENTIALS_FILE, { force: true });
|
|
87
|
+
}
|
|
88
|
+
export function validatePatFormat(pat) {
|
|
89
|
+
return PAT_REGEX.test(pat);
|
|
90
|
+
}
|
|
91
|
+
export async function exchangePatForJwt(pat) {
|
|
92
|
+
const response = await fetch(TOKEN_EXCHANGE_URL, {
|
|
93
|
+
method: 'POST',
|
|
94
|
+
headers: {
|
|
95
|
+
apikey: SUPABASE_ANON_KEY,
|
|
96
|
+
Authorization: `Bearer ${SUPABASE_ANON_KEY}`,
|
|
97
|
+
'Content-Type': 'application/json',
|
|
98
|
+
},
|
|
99
|
+
body: JSON.stringify({ token: pat }),
|
|
100
|
+
});
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
let message = response.statusText;
|
|
103
|
+
try {
|
|
104
|
+
const body = (await response.json());
|
|
105
|
+
if (body && typeof body.error === 'string' && body.error.length > 0) {
|
|
106
|
+
message = body.error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// body não era JSON — mantém statusText
|
|
111
|
+
}
|
|
112
|
+
const err = new Error(message);
|
|
113
|
+
err.status = response.status;
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
return (await response.json());
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/brand.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Fonte única de verdade de marca/atribuição do CLI. Rebrandear = editar este arquivo — ao
|
|
5
|
+
* trocar, casar em lockstep: `package.json` (`name`/`bin`/`description`/`keywords`/`repository`)
|
|
6
|
+
* e os docs .md que citam tools literalmente (CLAUDE.md, SKILL.md, docs/specs/**\/*.md, e o `brand.skillsRepo` externo).
|
|
7
|
+
* A tabela de tools do README é GERADA — depois de editar aqui, rode `bun run gen:docs`.
|
|
8
|
+
*
|
|
9
|
+
* Rebrand NIO (docs/specs/rebrand/0005-noclaf-to-nio.md): sem compat com o nome antigo — nenhum
|
|
10
|
+
* fallback de `NOCLAF_*`/`~/.noclaf` no código. Duas pendências cross-sistema documentadas na
|
|
11
|
+
* spec, não resolvidas só por este arquivo: `patPrefix` (backend precisa aceitar o prefixo novo
|
|
12
|
+
* antes do deploy) e `webUrl` (auth desacoplada do domínio antigo — mecanismo definitivo em
|
|
13
|
+
* docs/specs/auth/0002-cli-native-login.md, ainda em aberto).
|
|
14
|
+
*/
|
|
15
|
+
export const brand = {
|
|
16
|
+
// --- Identidade / display ---
|
|
17
|
+
/** Nome do comando/binário principal (nome no help do CLI + `bin` do package.json). */
|
|
18
|
+
name: 'nio',
|
|
19
|
+
/** Nome curto do produto, mostrado a usuários e agentes. */
|
|
20
|
+
productName: 'NOS',
|
|
21
|
+
/** Nome completo do produto. PENDENTE: expansão real a confirmar (não pode reintroduzir "Noclaf"). */
|
|
22
|
+
productFullName: 'NOS',
|
|
23
|
+
/** Empresa / fornecedor. */
|
|
24
|
+
company: 'Falcao-Tech',
|
|
25
|
+
/** Org/usuário do GitHub que hospeda o repo atual da CLI. */
|
|
26
|
+
githubOrg: 'hugoreiis12-png',
|
|
27
|
+
/** Nome do repo no GitHub (casing exato, como criado). */
|
|
28
|
+
githubRepo: 'NIO-CLI',
|
|
29
|
+
/** Pacote npm — usado nas mensagens de atualização. Org real confirmada: `nio-cli` (não `nio`). */
|
|
30
|
+
packageName: '@nio-cli/cli',
|
|
31
|
+
/** Binário do servidor MCP (segundo `bin` do package.json). */
|
|
32
|
+
mcpBinName: 'nio-cli',
|
|
33
|
+
/** Chave sob a qual o servidor MCP é registrado nos configs dos clientes. */
|
|
34
|
+
mcpServerKey: 'nio',
|
|
35
|
+
// --- URLs / endpoints ---
|
|
36
|
+
/**
|
|
37
|
+
* Base do app web — DESACOPLADA por decisão do rebrand: a CLI não depende mais de um
|
|
38
|
+
* domínio externo pra autenticação. Vazio até `docs/specs/auth/0002-cli-native-login.md`
|
|
39
|
+
* definir o mecanismo; os pontos de uso (`cli/commands/auth.ts`, `init/auth-step.ts`) já
|
|
40
|
+
* tratam string vazia sem imprimir link quebrado.
|
|
41
|
+
*/
|
|
42
|
+
webUrl: '',
|
|
43
|
+
supabaseUrl: 'https://wdshvtlsjoegjvmpqobx.supabase.co',
|
|
44
|
+
/** COPIE o literal de `src/constants.ts:6` — não redigite. */
|
|
45
|
+
supabaseAnonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Indkc2h2dGxzam9lZ2p2bXBxb2J4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzU3NDA4OTQsImV4cCI6MjA5MTMxNjg5NH0.4wlAsT_D5gDiBQ19WA-q5zu105fT9TsD1NKI_tGQt-4',
|
|
46
|
+
// --- Filesystem / namespacing ---
|
|
47
|
+
/** Dir de dados no home → `~/.nio`. */
|
|
48
|
+
homeDirName: '.nio',
|
|
49
|
+
/** Arquivo de binding do projeto na raiz do repo. */
|
|
50
|
+
projectConfigFile: 'nio.json',
|
|
51
|
+
// --- Contratos ---
|
|
52
|
+
/** Prefixo das env vars: `NIO` → `NIO_PAT`, `NIO_CLIENT`, … Contrato externo: Cowork/Codex setam `NIO_CLIENT` de fora — trocar aqui exige trocar lá também. */
|
|
53
|
+
envPrefix: 'NIO',
|
|
54
|
+
/**
|
|
55
|
+
* Prefixo do PAT. ⚠️ MUDANÇA COORDENADA: o backend hoje só valida `noc_`. Publicar com
|
|
56
|
+
* `nio_` antes do backend aceitar o prefixo novo quebra login de todo mundo — ver nota
|
|
57
|
+
* na spec de rebrand (F11-T0.4).
|
|
58
|
+
*/
|
|
59
|
+
patPrefix: 'nio_',
|
|
60
|
+
// --- Repo de skills ---
|
|
61
|
+
/** Refatorado por outro time (`noclaf-skills` → `nio-skills`). */
|
|
62
|
+
skillsRepo: 'hugoreiis12-png/NIO-SKILLS-',
|
|
63
|
+
skillsRef: 'main',
|
|
64
|
+
/** Pacote npm das skills — citado em mensagens de erro de "pacote não encontrado". ASSUME mesma org (`nio-cli`) do pacote da CLI — confirmar se as skills publicam em outro escopo. */
|
|
65
|
+
skillsPackage: '@nio-cli/skills',
|
|
66
|
+
// --- Prefixos dos nomes das tools MCP --- (dois por decisão de domínio: produto vs. CLI — mantidos separados no rebrand; formato validado pelos clientes MCP como `^[a-zA-Z0-9_-]{1,64}$`, só minúsculas/dígitos, termine com `_`)
|
|
67
|
+
/** Tools de domínio do produto: `nos_list_tasks`, `nos_move_task`, … (16 tools). Mantido — nomeia o produto NOS, não a marca da CLI. */
|
|
68
|
+
toolPrefix: 'nos_',
|
|
69
|
+
/** Tools que espelham verbos do CLI: `nio_plan`, `nio_exec_status`, … (4 tools). */
|
|
70
|
+
cliToolPrefix: 'nio_',
|
|
71
|
+
};
|
|
72
|
+
// Arte ASCII do `--help`/login — efeito Matrix, gerada por `renderMatrixLogo()`
|
|
73
|
+
// em `./matrix-logo.js` (fora deste objeto: é lógica de renderização, não
|
|
74
|
+
// valor de marca).
|
|
75
|
+
// ponytail: prefixo do PAT assumido alfanumérico + `_`; se um dia tiver metachar de
|
|
76
|
+
// regex, escapar antes de interpolar.
|
|
77
|
+
/** Regex do formato do PAT, derivada do prefixo: `nio_` + 64 hex. */
|
|
78
|
+
export const patRegex = new RegExp(`^${brand.patPrefix}[a-f0-9]{64}$`);
|
|
79
|
+
/** Caminho dentro do dir de dados: `homePath('skills')` → `~/.nio/skills`. */
|
|
80
|
+
export function homePath(...parts) {
|
|
81
|
+
return join(homedir(), brand.homeDirName, ...parts);
|
|
82
|
+
}
|
|
83
|
+
/** NOME completo da env var: `envName('CLIENT')` → `'NIO_CLIENT'`. */
|
|
84
|
+
export function envName(name) {
|
|
85
|
+
return `${brand.envPrefix}_${name}`;
|
|
86
|
+
}
|
|
87
|
+
/** VALOR da env var prefixada: `env('PAT')` → `process.env.NIO_PAT`. */
|
|
88
|
+
export function env(name) {
|
|
89
|
+
return process.env[envName(name)];
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=brand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brand.js","sourceRoot":"","sources":["../src/brand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,+BAA+B;IAC/B,uFAAuF;IACvF,IAAI,EAAE,KAAK;IACX,4DAA4D;IAC5D,WAAW,EAAE,KAAK;IAClB,sGAAsG;IACtG,eAAe,EAAE,KAAK;IACtB,4BAA4B;IAC5B,OAAO,EAAE,aAAa;IACtB,6DAA6D;IAC7D,SAAS,EAAE,iBAAiB;IAC5B,0DAA0D;IAC1D,UAAU,EAAE,SAAS;IACrB,mGAAmG;IACnG,WAAW,EAAE,cAAc;IAC3B,+DAA+D;IAC/D,UAAU,EAAE,SAAS;IACrB,6EAA6E;IAC7E,YAAY,EAAE,KAAK;IAEnB,2BAA2B;IAC3B;;;;;OAKG;IACH,MAAM,EAAE,EAAE;IACV,WAAW,EAAE,0CAA0C;IACvD,8DAA8D;IAC9D,eAAe,EAAE,kNAAkN;IAEnO,mCAAmC;IACnC,uCAAuC;IACvC,WAAW,EAAE,MAAM;IACnB,qDAAqD;IACrD,iBAAiB,EAAE,UAAU;IAE7B,oBAAoB;IACpB,+JAA+J;IAC/J,SAAS,EAAE,KAAK;IAChB;;;;OAIG;IACH,SAAS,EAAE,MAAM;IAEjB,yBAAyB;IACzB,kEAAkE;IAClE,UAAU,EAAE,6BAA6B;IACzC,SAAS,EAAE,MAAM;IACjB,uLAAuL;IACvL,aAAa,EAAE,iBAAiB;IAEhC,oOAAoO;IACpO,wIAAwI;IACxI,UAAU,EAAE,MAAM;IAClB,oFAAoF;IACpF,aAAa,EAAE,MAAM;CACb,CAAC;AAEX,gFAAgF;AAChF,0EAA0E;AAC1E,mBAAmB;AAEnB,oFAAoF;AACpF,sCAAsC;AACtC,qEAAqE;AACrE,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,eAAe,CAAC,CAAC;AAEvE,8EAA8E;AAC9E,MAAM,UAAU,QAAQ,CAAC,GAAG,KAAe;IACzC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,CAAC;AACtD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC;AACtC,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,GAAG,CAAC,IAAY;IAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { password } from "../../lib/prompts.js";
|
|
2
|
+
import { brand } from "../../brand.js";
|
|
3
|
+
import { renderMatrixLogo } from "../../matrix-logo.js";
|
|
4
|
+
import { startSpinner } from "../../spinner.js";
|
|
5
|
+
import { clearCredentials, exchangePatForJwt, loadCredentials, resolveIdentity, saveCredentials, validatePatFormat, } from "../../auth.js";
|
|
6
|
+
import { authCopy } from "../copy.js";
|
|
7
|
+
/** Obtém o PAT: usa o argumento se veio preenchido, senão pede via prompt mascarado. */
|
|
8
|
+
async function resolvePat(patArg) {
|
|
9
|
+
const trimmed = patArg?.trim();
|
|
10
|
+
if (trimmed)
|
|
11
|
+
return trimmed;
|
|
12
|
+
if (brand.webUrl)
|
|
13
|
+
console.log(`Gere um token pessoal em: ${brand.webUrl}/profile#mcp`);
|
|
14
|
+
const answer = await password({
|
|
15
|
+
message: authCopy.login.patPrompt,
|
|
16
|
+
mask: "*",
|
|
17
|
+
validate: (input) => validatePatFormat(input.trim()) || authCopy.login.patInvalid,
|
|
18
|
+
});
|
|
19
|
+
return answer.trim();
|
|
20
|
+
}
|
|
21
|
+
/** Troca o PAT por sessão e persiste as credenciais localmente. */
|
|
22
|
+
async function performLogin(pat) {
|
|
23
|
+
const result = await exchangePatForJwt(pat);
|
|
24
|
+
await saveCredentials({
|
|
25
|
+
pat,
|
|
26
|
+
user: result.user,
|
|
27
|
+
fetched_at: new Date().toISOString(),
|
|
28
|
+
});
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
function printLoginSuccess(u) {
|
|
32
|
+
console.log(renderMatrixLogo());
|
|
33
|
+
console.log("[ok] Autenticado!");
|
|
34
|
+
console.log(`Nome: ${u.full_name || "(sem nome)"}`);
|
|
35
|
+
console.log(`Usuário: ${u.username ? `@${u.username}` : "(sem username)"}`);
|
|
36
|
+
console.log(`Email: ${u.email}`);
|
|
37
|
+
}
|
|
38
|
+
/** Decide se dá pra pular o spinner de validação: só quando a sessão já está em
|
|
39
|
+
* cache (usuário + data de fetch salvos) e o caller não pediu revalidação forçada. */
|
|
40
|
+
export function shouldSkipWhoamiSpinner(creds, refresh) {
|
|
41
|
+
return !refresh && Boolean(creds.user && creds.fetched_at);
|
|
42
|
+
}
|
|
43
|
+
/** Traduz o erro de `resolveIdentity` pra mensagem exibida ao usuário. */
|
|
44
|
+
export function whoamiErrorMessage(err) {
|
|
45
|
+
const status = err.status;
|
|
46
|
+
return status === 401 || status === 403
|
|
47
|
+
? `Sessão inválida. Rode \`${brand.name} login <PAT>\` novamente.`
|
|
48
|
+
: `Falha ao validar token: ${err.message}`;
|
|
49
|
+
}
|
|
50
|
+
function printWhoamiIdentity(u) {
|
|
51
|
+
console.log(renderMatrixLogo());
|
|
52
|
+
console.log(`Nome: ${u.full_name || "(sem nome)"}`);
|
|
53
|
+
console.log(`Email: ${u.email}`);
|
|
54
|
+
console.log(`Usuário: ${u.username ? `@${u.username}` : "(sem username)"}`);
|
|
55
|
+
console.log(`ID: ${u.id}`);
|
|
56
|
+
}
|
|
57
|
+
function registerLoginCommand(program) {
|
|
58
|
+
program
|
|
59
|
+
.command("login")
|
|
60
|
+
.description("Salva o token de acesso pessoal (PAT) localmente")
|
|
61
|
+
.argument("[pat]", "Token gerado em /profile#mcp do NOS (opcional — será pedido se omitido)")
|
|
62
|
+
.action(async (patArg) => {
|
|
63
|
+
const pat = await resolvePat(patArg);
|
|
64
|
+
if (!validatePatFormat(pat)) {
|
|
65
|
+
console.error(`Token inválido. Formato esperado: \`${brand.patPrefix}\` + 64 caracteres hexadecimais.`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
const spinner = startSpinner("Autenticando...");
|
|
69
|
+
try {
|
|
70
|
+
const result = await performLogin(pat);
|
|
71
|
+
spinner.stop();
|
|
72
|
+
printLoginSuccess(result.user);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
spinner.fail(`Falha ao autenticar: ${err.message}`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function registerLogoutCommand(program) {
|
|
81
|
+
program
|
|
82
|
+
.command("logout")
|
|
83
|
+
.description("Remove credenciais locais")
|
|
84
|
+
.action(async () => {
|
|
85
|
+
await clearCredentials();
|
|
86
|
+
console.log("Sessão removida.");
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async function runWhoamiAction(opts) {
|
|
90
|
+
const creds = await loadCredentials();
|
|
91
|
+
if (!creds) {
|
|
92
|
+
console.error(`Não autenticado. Rode \`${brand.name} login <PAT>\`.`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
const cached = shouldSkipWhoamiSpinner(creds, opts.refresh);
|
|
96
|
+
const spinner = cached || opts.json ? null : startSpinner("Validando sessão...");
|
|
97
|
+
try {
|
|
98
|
+
const u = await resolveIdentity(creds, { refresh: opts.refresh });
|
|
99
|
+
spinner?.stop();
|
|
100
|
+
if (opts.json) {
|
|
101
|
+
console.log(JSON.stringify(u, null, 2));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
printWhoamiIdentity(u);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
const message = whoamiErrorMessage(err);
|
|
108
|
+
if (spinner)
|
|
109
|
+
spinner.fail(message);
|
|
110
|
+
else
|
|
111
|
+
console.error(message);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function registerWhoamiCommand(program) {
|
|
116
|
+
program
|
|
117
|
+
.command("whoami")
|
|
118
|
+
.description("Mostra o usuário autenticado")
|
|
119
|
+
.option("--json", "Emite a identidade como JSON")
|
|
120
|
+
.option("--refresh", "Ignora o cache e revalida o token")
|
|
121
|
+
.action(runWhoamiAction);
|
|
122
|
+
}
|
|
123
|
+
export function registerAuthCommands(program) {
|
|
124
|
+
registerLoginCommand(program);
|
|
125
|
+
registerLogoutCommand(program);
|
|
126
|
+
registerWhoamiCommand(program);
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/cli/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { rmSync, lstatSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { confirm } from "../../lib/prompts.js";
|
|
5
|
+
import { readSkillDocs } from "../../lib/skills.js";
|
|
6
|
+
import { c, sym } from "../../lib/colors.js";
|
|
7
|
+
/**
|
|
8
|
+
* Comando de limpeza: remove artefatos **legados** que versões antigas do nio
|
|
9
|
+
* instalaram e que hoje foram substituídos — commands que viraram skills, ou
|
|
10
|
+
* commands removidos de vez. Roda em `~/.claude` (Claude Code) e `~/.codex` (Codex).
|
|
11
|
+
*/
|
|
12
|
+
// Removidos de vez (não existem mais em nenhum formato).
|
|
13
|
+
const FULLY_REMOVED = [
|
|
14
|
+
"new-spec",
|
|
15
|
+
"new-bug",
|
|
16
|
+
"new-adr",
|
|
17
|
+
"apply-spec",
|
|
18
|
+
"apply-bug",
|
|
19
|
+
"to-skill",
|
|
20
|
+
];
|
|
21
|
+
// Eram commands e viraram skills — só o **command** legado deve sair (a skill atual fica).
|
|
22
|
+
const COMMAND_TO_SKILL = ["init-sdd", "to-tickets"];
|
|
23
|
+
/** Existe no disco (inclui symlink pendurado, que `existsSync` não pega)? */
|
|
24
|
+
function present(path) {
|
|
25
|
+
try {
|
|
26
|
+
lstatSync(path);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Ids atualmente válidos no bundle — guarda pra nunca remover algo em uso. */
|
|
34
|
+
function currentIds() {
|
|
35
|
+
try {
|
|
36
|
+
const docs = readSkillDocs();
|
|
37
|
+
return {
|
|
38
|
+
skills: new Set(docs.filter((d) => d.type === "skill").map((d) => d.id)),
|
|
39
|
+
commands: new Set(docs.filter((d) => d.type === "command").map((d) => d.id)),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return { skills: new Set(), commands: new Set() };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function collectLegacy() {
|
|
47
|
+
const cur = currentIds();
|
|
48
|
+
const out = [];
|
|
49
|
+
const add = (path, kind) => {
|
|
50
|
+
if (present(path))
|
|
51
|
+
out.push({ path, kind });
|
|
52
|
+
};
|
|
53
|
+
const claude = join(homedir(), ".claude");
|
|
54
|
+
const codex = join(homedir(), ".codex");
|
|
55
|
+
// Claude Code — commands legados (nenhum desses é command atual).
|
|
56
|
+
for (const id of [...FULLY_REMOVED, ...COMMAND_TO_SKILL]) {
|
|
57
|
+
if (!cur.commands.has(id))
|
|
58
|
+
add(join(claude, "commands", `${id}.md`), "claude command");
|
|
59
|
+
}
|
|
60
|
+
// Claude Code — skills só dos removidos de vez (init-sdd/to-tickets são skills atuais).
|
|
61
|
+
for (const id of FULLY_REMOVED) {
|
|
62
|
+
if (!cur.skills.has(id))
|
|
63
|
+
add(join(claude, "skills", id), "claude skill");
|
|
64
|
+
}
|
|
65
|
+
// Codex — dual-write dos removidos de vez (prompt + skill traduzida).
|
|
66
|
+
for (const id of FULLY_REMOVED) {
|
|
67
|
+
if (!cur.commands.has(id) && !cur.skills.has(id)) {
|
|
68
|
+
add(join(codex, "prompts", `${id}.md`), "codex prompt");
|
|
69
|
+
add(join(codex, "skills", id), "codex skill");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
export function registerCleanCommand(program) {
|
|
75
|
+
program
|
|
76
|
+
.command("clean-legacy")
|
|
77
|
+
.description("Remove commands/skills legados (substituídos) de ~/.claude e ~/.codex")
|
|
78
|
+
.option("--dry-run", "só lista o que seria removido, sem apagar")
|
|
79
|
+
.option("-y, --yes", "remove sem pedir confirmação")
|
|
80
|
+
.action(async (opts) => {
|
|
81
|
+
const targets = collectLegacy();
|
|
82
|
+
if (targets.length === 0) {
|
|
83
|
+
console.log("");
|
|
84
|
+
console.log(` ${c.green(sym.ok)} nada legado encontrado — já está limpo.`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
console.log("");
|
|
88
|
+
console.log(` ${c.bold("Artefatos legados encontrados:")}`);
|
|
89
|
+
for (const t of targets) {
|
|
90
|
+
console.log(` ${c.red("-")} ${t.path} ${c.dim(`(${t.kind})`)}`);
|
|
91
|
+
}
|
|
92
|
+
if (opts.dryRun) {
|
|
93
|
+
console.log("");
|
|
94
|
+
console.log(` ${c.dim("[dry-run] nada removido.")}`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const ok = opts.yes === true ||
|
|
98
|
+
(await confirm({
|
|
99
|
+
message: `Remover ${targets.length} item(ns) legado(s)?`,
|
|
100
|
+
default: false,
|
|
101
|
+
}));
|
|
102
|
+
if (!ok) {
|
|
103
|
+
console.log(` ${c.dim("cancelado.")}`);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
let removed = 0;
|
|
107
|
+
for (const t of targets) {
|
|
108
|
+
try {
|
|
109
|
+
rmSync(t.path, { recursive: true, force: true });
|
|
110
|
+
removed++;
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
console.error(` ${c.red(sym.err)} falha ao remover ${t.path}: ${err.message}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
console.log("");
|
|
117
|
+
console.log(` ${c.green(sym.ok)} ${removed} removido(s). Reinicie os clientes pra refletir.`);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=clean.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.js","sourceRoot":"","sources":["../../../src/cli/commands/clean.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { c, cmd } from "../../lib/colors.js";
|
|
2
|
+
import { brand } from "../../brand.js";
|
|
3
|
+
/** Nome do binário — vai literal nos scripts de completion gerados. */
|
|
4
|
+
const bin = brand.name;
|
|
5
|
+
function optFlags(command) {
|
|
6
|
+
const flags = [];
|
|
7
|
+
const opts = command.options;
|
|
8
|
+
for (const o of opts) {
|
|
9
|
+
if (o.long)
|
|
10
|
+
flags.push(o.long);
|
|
11
|
+
if (o.short)
|
|
12
|
+
flags.push(o.short);
|
|
13
|
+
}
|
|
14
|
+
flags.push("--help");
|
|
15
|
+
return flags;
|
|
16
|
+
}
|
|
17
|
+
function walk(command) {
|
|
18
|
+
return {
|
|
19
|
+
name: command.name(),
|
|
20
|
+
subs: command.commands.map(walk),
|
|
21
|
+
opts: optFlags(command),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Candidatos no nível 2 de um comando: seus subcomandos + suas flags. */
|
|
25
|
+
function level2(node) {
|
|
26
|
+
return [...node.subs.map((s) => s.name), ...node.opts].join(" ");
|
|
27
|
+
}
|
|
28
|
+
function bashScript(root) {
|
|
29
|
+
const top = root.subs.map((s) => s.name).join(" ");
|
|
30
|
+
const arms = root.subs
|
|
31
|
+
.filter((s) => s.subs.length > 0 || s.opts.length > 1)
|
|
32
|
+
.map((s) => ` ${s.name}) __c="${level2(s)}" ;;`)
|
|
33
|
+
.join("\n");
|
|
34
|
+
return `# ${bin} bash completion — gere com: ${bin} completion bash
|
|
35
|
+
_${bin}() {
|
|
36
|
+
local cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
37
|
+
local __c=""
|
|
38
|
+
if [ "\$COMP_CWORD" -eq 1 ]; then
|
|
39
|
+
__c="${top}"
|
|
40
|
+
else
|
|
41
|
+
case "\${COMP_WORDS[1]}" in
|
|
42
|
+
${arms}
|
|
43
|
+
*) __c="--help" ;;
|
|
44
|
+
esac
|
|
45
|
+
fi
|
|
46
|
+
COMPREPLY=( \$(compgen -W "\$__c" -- "\$cur") )
|
|
47
|
+
}
|
|
48
|
+
complete -F _${bin} ${bin}`;
|
|
49
|
+
}
|
|
50
|
+
function zshScript(root) {
|
|
51
|
+
const top = root.subs.map((s) => s.name).join(" ");
|
|
52
|
+
const arms = root.subs
|
|
53
|
+
.filter((s) => s.subs.length > 0 || s.opts.length > 1)
|
|
54
|
+
.map((s) => ` ${s.name}) __c=(${level2(s)}) ;;`)
|
|
55
|
+
.join("\n");
|
|
56
|
+
return `#compdef ${bin}
|
|
57
|
+
# ${bin} zsh completion — gere com: ${bin} completion zsh
|
|
58
|
+
_${bin}() {
|
|
59
|
+
local -a __c
|
|
60
|
+
if (( CURRENT == 2 )); then
|
|
61
|
+
__c=(${top})
|
|
62
|
+
else
|
|
63
|
+
case $words[2] in
|
|
64
|
+
${arms}
|
|
65
|
+
*) __c=(--help) ;;
|
|
66
|
+
esac
|
|
67
|
+
fi
|
|
68
|
+
compadd -a __c
|
|
69
|
+
}
|
|
70
|
+
compdef _${bin} ${bin}`;
|
|
71
|
+
}
|
|
72
|
+
function fishScript(root) {
|
|
73
|
+
const lines = [
|
|
74
|
+
`# ${bin} fish completion — gere com: ${bin} completion fish`,
|
|
75
|
+
`complete -c ${bin} -f`,
|
|
76
|
+
];
|
|
77
|
+
const top = root.subs.map((s) => s.name).join(" ");
|
|
78
|
+
lines.push(`complete -c ${bin} -n '__fish_use_subcommand' -a '${top}'`);
|
|
79
|
+
for (const s of root.subs) {
|
|
80
|
+
const cands = [...s.subs.map((x) => x.name), ...s.opts].join(" ");
|
|
81
|
+
lines.push(`complete -c ${bin} -n '__fish_seen_subcommand_from ${s.name}' -a '${cands}'`);
|
|
82
|
+
}
|
|
83
|
+
return lines.join("\n");
|
|
84
|
+
}
|
|
85
|
+
function detectShell() {
|
|
86
|
+
const sh = (process.env.SHELL ?? "").split("/").pop();
|
|
87
|
+
if (sh === "bash" || sh === "zsh" || sh === "fish")
|
|
88
|
+
return sh;
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
export function registerCompletionCommand(program) {
|
|
92
|
+
program
|
|
93
|
+
.command("completion [shell]")
|
|
94
|
+
.description(`Imprime o script de autocomplete (bash|zsh|fish). Ex.: eval "$(${bin} completion zsh)"`)
|
|
95
|
+
.action((shellArg) => {
|
|
96
|
+
const shell = shellArg ?? detectShell();
|
|
97
|
+
if (shell !== "bash" && shell !== "zsh" && shell !== "fish") {
|
|
98
|
+
console.error(`${c.yellow("shell não reconhecido.")} Use: ${cmd(`${bin} completion`)} ` +
|
|
99
|
+
`${c.dim("bash|zsh|fish")}`);
|
|
100
|
+
process.exitCode = 1;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const root = walk(program);
|
|
104
|
+
const script = shell === "bash"
|
|
105
|
+
? bashScript(root)
|
|
106
|
+
: shell === "zsh"
|
|
107
|
+
? zshScript(root)
|
|
108
|
+
: fishScript(root);
|
|
109
|
+
// Dica no stderr (o `eval "$(...)"` captura só o stdout, então não polui).
|
|
110
|
+
console.error(`${c.dim("# adicione ao seu rc:")} ${cmd(`eval "$(${bin} completion ${shell})"`)}`);
|
|
111
|
+
console.log(script);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/cli/commands/completion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,uEAAuE;AACvE,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC;AAcvB,SAAS,QAAQ,CAAC,OAAgB;IAChC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,OAA8D,CAAC;IACpF,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,CAAC,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,IAAI,CAAC,OAAgB;IAC5B,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE;QACpB,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QAChC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC;KACxB,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,SAAS,MAAM,CAAC,IAAa;IAC3B,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,UAAU,CAAC,IAAa;IAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACrD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,UAAU,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;SAClD,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,KAAK,GAAG,gCAAgC,GAAG;GACjD,GAAG;;;;WAIK,GAAG;;;EAGZ,IAAI;;;;;;eAMS,GAAG,IAAI,GAAG,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,SAAS,CAAC,IAAa;IAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACrD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,UAAU,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;SACpD,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,YAAY,GAAG;IACpB,GAAG,+BAA+B,GAAG;GACtC,GAAG;;;WAGK,GAAG;;;EAGZ,IAAI;;;;;;WAMK,GAAG,IAAI,GAAG,EAAE,CAAC;AACxB,CAAC;AAED,SAAS,UAAU,CAAC,IAAa;IAC/B,MAAM,KAAK,GAAa;QACtB,KAAK,GAAG,gCAAgC,GAAG,kBAAkB;QAC7D,eAAe,GAAG,KAAK;KACxB,CAAC;IACF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnD,KAAK,CAAC,IAAI,CAAC,eAAe,GAAG,mCAAmC,GAAG,GAAG,CAAC,CAAC;IACxE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClE,KAAK,CAAC,IAAI,CACR,eAAe,GAAG,oCAAoC,CAAC,CAAC,IAAI,SAAS,KAAK,GAAG,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAID,SAAS,WAAW;IAClB,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACtD,IAAI,EAAE,KAAK,MAAM,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,KAAK,MAAM;QAAE,OAAO,EAAE,CAAC;IAC9D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,OAAgB;IACxD,OAAO;SACJ,OAAO,CAAC,oBAAoB,CAAC;SAC7B,WAAW,CACV,kEAAkE,GAAG,mBAAmB,CACzF;SACA,MAAM,CAAC,CAAC,QAAiB,EAAE,EAAE;QAC5B,MAAM,KAAK,GAAI,QAAkB,IAAI,WAAW,EAAE,CAAC;QACnD,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YAC5D,OAAO,CAAC,KAAK,CACX,GAAG,CAAC,CAAC,MAAM,CAAC,wBAAwB,CAAC,SAAS,GAAG,CAAC,GAAG,GAAG,aAAa,CAAC,GAAG;gBACvE,GAAG,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAC9B,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,MAAM,MAAM,GACV,KAAK,KAAK,MAAM;YACd,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;YAClB,CAAC,CAAC,KAAK,KAAK,KAAK;gBACf,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;gBACjB,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACzB,2EAA2E;QAC3E,OAAO,CAAC,KAAK,CACX,GAAG,CAAC,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,GAAG,CAAC,WAAW,GAAG,eAAe,KAAK,IAAI,CAAC,EAAE,CACnF,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;AACP,CAAC"}
|