@autonsh/cli 0.16.4 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat.d.ts +3 -0
- package/dist/chat.js +350 -0
- package/dist/chat.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.js +90 -0
- package/dist/config.js.map +1 -0
- package/dist/index.js +269 -61
- package/dist/index.js.map +1 -1
- package/dist/login.d.ts +4 -11
- package/dist/login.js +47 -40
- package/dist/login.js.map +1 -1
- package/dist/model.d.ts +24 -0
- package/dist/model.js +195 -0
- package/dist/model.js.map +1 -0
- package/dist/picker.d.ts +8 -0
- package/dist/picker.js +52 -0
- package/dist/picker.js.map +1 -0
- package/dist/prompts.d.ts +8 -1
- package/dist/prompts.js +51 -1
- package/dist/prompts.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,7 +15,11 @@ import { SingleBar, Presets } from "cli-progress";
|
|
|
15
15
|
import pc from "picocolors";
|
|
16
16
|
import { ok, fail, info, dim, bold, url, spinner, logo, tagLine, statusColor, table, box, isTTY, } from "./ui.js";
|
|
17
17
|
import { cmdLogin as loginCmd, cmdLogout as logoutCmd, credentialEnv } from "./login.js";
|
|
18
|
-
import {
|
|
18
|
+
import { cmdModel, modelLs, modelSet, modelTest } from "./model.js";
|
|
19
|
+
import { cmdChat } from "./chat.js";
|
|
20
|
+
import { resolveAgent } from "./picker.js";
|
|
21
|
+
import { getDefaultModel, getActiveProvider } from "./config.js";
|
|
22
|
+
import { TEMPLATES, promptInit, promptConfirmUndeploy, promptGateApproval, promptGateQuestion, parseGateLine, } from "./prompts.js";
|
|
19
23
|
import { loadTaskManifest, MODES, SKILLS, EXIT, ExitError, } from "./task.js";
|
|
20
24
|
import { runVerify } from "./verify.js";
|
|
21
25
|
const SRC = dirname(fileURLToPath(import.meta.url));
|
|
@@ -168,38 +172,72 @@ function authHeaders(extra) {
|
|
|
168
172
|
h.Authorization = `Bearer ${token}`;
|
|
169
173
|
return h;
|
|
170
174
|
}
|
|
175
|
+
/** Nomes dos agentes deployados (0.17.0 — `auton <nome>` abre sessão). */
|
|
176
|
+
async function listAgentNames() {
|
|
177
|
+
try {
|
|
178
|
+
const res = await fetch(`${API}/v1/agents`, { headers: authHeaders() });
|
|
179
|
+
if (!res.ok)
|
|
180
|
+
return [];
|
|
181
|
+
return (await res.json()).map((a) => a.name);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return [];
|
|
185
|
+
}
|
|
186
|
+
}
|
|
171
187
|
const USAGE = `
|
|
172
188
|
auton — Tasks that start themselves
|
|
173
189
|
|
|
174
190
|
Usage:
|
|
175
|
-
auton
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
auton
|
|
181
|
-
auton
|
|
182
|
-
auton
|
|
183
|
-
auton
|
|
184
|
-
|
|
185
|
-
auton
|
|
191
|
+
auton <comando> [argumentos]
|
|
192
|
+
|
|
193
|
+
Modelos:
|
|
194
|
+
auton model Seletor interativo do modelo default
|
|
195
|
+
(local ollama + providers configurados)
|
|
196
|
+
auton model ls [--json] Lista modelos locais + providers
|
|
197
|
+
auton model set <spec> Define default (ex: ollama:qwen3)
|
|
198
|
+
auton model test Testa latência dos providers
|
|
199
|
+
auton login [provider] [--apikey X]
|
|
200
|
+
Conecta provider (gemini/groq/ollama)
|
|
201
|
+
auton logout [id] Remove provider configurado
|
|
202
|
+
|
|
203
|
+
Agentes:
|
|
204
|
+
auton [nome] Sessão de trabalho (estilo opencode): dá
|
|
205
|
+
tasks, acompanha o agente ao vivo, gates
|
|
206
|
+
inline. Sem nome: cwd/picker.
|
|
207
|
+
auton chat [name] Alias da sessão de trabalho
|
|
208
|
+
auton agent [dir] Deploy do agente no diretório
|
|
209
|
+
auton ps Lista agentes + status
|
|
210
|
+
auton logs [name] [--tail N] [--follow] [--since X] [--turn N]
|
|
211
|
+
Stream de logs do agente (SSE)
|
|
212
|
+
auton status [name] Status do agente
|
|
213
|
+
auton restart [name] Reinicia o agente
|
|
186
214
|
auton invoke [name] [--stream] [-- prompt]
|
|
187
|
-
|
|
188
|
-
auton kv get|set|ls [name] [key] [value]
|
|
189
|
-
Inspeciona o storage KV
|
|
190
|
-
auton context [name] Lista work context: decisions/findings/artifacts
|
|
215
|
+
Roda 1 turno (legado v0)
|
|
191
216
|
auton approve|reject [name] [-- razão]
|
|
192
|
-
|
|
193
|
-
auton
|
|
194
|
-
auton
|
|
217
|
+
Decide o gate de aprovação
|
|
218
|
+
auton answer [name] [-- texto] Responde pergunta pendente (ctx.ask)
|
|
219
|
+
auton context [name] Work context: decisions/findings/artifacts
|
|
220
|
+
auton undeploy [name] Remove o agente (--all remove tudo)
|
|
221
|
+
|
|
222
|
+
Tasks:
|
|
223
|
+
auton run [goal] [--model X] [--skip-verify]
|
|
224
|
+
Roda a task do diretório atual
|
|
225
|
+
auton verify [dir] [--json] Roda gates mecânicos do verify
|
|
226
|
+
auton inspect [dir] [--json] Inspeciona task + evidência
|
|
227
|
+
auton continue [name] [goal] Retoma a última task (sem redeploy)
|
|
228
|
+
auton init [nome] [template] Scaffold de task (support|with-approval|...)
|
|
229
|
+
|
|
230
|
+
Infra:
|
|
231
|
+
auton kv get|set|ls [name] [key] [value]
|
|
232
|
+
Inspeciona o storage KV
|
|
233
|
+
auton env set|get|ls [name] [key] [value]
|
|
234
|
+
Env vars por agente
|
|
195
235
|
|
|
196
236
|
Options:
|
|
197
237
|
--help, -h Mostra ajuda
|
|
198
|
-
--version, -v Mostra versão
|
|
238
|
+
--version, -v Mostra versão + modelo default
|
|
199
239
|
AUTON_API=http://... Base do control plane (default localhost:8080)
|
|
200
240
|
|
|
201
|
-
Nota: commandos legado v0 (deploy agent . / deploy invoke) continuam funcionando.
|
|
202
|
-
|
|
203
241
|
Exit codes (0.14):
|
|
204
242
|
0 ok · 1 erro genérico · 2 uso inválido · 3 verificação falhou
|
|
205
243
|
4 abortado pelo usuário (gate rejeitado) · 5 timeout (invoke)
|
|
@@ -414,12 +452,28 @@ async function cmdRun(dir, goalArg, skipVerify, model) {
|
|
|
414
452
|
const manifest = await loadTaskManifest(dir);
|
|
415
453
|
if (!skipVerify)
|
|
416
454
|
await verifyPreFlight(dir, manifest);
|
|
417
|
-
|
|
455
|
+
let goal = goalArg ?? manifest.goal;
|
|
418
456
|
if (!goal) {
|
|
419
|
-
|
|
457
|
+
if (isTTY) {
|
|
458
|
+
// 0.17: run sem goal pergunta (estilo `ollama run` sem modelo)
|
|
459
|
+
const { text, isCancel } = await import("@clack/prompts");
|
|
460
|
+
const answered = (await text({
|
|
461
|
+
message: `qual o objetivo da task ${manifest.name}?`,
|
|
462
|
+
validate: (v) => (!v || v.trim() === "" ? "objetivo não pode ser vazio" : undefined),
|
|
463
|
+
}));
|
|
464
|
+
if (isCancel(answered)) {
|
|
465
|
+
console.log(dim("cancelado"));
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
goal = answered.trim();
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
throw new Error(`task ${manifest.name} sem objetivo — passe "${bold('auton run "<objetivo>"')}" ou defina 'goal' no task.yaml`);
|
|
472
|
+
}
|
|
420
473
|
}
|
|
421
|
-
// 0.
|
|
422
|
-
|
|
474
|
+
// 0.17: modelo efetivo = --model > task.yaml > env > config default (auton model)
|
|
475
|
+
const defaultModel = getDefaultModel();
|
|
476
|
+
await precheckModel(model ?? manifest.models ?? process.env.AUTON_MODEL ?? defaultModel);
|
|
423
477
|
// 0.15.1: credencial do `auton login` injetada no deploy (key/base);
|
|
424
478
|
// --model (0.14.3) sobrescreve models: do task.yaml
|
|
425
479
|
await cmdDeploy(dir, { ...credentialEnv(), ...(model ? { AUTON_MODEL: model } : {}) });
|
|
@@ -431,7 +485,10 @@ async function cmdRun(dir, goalArg, skipVerify, model) {
|
|
|
431
485
|
async function precheckModel(model) {
|
|
432
486
|
if (!model)
|
|
433
487
|
return;
|
|
434
|
-
|
|
488
|
+
// 0.17.1 — separa provider do nome SEM cortar a tag (ollama:deepseek-coder:1.3b)
|
|
489
|
+
const sep = model.indexOf(":");
|
|
490
|
+
const provider = sep === -1 ? model : model.slice(0, sep);
|
|
491
|
+
const name = sep === -1 ? undefined : model.slice(sep + 1);
|
|
435
492
|
if (!name)
|
|
436
493
|
return;
|
|
437
494
|
if (provider === "ollama") {
|
|
@@ -462,30 +519,37 @@ async function precheckModel(model) {
|
|
|
462
519
|
return;
|
|
463
520
|
}
|
|
464
521
|
}
|
|
465
|
-
/** Roda o turno resolvendo gates pendentes em linha (TTY pergunta; pipe reporta).
|
|
522
|
+
/** Roda o turno resolvendo gates pendentes em linha (TTY pergunta; pipe reporta).
|
|
523
|
+
* 0.17.0: além de aprovação, resolve perguntas de clarificação (ctx.ask). */
|
|
466
524
|
async function runWithGates(name, goal) {
|
|
467
525
|
let lines = await cmdInvoke(name, goal, false);
|
|
468
526
|
for (let i = 0; i < 10; i++) {
|
|
469
|
-
const gate = lines.find((l) => l.startsWith("[APPROVAL:REQ]"));
|
|
527
|
+
const gate = lines.find((l) => l.startsWith("[APPROVAL:REQ]") || l.startsWith("[QUESTION:REQ]"));
|
|
470
528
|
if (!gate)
|
|
471
529
|
return lines;
|
|
530
|
+
const g = parseGateLine(gate);
|
|
531
|
+
if (!g)
|
|
532
|
+
return lines;
|
|
533
|
+
if (g.kind === "question") {
|
|
534
|
+
if (!isTTY) {
|
|
535
|
+
console.log(info("pergunta pendente — rode `auton answer <nome> -- \"resposta\"`"));
|
|
536
|
+
return lines;
|
|
537
|
+
}
|
|
538
|
+
const answer = await promptGateQuestion(String(g.payload?.question ?? "pergunta"));
|
|
539
|
+
if (answer === undefined)
|
|
540
|
+
return lines;
|
|
541
|
+
lines = await answerPost(name, answer);
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
472
544
|
if (!isTTY) {
|
|
473
545
|
console.log(info("aprovação pendente — rode `auton approve` ou `auton reject`"));
|
|
474
546
|
return lines;
|
|
475
547
|
}
|
|
476
|
-
|
|
477
|
-
try {
|
|
478
|
-
payload = gate.slice("[APPROVAL:REQ]".length).trim();
|
|
479
|
-
JSON.parse(payload);
|
|
480
|
-
}
|
|
481
|
-
catch {
|
|
482
|
-
payload = "{}";
|
|
483
|
-
}
|
|
484
|
-
const reason = JSON.parse(payload).reason ?? "ação";
|
|
548
|
+
const reason = g.payload?.reason ?? "ação";
|
|
485
549
|
const approved = await promptGateApproval(reason);
|
|
486
550
|
lines = await cmdInvokeApproval(name, approved, undefined);
|
|
487
551
|
}
|
|
488
|
-
throw new Error(`loop de
|
|
552
|
+
throw new Error(`loop de gates não convergiu (10)`);
|
|
489
553
|
}
|
|
490
554
|
/** POST de controle: resolve o gate pendente no worker (sem novo trigger). */
|
|
491
555
|
async function cmdInvokeApproval(name, approved, reason) {
|
|
@@ -506,6 +570,62 @@ async function cmdInvokeApproval(name, approved, reason) {
|
|
|
506
570
|
console.log(line);
|
|
507
571
|
return out.lines;
|
|
508
572
|
}
|
|
573
|
+
/** 0.17.0 — POST de controle de pergunta: resolve ctx.ask no worker (sem trigger novo). */
|
|
574
|
+
async function answerPost(name, answer) {
|
|
575
|
+
const res = await fetch(`${API}/v1/agents/${name}/invoke`, {
|
|
576
|
+
method: "POST",
|
|
577
|
+
headers: authHeaders({ "Content-Type": "application/json" }),
|
|
578
|
+
body: JSON.stringify({ question: { answer } }),
|
|
579
|
+
});
|
|
580
|
+
if (!res.ok) {
|
|
581
|
+
const body = await res.text();
|
|
582
|
+
if (res.status === 409 && body.includes("sem pergunta pendente")) {
|
|
583
|
+
throw new Error(`task ${name} sem pergunta pendente`);
|
|
584
|
+
}
|
|
585
|
+
throw new Error(`control plane ${res.status}: ${body}`);
|
|
586
|
+
}
|
|
587
|
+
const out = (await res.json());
|
|
588
|
+
return out.lines;
|
|
589
|
+
}
|
|
590
|
+
/** auton answer [name] [-- texto] — responde pergunta de clarificação pendente. */
|
|
591
|
+
async function cmdAnswer(name, answer) {
|
|
592
|
+
const agent = await resolveAgent("answer", name);
|
|
593
|
+
if (answer === undefined) {
|
|
594
|
+
if (!isTTY) {
|
|
595
|
+
throw new ExitError(EXIT.USAGE, `uso: auton answer <nome> -- "resposta" (pipe)`);
|
|
596
|
+
}
|
|
597
|
+
// mostra a pergunta pendente (logs recentes) e pede a resposta
|
|
598
|
+
let question = "pergunta pendente — responda:";
|
|
599
|
+
const logs = await fetch(`${API}/v1/agents/${agent}/logs?tail=30`, {
|
|
600
|
+
headers: authHeaders({ Accept: "application/json" }),
|
|
601
|
+
});
|
|
602
|
+
if (logs.ok) {
|
|
603
|
+
const entries = (await logs.json());
|
|
604
|
+
const qline = [...entries].reverse().find((e) => e.line.startsWith("[QUESTION:REQ]"));
|
|
605
|
+
if (qline) {
|
|
606
|
+
const g = parseGateLine(qline.line);
|
|
607
|
+
if (g)
|
|
608
|
+
question = String(g.payload?.question ?? question);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
answer = await promptGateQuestion(question);
|
|
612
|
+
if (answer === undefined) {
|
|
613
|
+
console.log(dim("cancelado — agente segue pausado"));
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
const lines = await answerPost(agent, answer);
|
|
618
|
+
console.log(ok(`resposta entregue — task ${bold(agent)} segue.`));
|
|
619
|
+
const done = lines.find((l) => l.startsWith("[TASK:DONE]"));
|
|
620
|
+
if (done) {
|
|
621
|
+
const ev = JSON.parse(done.slice("[TASK:DONE]".length).trim());
|
|
622
|
+
if (ev.result)
|
|
623
|
+
console.log(dim(`resultado: ${ev.result}`));
|
|
624
|
+
}
|
|
625
|
+
else if (lines.some((l) => l.startsWith("[QUESTION:REQ]"))) {
|
|
626
|
+
console.log(info("nova pergunta pendente — `auton answer` de novo."));
|
|
627
|
+
}
|
|
628
|
+
}
|
|
509
629
|
/** auton continue — retoma a última task sem re-passar o objetivo.
|
|
510
630
|
* O harness guarda o último input no KV ("ultima-task"); aqui só busca e
|
|
511
631
|
* invoca de novo (worker dormindo → cold start; KV persiste). */
|
|
@@ -531,15 +651,7 @@ async function cmdContinue(dir, nameArg, goalArg) {
|
|
|
531
651
|
* 0.12: vira POST de CONTROLE (resolve gate pendente no worker vivo);
|
|
532
652
|
* gate de legado (template com approval:) também é resolvido assim. */
|
|
533
653
|
async function cmdApproval(name, approved, reason) {
|
|
534
|
-
|
|
535
|
-
if (!agent) {
|
|
536
|
-
try {
|
|
537
|
-
agent = (await loadTaskManifest(process.cwd())).name;
|
|
538
|
-
}
|
|
539
|
-
catch {
|
|
540
|
-
throw new Error(`${approved ? "approve" : "reject"}: nenhum nome passado e cwd não é um agente — rode \`auton ${approved ? "approve" : "reject"} <nome>\``);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
654
|
+
const agent = await resolveAgent(approved ? "approve" : "reject", name);
|
|
543
655
|
const lines = await cmdInvokeApproval(agent, approved, reason);
|
|
544
656
|
const done = lines.find((l) => l.startsWith("[TASK:DONE]"));
|
|
545
657
|
if (done) {
|
|
@@ -559,14 +671,36 @@ async function cmdApproval(name, approved, reason) {
|
|
|
559
671
|
if (!approved)
|
|
560
672
|
process.exitCode = EXIT.ABORT;
|
|
561
673
|
}
|
|
562
|
-
|
|
563
|
-
|
|
674
|
+
/** 0.16.14: snapshot JSON c/ timestamp + filtro por turno (--turn N = últimos N turnos);
|
|
675
|
+
* --follow mantém SSE ao vivo (sem ts, como antes). */
|
|
676
|
+
async function cmdLogs(name, tail, since, follow = false, turn) {
|
|
677
|
+
const agent = name ?? (await resolveAgent("logs", undefined));
|
|
564
678
|
const params = new URLSearchParams();
|
|
565
679
|
if (tail !== undefined)
|
|
566
680
|
params.set("tail", String(tail));
|
|
567
681
|
if (since !== undefined)
|
|
568
682
|
params.set("since", since);
|
|
569
683
|
const url = `${API}/v1/agents/${agent}/logs${params.toString() ? "?" + params.toString() : ""}`;
|
|
684
|
+
if (!follow) {
|
|
685
|
+
const res = await fetch(url, { headers: authHeaders({ Accept: "application/json" }) });
|
|
686
|
+
if (!res.ok)
|
|
687
|
+
throw new Error(`control plane ${res.status}: ${await res.text()}`);
|
|
688
|
+
let entries = (await res.json());
|
|
689
|
+
if (turn !== undefined && turn > 0) {
|
|
690
|
+
const groups = [];
|
|
691
|
+
for (const e of entries) {
|
|
692
|
+
if (e.line.includes("[runtime] turno iniciado"))
|
|
693
|
+
groups.push([]);
|
|
694
|
+
if (groups.length > 0)
|
|
695
|
+
groups[groups.length - 1].push(e);
|
|
696
|
+
}
|
|
697
|
+
entries = groups.slice(-turn).flat();
|
|
698
|
+
}
|
|
699
|
+
for (const e of entries) {
|
|
700
|
+
console.log(tagLine(`${dim(e.ts.slice(11, 19))} ${e.line}`));
|
|
701
|
+
}
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
570
704
|
const res = await fetch(url, {
|
|
571
705
|
headers: authHeaders({ Accept: "text/event-stream" }),
|
|
572
706
|
});
|
|
@@ -575,6 +709,7 @@ async function cmdLogs(name, tail, since) {
|
|
|
575
709
|
}
|
|
576
710
|
if (!res.body)
|
|
577
711
|
throw new Error("resposta sem body");
|
|
712
|
+
console.log(dim(`— seguindo ${agent} — Ctrl+C sai —`));
|
|
578
713
|
const reader = res.body.getReader();
|
|
579
714
|
const decoder = new TextDecoder();
|
|
580
715
|
let buf = "";
|
|
@@ -597,7 +732,7 @@ async function cmdLogs(name, tail, since) {
|
|
|
597
732
|
}
|
|
598
733
|
}
|
|
599
734
|
async function cmdStatus(name) {
|
|
600
|
-
const agent =
|
|
735
|
+
const agent = await resolveAgent("status", name);
|
|
601
736
|
const res = await fetch(`${API}/v1/agents/${agent}`, {
|
|
602
737
|
headers: authHeaders(),
|
|
603
738
|
});
|
|
@@ -608,7 +743,7 @@ async function cmdStatus(name) {
|
|
|
608
743
|
}
|
|
609
744
|
async function cmdRestart(name) {
|
|
610
745
|
// 0.1.1 — reinicia o agente (SIGTERM + respawn, state preservado)
|
|
611
|
-
const agent =
|
|
746
|
+
const agent = await resolveAgent("restart", name);
|
|
612
747
|
const res = await fetch(`${API}/v1/agents/${agent}/restart`, {
|
|
613
748
|
method: "POST",
|
|
614
749
|
headers: authHeaders(),
|
|
@@ -639,7 +774,7 @@ async function cmdUndeploy(name) {
|
|
|
639
774
|
console.log(dim("(nada pra remover)"));
|
|
640
775
|
return;
|
|
641
776
|
}
|
|
642
|
-
const agent =
|
|
777
|
+
const agent = await resolveAgent("undeploy", name);
|
|
643
778
|
if (isTTY && !(await promptConfirmUndeploy(agent)))
|
|
644
779
|
return;
|
|
645
780
|
const res = await fetch(`${API}/v1/agents/${agent}`, {
|
|
@@ -797,7 +932,7 @@ async function cmdInvoke(name, prompt, stream) {
|
|
|
797
932
|
/** autonomous context [name] — imprime a memória do trabalho da task:
|
|
798
933
|
* decisions/findings/artifacts gravadas via ctx.work (KV "work:*"). */
|
|
799
934
|
async function cmdContext(name) {
|
|
800
|
-
const agent =
|
|
935
|
+
const agent = await resolveAgent("context", name);
|
|
801
936
|
const res = await fetch(`${API}/v1/agents/${agent}/kv`, { headers: authHeaders() });
|
|
802
937
|
if (!res.ok)
|
|
803
938
|
throw new Error(`control plane ${res.status}: ${await res.text()}`);
|
|
@@ -894,8 +1029,9 @@ async function cmdPs(json) {
|
|
|
894
1029
|
a.cron ? "sim" : "-",
|
|
895
1030
|
String(a.logs),
|
|
896
1031
|
String(a.kv),
|
|
1032
|
+
a.model ? String(a.model) : "-",
|
|
897
1033
|
]);
|
|
898
|
-
console.log(table(["AGENTE", "STATUS", "CRON", "LOGS", "KV"], rows));
|
|
1034
|
+
console.log(table(["AGENTE", "STATUS", "CRON", "LOGS", "KV", "MODEL"], rows));
|
|
899
1035
|
}
|
|
900
1036
|
async function cmdKv(op, name, key, value) {
|
|
901
1037
|
const agent = name ?? (await loadTaskManifest(process.cwd())).name;
|
|
@@ -945,12 +1081,22 @@ async function cmdLogin(args) {
|
|
|
945
1081
|
.find(() => true);
|
|
946
1082
|
await loginCmd(provider, apiKey);
|
|
947
1083
|
}
|
|
948
|
-
async function cmdLogout() {
|
|
949
|
-
await logoutCmd();
|
|
1084
|
+
async function cmdLogout(providerId) {
|
|
1085
|
+
await logoutCmd(providerId);
|
|
950
1086
|
}
|
|
951
1087
|
async function main() {
|
|
952
1088
|
const args = process.argv.slice(2);
|
|
953
|
-
if (args.length === 0
|
|
1089
|
+
if (args.length === 0) {
|
|
1090
|
+
// 0.17.0 — `auton` bare: abre sessão de trabalho (estilo opencode):
|
|
1091
|
+
// cwd é agente → sessão nele; senão picker. Pipe: mosta ajuda.
|
|
1092
|
+
if (isTTY) {
|
|
1093
|
+
await cmdChat(undefined);
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
console.log(USAGE);
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
if (args[0] === "--help" || args[0] === "-h") {
|
|
954
1100
|
console.log(USAGE);
|
|
955
1101
|
return;
|
|
956
1102
|
}
|
|
@@ -958,15 +1104,57 @@ async function main() {
|
|
|
958
1104
|
if (isTTY)
|
|
959
1105
|
console.log(logo());
|
|
960
1106
|
console.log(bold(`auton v${VERSION}`));
|
|
1107
|
+
const d = getDefaultModel();
|
|
1108
|
+
const active = getActiveProvider();
|
|
1109
|
+
if (d)
|
|
1110
|
+
console.log(dim(` modelo default: ${d}`));
|
|
1111
|
+
if (active)
|
|
1112
|
+
console.log(dim(` provider: ${active.id} (${active.quando.slice(0, 10)})`));
|
|
961
1113
|
return;
|
|
962
1114
|
}
|
|
1115
|
+
// 0.17.0 — `auton <nome-de-agente-deployado>` abre sessão (comandos têm prioridade).
|
|
1116
|
+
const KNOWN = new Set([
|
|
1117
|
+
"login", "logout", "model", "agent", "logs", "status", "restart", "run",
|
|
1118
|
+
"verify", "inspect", "continue", "invoke", "undeploy", "approve", "reject",
|
|
1119
|
+
"ps", "context", "env", "init", "kv", "chat", "answer",
|
|
1120
|
+
]);
|
|
1121
|
+
if (!KNOWN.has(args[0]) && isTTY) {
|
|
1122
|
+
const deployed = await listAgentNames();
|
|
1123
|
+
if (deployed.includes(args[0])) {
|
|
1124
|
+
await cmdChat(args[0]);
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
963
1128
|
switch (args[0]) {
|
|
964
1129
|
case "login":
|
|
965
1130
|
await cmdLogin(args.slice(1));
|
|
966
1131
|
break;
|
|
967
1132
|
case "logout":
|
|
968
|
-
await cmdLogout();
|
|
1133
|
+
await cmdLogout(args[1]);
|
|
969
1134
|
break;
|
|
1135
|
+
case "model": {
|
|
1136
|
+
// auton model [ls|set <spec>|test] — sem sub: seletor TTY
|
|
1137
|
+
const sub = args[1];
|
|
1138
|
+
const json = args.includes("--json");
|
|
1139
|
+
if (sub === "ls") {
|
|
1140
|
+
await modelLs(json);
|
|
1141
|
+
}
|
|
1142
|
+
else if (sub === "set") {
|
|
1143
|
+
if (!args[2])
|
|
1144
|
+
throw new ExitError(EXIT.USAGE, "uso: auton model set <provider:modelo>");
|
|
1145
|
+
await modelSet(args[2]);
|
|
1146
|
+
}
|
|
1147
|
+
else if (sub === "test") {
|
|
1148
|
+
await modelTest();
|
|
1149
|
+
}
|
|
1150
|
+
else if (sub === undefined || sub === "select") {
|
|
1151
|
+
await cmdModel();
|
|
1152
|
+
}
|
|
1153
|
+
else {
|
|
1154
|
+
throw new ExitError(EXIT.USAGE, `uso: auton model [ls|set <spec>|test] — subcomando desconhecido: ${sub}`);
|
|
1155
|
+
}
|
|
1156
|
+
break;
|
|
1157
|
+
}
|
|
970
1158
|
case "agent":
|
|
971
1159
|
if (args[1]) {
|
|
972
1160
|
const dir = resolve(args[1]);
|
|
@@ -979,13 +1167,15 @@ async function main() {
|
|
|
979
1167
|
}
|
|
980
1168
|
break;
|
|
981
1169
|
case "logs":
|
|
982
|
-
// args[1..]: [name] [--tail N] [--since RFC3339]
|
|
1170
|
+
// args[1..]: [name] [--tail N] [--since RFC3339] [--follow] [--turn N]
|
|
983
1171
|
const rest = args.slice(1);
|
|
984
1172
|
const tailIdx = rest.indexOf("--tail");
|
|
985
1173
|
const sinceIdx = rest.indexOf("--since");
|
|
986
1174
|
let name;
|
|
987
1175
|
let tail;
|
|
988
1176
|
let since;
|
|
1177
|
+
let follow = false;
|
|
1178
|
+
let turn;
|
|
989
1179
|
for (let i = 0; i < rest.length; i++) {
|
|
990
1180
|
const arg = rest[i];
|
|
991
1181
|
if (arg === "--tail" && i + 1 < rest.length) {
|
|
@@ -996,11 +1186,18 @@ async function main() {
|
|
|
996
1186
|
since = rest[i + 1];
|
|
997
1187
|
i++;
|
|
998
1188
|
}
|
|
1189
|
+
else if (arg === "--turn" && i + 1 < rest.length) {
|
|
1190
|
+
turn = Number(rest[i + 1]);
|
|
1191
|
+
i++;
|
|
1192
|
+
}
|
|
1193
|
+
else if (arg === "--follow") {
|
|
1194
|
+
follow = true;
|
|
1195
|
+
}
|
|
999
1196
|
else if (!arg.startsWith("-") && !name) {
|
|
1000
1197
|
name = arg;
|
|
1001
1198
|
}
|
|
1002
1199
|
}
|
|
1003
|
-
await cmdLogs(name, tail, since);
|
|
1200
|
+
await cmdLogs(name, tail, since, follow, turn);
|
|
1004
1201
|
break;
|
|
1005
1202
|
case "status":
|
|
1006
1203
|
await cmdStatus(args[1]);
|
|
@@ -1067,6 +1264,17 @@ async function main() {
|
|
|
1067
1264
|
await cmdApproval(name, approved, reason);
|
|
1068
1265
|
break;
|
|
1069
1266
|
}
|
|
1267
|
+
case "chat":
|
|
1268
|
+
await cmdChat(args[1]);
|
|
1269
|
+
break;
|
|
1270
|
+
case "answer": {
|
|
1271
|
+
const rest = args.slice(1);
|
|
1272
|
+
const dash = rest.indexOf("--");
|
|
1273
|
+
const name = dash === -1 ? rest[0] : dash === 0 ? undefined : rest[0];
|
|
1274
|
+
const answer = dash !== -1 ? rest.slice(dash + 1).join(" ") : undefined;
|
|
1275
|
+
await cmdAnswer(name, answer);
|
|
1276
|
+
break;
|
|
1277
|
+
}
|
|
1070
1278
|
case "ps":
|
|
1071
1279
|
await cmdPs(args[1] === "--json");
|
|
1072
1280
|
break;
|