@todoforai/cli 0.1.4 → 0.1.6
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 +3 -6
- package/dist/todoai.js +148 -57
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,13 +17,11 @@ todoai # prompts device login if no key found
|
|
|
17
17
|
todoai login # explicit login
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
API URL resolution: `--api-url` flag → `TODOFORAI_API_URL` env → `https://api.todofor.ai`.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
todoai --set-default-api-url http://localhost:4000 # or https://api.todofor.ai
|
|
24
|
-
```
|
|
22
|
+
Auth resolution: `--api-key` flag → `TODOFORAI_API_KEY` env → shared credentials (`~/.todoforai/credentials.json`) → device login.
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
Project, agent, and last-todo state are stored **per API URL** under `per_api_url[<url>]` in the config — switching between e.g. `https://api.todofor.ai` and `http://localhost:4000` keeps each environment's defaults isolated. Legacy top-level fields are auto-migrated on first run.
|
|
27
25
|
|
|
28
26
|
## Edge daemon
|
|
29
27
|
|
|
@@ -89,7 +87,6 @@ todoai --resume <todo-id> # resume specific todo
|
|
|
89
87
|
--safe Validate API key upfront
|
|
90
88
|
--debug, -d Debug output
|
|
91
89
|
--show-config Show config
|
|
92
|
-
--set-default-api-url Set default API URL
|
|
93
90
|
--reset-config Reset config file
|
|
94
91
|
--help, -h Show this help
|
|
95
92
|
```
|
package/dist/todoai.js
CHANGED
|
@@ -12960,7 +12960,7 @@ var require_http = __commonJS((exports, module) => {
|
|
|
12960
12960
|
return joined;
|
|
12961
12961
|
}
|
|
12962
12962
|
function http(hljs) {
|
|
12963
|
-
const
|
|
12963
|
+
const VERSION2 = "HTTP/(2|1\\.[01])";
|
|
12964
12964
|
const HEADER_NAME = /[A-Za-z][A-Za-z0-9-]*/;
|
|
12965
12965
|
const HEADER = {
|
|
12966
12966
|
className: "attribute",
|
|
@@ -12992,12 +12992,12 @@ var require_http = __commonJS((exports, module) => {
|
|
|
12992
12992
|
illegal: /\S/,
|
|
12993
12993
|
contains: [
|
|
12994
12994
|
{
|
|
12995
|
-
begin: "^(?=" +
|
|
12995
|
+
begin: "^(?=" + VERSION2 + " \\d{3})",
|
|
12996
12996
|
end: /$/,
|
|
12997
12997
|
contains: [
|
|
12998
12998
|
{
|
|
12999
12999
|
className: "meta",
|
|
13000
|
-
begin:
|
|
13000
|
+
begin: VERSION2
|
|
13001
13001
|
},
|
|
13002
13002
|
{
|
|
13003
13003
|
className: "number",
|
|
@@ -13011,7 +13011,7 @@ var require_http = __commonJS((exports, module) => {
|
|
|
13011
13011
|
}
|
|
13012
13012
|
},
|
|
13013
13013
|
{
|
|
13014
|
-
begin: "(?=^[A-Z]+ (.*?) " +
|
|
13014
|
+
begin: "(?=^[A-Z]+ (.*?) " + VERSION2 + "$)",
|
|
13015
13015
|
end: /$/,
|
|
13016
13016
|
contains: [
|
|
13017
13017
|
{
|
|
@@ -13023,7 +13023,7 @@ var require_http = __commonJS((exports, module) => {
|
|
|
13023
13023
|
},
|
|
13024
13024
|
{
|
|
13025
13025
|
className: "meta",
|
|
13026
|
-
begin:
|
|
13026
|
+
begin: VERSION2
|
|
13027
13027
|
},
|
|
13028
13028
|
{
|
|
13029
13029
|
className: "keyword",
|
|
@@ -43028,7 +43028,45 @@ class FrontendWebSocket {
|
|
|
43028
43028
|
|
|
43029
43029
|
// src/args.ts
|
|
43030
43030
|
import { parseArgs } from "util";
|
|
43031
|
+
// package.json
|
|
43032
|
+
var package_default = {
|
|
43033
|
+
name: "@todoforai/cli",
|
|
43034
|
+
version: "0.1.3",
|
|
43035
|
+
type: "module",
|
|
43036
|
+
bin: {
|
|
43037
|
+
todoai: "dist/todoai.js"
|
|
43038
|
+
},
|
|
43039
|
+
files: ["dist/todoai.js"],
|
|
43040
|
+
scripts: {
|
|
43041
|
+
build: "bun build src/index.ts --target=bun --outfile dist/todoai.js --external ws",
|
|
43042
|
+
prepublishOnly: "bun run build",
|
|
43043
|
+
start: "bun run src/index.ts",
|
|
43044
|
+
dev: "bun run src/index.ts",
|
|
43045
|
+
postinstall: "rm -rf node_modules/@todoforai/edge && ln -s ../../../edge/bun node_modules/@todoforai/edge"
|
|
43046
|
+
},
|
|
43047
|
+
dependencies: {
|
|
43048
|
+
"cli-highlight": "^2.1.11",
|
|
43049
|
+
"diff-match-patch": "^1.0.5",
|
|
43050
|
+
ws: "^8.18.0"
|
|
43051
|
+
},
|
|
43052
|
+
peerDependencies: {
|
|
43053
|
+
"@todoforai/edge": "file:../edge/bun"
|
|
43054
|
+
},
|
|
43055
|
+
peerDependenciesMeta: {
|
|
43056
|
+
"@todoforai/edge": {
|
|
43057
|
+
optional: true
|
|
43058
|
+
}
|
|
43059
|
+
},
|
|
43060
|
+
devDependencies: {
|
|
43061
|
+
"@types/ws": "^8.5.13",
|
|
43062
|
+
"@todoforai/edge": "file:../edge/bun",
|
|
43063
|
+
typescript: "^5.7.0"
|
|
43064
|
+
}
|
|
43065
|
+
};
|
|
43066
|
+
|
|
43067
|
+
// src/args.ts
|
|
43031
43068
|
var DEFAULT_API_URL = "https://api.todofor.ai";
|
|
43069
|
+
var VERSION = package_default.version;
|
|
43032
43070
|
function getEnv(name) {
|
|
43033
43071
|
return process.env[`TODOFORAI_${name}`] || process.env[`TODO4AI_${name}`] || "";
|
|
43034
43072
|
}
|
|
@@ -43069,8 +43107,8 @@ Options:
|
|
|
43069
43107
|
--safe Validate API key upfront
|
|
43070
43108
|
--debug, -d Debug output
|
|
43071
43109
|
--show-config Show config
|
|
43072
|
-
--set-default-api-url Set default API URL
|
|
43073
43110
|
--reset-config Reset config file
|
|
43111
|
+
--version, -v Print version and exit
|
|
43074
43112
|
--help, -h Show this help
|
|
43075
43113
|
`);
|
|
43076
43114
|
}
|
|
@@ -43098,10 +43136,10 @@ function parseCliArgs() {
|
|
|
43098
43136
|
safe: { type: "boolean", default: false },
|
|
43099
43137
|
debug: { type: "boolean", short: "d", default: false },
|
|
43100
43138
|
"show-config": { type: "boolean", default: false },
|
|
43101
|
-
"set-default-api-url": { type: "string" },
|
|
43102
43139
|
"reset-config": { type: "boolean", default: false },
|
|
43103
43140
|
"config-path": { type: "string" },
|
|
43104
|
-
help: { type: "boolean", short: "h", default: false }
|
|
43141
|
+
help: { type: "boolean", short: "h", default: false },
|
|
43142
|
+
version: { type: "boolean", short: "v", default: false }
|
|
43105
43143
|
},
|
|
43106
43144
|
allowPositionals: true,
|
|
43107
43145
|
strict: false
|
|
@@ -43495,20 +43533,50 @@ function getConfigDir() {
|
|
|
43495
43533
|
const xdg = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
43496
43534
|
return join(xdg, "todoai-cli");
|
|
43497
43535
|
}
|
|
43498
|
-
function
|
|
43536
|
+
function defaultScope() {
|
|
43499
43537
|
return {
|
|
43500
43538
|
default_project_id: null,
|
|
43501
43539
|
default_project_name: null,
|
|
43502
43540
|
default_agent_name: null,
|
|
43503
43541
|
default_agent_settings: null,
|
|
43504
43542
|
default_agent_settings_updated_at: null,
|
|
43505
|
-
default_api_url: null,
|
|
43506
43543
|
recent_projects: [],
|
|
43507
43544
|
recent_agents: [],
|
|
43508
|
-
last_todo_id: null
|
|
43509
|
-
|
|
43545
|
+
last_todo_id: null
|
|
43546
|
+
};
|
|
43547
|
+
}
|
|
43548
|
+
function defaultConfig() {
|
|
43549
|
+
return {
|
|
43550
|
+
input_history: [],
|
|
43551
|
+
per_api_url: {}
|
|
43510
43552
|
};
|
|
43511
43553
|
}
|
|
43554
|
+
function migrate(raw) {
|
|
43555
|
+
const cfg = { ...defaultConfig(), ...raw, per_api_url: raw.per_api_url || {} };
|
|
43556
|
+
const legacyKeys = [
|
|
43557
|
+
"default_project_id",
|
|
43558
|
+
"default_project_name",
|
|
43559
|
+
"default_agent_name",
|
|
43560
|
+
"default_agent_settings",
|
|
43561
|
+
"default_agent_settings_updated_at",
|
|
43562
|
+
"recent_projects",
|
|
43563
|
+
"recent_agents",
|
|
43564
|
+
"last_todo_id"
|
|
43565
|
+
];
|
|
43566
|
+
const hasLegacy = legacyKeys.some((k) => raw[k] != null);
|
|
43567
|
+
if (hasLegacy) {
|
|
43568
|
+
const url = raw.default_api_url || "https://api.todofor.ai";
|
|
43569
|
+
const scope = { ...defaultScope(), ...cfg.per_api_url[url] || {} };
|
|
43570
|
+
for (const k of legacyKeys)
|
|
43571
|
+
if (raw[k] != null)
|
|
43572
|
+
scope[k] = raw[k];
|
|
43573
|
+
cfg.per_api_url[url] = scope;
|
|
43574
|
+
}
|
|
43575
|
+
for (const k of legacyKeys)
|
|
43576
|
+
delete cfg[k];
|
|
43577
|
+
delete cfg.default_api_url;
|
|
43578
|
+
return cfg;
|
|
43579
|
+
}
|
|
43512
43580
|
|
|
43513
43581
|
class ConfigStore {
|
|
43514
43582
|
path;
|
|
@@ -43528,7 +43596,13 @@ class ConfigStore {
|
|
|
43528
43596
|
try {
|
|
43529
43597
|
const raw = JSON.parse(readFileSync(this.path, "utf-8"));
|
|
43530
43598
|
delete raw.default_api_key;
|
|
43531
|
-
|
|
43599
|
+
const cfg = migrate(raw);
|
|
43600
|
+
const needsMigration = raw.per_api_url == null;
|
|
43601
|
+
if (needsMigration) {
|
|
43602
|
+
this.data = cfg;
|
|
43603
|
+
this.save();
|
|
43604
|
+
}
|
|
43605
|
+
return cfg;
|
|
43532
43606
|
} catch {
|
|
43533
43607
|
return defaultConfig();
|
|
43534
43608
|
}
|
|
@@ -43539,26 +43613,10 @@ class ConfigStore {
|
|
|
43539
43613
|
writeFileSync(this.path, JSON.stringify(this.data, null, 2), "utf-8");
|
|
43540
43614
|
} catch {}
|
|
43541
43615
|
}
|
|
43542
|
-
|
|
43543
|
-
this.data.
|
|
43544
|
-
|
|
43545
|
-
|
|
43546
|
-
recent.unshift({ id, name: name || id });
|
|
43547
|
-
this.data.recent_projects = recent.slice(0, 10);
|
|
43548
|
-
this.save();
|
|
43549
|
-
}
|
|
43550
|
-
setDefaultAgent(name, settings) {
|
|
43551
|
-
this.data.default_agent_name = name;
|
|
43552
|
-
this.data.default_agent_settings = settings || null;
|
|
43553
|
-
this.data.default_agent_settings_updated_at = new Date().toISOString();
|
|
43554
|
-
const recent = this.data.recent_agents.filter((a) => a !== name);
|
|
43555
|
-
recent.unshift(name);
|
|
43556
|
-
this.data.recent_agents = recent.slice(0, 10);
|
|
43557
|
-
this.save();
|
|
43558
|
-
}
|
|
43559
|
-
setDefaultApiUrl(url) {
|
|
43560
|
-
this.data.default_api_url = url;
|
|
43561
|
-
this.save();
|
|
43616
|
+
scope(apiUrl) {
|
|
43617
|
+
if (!this.data.per_api_url[apiUrl])
|
|
43618
|
+
this.data.per_api_url[apiUrl] = defaultScope();
|
|
43619
|
+
return new ScopedConfig(this, apiUrl);
|
|
43562
43620
|
}
|
|
43563
43621
|
addToHistory(input) {
|
|
43564
43622
|
const trimmed = input.trim();
|
|
@@ -43576,6 +43634,37 @@ class ConfigStore {
|
|
|
43576
43634
|
}
|
|
43577
43635
|
}
|
|
43578
43636
|
|
|
43637
|
+
class ScopedConfig {
|
|
43638
|
+
store;
|
|
43639
|
+
apiUrl;
|
|
43640
|
+
constructor(store, apiUrl) {
|
|
43641
|
+
this.store = store;
|
|
43642
|
+
this.apiUrl = apiUrl;
|
|
43643
|
+
}
|
|
43644
|
+
get data() {
|
|
43645
|
+
return this.store.data.per_api_url[this.apiUrl];
|
|
43646
|
+
}
|
|
43647
|
+
setDefaultProject(id, name) {
|
|
43648
|
+
const s = this.data;
|
|
43649
|
+
s.default_project_id = id;
|
|
43650
|
+
s.default_project_name = name || id;
|
|
43651
|
+
s.recent_projects = [{ id, name: name || id }, ...s.recent_projects.filter((p) => p.id !== id)].slice(0, 10);
|
|
43652
|
+
this.store.save();
|
|
43653
|
+
}
|
|
43654
|
+
setDefaultAgent(name, settings) {
|
|
43655
|
+
const s = this.data;
|
|
43656
|
+
s.default_agent_name = name;
|
|
43657
|
+
s.default_agent_settings = settings || null;
|
|
43658
|
+
s.default_agent_settings_updated_at = new Date().toISOString();
|
|
43659
|
+
s.recent_agents = [name, ...s.recent_agents.filter((a) => a !== name)].slice(0, 10);
|
|
43660
|
+
this.store.save();
|
|
43661
|
+
}
|
|
43662
|
+
setLastTodoId(id) {
|
|
43663
|
+
this.data.last_todo_id = id;
|
|
43664
|
+
this.store.save();
|
|
43665
|
+
}
|
|
43666
|
+
}
|
|
43667
|
+
|
|
43579
43668
|
// src/credentials.ts
|
|
43580
43669
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
43581
43670
|
import { dirname as dirname2, join as join2 } from "path";
|
|
@@ -44955,6 +45044,10 @@ Cancelled by user (Ctrl+C)
|
|
|
44955
45044
|
process.exit(130);
|
|
44956
45045
|
});
|
|
44957
45046
|
const { values: args, positionals } = parseCliArgs();
|
|
45047
|
+
if (args.version) {
|
|
45048
|
+
console.log(VERSION);
|
|
45049
|
+
process.exit(0);
|
|
45050
|
+
}
|
|
44958
45051
|
if (args.help) {
|
|
44959
45052
|
printUsage();
|
|
44960
45053
|
process.exit(0);
|
|
@@ -44974,12 +45067,8 @@ Cancelled by user (Ctrl+C)
|
|
|
44974
45067
|
console.log("No configuration file to reset");
|
|
44975
45068
|
return;
|
|
44976
45069
|
}
|
|
44977
|
-
|
|
44978
|
-
|
|
44979
|
-
console.log(`Default API URL set to: ${args["set-default-api-url"]}`);
|
|
44980
|
-
return;
|
|
44981
|
-
}
|
|
44982
|
-
const apiUrl = normalizeApiUrl(args["api-url"] || cfg.data.default_api_url || getEnv("API_URL") || DEFAULT_API_URL);
|
|
45070
|
+
const apiUrl = normalizeApiUrl(args["api-url"] || getEnv("API_URL") || DEFAULT_API_URL);
|
|
45071
|
+
const cfgScope = cfg.scope(apiUrl);
|
|
44983
45072
|
async function deviceLogin() {
|
|
44984
45073
|
const loginApi = new ApiClient(apiUrl, "");
|
|
44985
45074
|
const { code, url, expiresIn } = await loginApi.initDeviceLogin("cli");
|
|
@@ -45039,8 +45128,6 @@ Cancelled by user (Ctrl+C)
|
|
|
45039
45128
|
apiKey = await deviceLogin();
|
|
45040
45129
|
}
|
|
45041
45130
|
const api = new ApiClient(apiUrl, apiKey);
|
|
45042
|
-
if (!args["no-edge"])
|
|
45043
|
-
ensureEdgeRunning(apiUrl, apiKey);
|
|
45044
45131
|
if (args["list-agents"]) {
|
|
45045
45132
|
await listAgentsCommand(api, { json: !!args.json, formatPath: formatPathWithTilde });
|
|
45046
45133
|
return;
|
|
@@ -45054,6 +45141,8 @@ Cancelled by user (Ctrl+C)
|
|
|
45054
45141
|
if (process.stderr.isTTY)
|
|
45055
45142
|
printLogo();
|
|
45056
45143
|
if (args.template) {
|
|
45144
|
+
if (!args["no-edge"] && !args["no-watch"])
|
|
45145
|
+
ensureEdgeRunning(apiUrl, apiKey);
|
|
45057
45146
|
const templateId = args.template;
|
|
45058
45147
|
const inputValues = {};
|
|
45059
45148
|
for (const kv of args.input || []) {
|
|
@@ -45088,7 +45177,7 @@ Cancelled by user (Ctrl+C)
|
|
|
45088
45177
|
const projects2 = await api.listProjects();
|
|
45089
45178
|
let projectId2 = args.project;
|
|
45090
45179
|
if (!projectId2) {
|
|
45091
|
-
projectId2 =
|
|
45180
|
+
projectId2 = cfgScope.data.default_project_id || projects2.find((p) => p.project?.isDefault)?.project?.id || projects2[0]?.project?.id;
|
|
45092
45181
|
}
|
|
45093
45182
|
if (!projectId2) {
|
|
45094
45183
|
process.stderr.write(`Error: No project found
|
|
@@ -45097,8 +45186,7 @@ Cancelled by user (Ctrl+C)
|
|
|
45097
45186
|
}
|
|
45098
45187
|
const todo2 = await api.startFromTemplate(projectId2, templateId, { inputValues });
|
|
45099
45188
|
const todoId = todo2.id;
|
|
45100
|
-
|
|
45101
|
-
cfg.save();
|
|
45189
|
+
cfgScope.setLastTodoId(todoId);
|
|
45102
45190
|
const frontendUrl2 = getFrontendUrl(apiUrl, projectId2, todoId);
|
|
45103
45191
|
if (args.json) {
|
|
45104
45192
|
console.log(JSON.stringify({ ...todo2, frontend_url: frontendUrl2 }, null, 2));
|
|
@@ -45141,7 +45229,9 @@ ${"\u2500".repeat(40)}
|
|
|
45141
45229
|
`);
|
|
45142
45230
|
}
|
|
45143
45231
|
if (args.resume || args.continue) {
|
|
45144
|
-
|
|
45232
|
+
if (!args["no-edge"])
|
|
45233
|
+
ensureEdgeRunning(apiUrl, apiKey);
|
|
45234
|
+
const todoId = args.resume || cfgScope.data.last_todo_id;
|
|
45145
45235
|
if (!todoId) {
|
|
45146
45236
|
process.stderr.write(`Error: No recent todo found
|
|
45147
45237
|
`);
|
|
@@ -45176,20 +45266,20 @@ Resumed todo: ${todoId}
|
|
|
45176
45266
|
`);
|
|
45177
45267
|
process.exit(1);
|
|
45178
45268
|
}
|
|
45179
|
-
|
|
45269
|
+
cfgScope.setDefaultAgent(getDisplayName(preMatchedAgent), preMatchedAgent);
|
|
45180
45270
|
} else {
|
|
45181
45271
|
const pathArg = args.path || ".";
|
|
45182
45272
|
const resolved = realpathSync(resolve3(pathArg));
|
|
45183
45273
|
const matches = await api.listAgentSettings({ workspacePath: resolved });
|
|
45184
45274
|
if (matches.length > 0) {
|
|
45185
45275
|
preMatchedAgent = matches[0];
|
|
45186
|
-
|
|
45276
|
+
cfgScope.setDefaultAgent(getDisplayName(preMatchedAgent), preMatchedAgent);
|
|
45187
45277
|
} else if (args.path) {
|
|
45188
45278
|
process.stderr.write(`No agent found for '${formatPathWithTilde(resolved)}', creating one...
|
|
45189
45279
|
`);
|
|
45190
45280
|
try {
|
|
45191
45281
|
preMatchedAgent = await autoCreateAgent(api, resolved);
|
|
45192
|
-
|
|
45282
|
+
cfgScope.setDefaultAgent(getDisplayName(preMatchedAgent), preMatchedAgent);
|
|
45193
45283
|
} catch (e) {
|
|
45194
45284
|
process.stderr.write(`Error: Failed to auto-create agent: ${e.message}
|
|
45195
45285
|
`);
|
|
@@ -45208,14 +45298,16 @@ Resumed todo: ${todoId}
|
|
|
45208
45298
|
}
|
|
45209
45299
|
process.stderr.write(`${DIM}Tip: ${randomTip()}${RESET}
|
|
45210
45300
|
`);
|
|
45301
|
+
if (!args["no-edge"] && !args["no-watch"])
|
|
45302
|
+
ensureEdgeRunning(apiUrl, apiKey);
|
|
45211
45303
|
let content;
|
|
45212
45304
|
if (positionals.length > 0) {
|
|
45213
45305
|
content = positionals.join(" ");
|
|
45214
45306
|
} else {
|
|
45215
45307
|
content = await readStdin();
|
|
45216
45308
|
}
|
|
45217
|
-
const hasProject = args.project ||
|
|
45218
|
-
const storedAgent =
|
|
45309
|
+
const hasProject = args.project || cfgScope.data.default_project_id;
|
|
45310
|
+
const storedAgent = cfgScope.data.default_agent_settings;
|
|
45219
45311
|
const hasAgent = preMatchedAgent || storedAgent?.id && !args.agent;
|
|
45220
45312
|
let projects = null;
|
|
45221
45313
|
if (!hasProject || !hasAgent || args.safe || args.debug) {
|
|
@@ -45233,11 +45325,11 @@ Resumed todo: ${todoId}
|
|
|
45233
45325
|
if (match)
|
|
45234
45326
|
projectName = getDisplayName(match);
|
|
45235
45327
|
}
|
|
45236
|
-
} else if (
|
|
45237
|
-
projectId =
|
|
45238
|
-
projectName =
|
|
45328
|
+
} else if (cfgScope.data.default_project_id && !projects) {
|
|
45329
|
+
projectId = cfgScope.data.default_project_id;
|
|
45330
|
+
projectName = cfgScope.data.default_project_name || projectId;
|
|
45239
45331
|
} else {
|
|
45240
|
-
const sel = await selectProject(projects,
|
|
45332
|
+
const sel = await selectProject(projects, cfgScope.data.default_project_id, (id, name) => cfgScope.setDefaultProject(id, name));
|
|
45241
45333
|
projectId = sel.id;
|
|
45242
45334
|
projectName = sel.name;
|
|
45243
45335
|
}
|
|
@@ -45247,7 +45339,7 @@ Resumed todo: ${todoId}
|
|
|
45247
45339
|
} else if (storedAgent?.id && !agents) {
|
|
45248
45340
|
agent = storedAgent;
|
|
45249
45341
|
} else {
|
|
45250
|
-
agent = await selectAgent(agents,
|
|
45342
|
+
agent = await selectAgent(agents, cfgScope.data.default_agent_name, (name, settings) => cfgScope.setDefaultAgent(name, settings));
|
|
45251
45343
|
}
|
|
45252
45344
|
const ws = args["no-watch"] ? null : new FrontendWebSocket(apiUrl, apiKey);
|
|
45253
45345
|
if (ws)
|
|
@@ -45261,8 +45353,7 @@ Resumed todo: ${todoId}
|
|
|
45261
45353
|
cfg.addToHistory(content);
|
|
45262
45354
|
const todo = await api.addMessage(projectId, content, agent);
|
|
45263
45355
|
const actualTodoId = todo.id || crypto.randomUUID();
|
|
45264
|
-
|
|
45265
|
-
cfg.save();
|
|
45356
|
+
cfgScope.setLastTodoId(actualTodoId);
|
|
45266
45357
|
const frontendUrl = getFrontendUrl(apiUrl, projectId, actualTodoId);
|
|
45267
45358
|
if (args.json) {
|
|
45268
45359
|
console.log(JSON.stringify({ ...todo, frontend_url: frontendUrl }, null, 2));
|