@runuai/host 0.6.0 → 0.7.0
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/lib/agent-cli.ts +31 -0
- package/lib/agents/transport.ts +18 -1
- package/lib/orchestrator.ts +15 -0
- package/package.json +1 -1
package/lib/agent-cli.ts
CHANGED
|
@@ -211,6 +211,34 @@ async function main() {
|
|
|
211
211
|
})).task);
|
|
212
212
|
break;
|
|
213
213
|
}
|
|
214
|
+
case "todo list": {
|
|
215
|
+
const todos = (await api("GET", "/api/agent/todos")).todos || [];
|
|
216
|
+
if (!todos.length) { out("punchlist is empty"); break; }
|
|
217
|
+
const done = todos.filter((t) => t.status === "done").length;
|
|
218
|
+
const lines = todos.map((t) => {
|
|
219
|
+
const box = t.status === "done" ? "[x]" : t.claimedBy ? "[~]" : "[ ]";
|
|
220
|
+
const who = t.status === "done"
|
|
221
|
+
? (t.claimedBy ? " — done by @" + t.claimedBy : " — done")
|
|
222
|
+
: t.claimedBy ? " — @" + t.claimedBy + " working" : "";
|
|
223
|
+
return " #" + t.shortId + " " + box + " " + t.text + who;
|
|
224
|
+
});
|
|
225
|
+
out("Punchlist (" + done + "/" + todos.length + " done):\\n" + lines.join("\\n"));
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
case "todo add": {
|
|
229
|
+
const text = pos.join(" ") || flags.text || "";
|
|
230
|
+
if (!text) { console.error("uai: todo add needs text"); process.exit(1); }
|
|
231
|
+
const t = (await api("POST", "/api/agent/todos", { op: "add", text })).todo;
|
|
232
|
+
out("added #" + t.shortId + ": " + t.text);
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
case "todo claim": case "todo done": case "todo reopen": case "todo unclaim": {
|
|
236
|
+
const ref = pos[0] || flags.id;
|
|
237
|
+
if (!ref) { console.error("uai: todo " + action + " needs an item id (see 'uai todo list')"); process.exit(1); }
|
|
238
|
+
const t = (await api("POST", "/api/agent/todos", { op: action, ref })).todo;
|
|
239
|
+
out(action + " #" + t.shortId + ": " + t.text);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
214
242
|
case "whoami ": case "whoami undefined": out({ apiUrl: API_URL }); break;
|
|
215
243
|
case "react heart": case "react check": case "react x": {
|
|
216
244
|
const r = await api("POST", "/api/agent/react", { emoji: action, msg: flags.msg || undefined });
|
|
@@ -227,6 +255,9 @@ async function main() {
|
|
|
227
255
|
" uai memory search <query>",
|
|
228
256
|
" uai memory save <text> [--project id] [--tags a,b]",
|
|
229
257
|
" uai memory delete <id>",
|
|
258
|
+
" uai todo list",
|
|
259
|
+
" uai todo add <text>",
|
|
260
|
+
" uai todo claim|done|reopen|unclaim <#id>",
|
|
230
261
|
" uai react <heart|check|x> [--msg #id] (no --msg = the message you were last handed)",
|
|
231
262
|
" uai whoami",
|
|
232
263
|
].join("\\n"));
|
package/lib/agents/transport.ts
CHANGED
|
@@ -155,7 +155,24 @@ export function createAgentTransport(opts: AgentTransportOptions): LineTransport
|
|
|
155
155
|
// before this feature (the workspace is mounted at its host path) and
|
|
156
156
|
// never skews against the host version.
|
|
157
157
|
const runnerInSession = join(sessionDir, "runner.mjs");
|
|
158
|
-
|
|
158
|
+
try {
|
|
159
|
+
copyFileSync(runnerScriptPath(), runnerInSession);
|
|
160
|
+
} catch (err) {
|
|
161
|
+
// Runner asset missing (a packaging miss — the 0.3.0/0.3.1 desktop
|
|
162
|
+
// builds vendored the agent without runner/). Degrade to legacy pipes:
|
|
163
|
+
// sessions work, they just don't survive host restarts.
|
|
164
|
+
console.warn(
|
|
165
|
+
`[transport] runner unavailable (${err instanceof Error ? err.message : err}) — falling back to direct pipes for ${opts.agentId}`,
|
|
166
|
+
);
|
|
167
|
+
const { command, args } = dockerExecArgs(
|
|
168
|
+
opts.containerName,
|
|
169
|
+
opts.cli,
|
|
170
|
+
opts.cliArgs,
|
|
171
|
+
opts.passEnv ?? [],
|
|
172
|
+
opts.explicitEnv ?? {},
|
|
173
|
+
);
|
|
174
|
+
return new LineProcess({ command, args, debugLabel: opts.debugLabel });
|
|
175
|
+
}
|
|
159
176
|
|
|
160
177
|
const envArgs: string[] = [];
|
|
161
178
|
for (const name of opts.passEnv ?? []) {
|
package/lib/orchestrator.ts
CHANGED
|
@@ -1227,6 +1227,9 @@ export function buildSystemPreamble(
|
|
|
1227
1227
|
(agent.permissions?.includes("memory.read")
|
|
1228
1228
|
? ", `memory search <query>`"
|
|
1229
1229
|
: "") +
|
|
1230
|
+
(agent.permissions?.includes("todo.write")
|
|
1231
|
+
? ", `todo list|add|claim|done`"
|
|
1232
|
+
: "") +
|
|
1230
1233
|
", `react <heart|check|x> [--msg #id]`.",
|
|
1231
1234
|
"**Reacting:** `uai react check` is a lightweight ack of the message",
|
|
1232
1235
|
"you were last handed — use it to acknowledge an instruction or",
|
|
@@ -1256,6 +1259,18 @@ export function buildSystemPreamble(
|
|
|
1256
1259
|
"— delete + save a corrected one).",
|
|
1257
1260
|
]
|
|
1258
1261
|
: []),
|
|
1262
|
+
...(agent.permissions?.includes("todo.write")
|
|
1263
|
+
? [
|
|
1264
|
+
"**Punchlist (ADR-063):** this task has a shared checklist —",
|
|
1265
|
+
`\`node ${CONTAINER_CLI_PATH} todo list\` shows every item, its`,
|
|
1266
|
+
"status, and who's on it. When you and your peers split a task",
|
|
1267
|
+
"into pieces, put them on the punchlist (`todo add <text>`), then",
|
|
1268
|
+
"**`todo claim <#id>` BEFORE you start** an item so two agents",
|
|
1269
|
+
"don't do the same work — and `todo done <#id>` when it's",
|
|
1270
|
+
"complete. Check `todo list` before picking up work. The human",
|
|
1271
|
+
"watches the same list in the task UI.",
|
|
1272
|
+
]
|
|
1273
|
+
: []),
|
|
1259
1274
|
"",
|
|
1260
1275
|
]
|
|
1261
1276
|
: []),
|
package/package.json
CHANGED