@todoforai/cli 0.1.20 → 0.1.22
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/todoai.js +226 -52
- package/package.json +1 -1
package/dist/todoai.js
CHANGED
|
@@ -42825,6 +42825,9 @@ class ApiClient {
|
|
|
42825
42825
|
deleteTodo(todoId) {
|
|
42826
42826
|
return this.request("DELETE", `/api/v1/todos/${todoId}`);
|
|
42827
42827
|
}
|
|
42828
|
+
listModels() {
|
|
42829
|
+
return this.request("GET", "/api/v1/models");
|
|
42830
|
+
}
|
|
42828
42831
|
listAgentSettings(filters) {
|
|
42829
42832
|
const params = new URLSearchParams;
|
|
42830
42833
|
if (filters?.workspacePath)
|
|
@@ -42923,7 +42926,7 @@ function normalizeApiUrl(url) {
|
|
|
42923
42926
|
return `https://${url}`;
|
|
42924
42927
|
return url;
|
|
42925
42928
|
}
|
|
42926
|
-
var SUBCOMMANDS = new Set(["login", "logout"]);
|
|
42929
|
+
var SUBCOMMANDS = new Set(["login", "logout", "update"]);
|
|
42927
42930
|
function credentialsPath() {
|
|
42928
42931
|
const sys = os2.platform();
|
|
42929
42932
|
if (sys === "win32") {
|
|
@@ -44093,26 +44096,34 @@ Usage:
|
|
|
44093
44096
|
todoforai-cli -c ["prompt"] # Resume last todo (optional prompt sent on attach)
|
|
44094
44097
|
todoforai-cli --resume <todo-id> ["prompt"] # Resume specific todo (optional prompt sent on attach)
|
|
44095
44098
|
todoforai-cli --inspect <todo-id>[@<slice>] # Read chat log. <slice> = -3:, :1, 5:10, 7 (Python-style)
|
|
44096
|
-
todoforai-cli
|
|
44099
|
+
todoforai-cli start <id> # Start a TODO from the registry (todoregistry.com)
|
|
44097
44100
|
todoforai-cli --list-agents # List available agents and exit
|
|
44101
|
+
todoforai-cli --list-models [filter] # List models usable with --model and exit
|
|
44098
44102
|
todoforai-cli agent update <agent> model=<model> # Update agent settings (see 'agent --help')
|
|
44099
44103
|
todoforai-cli list [-n 30] [--cursor N] [--all] [--status S] # List todos (paginated); see 'list --help'
|
|
44100
44104
|
todoforai-cli status <todo-id> <STATUS> # Update a todo's status (run 'status --help' for the full list)
|
|
44101
44105
|
todoforai-cli delete <todo-id> # Permanently delete a todo
|
|
44102
44106
|
todoforai-cli addmessage <todo-id> "text" # Add a message to an existing todo
|
|
44103
44107
|
todoforai-cli recommend --template <id> # Add a template as a NEXT-column card (see 'todoregistry-cli create')
|
|
44108
|
+
todoforai-cli claim mint --seed <projectId> [--emails a@x,b@y] [--ttl <sec>] # Mint /claim/<token> ownership links for a project you own
|
|
44109
|
+
todoforai-cli steering get # Show recommendation steering (direction + boosted/muted categories)
|
|
44110
|
+
todoforai-cli steering direction "<text>" # Set the direction the generator should follow
|
|
44111
|
+
todoforai-cli steering boost|mute <cat> # Favour / avoid a category
|
|
44112
|
+
todoforai-cli next # Generate steered NEXT-column recommendations
|
|
44104
44113
|
|
|
44105
44114
|
Options:
|
|
44106
44115
|
--path <dir> Workspace path (default: cwd)
|
|
44107
44116
|
--project <id> Project ID
|
|
44108
44117
|
--agent, -a <name> Agent name (partial match)
|
|
44118
|
+
--model <model> Override the agent's model for this todo
|
|
44119
|
+
(e.g. anthropic:anthropic/claude-opus-5, openai:openai/gpt-5.6-sol)
|
|
44109
44120
|
--list-agents List available agents (name, id, workspace paths) and exit
|
|
44121
|
+
--list-models List models usable with --model (optional substring filter) and exit
|
|
44110
44122
|
--api-url <url> API URL
|
|
44111
44123
|
--api-key <key> API key
|
|
44112
44124
|
--user-id <id> Admin HTTP impersonation; requires --no-watch
|
|
44113
44125
|
--inspect, -i <todo-id>[@<slice>] Print chat log (read-only)
|
|
44114
|
-
--template, -t <id> Start from a registry template
|
|
44115
|
-
--input <key=value> Template input (repeatable)
|
|
44126
|
+
--template, -t <id> Start from a registry template (alias: start <id>)
|
|
44116
44127
|
--resume, -r [todo-id] Resume existing todo
|
|
44117
44128
|
--continue, -c Continue most recent todo
|
|
44118
44129
|
--non-interactive, -n Run to completion and exit without interactive prompt
|
|
@@ -44163,16 +44174,19 @@ function parseCliArgs() {
|
|
|
44163
44174
|
agent: { type: "string", short: "a" },
|
|
44164
44175
|
model: { type: "string" },
|
|
44165
44176
|
"list-agents": { type: "boolean", default: false },
|
|
44177
|
+
"list-models": { type: "boolean", default: false },
|
|
44166
44178
|
"api-url": { type: "string" },
|
|
44167
44179
|
"api-key": { type: "string" },
|
|
44168
44180
|
"user-id": { type: "string" },
|
|
44169
44181
|
inspect: { type: "string", short: "i" },
|
|
44170
44182
|
template: { type: "string", short: "t" },
|
|
44171
|
-
input: { type: "string", multiple: true },
|
|
44172
44183
|
note: { type: "string" },
|
|
44173
44184
|
priority: { type: "string" },
|
|
44174
44185
|
title: { type: "string" },
|
|
44175
44186
|
"business-context": { type: "string" },
|
|
44187
|
+
seed: { type: "string" },
|
|
44188
|
+
emails: { type: "string" },
|
|
44189
|
+
ttl: { type: "string" },
|
|
44176
44190
|
resume: { type: "string", short: "r" },
|
|
44177
44191
|
continue: { type: "boolean", short: "c", default: false },
|
|
44178
44192
|
"non-interactive": { type: "boolean", short: "n", default: false },
|
|
@@ -44201,9 +44215,6 @@ function parseCliArgs() {
|
|
|
44201
44215
|
return { values, positionals };
|
|
44202
44216
|
}
|
|
44203
44217
|
|
|
44204
|
-
// src/input.ts
|
|
44205
|
-
import { createInterface } from "readline";
|
|
44206
|
-
|
|
44207
44218
|
// src/colors.ts
|
|
44208
44219
|
var on = !process.env.NO_COLOR && !!process.stdout.isTTY;
|
|
44209
44220
|
var c = (seq) => on ? seq : "";
|
|
@@ -44224,15 +44235,6 @@ var BG_RED_HL = c("\x1B[48;2;100;35;35m");
|
|
|
44224
44235
|
var BG_GREEN_HL = c("\x1B[48;2;35;85;35m");
|
|
44225
44236
|
|
|
44226
44237
|
// src/input.ts
|
|
44227
|
-
function readLine(prompt) {
|
|
44228
|
-
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
44229
|
-
return new Promise((res) => {
|
|
44230
|
-
rl.question(prompt, (ans) => {
|
|
44231
|
-
rl.close();
|
|
44232
|
-
res(ans.trim());
|
|
44233
|
-
});
|
|
44234
|
-
});
|
|
44235
|
-
}
|
|
44236
44238
|
function readMultiline(prompt, history) {
|
|
44237
44239
|
let cancelFn = () => {};
|
|
44238
44240
|
const promise = new Promise((resolve, reject) => {
|
|
@@ -45304,7 +45306,7 @@ ${label}${ts}
|
|
|
45304
45306
|
}
|
|
45305
45307
|
|
|
45306
45308
|
// src/select.ts
|
|
45307
|
-
import { createInterface
|
|
45309
|
+
import { createInterface } from "readline";
|
|
45308
45310
|
function getDisplayName(item) {
|
|
45309
45311
|
if (item?.project?.name)
|
|
45310
45312
|
return item.project.name;
|
|
@@ -45338,7 +45340,7 @@ function resolveAgentMatch(agents, query) {
|
|
|
45338
45340
|
return {};
|
|
45339
45341
|
}
|
|
45340
45342
|
function terminalLine(prompt) {
|
|
45341
|
-
const rl =
|
|
45343
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
45342
45344
|
return new Promise((resolve3) => {
|
|
45343
45345
|
rl.question(prompt, (answer) => {
|
|
45344
45346
|
rl.close();
|
|
@@ -46065,6 +46067,20 @@ async function listAgentsCommand(api, opts) {
|
|
|
46065
46067
|
}
|
|
46066
46068
|
}
|
|
46067
46069
|
|
|
46070
|
+
// src/list-models.ts
|
|
46071
|
+
async function listModelsCommand(api, opts) {
|
|
46072
|
+
const res = await api.listModels();
|
|
46073
|
+
const q = opts.filter?.toLowerCase();
|
|
46074
|
+
const ids = (res?.data || []).map((m) => String(m.id).includes("/") ? `${String(m.id).split("/")[0]}:${m.id}` : String(m.id)).filter((id) => !q || id.toLowerCase().includes(q));
|
|
46075
|
+
if (opts.json) {
|
|
46076
|
+
console.log(JSON.stringify(ids, null, 2));
|
|
46077
|
+
return;
|
|
46078
|
+
}
|
|
46079
|
+
for (const id of ids)
|
|
46080
|
+
process.stderr.write(`${BRAND}${id}${RESET}
|
|
46081
|
+
`);
|
|
46082
|
+
}
|
|
46083
|
+
|
|
46068
46084
|
// src/agent-command.ts
|
|
46069
46085
|
function printAgentHelp() {
|
|
46070
46086
|
process.stderr.write(`
|
|
@@ -46374,6 +46390,92 @@ async function listTodosCommand(api, defaultProjectId, argv) {
|
|
|
46374
46390
|
`);
|
|
46375
46391
|
}
|
|
46376
46392
|
|
|
46393
|
+
// src/steering-command.ts
|
|
46394
|
+
var RED2 = "\x1B[31m";
|
|
46395
|
+
var GREEN2 = "\x1B[32m";
|
|
46396
|
+
var DIM2 = "\x1B[2m";
|
|
46397
|
+
var RESET2 = "\x1B[0m";
|
|
46398
|
+
async function rest(ctx, method, path4, body) {
|
|
46399
|
+
const res = await fetch(`${ctx.apiUrl}/api/v1${path4}`, {
|
|
46400
|
+
method,
|
|
46401
|
+
headers: { "content-type": "application/json", "x-api-key": ctx.apiKey },
|
|
46402
|
+
...body ? { body: JSON.stringify(body) } : {},
|
|
46403
|
+
signal: AbortSignal.timeout(30000)
|
|
46404
|
+
});
|
|
46405
|
+
const text = await res.text();
|
|
46406
|
+
if (!res.ok)
|
|
46407
|
+
throw new Error(`${method} ${path4} failed: ${res.status} ${text}`);
|
|
46408
|
+
return text ? JSON.parse(text) : null;
|
|
46409
|
+
}
|
|
46410
|
+
function printSteering(s) {
|
|
46411
|
+
process.stderr.write(`${GREEN2}Direction:${RESET2} ${s.direction || DIM2 + "(none)" + RESET2}
|
|
46412
|
+
`);
|
|
46413
|
+
process.stderr.write(`${GREEN2}Boosted:${RESET2} ${s.boostedCategoryIds?.join(", ") || DIM2 + "(none)" + RESET2}
|
|
46414
|
+
`);
|
|
46415
|
+
process.stderr.write(`${GREEN2}Muted:${RESET2} ${s.mutedCategoryIds?.join(", ") || DIM2 + "(none)" + RESET2}
|
|
46416
|
+
`);
|
|
46417
|
+
}
|
|
46418
|
+
var USAGE = `${RED2}Usage:
|
|
46419
|
+
todoforai-cli steering get [--project <id>]
|
|
46420
|
+
todoforai-cli steering direction "<text>" [--project <id>] (empty text clears it)
|
|
46421
|
+
todoforai-cli steering boost <categoryId> [--project <id>]
|
|
46422
|
+
todoforai-cli steering mute <categoryId> [--project <id>]
|
|
46423
|
+
todoforai-cli steering clear [--project <id>] (clears all steering)${RESET2}`;
|
|
46424
|
+
async function steeringCommand(ctx, argv) {
|
|
46425
|
+
const sub = argv[0];
|
|
46426
|
+
const path4 = `/projects/${ctx.projectId}/recommendation-steering`;
|
|
46427
|
+
if (!sub || sub === "get") {
|
|
46428
|
+
const s = await rest(ctx, "GET", path4);
|
|
46429
|
+
if (ctx.json)
|
|
46430
|
+
console.log(JSON.stringify(s, null, 2));
|
|
46431
|
+
else
|
|
46432
|
+
printSteering(s);
|
|
46433
|
+
return;
|
|
46434
|
+
}
|
|
46435
|
+
if (sub === "direction") {
|
|
46436
|
+
const text = argv.slice(1).join(" ").trim();
|
|
46437
|
+
const s = await rest(ctx, "PATCH", path4, { projectId: ctx.projectId, direction: text || null });
|
|
46438
|
+
if (ctx.json)
|
|
46439
|
+
console.log(JSON.stringify(s, null, 2));
|
|
46440
|
+
else
|
|
46441
|
+
process.stderr.write(`${GREEN2}\u2705 ${text ? `Direction set: ${text}` : "Direction cleared"}${RESET2}
|
|
46442
|
+
`);
|
|
46443
|
+
return;
|
|
46444
|
+
}
|
|
46445
|
+
if (sub === "boost" || sub === "mute") {
|
|
46446
|
+
const categoryId = argv[1];
|
|
46447
|
+
if (!categoryId) {
|
|
46448
|
+
process.stderr.write(USAGE + `
|
|
46449
|
+
`);
|
|
46450
|
+
process.exit(2);
|
|
46451
|
+
}
|
|
46452
|
+
const current = await rest(ctx, "GET", path4);
|
|
46453
|
+
const key = sub === "boost" ? "boostedCategoryIds" : "mutedCategoryIds";
|
|
46454
|
+
const other = sub === "boost" ? "mutedCategoryIds" : "boostedCategoryIds";
|
|
46455
|
+
const next = Array.from(new Set([...current[key] ?? [], categoryId]));
|
|
46456
|
+
const nextOther = (current[other] ?? []).filter((c2) => c2 !== categoryId);
|
|
46457
|
+
const s = await rest(ctx, "PATCH", path4, { projectId: ctx.projectId, [key]: next, [other]: nextOther });
|
|
46458
|
+
if (ctx.json)
|
|
46459
|
+
console.log(JSON.stringify(s, null, 2));
|
|
46460
|
+
else
|
|
46461
|
+
process.stderr.write(`${GREEN2}\u2705 ${sub === "boost" ? "Boosted" : "Muted"} ${categoryId}${RESET2}
|
|
46462
|
+
`);
|
|
46463
|
+
return;
|
|
46464
|
+
}
|
|
46465
|
+
if (sub === "clear") {
|
|
46466
|
+
const s = await rest(ctx, "PATCH", path4, { projectId: ctx.projectId, direction: null, boostedCategoryIds: [], mutedCategoryIds: [] });
|
|
46467
|
+
if (ctx.json)
|
|
46468
|
+
console.log(JSON.stringify(s, null, 2));
|
|
46469
|
+
else
|
|
46470
|
+
process.stderr.write(`${GREEN2}\u2705 Steering cleared${RESET2}
|
|
46471
|
+
`);
|
|
46472
|
+
return;
|
|
46473
|
+
}
|
|
46474
|
+
process.stderr.write(USAGE + `
|
|
46475
|
+
`);
|
|
46476
|
+
process.exit(2);
|
|
46477
|
+
}
|
|
46478
|
+
|
|
46377
46479
|
// src/index.ts
|
|
46378
46480
|
try {
|
|
46379
46481
|
const pkgPath = path4.resolve(fileURLToPath(import.meta.url), "../../package.json");
|
|
@@ -46464,6 +46566,15 @@ Cancelled by user (Ctrl+C)
|
|
|
46464
46566
|
process.exit(130);
|
|
46465
46567
|
});
|
|
46466
46568
|
const { values: args, positionals } = parseCliArgs();
|
|
46569
|
+
if (positionals[0] === "start") {
|
|
46570
|
+
if (!positionals[1] && !args.template) {
|
|
46571
|
+
process.stderr.write(`${RED}Usage: todoforai-cli start <todo-id>${RESET}
|
|
46572
|
+
`);
|
|
46573
|
+
process.exit(2);
|
|
46574
|
+
}
|
|
46575
|
+
if (!args.template)
|
|
46576
|
+
args.template = positionals[1];
|
|
46577
|
+
}
|
|
46467
46578
|
if (args.version) {
|
|
46468
46579
|
console.log(VERSION);
|
|
46469
46580
|
process.exit(0);
|
|
@@ -46565,7 +46676,8 @@ Cancelled by user (Ctrl+C)
|
|
|
46565
46676
|
await deviceLogin();
|
|
46566
46677
|
return;
|
|
46567
46678
|
}
|
|
46568
|
-
|
|
46679
|
+
const notDst = (t) => t.startsWith("dst_") ? "" : t;
|
|
46680
|
+
let apiKey = args["api-key"] || notDst(readCredential(apiUrl)) || notDst(getEnv("API_TOKEN")) || "";
|
|
46569
46681
|
if (!apiKey) {
|
|
46570
46682
|
apiKey = await deviceLogin();
|
|
46571
46683
|
}
|
|
@@ -46609,8 +46721,8 @@ Cancelled by user (Ctrl+C)
|
|
|
46609
46721
|
return;
|
|
46610
46722
|
}
|
|
46611
46723
|
if (positionals[0] === "addmessage") {
|
|
46612
|
-
const [, todoId, ...
|
|
46613
|
-
const content2 =
|
|
46724
|
+
const [, todoId, ...rest2] = positionals;
|
|
46725
|
+
const content2 = rest2.join(" ") || await readStdin();
|
|
46614
46726
|
if (!todoId || !content2) {
|
|
46615
46727
|
process.stderr.write(`${RED}Usage: todoforai-cli addmessage <todo-id> "content"${RESET}
|
|
46616
46728
|
`);
|
|
@@ -46652,7 +46764,7 @@ Cancelled by user (Ctrl+C)
|
|
|
46652
46764
|
}
|
|
46653
46765
|
const rec = await api.recommend({
|
|
46654
46766
|
projectId: projectId2,
|
|
46655
|
-
templateId,
|
|
46767
|
+
specId: templateId,
|
|
46656
46768
|
...args.title ? { title: args.title } : {},
|
|
46657
46769
|
...args.note ? { note: args.note } : {},
|
|
46658
46770
|
...priority ? { priority } : {},
|
|
@@ -46665,10 +46777,92 @@ Cancelled by user (Ctrl+C)
|
|
|
46665
46777
|
`);
|
|
46666
46778
|
return;
|
|
46667
46779
|
}
|
|
46780
|
+
if (positionals[0] === "claim" && positionals[1] === "mint") {
|
|
46781
|
+
let seedProjectId = args.seed || args.project || cfgScope.data.default_project_id;
|
|
46782
|
+
if (!seedProjectId) {
|
|
46783
|
+
const projects2 = await api.listProjects();
|
|
46784
|
+
seedProjectId = projects2.find((p) => p.project?.isDefault)?.project?.id || projects2[0]?.project?.id;
|
|
46785
|
+
}
|
|
46786
|
+
if (!seedProjectId) {
|
|
46787
|
+
process.stderr.write(`${RED}Usage: todoforai-cli claim mint --seed <projectId> [--emails a@x,b@y] [--ttl <sec>]${RESET}
|
|
46788
|
+
`);
|
|
46789
|
+
process.exit(2);
|
|
46790
|
+
}
|
|
46791
|
+
const emails = args.emails?.split(",").map((e) => e.trim()).filter(Boolean);
|
|
46792
|
+
let ttlSec;
|
|
46793
|
+
if (args.ttl !== undefined) {
|
|
46794
|
+
ttlSec = Number(args.ttl);
|
|
46795
|
+
if (!Number.isFinite(ttlSec)) {
|
|
46796
|
+
process.stderr.write(`${RED}--ttl must be a number (seconds)${RESET}
|
|
46797
|
+
`);
|
|
46798
|
+
process.exit(2);
|
|
46799
|
+
}
|
|
46800
|
+
}
|
|
46801
|
+
const res = await fetch(`${apiUrl}/api/v1/claims/mint`, {
|
|
46802
|
+
method: "POST",
|
|
46803
|
+
headers: { "content-type": "application/json", "x-api-key": apiKey },
|
|
46804
|
+
body: JSON.stringify({ seedProjectId, ...emails?.length ? { emails } : {}, ...ttlSec !== undefined ? { ttlSec } : {} }),
|
|
46805
|
+
signal: AbortSignal.timeout(30000)
|
|
46806
|
+
});
|
|
46807
|
+
const text = await res.text();
|
|
46808
|
+
if (!res.ok) {
|
|
46809
|
+
process.stderr.write(`${RED}Mint failed: ${res.status} ${text}${RESET}
|
|
46810
|
+
`);
|
|
46811
|
+
process.exit(1);
|
|
46812
|
+
}
|
|
46813
|
+
const out = JSON.parse(text);
|
|
46814
|
+
if (args.json)
|
|
46815
|
+
console.log(JSON.stringify(out, null, 2));
|
|
46816
|
+
else
|
|
46817
|
+
for (const l of out.links)
|
|
46818
|
+
process.stdout.write(`${l.email ? `${l.email} ` : ""}${CYAN}${l.url}${RESET}
|
|
46819
|
+
`);
|
|
46820
|
+
return;
|
|
46821
|
+
}
|
|
46822
|
+
if (positionals[0] === "steering" || positionals[0] === "next") {
|
|
46823
|
+
let projectId2 = args.project || cfgScope.data.default_project_id;
|
|
46824
|
+
if (!projectId2) {
|
|
46825
|
+
const projects2 = await api.listProjects();
|
|
46826
|
+
projectId2 = projects2.find((p) => p.project?.isDefault)?.project?.id || projects2[0]?.project?.id;
|
|
46827
|
+
}
|
|
46828
|
+
if (!projectId2) {
|
|
46829
|
+
process.stderr.write(`${RED}No project found \u2014 pass --project <id>${RESET}
|
|
46830
|
+
`);
|
|
46831
|
+
process.exit(2);
|
|
46832
|
+
}
|
|
46833
|
+
const sctx = { apiUrl, apiKey, projectId: projectId2, json: !!args.json };
|
|
46834
|
+
if (positionals[0] === "next") {
|
|
46835
|
+
const res = await fetch(`${apiUrl}/api/v1/projects/${projectId2}/recommendations/generate`, {
|
|
46836
|
+
method: "POST",
|
|
46837
|
+
headers: { "content-type": "application/json", "x-api-key": apiKey },
|
|
46838
|
+
body: JSON.stringify({ projectId: projectId2, ...args["business-context"] ? { businessContextId: args["business-context"] } : {} }),
|
|
46839
|
+
signal: AbortSignal.timeout(30000)
|
|
46840
|
+
});
|
|
46841
|
+
const text = await res.text();
|
|
46842
|
+
if (!res.ok) {
|
|
46843
|
+
process.stderr.write(`${RED}Generate failed: ${res.status} ${text}${RESET}
|
|
46844
|
+
`);
|
|
46845
|
+
process.exit(1);
|
|
46846
|
+
}
|
|
46847
|
+
const out = JSON.parse(text);
|
|
46848
|
+
if (args.json)
|
|
46849
|
+
console.log(JSON.stringify(out, null, 2));
|
|
46850
|
+
else
|
|
46851
|
+
process.stderr.write(`${GREEN}\u2705 Generating recommendations \u2014 analyzer todo ${out.todoId}${RESET}
|
|
46852
|
+
`);
|
|
46853
|
+
return;
|
|
46854
|
+
}
|
|
46855
|
+
await steeringCommand(sctx, positionals.slice(1));
|
|
46856
|
+
return;
|
|
46857
|
+
}
|
|
46668
46858
|
if (args["list-agents"]) {
|
|
46669
46859
|
await listAgentsCommand(api, { json: !!args.json, formatPath: formatPathWithTilde });
|
|
46670
46860
|
return;
|
|
46671
46861
|
}
|
|
46862
|
+
if (args["list-models"]) {
|
|
46863
|
+
await listModelsCommand(api, { json: !!args.json, filter: positionals[0] });
|
|
46864
|
+
return;
|
|
46865
|
+
}
|
|
46672
46866
|
if (positionals[0] === "agent") {
|
|
46673
46867
|
await agentCommand(api, positionals, args, formatPathWithTilde);
|
|
46674
46868
|
return;
|
|
@@ -46722,36 +46916,12 @@ Cancelled by user (Ctrl+C)
|
|
|
46722
46916
|
if (!args["no-bridge"] && !args["no-watch"])
|
|
46723
46917
|
ensureBridgeRunning(apiUrl, apiKey);
|
|
46724
46918
|
const templateId = args.template;
|
|
46725
|
-
const
|
|
46726
|
-
|
|
46727
|
-
const eq = kv.indexOf("=");
|
|
46728
|
-
if (eq > 0)
|
|
46729
|
-
inputValues[kv.slice(0, eq)] = kv.slice(eq + 1);
|
|
46730
|
-
}
|
|
46731
|
-
const template = await api.getRegistryTemplate(templateId);
|
|
46732
|
-
process.stderr.write(`${DIM}Template:${RESET} ${BRAND}${template.todoname}${RESET}
|
|
46733
|
-
`);
|
|
46734
|
-
if (template.description)
|
|
46735
|
-
process.stderr.write(`${DIM}${template.description}${RESET}
|
|
46919
|
+
const spec = await api.getRegistrySpec(templateId);
|
|
46920
|
+
process.stderr.write(`${DIM}Template:${RESET} ${BRAND}${spec.name}${RESET}
|
|
46736
46921
|
`);
|
|
46737
|
-
|
|
46738
|
-
|
|
46739
|
-
for (const inp of templateInputs) {
|
|
46740
|
-
const key = inp.label.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/_+$/, "");
|
|
46741
|
-
if (inputValues[key])
|
|
46742
|
-
continue;
|
|
46743
|
-
const req = inp.required ? ` ${RED}*${RESET}` : "";
|
|
46744
|
-
const hint = inp.placeholder ? ` ${DIM}(${inp.placeholder.split(`
|
|
46745
|
-
`)[0]})${RESET}` : "";
|
|
46746
|
-
const val = await readLine(`${inp.label}${req}${hint}: `);
|
|
46747
|
-
if (val)
|
|
46748
|
-
inputValues[key] = val;
|
|
46749
|
-
}
|
|
46750
|
-
}
|
|
46751
|
-
if (Object.keys(inputValues).length) {
|
|
46752
|
-
process.stderr.write(`${DIM}Inputs:${RESET} ${JSON.stringify(inputValues)}
|
|
46922
|
+
if (spec.description)
|
|
46923
|
+
process.stderr.write(`${DIM}${spec.description}${RESET}
|
|
46753
46924
|
`);
|
|
46754
|
-
}
|
|
46755
46925
|
const projects2 = await api.listProjects();
|
|
46756
46926
|
let projectId2 = args.project;
|
|
46757
46927
|
if (!projectId2) {
|
|
@@ -46762,12 +46932,14 @@ Cancelled by user (Ctrl+C)
|
|
|
46762
46932
|
`);
|
|
46763
46933
|
process.exit(1);
|
|
46764
46934
|
}
|
|
46765
|
-
const todo2 = await api.
|
|
46935
|
+
const todo2 = await api.startFromSpec(projectId2, templateId);
|
|
46766
46936
|
const todoId = todo2.id;
|
|
46767
46937
|
cfgScope.setLastTodoId(todoId);
|
|
46768
46938
|
const frontendUrl2 = getFrontendUrl(apiUrl, projectId2, todoId);
|
|
46769
46939
|
if (args.json) {
|
|
46770
46940
|
console.log(JSON.stringify({ ...todo2, frontend_url: frontendUrl2 }, null, 2));
|
|
46941
|
+
} else if (args["no-watch"]) {
|
|
46942
|
+
console.log(`created ${todoId}`);
|
|
46771
46943
|
} else {
|
|
46772
46944
|
process.stderr.write(`${DIM}TODO:${RESET} ${CYAN}${frontendUrl2}${RESET}
|
|
46773
46945
|
`);
|
|
@@ -46962,6 +47134,8 @@ Resumed: ${CYAN}${getFrontendUrl(apiUrl, projectId2, todoId)}${RESET}
|
|
|
46962
47134
|
const frontendUrl = getFrontendUrl(apiUrl, projectId, actualTodoId);
|
|
46963
47135
|
if (args.json) {
|
|
46964
47136
|
console.log(JSON.stringify({ ...todo, frontend_url: frontendUrl }, null, 2));
|
|
47137
|
+
} else if (!ws) {
|
|
47138
|
+
console.log(`created ${actualTodoId}`);
|
|
46965
47139
|
} else {
|
|
46966
47140
|
process.stderr.write(`${DIM}TODO:${RESET} ${CYAN}${frontendUrl}${RESET}
|
|
46967
47141
|
`);
|