@todos-dev/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/dist/index.js +35 -113
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -481,16 +481,13 @@ function text(s, details) {
|
|
|
481
481
|
return { content: [{ type: "text", text: s }], details };
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
-
// src/lib/
|
|
484
|
+
// src/lib/remoteTools.ts
|
|
485
485
|
var REQUEST_TIMEOUT_MS = 1e4;
|
|
486
|
-
|
|
487
|
-
async function request(serverUrl, method, path, token, body) {
|
|
488
|
-
const headers = { "Content-Type": "application/json" };
|
|
489
|
-
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
486
|
+
async function request(serverUrl, path, token, body) {
|
|
490
487
|
const res = await fetch(`${serverUrl}${path}`, {
|
|
491
|
-
method,
|
|
492
|
-
headers,
|
|
493
|
-
|
|
488
|
+
method: "POST",
|
|
489
|
+
headers: { "Content-Type": "application/json", ...token ? { Authorization: `Bearer ${token}` } : {} },
|
|
490
|
+
body: JSON.stringify(body),
|
|
494
491
|
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
495
492
|
});
|
|
496
493
|
const json2 = await res.json().catch(() => null);
|
|
@@ -499,108 +496,21 @@ async function request(serverUrl, method, path, token, body) {
|
|
|
499
496
|
function text2(s) {
|
|
500
497
|
return { content: [{ type: "text", text: s }], details: {} };
|
|
501
498
|
}
|
|
502
|
-
function
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
makeListTodosTool(serverUrl, token, step),
|
|
509
|
-
makeCreateTodoTool(serverUrl, token, step),
|
|
510
|
-
makeUpdateTodoTool(serverUrl, token, step)
|
|
511
|
-
];
|
|
512
|
-
}
|
|
513
|
-
function makeListTodosTool(serverUrl, token, step) {
|
|
514
|
-
const projectId = step.workspace?.projectId;
|
|
515
|
-
return {
|
|
516
|
-
name: "list_todos",
|
|
517
|
-
label: "List Todos",
|
|
518
|
-
description: `List the todos in this project so you can see existing/related work and find a todo to update. The first line lists the project's tags with their ids (usable as update_todo's tagIds). Returns each todo as "#<seq> [<phase>] <title> (id: <id>) [tags: \u2026]"; todos you created are marked (yours).`,
|
|
519
|
-
parameters: { type: "object", properties: {}, required: [], additionalProperties: false },
|
|
520
|
-
async execute() {
|
|
521
|
-
if (!projectId) return text2("No project context for this turn \u2014 todos are unavailable.");
|
|
522
|
-
const [reply, tagsReply] = await Promise.all([
|
|
523
|
-
request(serverUrl, "GET", `/api/projects/${projectId}/todos`, token),
|
|
524
|
-
request(serverUrl, "GET", `/api/projects/${projectId}/tags`, token)
|
|
525
|
-
]);
|
|
526
|
-
if (!reply.ok) return text2(errorText(reply, "Failed to list todos"));
|
|
527
|
-
const todos = reply.body ?? [];
|
|
528
|
-
if (!todos.length) return text2("No todos in this project yet.");
|
|
529
|
-
const tags = tagsReply.ok ? tagsReply.body ?? [] : [];
|
|
530
|
-
const tagName = new Map(tags.map((t) => [t.id, t.name]));
|
|
531
|
-
const header = tags.length ? `Project tags: ${tags.map((t) => `${t.name} (id: ${t.id})`).join(", ")}
|
|
532
|
-
` : "";
|
|
533
|
-
const lines = todos.map((t) => {
|
|
534
|
-
const mine = t.createdBy === step.agent.agentId ? " (yours)" : "";
|
|
535
|
-
const names = (t.tagIds ?? []).map((id) => tagName.get(id)).filter(Boolean);
|
|
536
|
-
const tagsStr = names.length ? ` [tags: ${names.join(", ")}]` : "";
|
|
537
|
-
return `#${t.seqNum} [${t.phase}] ${t.title} (id: ${t.id})${tagsStr}${mine}`;
|
|
538
|
-
});
|
|
539
|
-
let out = header + lines.join("\n");
|
|
540
|
-
if (out.length > LIST_CAP) out = out.slice(0, LIST_CAP) + "\n\u2026(truncated)";
|
|
541
|
-
return text2(out);
|
|
542
|
-
}
|
|
543
|
-
};
|
|
544
|
-
}
|
|
545
|
-
function makeCreateTodoTool(serverUrl, token, step) {
|
|
546
|
-
const projectId = step.workspace?.projectId;
|
|
547
|
-
return {
|
|
548
|
-
name: "create_todo",
|
|
549
|
-
label: "Create Todo",
|
|
550
|
-
description: "Create a follow-up todo for work you discovered but that is out of scope for the current task (e.g. a refactor, a separate bug, a next step). The new todo is added to the project backlog and does NOT run automatically \u2014 the user decides when to start it. Use a clear, actionable title and put the context/acceptance criteria in spec.",
|
|
551
|
-
parameters: {
|
|
552
|
-
type: "object",
|
|
553
|
-
properties: {
|
|
554
|
-
title: { type: "string", description: "Short, actionable title for the follow-up work." },
|
|
555
|
-
spec: { type: "string", description: "Details: what to do, why, and any acceptance criteria. Optional but recommended." }
|
|
556
|
-
},
|
|
557
|
-
required: ["title"],
|
|
558
|
-
additionalProperties: false
|
|
559
|
-
},
|
|
560
|
-
async execute(_id, params) {
|
|
561
|
-
if (!projectId) return text2("No project context for this turn \u2014 cannot create a todo.");
|
|
562
|
-
const p = params ?? {};
|
|
563
|
-
if (!p.title?.trim()) return text2("A title is required to create a todo.");
|
|
564
|
-
const reply = await request(serverUrl, "POST", `/api/projects/${projectId}/todos`, token, {
|
|
565
|
-
title: p.title,
|
|
566
|
-
spec: p.spec ?? "",
|
|
567
|
-
buildId: step.conversationId
|
|
568
|
-
});
|
|
569
|
-
if (!reply.ok) return text2(errorText(reply, "Failed to create todo"));
|
|
570
|
-
const t = reply.body;
|
|
571
|
-
return text2(`Created todo #${t.seqNum} "${t.title}". It is in the backlog and will not run until the user starts it.`);
|
|
572
|
-
}
|
|
573
|
-
};
|
|
574
|
-
}
|
|
575
|
-
function makeUpdateTodoTool(serverUrl, token, step) {
|
|
576
|
-
return {
|
|
577
|
-
name: "update_todo",
|
|
578
|
-
label: "Update Todo",
|
|
579
|
-
description: `Update a todo YOU created (only your own \u2014 found via list_todos, marked "(yours)"). You can change its title, spec, or tags (tag ids come from the "Project tags" line of list_todos). Use this to refine a follow-up todo as you learn more. You cannot edit todos created by others or the user, change a todo's phase, or start a build.`,
|
|
580
|
-
parameters: {
|
|
581
|
-
type: "object",
|
|
582
|
-
properties: {
|
|
583
|
-
id: { type: "string", description: "The id of the todo to update (from list_todos)." },
|
|
584
|
-
title: { type: "string", description: "New title (optional)." },
|
|
585
|
-
spec: { type: "string", description: "New spec/description (optional)." },
|
|
586
|
-
tagIds: { type: "array", items: { type: "string" }, description: `Replacement tag id list; ids come from list_todos's "Project tags" line (optional).` }
|
|
587
|
-
},
|
|
588
|
-
required: ["id"],
|
|
589
|
-
additionalProperties: false
|
|
590
|
-
},
|
|
499
|
+
function makeRemoteTools(serverUrl, token, step) {
|
|
500
|
+
return (step.remoteTools ?? []).map((def) => ({
|
|
501
|
+
name: def.name,
|
|
502
|
+
label: def.label,
|
|
503
|
+
description: def.description,
|
|
504
|
+
parameters: def.parameters,
|
|
591
505
|
async execute(_id, params) {
|
|
592
|
-
const
|
|
593
|
-
if (!
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
const reply = await request(serverUrl, "PATCH", `/api/todos/${p.id}`, token, patch);
|
|
599
|
-
if (!reply.ok) return text2(errorText(reply, "Failed to update todo"));
|
|
600
|
-
const t = reply.body;
|
|
601
|
-
return text2(`Updated todo #${t.seqNum} "${t.title}".`);
|
|
506
|
+
const reply = await request(serverUrl, `/api/machine/tool/${step.stepId}`, token, { name: def.name, params });
|
|
507
|
+
if (!reply.ok) {
|
|
508
|
+
const msg = reply.body?.error;
|
|
509
|
+
return text2(typeof msg === "string" ? msg : `${def.name} failed (HTTP ${reply.status}).`);
|
|
510
|
+
}
|
|
511
|
+
return text2(typeof reply.body?.text === "string" ? reply.body.text : "");
|
|
602
512
|
}
|
|
603
|
-
};
|
|
513
|
+
}));
|
|
604
514
|
}
|
|
605
515
|
|
|
606
516
|
// src/lib/sessionStore.ts
|
|
@@ -1212,7 +1122,7 @@ async function executeStep(step, serverUrl, token, tunnel) {
|
|
|
1212
1122
|
const skills = await materializeSkills(step.skills, agentDir);
|
|
1213
1123
|
const extraCustomTools = [
|
|
1214
1124
|
makeClientShellTool(tunnel, conversationId, runnersRef),
|
|
1215
|
-
...
|
|
1125
|
+
...makeRemoteTools(serverUrl, token, step)
|
|
1216
1126
|
];
|
|
1217
1127
|
const session = await createSession(sdk, {
|
|
1218
1128
|
authStorage,
|
|
@@ -1220,7 +1130,7 @@ async function executeStep(step, serverUrl, token, tunnel) {
|
|
|
1220
1130
|
model,
|
|
1221
1131
|
cwd,
|
|
1222
1132
|
agentDir,
|
|
1223
|
-
tools: step.tools,
|
|
1133
|
+
tools: [...step.tools, ...(step.remoteTools ?? []).map((t) => t.name)],
|
|
1224
1134
|
sessionManager: m.sessionManager,
|
|
1225
1135
|
thinkingLevel: step.agent.thinkingLevel ?? "",
|
|
1226
1136
|
webSearch: true,
|
|
@@ -16031,7 +15941,8 @@ var STEP_DEF = {
|
|
|
16031
15941
|
implement_revision: { track: "implement", sink: "chat", phase: { busy: "building", rest: "review", notify: "build_review" } },
|
|
16032
15942
|
merge: { track: "implement", sink: "chat", phase: { busy: "building", rest: "review", notify: "build_review" } },
|
|
16033
15943
|
plan_review: { track: "plan", sink: "review" },
|
|
16034
|
-
implement_review: { track: "implement", sink: "review" }
|
|
15944
|
+
implement_review: { track: "implement", sink: "review" },
|
|
15945
|
+
chief: { sink: "chief" }
|
|
16035
15946
|
};
|
|
16036
15947
|
var isReviewStep = (k) => STEP_DEF[k].sink === "review";
|
|
16037
15948
|
var REVIEW_STEP_KINDS = Object.keys(STEP_DEF).filter(isReviewStep);
|
|
@@ -16106,8 +16017,19 @@ var UpdateTodoRequestSchema = external_exports.object({
|
|
|
16106
16017
|
orderIndex: external_exports.number().optional(),
|
|
16107
16018
|
assignment: AgentAssignmentSchema.nullable().optional()
|
|
16108
16019
|
});
|
|
16109
|
-
var
|
|
16110
|
-
|
|
16020
|
+
var UpdateChiefRequestSchema = external_exports.object({
|
|
16021
|
+
agent: AgentEntrySchema.nullable().optional(),
|
|
16022
|
+
charter: external_exports.string().optional()
|
|
16023
|
+
});
|
|
16024
|
+
var ChiefStepRequestSchema = external_exports.object({
|
|
16025
|
+
content: external_exports.string().trim().min(1)
|
|
16026
|
+
});
|
|
16027
|
+
var DispatchItemSchema = external_exports.object({
|
|
16028
|
+
todoId: external_exports.string().min(1),
|
|
16029
|
+
withPlan: external_exports.boolean().optional(),
|
|
16030
|
+
agent: AgentEntrySchema.optional(),
|
|
16031
|
+
reason: external_exports.string().optional()
|
|
16032
|
+
});
|
|
16111
16033
|
var TriggerBuildRequestSchema = external_exports.object({
|
|
16112
16034
|
todoIds: external_exports.array(external_exports.string()).min(1),
|
|
16113
16035
|
// One-time assignment override; falls back to todo.assignment. Server enriches model.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@todos-dev/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"bin": {
|
|
5
5
|
"tds": "dist/index.js"
|
|
6
6
|
},
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"@tds/types": "0.1.0"
|
|
28
28
|
},
|
|
29
29
|
"optionalDependencies": {
|
|
30
|
-
"@todos-dev/cli-darwin-arm64": "0.1.
|
|
31
|
-
"@todos-dev/cli-darwin-x64": "0.1.
|
|
32
|
-
"@todos-dev/cli-linux-x64": "0.1.
|
|
33
|
-
"@todos-dev/cli-linux-arm64": "0.1.
|
|
34
|
-
"@todos-dev/cli-win32-x64": "0.1.
|
|
35
|
-
"@todos-dev/cli-win32-arm64": "0.1.
|
|
30
|
+
"@todos-dev/cli-darwin-arm64": "0.1.6",
|
|
31
|
+
"@todos-dev/cli-darwin-x64": "0.1.6",
|
|
32
|
+
"@todos-dev/cli-linux-x64": "0.1.6",
|
|
33
|
+
"@todos-dev/cli-linux-arm64": "0.1.6",
|
|
34
|
+
"@todos-dev/cli-win32-x64": "0.1.6",
|
|
35
|
+
"@todos-dev/cli-win32-arm64": "0.1.6"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"dev": "tsx watch src/index.ts",
|