@gaberrb/polypus 0.4.8 → 0.4.9
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 +193 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import
|
|
5
|
+
import pc15 from "picocolors";
|
|
6
6
|
|
|
7
7
|
// src/cli/commands/add-agent.ts
|
|
8
8
|
import pc from "picocolors";
|
|
@@ -113,6 +113,9 @@ var en = {
|
|
|
113
113
|
"cli.opt.verify": "after the agent finishes, run project checks (typecheck/build/test) and iterate until they pass",
|
|
114
114
|
"cli.opt.budget": "stop the run when the estimated session cost reaches this USD amount (OpenRouter pricing)",
|
|
115
115
|
"cli.cmd.usage": "Show token/cost analytics aggregated per day",
|
|
116
|
+
"cli.cmd.sessions": "List saved sessions that can be resumed",
|
|
117
|
+
"cli.opt.continue": "resume the most recent saved session",
|
|
118
|
+
"cli.opt.resume": "resume a specific saved session by id",
|
|
116
119
|
"cli.arg.swarmTask": "high-level task to split across agents",
|
|
117
120
|
"cli.opt.agents": "comma-separated agent names (default: all configured)",
|
|
118
121
|
"cli.opt.maxSubtasks": "maximum number of parallel subtasks",
|
|
@@ -156,6 +159,13 @@ var en = {
|
|
|
156
159
|
"usage.empty": "No usage recorded yet. Run a task to start tracking.",
|
|
157
160
|
"usage.total": "total",
|
|
158
161
|
"usage.runs": "runs",
|
|
162
|
+
// sessions
|
|
163
|
+
"sessions.header": "Saved sessions (most recent first):",
|
|
164
|
+
"sessions.empty": "No saved sessions yet.",
|
|
165
|
+
"sessions.hint": "Resume with `polypus run --continue` or `polypus run --resume <id>`.",
|
|
166
|
+
"sessions.notFound": 'No saved session with id "{id}".',
|
|
167
|
+
"sessions.noneToContinue": "No previous session to continue \u2014 starting fresh.",
|
|
168
|
+
"sessions.resumed": "\u21BA resumed session {id} ({n} messages)",
|
|
159
169
|
// repl
|
|
160
170
|
"repl.welcome": "Polypus interactive session.",
|
|
161
171
|
"repl.welcomeHint": " Type /help for commands, /exit to quit.",
|
|
@@ -182,6 +192,8 @@ var en = {
|
|
|
182
192
|
" /allow <glob> add a path glob to the allow-list",
|
|
183
193
|
" /allow show the current allow-list and mode",
|
|
184
194
|
" /reset clear the conversation history",
|
|
195
|
+
" /sessions list saved sessions you can resume",
|
|
196
|
+
" /resume <id> resume a saved session",
|
|
185
197
|
" /help show this help",
|
|
186
198
|
" /exit quit",
|
|
187
199
|
"Anything else is sent to the agent as a task."
|
|
@@ -362,6 +374,9 @@ var ptBR = {
|
|
|
362
374
|
"cli.opt.verify": "ap\xF3s o agente terminar, roda as checagens do projeto (typecheck/build/test) e itera at\xE9 passar",
|
|
363
375
|
"cli.opt.budget": "interrompe a execu\xE7\xE3o quando o custo estimado da sess\xE3o atingir este valor em USD (pre\xE7os do OpenRouter)",
|
|
364
376
|
"cli.cmd.usage": "Mostra analytics de tokens/custo agregados por dia",
|
|
377
|
+
"cli.cmd.sessions": "Lista as sess\xF5es salvas que podem ser retomadas",
|
|
378
|
+
"cli.opt.continue": "retoma a sess\xE3o salva mais recente",
|
|
379
|
+
"cli.opt.resume": "retoma uma sess\xE3o salva espec\xEDfica pelo id",
|
|
365
380
|
"cli.arg.swarmTask": "tarefa de alto n\xEDvel para dividir entre os agentes",
|
|
366
381
|
"cli.opt.agents": "nomes de agentes separados por v\xEDrgula (padr\xE3o: todos)",
|
|
367
382
|
"cli.opt.maxSubtasks": "n\xFAmero m\xE1ximo de subtarefas paralelas",
|
|
@@ -403,6 +418,13 @@ var ptBR = {
|
|
|
403
418
|
"usage.empty": "Nenhum uso registrado ainda. Rode uma tarefa para come\xE7ar a medir.",
|
|
404
419
|
"usage.total": "total",
|
|
405
420
|
"usage.runs": "execu\xE7\xF5es",
|
|
421
|
+
// sessions
|
|
422
|
+
"sessions.header": "Sess\xF5es salvas (mais recentes primeiro):",
|
|
423
|
+
"sessions.empty": "Nenhuma sess\xE3o salva ainda.",
|
|
424
|
+
"sessions.hint": "Retome com `polypus run --continue` ou `polypus run --resume <id>`.",
|
|
425
|
+
"sessions.notFound": 'Nenhuma sess\xE3o salva com id "{id}".',
|
|
426
|
+
"sessions.noneToContinue": "Nenhuma sess\xE3o anterior para continuar \u2014 come\xE7ando do zero.",
|
|
427
|
+
"sessions.resumed": "\u21BA sess\xE3o {id} retomada ({n} mensagens)",
|
|
406
428
|
"repl.welcome": "Sess\xE3o interativa do Polypus.",
|
|
407
429
|
"repl.welcomeHint": " Digite /help para comandos, /exit para sair.",
|
|
408
430
|
"repl.modeChanged": "modo \u2192 {mode}",
|
|
@@ -428,6 +450,8 @@ var ptBR = {
|
|
|
428
450
|
" /allow <glob> adiciona um glob de caminho \xE0 allow-list",
|
|
429
451
|
" /allow mostra a allow-list e o modo atuais",
|
|
430
452
|
" /reset limpa o hist\xF3rico da conversa",
|
|
453
|
+
" /sessions lista as sess\xF5es salvas que voc\xEA pode retomar",
|
|
454
|
+
" /resume <id> retoma uma sess\xE3o salva",
|
|
431
455
|
" /help mostra esta ajuda",
|
|
432
456
|
" /exit sair",
|
|
433
457
|
"Qualquer outra coisa \xE9 enviada ao agente como tarefa."
|
|
@@ -1086,6 +1110,13 @@ var SECRET_PATTERNS = [
|
|
|
1086
1110
|
{ re: /\bsk-[A-Za-z0-9]{32,}\b/, kind: "OpenAI-style secret key" },
|
|
1087
1111
|
{ re: /\bAIza[0-9A-Za-z_-]{35}\b/, kind: "Google API key" }
|
|
1088
1112
|
];
|
|
1113
|
+
function redactSecrets(text2) {
|
|
1114
|
+
let out = text2;
|
|
1115
|
+
for (const { re } of SECRET_PATTERNS) {
|
|
1116
|
+
out = out.replace(new RegExp(re.source, re.flags.includes("g") ? re.flags : re.flags + "g"), "[redacted]");
|
|
1117
|
+
}
|
|
1118
|
+
return out;
|
|
1119
|
+
}
|
|
1089
1120
|
function scanSecrets(text2) {
|
|
1090
1121
|
const findings = [];
|
|
1091
1122
|
const lines = text2.split("\n");
|
|
@@ -2461,6 +2492,69 @@ function accumulate(bucket, e) {
|
|
|
2461
2492
|
bucket.runs += 1;
|
|
2462
2493
|
}
|
|
2463
2494
|
|
|
2495
|
+
// src/core/agent/session-store.ts
|
|
2496
|
+
import { mkdir as mkdir4, readFile as readFile11, readdir as readdir5, writeFile as writeFile4 } from "fs/promises";
|
|
2497
|
+
import { join as join5 } from "path";
|
|
2498
|
+
function sessionsDir() {
|
|
2499
|
+
return join5(configDir(), "sessions");
|
|
2500
|
+
}
|
|
2501
|
+
function newSessionId() {
|
|
2502
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2503
|
+
const rand = Math.random().toString(36).slice(2, 6);
|
|
2504
|
+
return `${stamp}-${rand}`;
|
|
2505
|
+
}
|
|
2506
|
+
function sessionPath(id) {
|
|
2507
|
+
return join5(sessionsDir(), `${id}.json`);
|
|
2508
|
+
}
|
|
2509
|
+
async function saveSession(record) {
|
|
2510
|
+
await mkdir4(sessionsDir(), { recursive: true });
|
|
2511
|
+
const safe = {
|
|
2512
|
+
...record,
|
|
2513
|
+
messages: record.messages.map((m) => ({ ...m, content: redactSecrets(m.content) }))
|
|
2514
|
+
};
|
|
2515
|
+
await writeFile4(sessionPath(record.id), JSON.stringify(safe, null, 2) + "\n", "utf8");
|
|
2516
|
+
}
|
|
2517
|
+
async function loadSession(id) {
|
|
2518
|
+
try {
|
|
2519
|
+
return JSON.parse(await readFile11(sessionPath(id), "utf8"));
|
|
2520
|
+
} catch {
|
|
2521
|
+
return void 0;
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
async function listSessions() {
|
|
2525
|
+
let files;
|
|
2526
|
+
try {
|
|
2527
|
+
files = (await readdir5(sessionsDir())).filter((f) => f.endsWith(".json"));
|
|
2528
|
+
} catch {
|
|
2529
|
+
return [];
|
|
2530
|
+
}
|
|
2531
|
+
const summaries = [];
|
|
2532
|
+
for (const f of files) {
|
|
2533
|
+
try {
|
|
2534
|
+
const r = JSON.parse(await readFile11(join5(sessionsDir(), f), "utf8"));
|
|
2535
|
+
summaries.push({
|
|
2536
|
+
id: r.id,
|
|
2537
|
+
updatedAt: r.updatedAt,
|
|
2538
|
+
title: r.title,
|
|
2539
|
+
agentName: r.agentName,
|
|
2540
|
+
mode: r.mode,
|
|
2541
|
+
messageCount: r.messages?.length ?? 0
|
|
2542
|
+
});
|
|
2543
|
+
} catch {
|
|
2544
|
+
}
|
|
2545
|
+
}
|
|
2546
|
+
return summaries.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
2547
|
+
}
|
|
2548
|
+
async function latestSession() {
|
|
2549
|
+
const [latest] = await listSessions();
|
|
2550
|
+
return latest ? loadSession(latest.id) : void 0;
|
|
2551
|
+
}
|
|
2552
|
+
function deriveTitle(messages) {
|
|
2553
|
+
const firstUser = messages.find((m) => m.role === "user");
|
|
2554
|
+
const text2 = (firstUser?.content ?? "").replace(/\s+/g, " ").trim();
|
|
2555
|
+
return text2.length > 60 ? text2.slice(0, 60) + "\u2026" : text2 || "(untitled)";
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2464
2558
|
// src/cli/commands/json-output.ts
|
|
2465
2559
|
var OUTPUT_PREVIEW = 500;
|
|
2466
2560
|
function createJsonCollector() {
|
|
@@ -3145,6 +3239,36 @@ async function handleCommand(cmd, arg, ctx) {
|
|
|
3145
3239
|
session.history = [];
|
|
3146
3240
|
console.log(pc6.dim(t("repl.historyCleared")));
|
|
3147
3241
|
return;
|
|
3242
|
+
case "sessions": {
|
|
3243
|
+
const all = await listSessions();
|
|
3244
|
+
if (all.length === 0) {
|
|
3245
|
+
console.log(pc6.yellow(t("sessions.empty")));
|
|
3246
|
+
return;
|
|
3247
|
+
}
|
|
3248
|
+
console.log(pc6.bold(t("sessions.header")));
|
|
3249
|
+
for (const s of all) {
|
|
3250
|
+
console.log(` ${pc6.cyan(s.id)} ${pc6.dim(`[${s.messageCount} msgs]`)} ${s.title}`);
|
|
3251
|
+
}
|
|
3252
|
+
return;
|
|
3253
|
+
}
|
|
3254
|
+
case "resume": {
|
|
3255
|
+
if (!arg) {
|
|
3256
|
+
console.log(pc6.yellow(t("repl.needName", { usage: "/resume <id>" })));
|
|
3257
|
+
return;
|
|
3258
|
+
}
|
|
3259
|
+
const record = await loadSession(arg);
|
|
3260
|
+
if (!record) {
|
|
3261
|
+
console.log(pc6.red(t("sessions.notFound", { id: arg })));
|
|
3262
|
+
return;
|
|
3263
|
+
}
|
|
3264
|
+
session.id = record.id;
|
|
3265
|
+
session.title = record.title;
|
|
3266
|
+
session.agentName = record.agentName;
|
|
3267
|
+
session.mode = record.mode;
|
|
3268
|
+
session.history = record.messages;
|
|
3269
|
+
console.log(pc6.green(t("sessions.resumed", { id: record.id, n: record.messages.length })));
|
|
3270
|
+
return;
|
|
3271
|
+
}
|
|
3148
3272
|
case "swarm": {
|
|
3149
3273
|
if (!arg) {
|
|
3150
3274
|
console.log(pc6.yellow(t("repl.needName", { usage: "/swarm <task>" })));
|
|
@@ -3226,7 +3350,7 @@ import pc7 from "picocolors";
|
|
|
3226
3350
|
// src/core/git/worktree.ts
|
|
3227
3351
|
import { mkdtemp } from "fs/promises";
|
|
3228
3352
|
import { tmpdir } from "os";
|
|
3229
|
-
import { join as
|
|
3353
|
+
import { join as join6 } from "path";
|
|
3230
3354
|
import { simpleGit } from "simple-git";
|
|
3231
3355
|
async function ensureRepo(workspace) {
|
|
3232
3356
|
const git = simpleGit(workspace);
|
|
@@ -3247,7 +3371,7 @@ async function identityArgs(git) {
|
|
|
3247
3371
|
}
|
|
3248
3372
|
async function createWorktree(git, label) {
|
|
3249
3373
|
const branch = `polypus/${label}-${Date.now().toString(36)}`;
|
|
3250
|
-
const path = await mkdtemp(
|
|
3374
|
+
const path = await mkdtemp(join6(tmpdir(), "polypus-wt-"));
|
|
3251
3375
|
await git.raw(["worktree", "add", "-b", branch, path, "HEAD"]);
|
|
3252
3376
|
return { path, branch };
|
|
3253
3377
|
}
|
|
@@ -3678,19 +3802,32 @@ var Spinner = class {
|
|
|
3678
3802
|
var MAX_VERIFY_FIXES = 3;
|
|
3679
3803
|
async function run(task, opts) {
|
|
3680
3804
|
let config = await loadConfig();
|
|
3681
|
-
const agentConfig = resolveAgent(config, opts.agent);
|
|
3682
3805
|
const workspace = process.cwd();
|
|
3806
|
+
let seeded;
|
|
3807
|
+
if (opts.resume) {
|
|
3808
|
+
seeded = await loadSession(opts.resume);
|
|
3809
|
+
if (!seeded) throw new Error(t("sessions.notFound", { id: opts.resume }));
|
|
3810
|
+
} else if (opts.continue) {
|
|
3811
|
+
seeded = await latestSession();
|
|
3812
|
+
if (!seeded && !opts.json) console.log(pc8.dim(t("sessions.noneToContinue")));
|
|
3813
|
+
}
|
|
3814
|
+
const agentConfig = resolveAgent(config, opts.agent ?? seeded?.agentName);
|
|
3683
3815
|
const session = {
|
|
3816
|
+
id: seeded?.id ?? newSessionId(),
|
|
3817
|
+
title: seeded?.title ?? "",
|
|
3684
3818
|
agentName: agentConfig.name,
|
|
3685
|
-
mode: opts.mode ?? config.permissions.mode,
|
|
3819
|
+
mode: opts.mode ?? seeded?.mode ?? config.permissions.mode,
|
|
3686
3820
|
allow: config.permissions.allow,
|
|
3687
3821
|
deny: config.permissions.deny,
|
|
3688
3822
|
allowedCommands: config.permissions.allowedCommands,
|
|
3689
3823
|
maxSteps: opts.maxSteps ? Number(opts.maxSteps) : void 0,
|
|
3690
|
-
history: [],
|
|
3824
|
+
history: seeded?.messages ?? [],
|
|
3691
3825
|
budget: opts.budget ? Number(opts.budget) : void 0,
|
|
3692
3826
|
costUsd: 0
|
|
3693
3827
|
};
|
|
3828
|
+
if (seeded && !opts.json) {
|
|
3829
|
+
console.log(pc8.dim(t("sessions.resumed", { id: seeded.id, n: seeded.messages.length })));
|
|
3830
|
+
}
|
|
3694
3831
|
const runTask = async (taskText) => {
|
|
3695
3832
|
const active = resolveAgent(config, session.agentName);
|
|
3696
3833
|
const resolved2 = createProvider(active);
|
|
@@ -3803,6 +3940,16 @@ async function executeTask(task, resolved, workspace, session, json = false, ver
|
|
|
3803
3940
|
spinner3.stop();
|
|
3804
3941
|
cancel2.dispose();
|
|
3805
3942
|
}
|
|
3943
|
+
if (!session.title) session.title = deriveTitle(session.history);
|
|
3944
|
+
await saveSession({
|
|
3945
|
+
id: session.id,
|
|
3946
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3947
|
+
title: session.title,
|
|
3948
|
+
agentName: session.agentName,
|
|
3949
|
+
mode: session.mode,
|
|
3950
|
+
messages: session.history
|
|
3951
|
+
}).catch(() => {
|
|
3952
|
+
});
|
|
3806
3953
|
const runCost = pricing ? estimateCost(result.usage, pricing) : 0;
|
|
3807
3954
|
session.costUsd += runCost;
|
|
3808
3955
|
await recordUsage({
|
|
@@ -3977,8 +4124,8 @@ async function setup() {
|
|
|
3977
4124
|
import pc9 from "picocolors";
|
|
3978
4125
|
|
|
3979
4126
|
// src/core/scaffold/init.ts
|
|
3980
|
-
import { mkdir as
|
|
3981
|
-
import { dirname as dirname3, join as
|
|
4127
|
+
import { mkdir as mkdir5, writeFile as writeFile5, access } from "fs/promises";
|
|
4128
|
+
import { dirname as dirname3, join as join7 } from "path";
|
|
3982
4129
|
|
|
3983
4130
|
// src/core/scaffold/templates.ts
|
|
3984
4131
|
function polyTemplates(locale) {
|
|
@@ -4221,13 +4368,13 @@ async function scaffoldPoly(workspace, opts) {
|
|
|
4221
4368
|
const skipped = [];
|
|
4222
4369
|
for (const [rel, content] of Object.entries(templates)) {
|
|
4223
4370
|
const display = `.poly/${rel}`;
|
|
4224
|
-
const abs =
|
|
4371
|
+
const abs = join7(workspace, ".poly", ...rel.split("/"));
|
|
4225
4372
|
if (!opts.force && await exists(abs)) {
|
|
4226
4373
|
skipped.push(display);
|
|
4227
4374
|
continue;
|
|
4228
4375
|
}
|
|
4229
|
-
await
|
|
4230
|
-
await
|
|
4376
|
+
await mkdir5(dirname3(abs), { recursive: true });
|
|
4377
|
+
await writeFile5(abs, content, "utf8");
|
|
4231
4378
|
created.push(display);
|
|
4232
4379
|
}
|
|
4233
4380
|
return { created, skipped };
|
|
@@ -4341,11 +4488,30 @@ function fmtTokens2(n) {
|
|
|
4341
4488
|
return n >= 1e3 ? `${(n / 1e3).toFixed(1)}k` : String(n);
|
|
4342
4489
|
}
|
|
4343
4490
|
|
|
4491
|
+
// src/cli/commands/sessions.ts
|
|
4492
|
+
import pc12 from "picocolors";
|
|
4493
|
+
async function sessions() {
|
|
4494
|
+
const all = await listSessions();
|
|
4495
|
+
if (all.length === 0) {
|
|
4496
|
+
console.log(pc12.yellow(t("sessions.empty")));
|
|
4497
|
+
return;
|
|
4498
|
+
}
|
|
4499
|
+
console.log(pc12.bold(t("sessions.header")));
|
|
4500
|
+
for (const s of all) {
|
|
4501
|
+
const when = s.updatedAt.replace("T", " ").slice(0, 16);
|
|
4502
|
+
console.log(
|
|
4503
|
+
` ${pc12.cyan(s.id)} ${pc12.dim(when)} ${pc12.dim(`[${s.agentName} \xB7 ${s.mode} \xB7 ${s.messageCount} msgs]`)}`
|
|
4504
|
+
);
|
|
4505
|
+
console.log(` ${s.title}`);
|
|
4506
|
+
}
|
|
4507
|
+
console.log(pc12.dim("\n" + t("sessions.hint")));
|
|
4508
|
+
}
|
|
4509
|
+
|
|
4344
4510
|
// src/cli/commands/prd.ts
|
|
4345
|
-
import { writeFile as
|
|
4511
|
+
import { writeFile as writeFile6, readFile as readFile12 } from "fs/promises";
|
|
4346
4512
|
import { execFile } from "child_process";
|
|
4347
4513
|
import { promisify as promisify3 } from "util";
|
|
4348
|
-
import
|
|
4514
|
+
import pc13 from "picocolors";
|
|
4349
4515
|
|
|
4350
4516
|
// src/core/agent/prd.ts
|
|
4351
4517
|
var SYSTEM = [
|
|
@@ -4473,15 +4639,15 @@ async function prd(issueRef, opts) {
|
|
|
4473
4639
|
const guide = readProjectGuide(["context.md"]);
|
|
4474
4640
|
const markdown = await withRetry(() => generatePrd(issue, provider, guide));
|
|
4475
4641
|
if (opts.out) {
|
|
4476
|
-
await
|
|
4477
|
-
console.error(
|
|
4642
|
+
await writeFile6(opts.out, markdown + "\n", "utf8");
|
|
4643
|
+
console.error(pc13.green(t("prd.wrote", { path: opts.out })));
|
|
4478
4644
|
} else {
|
|
4479
4645
|
process.stdout.write(markdown + "\n");
|
|
4480
4646
|
}
|
|
4481
4647
|
}
|
|
4482
4648
|
async function loadIssue(issueRef, input) {
|
|
4483
4649
|
if (input) {
|
|
4484
|
-
const raw = input === "-" ? await readStdin() : await
|
|
4650
|
+
const raw = input === "-" ? await readStdin() : await readFile12(input, "utf8");
|
|
4485
4651
|
return normalize2(JSON.parse(stripBom(raw)));
|
|
4486
4652
|
}
|
|
4487
4653
|
const num = numericRef(issueRef);
|
|
@@ -4500,10 +4666,10 @@ function normalize2(raw) {
|
|
|
4500
4666
|
}
|
|
4501
4667
|
|
|
4502
4668
|
// src/cli/commands/review.ts
|
|
4503
|
-
import { writeFile as
|
|
4669
|
+
import { writeFile as writeFile7, readFile as readFile13 } from "fs/promises";
|
|
4504
4670
|
import { execFile as execFile2 } from "child_process";
|
|
4505
4671
|
import { promisify as promisify4 } from "util";
|
|
4506
|
-
import
|
|
4672
|
+
import pc14 from "picocolors";
|
|
4507
4673
|
|
|
4508
4674
|
// src/core/agent/review.ts
|
|
4509
4675
|
var MAX_DIFF_CHARS = Number(process.env.POLYPUS_MAX_DIFF_CHARS) || 6e4;
|
|
@@ -4569,14 +4735,14 @@ async function review(prRef, opts) {
|
|
|
4569
4735
|
const guide = readProjectGuide(["rules.md", "context.md"]);
|
|
4570
4736
|
const markdown = await withRetry(() => reviewDiff(diff, meta, provider, guide));
|
|
4571
4737
|
if (opts.out) {
|
|
4572
|
-
await
|
|
4573
|
-
console.error(
|
|
4738
|
+
await writeFile7(opts.out, markdown + "\n", "utf8");
|
|
4739
|
+
console.error(pc14.green(t("review.wrote", { path: opts.out })));
|
|
4574
4740
|
} else {
|
|
4575
4741
|
process.stdout.write(markdown + "\n");
|
|
4576
4742
|
}
|
|
4577
4743
|
}
|
|
4578
4744
|
async function loadDiff(num, input) {
|
|
4579
|
-
if (input) return input === "-" ? readStdin() :
|
|
4745
|
+
if (input) return input === "-" ? readStdin() : readFile13(input, "utf8");
|
|
4580
4746
|
const { stdout: stdout2 } = await exec4("gh", ["pr", "diff", num]);
|
|
4581
4747
|
return stdout2;
|
|
4582
4748
|
}
|
|
@@ -4588,7 +4754,7 @@ async function loadMeta(num, input) {
|
|
|
4588
4754
|
}
|
|
4589
4755
|
|
|
4590
4756
|
// src/cli/index.ts
|
|
4591
|
-
import { join as
|
|
4757
|
+
import { join as join8 } from "path";
|
|
4592
4758
|
|
|
4593
4759
|
// src/core/config/dotenv.ts
|
|
4594
4760
|
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
@@ -4621,7 +4787,7 @@ async function launchInteractive() {
|
|
|
4621
4787
|
const config = await loadConfig();
|
|
4622
4788
|
if (config.agents.length === 0) {
|
|
4623
4789
|
console.log(banner());
|
|
4624
|
-
console.log(" " +
|
|
4790
|
+
console.log(" " + pc15.yellow(t("welcome.firstRun")) + "\n");
|
|
4625
4791
|
await setup();
|
|
4626
4792
|
}
|
|
4627
4793
|
await run(void 0, {});
|
|
@@ -4648,21 +4814,22 @@ function buildProgram() {
|
|
|
4648
4814
|
program.command("add-agent").argument("<name>", t("cli.arg.addAgentName")).requiredOption("--provider <provider>", t("cli.opt.provider")).requiredOption("--model <model>", t("cli.opt.model")).option("--api-key <key>", t("cli.opt.apiKey")).option("--base-url <url>", t("cli.opt.baseUrl")).option("--tool-mode <mode>", t("cli.opt.toolMode"), "auto").option("--set-default", t("cli.opt.setDefault")).description(t("cli.cmd.addAgent")).action((name, opts) => addAgent(name, opts));
|
|
4649
4815
|
program.command("remove-agent").argument("<name>", t("cli.arg.removeAgentName")).description(t("cli.cmd.removeAgent")).action((name) => removeAgent(name));
|
|
4650
4816
|
program.command("list-agents").alias("agents").description(t("cli.cmd.listAgents")).action(() => listAgents());
|
|
4651
|
-
program.command("run").argument("[task]", t("cli.arg.runTask")).option("--agent <name>", t("cli.opt.agent")).option("--mode <mode>", t("cli.opt.mode")).option("--max-steps <n>", t("cli.opt.maxSteps")).option("--json", t("cli.opt.json")).option("--verify", t("cli.opt.verify")).option("--budget <usd>", t("cli.opt.budget")).description(t("cli.cmd.run")).action((task, opts) => run(task, opts));
|
|
4817
|
+
program.command("run").argument("[task]", t("cli.arg.runTask")).option("--agent <name>", t("cli.opt.agent")).option("--mode <mode>", t("cli.opt.mode")).option("--max-steps <n>", t("cli.opt.maxSteps")).option("--json", t("cli.opt.json")).option("--verify", t("cli.opt.verify")).option("--budget <usd>", t("cli.opt.budget")).option("--continue", t("cli.opt.continue")).option("--resume <id>", t("cli.opt.resume")).description(t("cli.cmd.run")).action((task, opts) => run(task, opts));
|
|
4652
4818
|
program.command("swarm").argument("<task>", t("cli.arg.swarmTask")).option("--agents <names>", t("cli.opt.agents")).option("--max-subtasks <n>", t("cli.opt.maxSubtasks")).description(t("cli.cmd.swarm")).action((task, opts) => swarm(task, opts));
|
|
4653
4819
|
program.command("models").option("--search <text>", t("cli.opt.search")).option("--tools", t("cli.opt.toolsOnly")).option("--free", t("cli.opt.free")).option("--max-price <usd>", t("cli.opt.maxPrice")).option("--sort <order>", t("cli.opt.sort")).option("--limit <n>", t("cli.opt.limit")).description(t("cli.cmd.models")).action((opts) => models(opts));
|
|
4654
4820
|
program.command("usage").description(t("cli.cmd.usage")).action(() => usage());
|
|
4821
|
+
program.command("sessions").description(t("cli.cmd.sessions")).action(() => sessions());
|
|
4655
4822
|
program.command("prd").argument("<issue>", t("cli.arg.prdIssue")).option("--out <file>", t("cli.opt.out")).option("--model <model>", t("cli.opt.model")).option("--input <file>", t("cli.opt.input")).description(t("cli.cmd.prd")).action((issue, opts) => prd(issue, opts));
|
|
4656
4823
|
program.command("review").argument("<pr>", t("cli.arg.reviewPr")).option("--out <file>", t("cli.opt.out")).option("--model <model>", t("cli.opt.model")).option("--input <file>", t("cli.opt.input")).description(t("cli.cmd.review")).action((pr, opts) => review(pr, opts));
|
|
4657
4824
|
return program;
|
|
4658
4825
|
}
|
|
4659
4826
|
async function main() {
|
|
4660
4827
|
try {
|
|
4661
|
-
loadDotenv([
|
|
4828
|
+
loadDotenv([join8(configDir(), ".env"), join8(process.cwd(), ".env")]);
|
|
4662
4829
|
await resolveLocale();
|
|
4663
4830
|
await buildProgram().parseAsync(process.argv);
|
|
4664
4831
|
} catch (err) {
|
|
4665
|
-
console.error(
|
|
4832
|
+
console.error(pc15.red(`\u2717 ${err.message}`));
|
|
4666
4833
|
process.exitCode = 1;
|
|
4667
4834
|
}
|
|
4668
4835
|
}
|