@autonsh/cli 0.17.2 → 0.18.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/dist/index.js +245 -58
- package/dist/index.js.map +1 -1
- package/dist/prompts.d.ts +34 -8
- package/dist/prompts.js +186 -8
- package/dist/prompts.js.map +1 -1
- package/dist/task.d.ts +9 -1
- package/dist/task.js +21 -0
- package/dist/task.js.map +1 -1
- package/dist/template-engine.d.ts +19 -0
- package/dist/template-engine.js +187 -0
- package/dist/template-engine.js.map +1 -0
- package/dist/template-registry.d.ts +36 -0
- package/dist/template-registry.js +294 -0
- package/dist/template-registry.js.map +1 -0
- package/package.json +2 -1
- package/templates/coding/agent.md +39 -0
- package/templates/coding/agent.ts +83 -0
- package/templates/coding/task.yaml +36 -0
- package/templates/harness/agent.md +43 -0
- package/templates/harness/harness.ts +145 -0
- package/templates/harness/task.yaml +15 -0
- package/templates/research/task.yaml +32 -0
package/dist/index.js
CHANGED
|
@@ -19,7 +19,9 @@ import { cmdModel, modelLs, modelSet, modelTest } from "./model.js";
|
|
|
19
19
|
import { cmdChat } from "./chat.js";
|
|
20
20
|
import { resolveAgent } from "./picker.js";
|
|
21
21
|
import { getDefaultModel, getActiveProvider } from "./config.js";
|
|
22
|
-
import {
|
|
22
|
+
import { promptInit, promptConfirmUndeploy, promptGateApproval, promptGateQuestion, parseGateLine, listTemplatesForDisplay, } from "./prompts.js";
|
|
23
|
+
import { getTemplateRegistry } from "./template-registry.js";
|
|
24
|
+
import { renderTemplate } from "./template-engine.js";
|
|
23
25
|
import { loadTaskManifest, MODES, SKILLS, EXIT, ExitError, } from "./task.js";
|
|
24
26
|
import { runVerify } from "./verify.js";
|
|
25
27
|
const SRC = dirname(fileURLToPath(import.meta.url));
|
|
@@ -109,59 +111,113 @@ async function installRuntime(dir) {
|
|
|
109
111
|
bar.stop();
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
|
-
async function cmdInit(name,
|
|
114
|
+
async function cmdInit(name, templateId, opts = {}) {
|
|
115
|
+
const registry = await getTemplateRegistry();
|
|
116
|
+
const template = await registry.get(templateId);
|
|
117
|
+
if (!template) {
|
|
118
|
+
throw new ExitError(EXIT.USAGE, `template não encontrado: ${templateId}. Rode 'auton template list' para ver disponíveis.`);
|
|
119
|
+
}
|
|
113
120
|
const plain = name === "." ? basename(process.cwd()) : name;
|
|
114
121
|
const dir = resolve(name === "." ? process.cwd() : join(process.cwd(), name));
|
|
115
122
|
if (existsSync(dir) && readdirSync(dir).length > 0) {
|
|
116
123
|
throw new ExitError(EXIT.USAGE, `diretório não vazio: ${dir}`);
|
|
117
124
|
}
|
|
125
|
+
// Prepara contexto de renderização
|
|
126
|
+
const context = {
|
|
127
|
+
name: plain,
|
|
128
|
+
...opts.variables,
|
|
129
|
+
};
|
|
130
|
+
if (opts.dryRun) {
|
|
131
|
+
console.log(info(`[dry-run] Scaffold seria criado em: ${dir}`));
|
|
132
|
+
console.log(info(`[dry-run] Template: ${template.name} (${template.id})`));
|
|
133
|
+
console.log(info(`[dry-run] Variáveis: ${JSON.stringify(context, null, 2)}`));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
118
136
|
mkdirSync(dir, { recursive: true });
|
|
119
|
-
|
|
120
|
-
|
|
137
|
+
// Renderiza template via engine (Handlebars)
|
|
138
|
+
const result = await renderTemplate(template, context, dir);
|
|
139
|
+
// Substitui name no task.yaml (backward compat: templates built-in têm name hardcoded)
|
|
121
140
|
const yamlPath = join(dir, "task.yaml");
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
141
|
+
if (existsSync(yamlPath)) {
|
|
142
|
+
let yaml = await readFile(yamlPath, "utf8");
|
|
143
|
+
yaml = yaml.replace(/^name: .*$/m, `name: ${plain}`);
|
|
144
|
+
await writeFile(yamlPath, yaml);
|
|
145
|
+
}
|
|
146
|
+
// Garante package.json (pode vir do template ou ser gerado)
|
|
147
|
+
const pkgPath = join(dir, "package.json");
|
|
148
|
+
if (!existsSync(pkgPath)) {
|
|
149
|
+
const pkgName = plain.toLowerCase().replace(/[^a-z0-9._-]/g, "-");
|
|
150
|
+
await writeFile(pkgPath, JSON.stringify({
|
|
151
|
+
name: pkgName || "agent",
|
|
152
|
+
version: "0.0.0",
|
|
153
|
+
private: true,
|
|
154
|
+
type: "module",
|
|
155
|
+
dependencies: { "@autonsh/runtime": "^0.11.0" },
|
|
156
|
+
}, null, 2) + "\n");
|
|
157
|
+
}
|
|
158
|
+
// Genesis custom (se fornecido via --genesis ou prompt)
|
|
159
|
+
if (opts.genesis) {
|
|
160
|
+
const yamlPath = join(dir, "task.yaml");
|
|
161
|
+
let yaml = await readFile(yamlPath, "utf8");
|
|
162
|
+
// Substitui ou adiciona bloco genesis
|
|
163
|
+
if (yaml.includes("genesis:")) {
|
|
164
|
+
yaml = yaml.replace(/^genesis:[\s\S]*?(?=\n\S|\n*$)/m, `genesis: |\n ${opts.genesis.replace(/\n/g, "\n ")}\n`);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
yaml += `\ngenesis: |\n ${opts.genesis.replace(/\n/g, "\n ")}\n`;
|
|
168
|
+
}
|
|
169
|
+
await writeFile(yamlPath, yaml);
|
|
170
|
+
}
|
|
171
|
+
// Mode + skills do template (podem ser sobrescritos por opts)
|
|
125
172
|
const mode = opts.mode && MODES.includes(opts.mode)
|
|
126
173
|
? opts.mode
|
|
127
|
-
:
|
|
174
|
+
: template.defaultMode;
|
|
175
|
+
const skills = (opts.skills ?? template.skills).filter((s) => SKILLS.includes(s));
|
|
176
|
+
// Atualiza task.yaml com mode/skills apenas se override explícito
|
|
177
|
+
if (opts.mode || opts.skills) {
|
|
178
|
+
const yamlPath2 = join(dir, "task.yaml");
|
|
179
|
+
let yaml = await readFile(yamlPath2, "utf8");
|
|
180
|
+
yaml = yaml
|
|
181
|
+
.split("\n")
|
|
182
|
+
.filter((line) => !/^(mode|skills):/m.test(line) && !/^\s*-\s/.test(line))
|
|
183
|
+
.join("\n")
|
|
184
|
+
.trimEnd()
|
|
185
|
+
.concat("\n", `mode: ${mode}`, skills.length > 0
|
|
186
|
+
? `\nskills:\n${skills.map((s) => ` - ${s}`).join("\n")}`
|
|
187
|
+
: "")
|
|
188
|
+
.concat("\n");
|
|
189
|
+
await writeFile(yamlPath2, yaml);
|
|
190
|
+
}
|
|
191
|
+
// Copia agent.md do modo se não existir
|
|
128
192
|
const modeDoc = join(TEMPLATES_SRC, "modes", mode, "agent.md");
|
|
129
|
-
if (existsSync(modeDoc)) {
|
|
193
|
+
if (existsSync(modeDoc) && !existsSync(join(dir, "agent.md"))) {
|
|
130
194
|
cpSync(modeDoc, join(dir, "agent.md"));
|
|
131
195
|
}
|
|
132
|
-
|
|
196
|
+
// Skills built-in
|
|
133
197
|
for (const s of skills) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
198
|
+
try {
|
|
199
|
+
cpSync(join(TEMPLATES_SRC, "skills", s, "SKILL.md"), join(dir, "skills", s, "SKILL.md"), {
|
|
200
|
+
recursive: true,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
// skill não existe — ignora
|
|
205
|
+
}
|
|
137
206
|
}
|
|
138
|
-
await writeFile(yamlPath, yaml
|
|
139
|
-
.split("\n")
|
|
140
|
-
.filter((line) => !/^(mode|skills):/m.test(line))
|
|
141
|
-
.join("\n")
|
|
142
|
-
.trimEnd()
|
|
143
|
-
.concat("\n", `mode: ${mode}`, skills.length > 0
|
|
144
|
-
? `\nskills:\n${skills.map((s) => ` - ${s}`).join("\n")}`
|
|
145
|
-
: "")
|
|
146
|
-
.concat("\n"));
|
|
147
|
-
// package.json do projeto (0.0.7): remove o passo manual de criar pacote.
|
|
148
|
-
// `npm install` abaixo salva/adiciona a dep se preciso; aqui o pacote já existe.
|
|
149
|
-
const pkgName = plain.toLowerCase().replace(/[^a-z0-9._-]/g, "-");
|
|
150
|
-
await writeFile(join(dir, "package.json"), JSON.stringify({
|
|
151
|
-
name: pkgName || "agent",
|
|
152
|
-
version: "0.0.0",
|
|
153
|
-
private: true,
|
|
154
|
-
type: "module",
|
|
155
|
-
dependencies: { "@autonsh/runtime": "^0.11.0" },
|
|
156
|
-
}, null, 2) + "\n");
|
|
157
207
|
ensureRuntimeLink(dir);
|
|
158
208
|
if (!HAS_LOCAL_RUNTIME) {
|
|
159
209
|
await installRuntime(dir);
|
|
160
210
|
}
|
|
161
211
|
if (isTTY)
|
|
162
212
|
console.log(logo());
|
|
163
|
-
console.log(ok(`${plain} (template: ${template}) em ${dim(dir)}`));
|
|
213
|
+
console.log(ok(`${plain} (template: ${template.name}) em ${dim(dir)}`));
|
|
164
214
|
console.log(info(`próximo: ${bold(`cd ${plain} && auton run "<objetivo>"`)}`));
|
|
215
|
+
// Deploy opcional
|
|
216
|
+
if (opts.deploy) {
|
|
217
|
+
console.log(info(`deployando ${bold(plain)}...`));
|
|
218
|
+
await cmdDeploy(dir);
|
|
219
|
+
console.log(ok(`${plain} deployado`));
|
|
220
|
+
}
|
|
165
221
|
}
|
|
166
222
|
const VERSION = JSON.parse(readFileSync(resolve(SRC, "../package.json"), "utf8")).version;
|
|
167
223
|
const API = process.env.AUTON_API ?? "http://localhost:8080";
|
|
@@ -261,29 +317,29 @@ Usage:
|
|
|
261
317
|
|
|
262
318
|
Modelos:
|
|
263
319
|
auton model Seletor interativo do modelo default
|
|
264
|
-
|
|
320
|
+
(local ollama + providers configurados)
|
|
265
321
|
auton model ls [--json] Lista modelos locais + providers
|
|
266
322
|
auton model set <spec> Define default (ex: ollama:qwen3)
|
|
267
323
|
auton model test Testa latência dos providers
|
|
268
324
|
auton login [provider] [--apikey X]
|
|
269
|
-
|
|
325
|
+
Conecta provider (gemini/groq/ollama)
|
|
270
326
|
auton logout [id] Remove provider configurado
|
|
271
327
|
|
|
272
328
|
Agentes:
|
|
273
329
|
auton [nome] Sessão de trabalho (estilo opencode): dá
|
|
274
|
-
|
|
275
|
-
|
|
330
|
+
tasks, acompanha o agente ao vivo, gates
|
|
331
|
+
inline. Sem nome: cwd/picker.
|
|
276
332
|
auton chat [name] Alias da sessão de trabalho
|
|
277
333
|
auton agent [dir] Deploy do agente no diretório
|
|
278
334
|
auton ps Lista agentes + status
|
|
279
335
|
auton logs [name] [--tail N] [--follow] [--since X] [--turn N]
|
|
280
|
-
|
|
336
|
+
Stream de logs do agente (SSE)
|
|
281
337
|
auton status [name] Status do agente
|
|
282
338
|
auton restart [name] Reinicia o agente
|
|
283
339
|
auton invoke [name] [--stream] [-- prompt]
|
|
284
|
-
|
|
340
|
+
Roda 1 turno (legado v0)
|
|
285
341
|
auton approve|reject [name] [-- razão]
|
|
286
|
-
|
|
342
|
+
Decide o gate de aprovação
|
|
287
343
|
auton answer [name] [-- texto] Responde pergunta pendente (ctx.ask)
|
|
288
344
|
auton context [name] Work context: decisions/findings/artifacts
|
|
289
345
|
auton undeploy [name] Remove o agente (--all remove tudo)
|
|
@@ -296,13 +352,18 @@ Tasks:
|
|
|
296
352
|
auton verify [dir] [--json] Roda gates mecânicos do verify
|
|
297
353
|
auton inspect [dir] [--json] Inspeciona task + evidência
|
|
298
354
|
auton continue [name] [goal] Retoma a última task (sem redeploy)
|
|
299
|
-
auton init [nome] [template]
|
|
355
|
+
auton init [nome] [template] [--mode=X] [--skills=a,b] [--deploy] [--dry-run] [--genesis] [--var key=value]
|
|
356
|
+
Scaffold de task (templates built-in + custom)
|
|
357
|
+
|
|
358
|
+
Templates:
|
|
359
|
+
auton template list [--json] Lista templates (built-in + custom)
|
|
360
|
+
auton template create <id> Cria template custom (futuro)
|
|
300
361
|
|
|
301
362
|
Infra:
|
|
302
363
|
auton kv get|set|ls [name] [key] [value]
|
|
303
|
-
|
|
364
|
+
Inspeciona o storage KV
|
|
304
365
|
auton env set|get|ls [name] [key] [value]
|
|
305
|
-
|
|
366
|
+
Env vars por agente
|
|
306
367
|
|
|
307
368
|
Options:
|
|
308
369
|
--help, -h Mostra ajuda
|
|
@@ -1303,6 +1364,69 @@ async function cmdLogin(realArgs) {
|
|
|
1303
1364
|
async function cmdLogout(providerId) {
|
|
1304
1365
|
await logoutCmd(providerId);
|
|
1305
1366
|
}
|
|
1367
|
+
/** Project mode: `auton` bare — se não há agente, cria + deploya + entra no chat. */
|
|
1368
|
+
async function cmdProject() {
|
|
1369
|
+
// 1. Tenta achar agente no cwd (task.yaml)
|
|
1370
|
+
let agentName;
|
|
1371
|
+
try {
|
|
1372
|
+
const { loadTaskManifest } = await import("./task.js");
|
|
1373
|
+
const manifest = await loadTaskManifest(process.cwd());
|
|
1374
|
+
if (manifest?.name)
|
|
1375
|
+
agentName = manifest.name;
|
|
1376
|
+
}
|
|
1377
|
+
catch {
|
|
1378
|
+
// sem task.yaml
|
|
1379
|
+
}
|
|
1380
|
+
// 2. Se não há no cwd, tenta deployed agents
|
|
1381
|
+
if (!agentName) {
|
|
1382
|
+
const deployed = await listAgentNames();
|
|
1383
|
+
if (deployed.length === 1) {
|
|
1384
|
+
agentName = deployed[0];
|
|
1385
|
+
}
|
|
1386
|
+
else if (deployed.length > 1) {
|
|
1387
|
+
// Múltiplos deployados — usa picker (cmdChat já faz isso)
|
|
1388
|
+
await cmdChat(undefined);
|
|
1389
|
+
return;
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
// 3. Tem agente (cwd ou único deployado) → entra no chat
|
|
1393
|
+
if (agentName) {
|
|
1394
|
+
console.log(info(`entrando no agente ${bold(agentName)}...`));
|
|
1395
|
+
await cmdChat(agentName);
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
// 4. Nenhum agente — oferece init interativo
|
|
1399
|
+
console.log(box("auton — nenhum agente encontrado", [
|
|
1400
|
+
"Este diretório não tem task.yaml e não há agentes deployados.",
|
|
1401
|
+
"Quer criar um novo agente aqui?",
|
|
1402
|
+
]));
|
|
1403
|
+
const { confirm } = await import("@clack/prompts");
|
|
1404
|
+
const create = await confirm({
|
|
1405
|
+
message: "criar novo agente neste diretório?",
|
|
1406
|
+
active: "sim",
|
|
1407
|
+
inactive: "não",
|
|
1408
|
+
});
|
|
1409
|
+
if (!create) {
|
|
1410
|
+
console.log(dim("até logo."));
|
|
1411
|
+
return;
|
|
1412
|
+
}
|
|
1413
|
+
// Init interativo
|
|
1414
|
+
const { promptInit } = await import("./prompts.js");
|
|
1415
|
+
const p = await promptInit();
|
|
1416
|
+
// Deploy automático
|
|
1417
|
+
console.log(info(`criando e deployando ${bold(p.name)}...`));
|
|
1418
|
+
await cmdInit(p.name, p.templateId, {
|
|
1419
|
+
mode: p.mode,
|
|
1420
|
+
skills: p.skills,
|
|
1421
|
+
genesis: p.genesis,
|
|
1422
|
+
deploy: true,
|
|
1423
|
+
dryRun: false,
|
|
1424
|
+
variables: p.variables,
|
|
1425
|
+
});
|
|
1426
|
+
// Entra no chat
|
|
1427
|
+
console.log(info(`entrando no agente ${bold(p.name)}...`));
|
|
1428
|
+
await cmdChat(p.name);
|
|
1429
|
+
}
|
|
1306
1430
|
async function main() {
|
|
1307
1431
|
let realArgs = process.argv.slice(2);
|
|
1308
1432
|
// G3: auto-start CP para comandos que precisam dele (--no-auto-cp desliga)
|
|
@@ -1317,8 +1441,9 @@ async function main() {
|
|
|
1317
1441
|
if (realArgs.length === 0) {
|
|
1318
1442
|
// 0.17.0 — `auton` bare: abre sessão de trabalho (estilo opencode):
|
|
1319
1443
|
// cwd é agente → sessão nele; senão picker. Pipe: mosta ajuda.
|
|
1444
|
+
// NOVO: project mode — se não há agente, oferece init + deploy + chat
|
|
1320
1445
|
if (isTTY) {
|
|
1321
|
-
await
|
|
1446
|
+
await cmdProject();
|
|
1322
1447
|
return;
|
|
1323
1448
|
}
|
|
1324
1449
|
console.log(USAGE);
|
|
@@ -1345,6 +1470,7 @@ async function main() {
|
|
|
1345
1470
|
"login", "logout", "model", "agent", "logs", "status", "restart", "run",
|
|
1346
1471
|
"verify", "inspect", "continue", "invoke", "undeploy", "approve", "reject",
|
|
1347
1472
|
"ps", "context", "env", "init", "kv", "chat", "answer", "wait", "result",
|
|
1473
|
+
"template",
|
|
1348
1474
|
]);
|
|
1349
1475
|
if (!KNOWN.has(realArgs[0]) && isTTY) {
|
|
1350
1476
|
const deployed = await listAgentNames();
|
|
@@ -1594,27 +1720,88 @@ async function main() {
|
|
|
1594
1720
|
break;
|
|
1595
1721
|
}
|
|
1596
1722
|
case "init": {
|
|
1597
|
-
//
|
|
1723
|
+
// auton init [nome] [template] [--mode=X] [--skills=a,b] [--deploy] [--dry-run] [--genesis] [--var key=value]
|
|
1598
1724
|
const initFlags = realArgs.filter((a) => a.startsWith("--"));
|
|
1599
1725
|
const initPos = realArgs.filter((a) => !a.startsWith("--"));
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1726
|
+
// Parse flags
|
|
1727
|
+
const deploy = initFlags.includes("--deploy");
|
|
1728
|
+
const dryRun = initFlags.includes("--dry-run");
|
|
1729
|
+
const mode = initFlags.find((f) => f.startsWith("--mode="))?.slice(7);
|
|
1730
|
+
const skills = initFlags
|
|
1731
|
+
.find((f) => f.startsWith("--skills="))
|
|
1732
|
+
?.slice(9)
|
|
1733
|
+
.split(",")
|
|
1734
|
+
.filter(Boolean);
|
|
1735
|
+
const genesis = initFlags.find((f) => f.startsWith("--genesis="))?.slice(10);
|
|
1736
|
+
// Parse --var key=value
|
|
1737
|
+
const variables = {};
|
|
1738
|
+
for (const f of initFlags) {
|
|
1739
|
+
if (f.startsWith("--var=")) {
|
|
1740
|
+
const rest = f.slice(6); // remove "--var="
|
|
1741
|
+
const eqIdx = rest.indexOf("=");
|
|
1742
|
+
if (eqIdx > 0) {
|
|
1743
|
+
const key = rest.slice(0, eqIdx);
|
|
1744
|
+
const val = rest.slice(eqIdx + 1);
|
|
1745
|
+
variables[key] = val === "true" ? true : val === "false" ? false : val;
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1608
1749
|
if (isTTY && !initPos[1] && !initPos[2]) {
|
|
1609
1750
|
const p = await promptInit();
|
|
1610
|
-
await cmdInit(p.name, p.
|
|
1751
|
+
await cmdInit(p.name, p.templateId, {
|
|
1752
|
+
mode: p.mode ?? mode,
|
|
1753
|
+
skills: p.skills ?? skills,
|
|
1754
|
+
genesis: p.genesis ?? genesis,
|
|
1755
|
+
deploy,
|
|
1756
|
+
dryRun,
|
|
1757
|
+
variables,
|
|
1758
|
+
});
|
|
1611
1759
|
}
|
|
1612
1760
|
else {
|
|
1613
|
-
const
|
|
1614
|
-
|
|
1615
|
-
|
|
1761
|
+
const name = initPos[1] ?? ".";
|
|
1762
|
+
const templateId = initPos[2];
|
|
1763
|
+
if (!templateId) {
|
|
1764
|
+
throw new ExitError(EXIT.USAGE, "uso: auton init <nome> <template-id> [--deploy] [--dry-run] ...");
|
|
1616
1765
|
}
|
|
1617
|
-
|
|
1766
|
+
// Valida template existe
|
|
1767
|
+
const registry = await getTemplateRegistry();
|
|
1768
|
+
const tpl = await registry.get(templateId);
|
|
1769
|
+
if (!tpl) {
|
|
1770
|
+
const list = await listTemplatesForDisplay();
|
|
1771
|
+
throw new ExitError(EXIT.USAGE, `template desconhecido: ${templateId}\nDisponíveis: ${list.map(t => `${t.id} (${t.category})`).join(", ")}`);
|
|
1772
|
+
}
|
|
1773
|
+
await cmdInit(name, templateId, {
|
|
1774
|
+
mode,
|
|
1775
|
+
skills,
|
|
1776
|
+
genesis,
|
|
1777
|
+
deploy,
|
|
1778
|
+
dryRun,
|
|
1779
|
+
variables,
|
|
1780
|
+
});
|
|
1781
|
+
}
|
|
1782
|
+
break;
|
|
1783
|
+
}
|
|
1784
|
+
case "template": {
|
|
1785
|
+
const sub = realArgs[1];
|
|
1786
|
+
if (sub === "list" || sub === "ls" || !sub) {
|
|
1787
|
+
const list = await listTemplatesForDisplay();
|
|
1788
|
+
if (realArgs.includes("--json")) {
|
|
1789
|
+
console.log(JSON.stringify(list, null, 2));
|
|
1790
|
+
}
|
|
1791
|
+
else {
|
|
1792
|
+
console.log(bold("Templates disponíveis:"));
|
|
1793
|
+
for (const t of list) {
|
|
1794
|
+
const srcTag = t.source === "custom" ? pc.cyan("(custom)") : pc.dim("(builtin)");
|
|
1795
|
+
console.log(` ${bold(t.id)} ${srcTag} — ${t.name} [${t.category}]`);
|
|
1796
|
+
console.log(` ${dim(t.description)}`);
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
else if (sub === "create") {
|
|
1801
|
+
console.log(info("Use 'auton init' com template custom — criação de template virá em versão futura"));
|
|
1802
|
+
}
|
|
1803
|
+
else {
|
|
1804
|
+
console.log(USAGE);
|
|
1618
1805
|
}
|
|
1619
1806
|
break;
|
|
1620
1807
|
}
|