@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
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, copyFileSync, rmSync, } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { readJson, writeJson } from './file-merge.js';
|
|
5
|
+
import { skillsDir } from './skills.js';
|
|
6
|
+
import { ensureDir } from './provision.js';
|
|
7
|
+
import { DEV_ROLE } from './sections.js';
|
|
8
|
+
import { brand } from '../brand.js';
|
|
9
|
+
/**
|
|
10
|
+
* Provisionamento de hooks (só Claude Code). Um hook é um script + um gatilho que
|
|
11
|
+
* precisa estar registrado no `settings.json` — então, além de copiar o script pro
|
|
12
|
+
* namespace `hooks/nio/`, o CLI faz merge não-destrutivo do binding. Fonte:
|
|
13
|
+
* `@nio-cli/skills/hooks/hooks.json` (flat — hooks são sempre de dev).
|
|
14
|
+
*/
|
|
15
|
+
/** Namespace sob o targetDir onde os scripts do nio vivem. Marca "nossa" entrada. */
|
|
16
|
+
const HOOKS_NS = `hooks/${brand.name}`;
|
|
17
|
+
function defaultTargetDir() {
|
|
18
|
+
return join(homedir(), '.claude');
|
|
19
|
+
}
|
|
20
|
+
/** Lê e valida um `hooks.json`, devolvendo as entradas bem-formadas. */
|
|
21
|
+
function readManifest(path) {
|
|
22
|
+
let parsed;
|
|
23
|
+
try {
|
|
24
|
+
parsed = JSON.parse(readFileSync(path, 'utf-8'));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const list = parsed?.hooks;
|
|
30
|
+
if (!Array.isArray(list))
|
|
31
|
+
return [];
|
|
32
|
+
const out = [];
|
|
33
|
+
for (const raw of list) {
|
|
34
|
+
if (!raw || typeof raw !== 'object')
|
|
35
|
+
continue;
|
|
36
|
+
const e = raw;
|
|
37
|
+
if (typeof e.event !== 'string' || typeof e.script !== 'string')
|
|
38
|
+
continue;
|
|
39
|
+
out.push({
|
|
40
|
+
id: typeof e.id === 'number' ? e.id : undefined,
|
|
41
|
+
event: e.event,
|
|
42
|
+
matcher: typeof e.matcher === 'string' ? e.matcher : undefined,
|
|
43
|
+
description: typeof e.description === 'string' ? e.description : undefined,
|
|
44
|
+
script: e.script,
|
|
45
|
+
clients: Array.isArray(e.clients)
|
|
46
|
+
? e.clients.filter((c) => typeof c === 'string')
|
|
47
|
+
: undefined,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Descobre e resolve os hooks aplicáveis: lê `hooks/hooks.json` (flat), filtra por
|
|
54
|
+
* cliente (`clients`), e devolve as entradas com o script de origem. Hooks são de
|
|
55
|
+
* código → só entram se a seleção incluir o role `dev` (ou sem seleção).
|
|
56
|
+
*/
|
|
57
|
+
function collectHooks(dir, surface, selection) {
|
|
58
|
+
if (selection && !selection.roles.includes(DEV_ROLE))
|
|
59
|
+
return [];
|
|
60
|
+
const hooksRoot = join(dir, 'hooks');
|
|
61
|
+
const manifestPath = join(hooksRoot, 'hooks.json');
|
|
62
|
+
if (!existsSync(manifestPath))
|
|
63
|
+
return [];
|
|
64
|
+
const out = [];
|
|
65
|
+
for (const entry of readManifest(manifestPath)) {
|
|
66
|
+
if (entry.clients && !entry.clients.includes(surface))
|
|
67
|
+
continue;
|
|
68
|
+
const srcAbs = join(hooksRoot, entry.script);
|
|
69
|
+
if (!existsSync(srcAbs))
|
|
70
|
+
continue;
|
|
71
|
+
out.push({
|
|
72
|
+
id: entry.id ?? null,
|
|
73
|
+
event: entry.event,
|
|
74
|
+
matcher: entry.matcher,
|
|
75
|
+
description: entry.description,
|
|
76
|
+
script: entry.script,
|
|
77
|
+
srcAbs,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
}
|
|
82
|
+
/** Uma entrada de comando é "nossa" se aponta pro namespace `hooks/nio/`. */
|
|
83
|
+
function isOurs(hook) {
|
|
84
|
+
const cmd = hook?.command;
|
|
85
|
+
return typeof cmd === 'string' && cmd.includes(`${HOOKS_NS}/`);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Remove todas as entradas do nio de um bloco de `hooks` do settings, deixando
|
|
89
|
+
* intactas as do usuário. Devolve o bloco limpo (eventos/grupos vazios removidos).
|
|
90
|
+
*/
|
|
91
|
+
function stripOurs(hooksCfg) {
|
|
92
|
+
const clean = {};
|
|
93
|
+
for (const [event, groups] of Object.entries(hooksCfg)) {
|
|
94
|
+
if (!Array.isArray(groups))
|
|
95
|
+
continue;
|
|
96
|
+
const keptGroups = [];
|
|
97
|
+
for (const group of groups) {
|
|
98
|
+
const list = Array.isArray(group?.hooks) ? group.hooks : [];
|
|
99
|
+
const kept = list.filter((h) => !isOurs(h));
|
|
100
|
+
if (kept.length > 0)
|
|
101
|
+
keptGroups.push({ ...group, hooks: kept });
|
|
102
|
+
}
|
|
103
|
+
if (keptGroups.length > 0)
|
|
104
|
+
clean[event] = keptGroups;
|
|
105
|
+
}
|
|
106
|
+
return clean;
|
|
107
|
+
}
|
|
108
|
+
/** Remove recursivamente arquivos órfãos sob o namespace, exceto os recém-escritos. */
|
|
109
|
+
function pruneScripts(scriptsDir, keep, dryRun, pruned) {
|
|
110
|
+
if (!existsSync(scriptsDir))
|
|
111
|
+
return;
|
|
112
|
+
const walk = (abs) => {
|
|
113
|
+
for (const entry of readdirSync(abs, { withFileTypes: true })) {
|
|
114
|
+
const childAbs = join(abs, entry.name);
|
|
115
|
+
if (entry.isDirectory()) {
|
|
116
|
+
walk(childAbs);
|
|
117
|
+
try {
|
|
118
|
+
if (readdirSync(childAbs).length === 0 && !dryRun)
|
|
119
|
+
rmSync(childAbs, { recursive: true });
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
/* ignore */
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else if (entry.isFile()) {
|
|
126
|
+
if (!keep.has(childAbs)) {
|
|
127
|
+
if (!dryRun)
|
|
128
|
+
rmSync(childAbs);
|
|
129
|
+
pruned.push(childAbs);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
walk(scriptsDir);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Provisiona os hooks do nio no Claude Code. Idempotente e não-destrutivo.
|
|
138
|
+
* No-op (installed vazio) se o pacote não tem `hooks/` ou nada casa a seleção.
|
|
139
|
+
*/
|
|
140
|
+
export function provisionHooks(options = {}) {
|
|
141
|
+
const dryRun = options.dryRun ?? false;
|
|
142
|
+
const dir = options.skillsDir ?? skillsDir();
|
|
143
|
+
const targetDir = options.targetDir ?? defaultTargetDir();
|
|
144
|
+
const surface = options.surface ?? 'claude-code';
|
|
145
|
+
const settingsPath = join(targetDir, 'settings.json');
|
|
146
|
+
const scriptsDir = join(targetDir, HOOKS_NS);
|
|
147
|
+
const resolved = collectHooks(dir, surface, options.selection);
|
|
148
|
+
const writtenScripts = new Set();
|
|
149
|
+
const installed = [];
|
|
150
|
+
for (const h of resolved) {
|
|
151
|
+
const destAbs = join(scriptsDir, h.script);
|
|
152
|
+
if (!dryRun) {
|
|
153
|
+
ensureDir(scriptsDir);
|
|
154
|
+
copyFileSync(h.srcAbs, destAbs);
|
|
155
|
+
}
|
|
156
|
+
writtenScripts.add(destAbs);
|
|
157
|
+
installed.push({
|
|
158
|
+
event: h.event,
|
|
159
|
+
matcher: h.matcher,
|
|
160
|
+
script: h.script,
|
|
161
|
+
description: h.description,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
const prunedScripts = [];
|
|
165
|
+
pruneScripts(scriptsDir, writtenScripts, dryRun, prunedScripts);
|
|
166
|
+
// Merge no settings.json: tira as nossas entradas antigas, re-adiciona as atuais.
|
|
167
|
+
const settings = readJson(settingsPath) ?? {};
|
|
168
|
+
const currentHooks = settings.hooks ?? {};
|
|
169
|
+
const merged = stripOurs(currentHooks);
|
|
170
|
+
for (const h of resolved) {
|
|
171
|
+
const commandPath = join(scriptsDir, h.script).split('\\').join('/');
|
|
172
|
+
const ourHook = { type: 'command', command: `python3 "${commandPath}"` };
|
|
173
|
+
const groups = merged[h.event] ?? (merged[h.event] = []);
|
|
174
|
+
let group = groups.find((g) => g.matcher === h.matcher);
|
|
175
|
+
if (!group) {
|
|
176
|
+
group = h.matcher !== undefined ? { matcher: h.matcher, hooks: [] } : { hooks: [] };
|
|
177
|
+
groups.push(group);
|
|
178
|
+
}
|
|
179
|
+
group.hooks.push(ourHook);
|
|
180
|
+
}
|
|
181
|
+
if (!dryRun) {
|
|
182
|
+
if (Object.keys(merged).length > 0) {
|
|
183
|
+
settings.hooks = merged;
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
delete settings.hooks;
|
|
187
|
+
}
|
|
188
|
+
writeJson(settingsPath, settings);
|
|
189
|
+
}
|
|
190
|
+
return { settingsPath, scriptsDir, dryRun, installed, prunedScripts };
|
|
191
|
+
}
|
|
192
|
+
/** Remove tudo que o nio instalou de hooks (scripts + entradas do settings). */
|
|
193
|
+
export function uninstallHooks(options = {}) {
|
|
194
|
+
const dryRun = options.dryRun ?? false;
|
|
195
|
+
const targetDir = options.targetDir ?? defaultTargetDir();
|
|
196
|
+
const settingsPath = join(targetDir, 'settings.json');
|
|
197
|
+
const scriptsDir = join(targetDir, HOOKS_NS);
|
|
198
|
+
const removedScripts = [];
|
|
199
|
+
if (existsSync(scriptsDir)) {
|
|
200
|
+
if (!dryRun)
|
|
201
|
+
rmSync(scriptsDir, { recursive: true, force: true });
|
|
202
|
+
removedScripts.push(scriptsDir);
|
|
203
|
+
}
|
|
204
|
+
const settings = readJson(settingsPath);
|
|
205
|
+
if (settings && settings.hooks) {
|
|
206
|
+
const merged = stripOurs(settings.hooks);
|
|
207
|
+
if (!dryRun) {
|
|
208
|
+
if (Object.keys(merged).length > 0)
|
|
209
|
+
settings.hooks = merged;
|
|
210
|
+
else
|
|
211
|
+
delete settings.hooks;
|
|
212
|
+
writeJson(settingsPath, settings);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return { settingsPath, removedScripts, dryRun };
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/lib/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { readSkillDocs } from './skills.js';
|
|
5
|
+
/**
|
|
6
|
+
* Patterns do harness — a parte que **precisa de IA**. O CLI não raciocina sobre o
|
|
7
|
+
* código, então dispara um agente **headless** (`claude -p` / `codex exec`), com
|
|
8
|
+
* consentimento, pra analisar o repo e escrever `docs/_patterns.md`. Best-effort.
|
|
9
|
+
*/
|
|
10
|
+
export const PATTERNS_REL = 'docs/_patterns.md';
|
|
11
|
+
export function patternsPath(cwd) {
|
|
12
|
+
return join(cwd, PATTERNS_REL);
|
|
13
|
+
}
|
|
14
|
+
export function patternsExist(cwd) {
|
|
15
|
+
return existsSync(patternsPath(cwd));
|
|
16
|
+
}
|
|
17
|
+
/** Prompt da análise: corpo da skill `detect-patterns` (fonte única) ou fallback embutido. */
|
|
18
|
+
const FALLBACK_PROMPT = `Analise ESTE repositório e escreva \`${PATTERNS_REL}\` (arquivo único, sobrescreva se existir) com os PADRÕES REAIS já usados no código: estrutura de pastas/camadas, convenções de naming, stack/libs e como são usadas, e padrões de estado/dados/erros/testes. Baseie-se SÓ no que existe — não invente nem recomende. Seja conciso (poucas dezenas de linhas): é contexto pra outros agentes, não pode inflar. Não toque em nenhum outro arquivo.`;
|
|
19
|
+
function analysisPrompt() {
|
|
20
|
+
try {
|
|
21
|
+
const doc = readSkillDocs().find((d) => d.id === 'detect-patterns' && d.type === 'skill');
|
|
22
|
+
if (doc?.content.trim())
|
|
23
|
+
return doc.content.trim();
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
/* skill ausente do cache → fallback */
|
|
27
|
+
}
|
|
28
|
+
return FALLBACK_PROMPT;
|
|
29
|
+
}
|
|
30
|
+
/** Existe um binário no PATH (via `--version`)? */
|
|
31
|
+
function hasBin(bin) {
|
|
32
|
+
try {
|
|
33
|
+
const r = spawnSync(bin, ['--version'], { stdio: 'ignore' });
|
|
34
|
+
return !r.error;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Roda a análise de patterns headless no `cwd`. Prefere `claude`, cai pro `codex`;
|
|
42
|
+
* sem nenhum no PATH, não roda (retorna `ran:false`). Nunca lança.
|
|
43
|
+
*/
|
|
44
|
+
export function runPatternsAnalysis(cwd) {
|
|
45
|
+
const prompt = analysisPrompt();
|
|
46
|
+
// stdin ignorado (o prompt vai por arg) — evita o agente ficar esperando stdin.
|
|
47
|
+
const stdio = ['ignore', 'inherit', 'inherit'];
|
|
48
|
+
if (hasBin('claude')) {
|
|
49
|
+
const r = spawnSync('claude', ['-p', prompt, '--permission-mode', 'acceptEdits'], {
|
|
50
|
+
cwd,
|
|
51
|
+
stdio,
|
|
52
|
+
});
|
|
53
|
+
return { ran: true, ok: !r.error && r.status === 0, agent: 'claude' };
|
|
54
|
+
}
|
|
55
|
+
if (hasBin('codex')) {
|
|
56
|
+
const r = spawnSync('codex', ['exec', prompt], { cwd, stdio });
|
|
57
|
+
return { ran: true, ok: !r.error && r.status === 0, agent: 'codex' };
|
|
58
|
+
}
|
|
59
|
+
return { ran: false, reason: 'sem `claude` nem `codex` no PATH pra rodar a análise' };
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/lib/patterns.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;GAIG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAEhD,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,8FAA8F;AAC9F,MAAM,eAAe,GAAG,wCAAwC,YAAY,mYAAmY,CAAC;AAEhd,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,iBAAiB,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAC1F,IAAI,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE;YAAE,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,uCAAuC;IACzC,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,mDAAmD;AACnD,SAAS,MAAM,CAAC,GAAW;IACzB,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;IAEhC,gFAAgF;IAChF,MAAM,KAAK,GAAqC,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAEjF,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,aAAa,CAAC,EAAE;YAChF,GAAG;YACH,KAAK;SACN,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACxE,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACpB,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/D,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACvE,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,sDAAsD,EAAE,CAAC;AACxF,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { PLAN_ENGINE, engineArgs, engineMissingError, resolveEngineBin, } from './exec-engines.js';
|
|
5
|
+
import { HARNESS_RULES_REL } from './harness.js';
|
|
6
|
+
/** Semente pré-SDD: estrutura mínima pro engine preencher na primeira rodada. */
|
|
7
|
+
export const PLAN_TEMPLATE = [
|
|
8
|
+
'# Plano',
|
|
9
|
+
'',
|
|
10
|
+
'## Contexto',
|
|
11
|
+
'',
|
|
12
|
+
'## Problema',
|
|
13
|
+
'',
|
|
14
|
+
'## Solução',
|
|
15
|
+
'',
|
|
16
|
+
'## Escopo',
|
|
17
|
+
'',
|
|
18
|
+
'### Fora de escopo',
|
|
19
|
+
'',
|
|
20
|
+
'## Decisões',
|
|
21
|
+
'',
|
|
22
|
+
'## Tarefas',
|
|
23
|
+
'',
|
|
24
|
+
].join('\n');
|
|
25
|
+
export function planPath(project) {
|
|
26
|
+
return join(project, 'plan.md');
|
|
27
|
+
}
|
|
28
|
+
/** Base do refino: conteúdo atual do `plan.md`, ou o template quando ainda não existe. */
|
|
29
|
+
export function planBase(project) {
|
|
30
|
+
try {
|
|
31
|
+
const current = readFileSync(planPath(project), 'utf8');
|
|
32
|
+
return current.trim() ? current : PLAN_TEMPLATE;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return PLAN_TEMPLATE;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** Preâmbulo de planejamento: ancora no harness e proíbe explicitamente escrever código. */
|
|
39
|
+
export function buildPlanPrompt(instruction, base) {
|
|
40
|
+
return [
|
|
41
|
+
'Você está RASCUNHANDO/REFINANDO um plano — não implemente nada.',
|
|
42
|
+
`Antes: leia AGENTS.md e ${HARNESS_RULES_REL} deste projeto e respeite o harness.`,
|
|
43
|
+
'NÃO escreva código, NÃO edite arquivos, NÃO rode comandos.',
|
|
44
|
+
'Parta do plano atual abaixo e refine-o à luz da instrução; não descarte raciocínio já feito.',
|
|
45
|
+
'Responda APENAS com o markdown final do plan.md, sem cercas de código e sem comentários.',
|
|
46
|
+
'',
|
|
47
|
+
`## Instrução`,
|
|
48
|
+
instruction,
|
|
49
|
+
'',
|
|
50
|
+
'## Plano atual',
|
|
51
|
+
base,
|
|
52
|
+
].join('\n');
|
|
53
|
+
}
|
|
54
|
+
/** O engine às vezes embrulha a resposta em ```markdown — o arquivo não quer a cerca. */
|
|
55
|
+
export function stripFence(text) {
|
|
56
|
+
const t = text.trim();
|
|
57
|
+
const m = /^```[a-zA-Z]*\n([\s\S]*?)\n?```$/.exec(t);
|
|
58
|
+
return (m ? m[1] : t).trim();
|
|
59
|
+
}
|
|
60
|
+
/** Write-then-rename: o plano anterior sobrevive até a escrita concluir. */
|
|
61
|
+
function writeAtomic(project, content) {
|
|
62
|
+
const target = planPath(project);
|
|
63
|
+
const tmp = `${target}.tmp`;
|
|
64
|
+
writeFileSync(tmp, `${content}\n`, 'utf8');
|
|
65
|
+
renameSync(tmp, target);
|
|
66
|
+
return target;
|
|
67
|
+
}
|
|
68
|
+
function spawnPlan(bin, engine, prompt, project, echo) {
|
|
69
|
+
return new Promise((resolve) => {
|
|
70
|
+
const child = spawn(bin, engineArgs(engine, prompt), {
|
|
71
|
+
cwd: project,
|
|
72
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
73
|
+
});
|
|
74
|
+
let markdown = '';
|
|
75
|
+
child.stdout.on('data', (d) => (markdown += d.toString()));
|
|
76
|
+
child.stderr.on('data', (d) => echo && process.stderr.write(d.toString()));
|
|
77
|
+
const fail = (error) => {
|
|
78
|
+
resolve({ ok: false, path: planPath(project), engine, error });
|
|
79
|
+
};
|
|
80
|
+
child.on('error', (e) => fail(e.message));
|
|
81
|
+
child.on('close', (code) => {
|
|
82
|
+
if (code !== 0)
|
|
83
|
+
return fail(`engine ${engine} falhou (exit ${code})`);
|
|
84
|
+
const content = stripFence(markdown);
|
|
85
|
+
if (!content)
|
|
86
|
+
return fail(`engine ${engine} não devolveu markdown`);
|
|
87
|
+
resolve({ ok: true, path: writeAtomic(project, content), engine });
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/** Bloqueante: roda o engine pensante e escreve o `plan.md`. `echo` streama log no stderr. */
|
|
92
|
+
export function runPlan(opts) {
|
|
93
|
+
const engine = opts.engine ?? PLAN_ENGINE;
|
|
94
|
+
const bin = resolveEngineBin(engine);
|
|
95
|
+
if (!bin) {
|
|
96
|
+
return Promise.resolve({
|
|
97
|
+
ok: false,
|
|
98
|
+
path: planPath(opts.project),
|
|
99
|
+
engine,
|
|
100
|
+
error: engineMissingError(engine),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const prompt = buildPlanPrompt(opts.instruction, planBase(opts.project));
|
|
104
|
+
return spawnPlan(bin, engine, prompt, opts.project, opts.echo === true);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=plan-delegate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-delegate.js","sourceRoot":"","sources":["../../src/lib/plan-delegate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { brand } from '../brand.js';
|
|
2
|
+
/**
|
|
3
|
+
* Erro com mensagem em pt-BR pronta pra mostrar ao usuário.
|
|
4
|
+
* Wrappers (tool MCP, CLI) só precisam pegar `.message`.
|
|
5
|
+
*/
|
|
6
|
+
export class ProjectContextError extends Error {
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Texto de "Sobre o projeto" pro harness (`AGENTS.md`), montado do `ai_context` do NOS —
|
|
10
|
+
* projeto + cada repo que tenha contexto. Determinístico (não usa LLM). `''` se nada.
|
|
11
|
+
*/
|
|
12
|
+
export function buildProjectOverview(ctx) {
|
|
13
|
+
const parts = [];
|
|
14
|
+
if (ctx.project.ai_context?.trim())
|
|
15
|
+
parts.push(ctx.project.ai_context.trim());
|
|
16
|
+
// Escopo pelo **repositório atribuído** (`repository_id`) quando há um selecionado — o
|
|
17
|
+
// harness vive dentro dele. Sem repo (binding no projeto) → todos, pra orquestração.
|
|
18
|
+
const repos = ctx.current_repository ? [ctx.current_repository] : ctx.repositories;
|
|
19
|
+
for (const r of repos) {
|
|
20
|
+
if (r.ai_context?.trim())
|
|
21
|
+
parts.push(`### ${r.name}\n\n${r.ai_context.trim()}`);
|
|
22
|
+
}
|
|
23
|
+
return parts.join('\n\n');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Projetos **ativos em que o usuário é membro** (`project_members`). Duas queries
|
|
27
|
+
* (memberships → projetos) pra tipagem limpa e independente de RLS: mesmo que o
|
|
28
|
+
* usuário seja admin e o RLS deixe ver tudo, aqui recortamos pra atribuição real.
|
|
29
|
+
*/
|
|
30
|
+
export async function listMemberProjects(supabase, userId) {
|
|
31
|
+
const membersRes = await supabase
|
|
32
|
+
.from('project_members')
|
|
33
|
+
.select('project_id')
|
|
34
|
+
.eq('user_id', userId);
|
|
35
|
+
if (membersRes.error) {
|
|
36
|
+
throw new ProjectContextError(`Erro ao listar suas atribuições: ${membersRes.error.message}`);
|
|
37
|
+
}
|
|
38
|
+
const ids = [...new Set((membersRes.data ?? []).map((r) => r.project_id))];
|
|
39
|
+
if (ids.length === 0)
|
|
40
|
+
return [];
|
|
41
|
+
const projectsRes = await supabase
|
|
42
|
+
.from('projects')
|
|
43
|
+
.select('id, name')
|
|
44
|
+
.eq('is_active', true)
|
|
45
|
+
.in('id', ids)
|
|
46
|
+
.order('name');
|
|
47
|
+
if (projectsRes.error) {
|
|
48
|
+
throw new ProjectContextError(`Erro ao listar projetos: ${projectsRes.error.message}`);
|
|
49
|
+
}
|
|
50
|
+
return (projectsRes.data ?? []).map((p) => ({ id: p.id, name: p.name }));
|
|
51
|
+
}
|
|
52
|
+
export async function fetchProjectContext(supabase, config, user) {
|
|
53
|
+
const projectId = config.project_id;
|
|
54
|
+
const [projectRes, reposRes, sprintRes, membersRes] = await Promise.all([
|
|
55
|
+
supabase
|
|
56
|
+
.from('projects')
|
|
57
|
+
.select('id, name, color, monthly_hours, notes, ai_context')
|
|
58
|
+
.eq('id', projectId)
|
|
59
|
+
.maybeSingle(),
|
|
60
|
+
supabase
|
|
61
|
+
.from('repositories')
|
|
62
|
+
.select('id, project_id, name, url, default_branch, ai_context')
|
|
63
|
+
.eq('project_id', projectId)
|
|
64
|
+
.order('name'),
|
|
65
|
+
supabase
|
|
66
|
+
.from('sprints')
|
|
67
|
+
.select('id, name, start_date, end_date')
|
|
68
|
+
.eq('project_id', projectId)
|
|
69
|
+
.eq('status', 'ativa')
|
|
70
|
+
.maybeSingle(),
|
|
71
|
+
supabase
|
|
72
|
+
.from('project_members')
|
|
73
|
+
.select('user_id, profiles:profiles!inner(id, full_name, username, avatar_url)')
|
|
74
|
+
.eq('project_id', projectId),
|
|
75
|
+
]);
|
|
76
|
+
if (projectRes.error) {
|
|
77
|
+
throw new ProjectContextError(`Erro ao buscar projeto: ${projectRes.error.message}`);
|
|
78
|
+
}
|
|
79
|
+
if (!projectRes.data) {
|
|
80
|
+
throw new ProjectContextError(`Projeto ${projectId} não encontrado ou você não tem acesso. Rode \`${brand.name} init\` pra revincular.`);
|
|
81
|
+
}
|
|
82
|
+
if (reposRes.error) {
|
|
83
|
+
throw new ProjectContextError(`Erro ao buscar repositórios: ${reposRes.error.message}`);
|
|
84
|
+
}
|
|
85
|
+
if (sprintRes.error) {
|
|
86
|
+
throw new ProjectContextError(`Erro ao buscar sprint ativa: ${sprintRes.error.message}`);
|
|
87
|
+
}
|
|
88
|
+
if (membersRes.error) {
|
|
89
|
+
throw new ProjectContextError(`Erro ao buscar membros: ${membersRes.error.message}`);
|
|
90
|
+
}
|
|
91
|
+
const project = projectRes.data;
|
|
92
|
+
const allRepos = reposRes.data ?? [];
|
|
93
|
+
const sprint = sprintRes.data;
|
|
94
|
+
const memberRows = (membersRes.data ?? []);
|
|
95
|
+
let currentRepository = null;
|
|
96
|
+
if (config.repository_id) {
|
|
97
|
+
const match = allRepos.find((r) => r.id === config.repository_id);
|
|
98
|
+
if (match) {
|
|
99
|
+
currentRepository = {
|
|
100
|
+
id: match.id,
|
|
101
|
+
name: match.name,
|
|
102
|
+
url: match.url,
|
|
103
|
+
default_branch: match.default_branch,
|
|
104
|
+
ai_context: match.ai_context,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const members = memberRows.map((row) => {
|
|
109
|
+
const profile = Array.isArray(row.profiles) ? row.profiles[0] : row.profiles;
|
|
110
|
+
return {
|
|
111
|
+
user_id: row.user_id,
|
|
112
|
+
full_name: profile?.full_name ?? null,
|
|
113
|
+
username: profile?.username ?? null,
|
|
114
|
+
avatar_url: profile?.avatar_url ?? null,
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
return {
|
|
118
|
+
project: {
|
|
119
|
+
id: project.id,
|
|
120
|
+
name: project.name,
|
|
121
|
+
color: project.color,
|
|
122
|
+
monthly_hours: project.monthly_hours,
|
|
123
|
+
notes: project.notes,
|
|
124
|
+
ai_context: project.ai_context,
|
|
125
|
+
},
|
|
126
|
+
current_repository: currentRepository,
|
|
127
|
+
repositories: allRepos.map((r) => ({
|
|
128
|
+
id: r.id,
|
|
129
|
+
name: r.name,
|
|
130
|
+
url: r.url,
|
|
131
|
+
default_branch: r.default_branch,
|
|
132
|
+
ai_context: r.ai_context,
|
|
133
|
+
})),
|
|
134
|
+
active_sprint: sprint
|
|
135
|
+
? {
|
|
136
|
+
id: sprint.id,
|
|
137
|
+
name: sprint.name,
|
|
138
|
+
start_date: sprint.start_date,
|
|
139
|
+
end_date: sprint.end_date,
|
|
140
|
+
}
|
|
141
|
+
: null,
|
|
142
|
+
members,
|
|
143
|
+
current_user: {
|
|
144
|
+
id: user.id,
|
|
145
|
+
email: user.email,
|
|
146
|
+
full_name: user.full_name,
|
|
147
|
+
username: user.username,
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=project-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-context.js","sourceRoot":"","sources":["../../src/lib/project-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { text, password as clackPassword, confirm as clackConfirm, select as clackSelect, multiselect, isCancel, cancel, } from '@clack/prompts';
|
|
2
|
+
/**
|
|
3
|
+
* Wrapper drop-in do `@clack/prompts` com a MESMA assinatura que o CLI já usava
|
|
4
|
+
* do `@inquirer/prompts` — então trocar o cliente de prompts é só mudar o import.
|
|
5
|
+
*
|
|
6
|
+
* Extras que o clack traz de graça: gutter `│`, símbolos `◇/◆/✓`, e cancelamento
|
|
7
|
+
* (Ctrl-C) tratado de forma central por `unwrap()` (encerra limpo em vez de stack).
|
|
8
|
+
*/
|
|
9
|
+
/** Encerra limpo se o usuário cancelar (Ctrl-C) qualquer prompt. */
|
|
10
|
+
function unwrap(value) {
|
|
11
|
+
if (isCancel(value)) {
|
|
12
|
+
cancel('Operação cancelada.');
|
|
13
|
+
process.exit(130);
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Converte o `validate` do inquirer (`(v: string) => true | string`) pro do clack
|
|
19
|
+
* (`Validate<string>` = `(v: string | undefined) => string | undefined`).
|
|
20
|
+
*/
|
|
21
|
+
function adaptValidate(validate) {
|
|
22
|
+
if (!validate)
|
|
23
|
+
return undefined;
|
|
24
|
+
return (value) => {
|
|
25
|
+
const result = validate(value ?? '');
|
|
26
|
+
return result === true ? undefined : result || undefined;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export async function password(opts) {
|
|
30
|
+
return unwrap(await clackPassword({
|
|
31
|
+
message: opts.message,
|
|
32
|
+
mask: opts.mask,
|
|
33
|
+
validate: adaptValidate(opts.validate),
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
export async function input(opts) {
|
|
37
|
+
return unwrap(await text({
|
|
38
|
+
message: opts.message,
|
|
39
|
+
initialValue: opts.default,
|
|
40
|
+
validate: adaptValidate(opts.validate),
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
export async function confirm(opts) {
|
|
44
|
+
return unwrap(await clackConfirm({ message: opts.message, initialValue: opts.default }));
|
|
45
|
+
}
|
|
46
|
+
export async function select(opts) {
|
|
47
|
+
const options = opts.choices.map((ch) => ({
|
|
48
|
+
value: ch.value,
|
|
49
|
+
label: ch.name,
|
|
50
|
+
hint: ch.description,
|
|
51
|
+
}));
|
|
52
|
+
return unwrap(await clackSelect({ message: opts.message, options: options, initialValue: opts.default }));
|
|
53
|
+
}
|
|
54
|
+
/** Sentinela da opção "Todos" — `Symbol` não colide com nenhum valor real de `T`. */
|
|
55
|
+
const SELECT_ALL = Symbol("select-all");
|
|
56
|
+
export async function checkbox(opts) {
|
|
57
|
+
const withAll = Boolean(opts.all) && opts.choices.length > 1;
|
|
58
|
+
const allLabel = typeof opts.all === "string" ? opts.all : "Todos";
|
|
59
|
+
const options = [
|
|
60
|
+
...(withAll ? [{ value: SELECT_ALL, label: allLabel, hint: "marca tudo" }] : []),
|
|
61
|
+
...opts.choices.map((ch) => ({ value: ch.value, label: ch.name, hint: ch.description })),
|
|
62
|
+
];
|
|
63
|
+
const picked = unwrap(await multiselect({ message: opts.message, options: options, required: false }));
|
|
64
|
+
if (withAll && picked.includes(SELECT_ALL)) {
|
|
65
|
+
return opts.choices.map((ch) => ch.value);
|
|
66
|
+
}
|
|
67
|
+
return picked.filter((v) => v !== SELECT_ALL);
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/lib/prompts.ts"],"names":[],"mappings":"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"}
|